From b56363ba319f0be594a9f2bec5f85359e58c9c9d Mon Sep 17 00:00:00 2001 From: MobiusDev <8391001+MobiusDevelopment@users.noreply.github.com> Date: Sun, 19 Jun 2016 21:37:49 +0000 Subject: [PATCH] Skill enchant related work in progress. --- trunk/dist/game/data/EnchantItemGroups.xml | 3 + trunk/dist/game/data/EnchantItemOptions.xml | 242 +++++++- trunk/dist/game/data/EnchantSkillGroups.xml | 284 ++++++---- trunk/dist/game/data/xsd/EnchantItemData.xsd | 58 +- .../dist/game/data/xsd/EnchantSkillGroups.xsd | 65 +++ .../data/xml/impl/EnchantSkillGroupsData.java | 25 +- .../gameserver/data/xml/impl/SkillData.java | 17 +- .../data/xml/impl/SkillTreesData.java | 12 + .../clientpackets/RequestExEnchantSkill.java | 529 ++++++++++++++---- .../RequestExEnchantSkillInfo.java | 13 +- .../RequestExEnchantSkillInfoDetail.java | 20 +- .../serverpackets/ExEnchantSkillInfo.java | 40 +- .../ExEnchantSkillInfoDetail.java | 129 ++++- .../serverpackets/ExEnchantSkillList.java | 34 +- 14 files changed, 1200 insertions(+), 271 deletions(-) diff --git a/trunk/dist/game/data/EnchantItemGroups.xml b/trunk/dist/game/data/EnchantItemGroups.xml index 11cc247d4a..f876bd2ed1 100644 --- a/trunk/dist/game/data/EnchantItemGroups.xml +++ b/trunk/dist/game/data/EnchantItemGroups.xml @@ -51,6 +51,9 @@ + + + diff --git a/trunk/dist/game/data/EnchantItemOptions.xml b/trunk/dist/game/data/EnchantItemOptions.xml index b307369579..493fc6cc72 100644 --- a/trunk/dist/game/data/EnchantItemOptions.xml +++ b/trunk/dist/game/data/EnchantItemOptions.xml @@ -1113,7 +1113,7 @@ - + @@ -1126,7 +1126,98 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1139,4 +1230,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/dist/game/data/EnchantSkillGroups.xml b/trunk/dist/game/data/EnchantSkillGroups.xml index 7c0300c363..c9e955a0c4 100644 --- a/trunk/dist/game/data/EnchantSkillGroups.xml +++ b/trunk/dist/game/data/EnchantSkillGroups.xml @@ -2,118 +2,202 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/dist/game/data/xsd/EnchantItemData.xsd b/trunk/dist/game/data/xsd/EnchantItemData.xsd index a91741a716..a89c119d89 100644 --- a/trunk/dist/game/data/xsd/EnchantItemData.xsd +++ b/trunk/dist/game/data/xsd/EnchantItemData.xsd @@ -19,6 +19,14 @@ + + + + + + + + @@ -27,6 +35,22 @@ + + + + + + + + + + + + + + + + @@ -53,6 +77,14 @@ + + + + + + + + @@ -61,7 +93,30 @@ - + + + + + + + + + + + + + + + + + + + + + + + + @@ -70,6 +125,7 @@ + diff --git a/trunk/dist/game/data/xsd/EnchantSkillGroups.xsd b/trunk/dist/game/data/xsd/EnchantSkillGroups.xsd index 2f7ff237e7..1761bfcf63 100644 --- a/trunk/dist/game/data/xsd/EnchantSkillGroups.xsd +++ b/trunk/dist/game/data/xsd/EnchantSkillGroups.xsd @@ -203,6 +203,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -226,6 +290,7 @@ + diff --git a/trunk/java/com/l2jmobius/gameserver/data/xml/impl/EnchantSkillGroupsData.java b/trunk/java/com/l2jmobius/gameserver/data/xml/impl/EnchantSkillGroupsData.java index 5259e58297..c7c0d87e7e 100644 --- a/trunk/java/com/l2jmobius/gameserver/data/xml/impl/EnchantSkillGroupsData.java +++ b/trunk/java/com/l2jmobius/gameserver/data/xml/impl/EnchantSkillGroupsData.java @@ -25,6 +25,7 @@ import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; +import com.l2jmobius.Config; import com.l2jmobius.commons.util.IGameXmlReader; import com.l2jmobius.gameserver.model.L2EnchantSkillGroup; import com.l2jmobius.gameserver.model.L2EnchantSkillGroup.EnchantSkillHolder; @@ -41,10 +42,26 @@ public class EnchantSkillGroupsData implements IGameXmlReader { private static final Logger LOGGER = Logger.getLogger(EnchantSkillGroupsData.class.getName()); - public static final int NORMAL_ENCHANT_BOOK = 6622; - public static final int SAFE_ENCHANT_BOOK = 9627; - public static final int CHANGE_ENCHANT_BOOK = 9626; - public static final int UNTRAIN_ENCHANT_BOOK = 9625; + public static final int NORMAL_ENCHANT_COST_MULTIPLIER = Config.NORMAL_ENCHANT_COST_MULTIPLIER; + public static final int SAFE_ENCHANT_COST_MULTIPLIER = Config.SAFE_ENCHANT_COST_MULTIPLIER; + + public static final int NORMAL_ENCHANT_BOOK_OLD = 6622; + public static final int SAFE_ENCHANT_BOOK_OLD = 9627; + public static final int CHANGE_ENCHANT_BOOK_OLD = 9626; + public static final int UNTRAIN_ENCHANT_BOOK_OLD = 9625; + public static final int NORMAL_ENCHANT_BOOK = 30297; + public static final int SAFE_ENCHANT_BOOK = 30298; + public static final int CHANGE_ENCHANT_BOOK = 30299; + public static final int UNTRAIN_ENCHANT_BOOK = 30300; + public static final int IMMORTAL_SCROLL = 37044; + public static final int NORMAL_ENCHANT_BOOK_V2 = 46150; + public static final int SAFE_ENCHANT_BOOK_V2 = 46151; + public static final int CHANGE_ENCHANT_BOOK_V2 = 46152; + public static final int IMMORTAL_SCROLL_V2 = 46153; + public static final int NORMAL_ENCHANT_BOOK_V3 = 46154; + public static final int SAFE_ENCHANT_BOOK_V3 = 46155; + public static final int CHANGE_ENCHANT_BOOK_V3 = 46156; + public static final int IMMORTAL_SCROLL_V3 = 46157; private final Map _enchantSkillGroups = new HashMap<>(); private final Map _enchantSkillTrees = new HashMap<>(); diff --git a/trunk/java/com/l2jmobius/gameserver/data/xml/impl/SkillData.java b/trunk/java/com/l2jmobius/gameserver/data/xml/impl/SkillData.java index bc35c2194f..950be7d1b0 100644 --- a/trunk/java/com/l2jmobius/gameserver/data/xml/impl/SkillData.java +++ b/trunk/java/com/l2jmobius/gameserver/data/xml/impl/SkillData.java @@ -56,20 +56,10 @@ public class SkillData implements IGameXmlReader { private static final Logger LOGGER = Logger.getLogger(SkillData.class.getName()); - private static final Set BLOCK_ITEM_VALUE_ELEMENTS = new HashSet<>(); - private static final Set BLOCK_ITEM_ELEMENTS = new HashSet<>(); - private final Map _skills = new HashMap<>(); private final Map _skillsMaxLevel = new HashMap<>(); private final Set _enchantable = new HashSet<>(); - static - { - BLOCK_ITEM_VALUE_ELEMENTS.add("item"); - BLOCK_ITEM_VALUE_ELEMENTS.add("value"); - BLOCK_ITEM_ELEMENTS.add("item"); - } - private class NamedParamInfo { private final String _name; @@ -150,7 +140,7 @@ public class SkillData implements IGameXmlReader */ public static int getSkillHashCode(int skillId, int skillLevel) { - return (skillId * 1021) + skillLevel; + return (skillId * 1031) + skillLevel; } public Skill getSkill(int skillId, int level) @@ -423,7 +413,10 @@ public class SkillData implements IGameXmlReader _skills.put(getSkillHashCode(skill), skill); _skillsMaxLevel.merge(skill.getId(), skill.getLevel(), Integer::max); - // TODO: add enchantable + if ((skill.getLevel() > 99) && !_enchantable.contains(skill.getId())) + { + _enchantable.add(skill.getId()); + } }); }); } diff --git a/trunk/java/com/l2jmobius/gameserver/data/xml/impl/SkillTreesData.java b/trunk/java/com/l2jmobius/gameserver/data/xml/impl/SkillTreesData.java index 3315ecc00d..0f5ed59269 100644 --- a/trunk/java/com/l2jmobius/gameserver/data/xml/impl/SkillTreesData.java +++ b/trunk/java/com/l2jmobius/gameserver/data/xml/impl/SkillTreesData.java @@ -240,25 +240,37 @@ public final class SkillTreesData implements IGameXmlReader switch (b.getNodeName()) { case "item": + { skillLearn.addRequiredItem(new ItemHolder(parseInteger(attrs, "id"), parseInteger(attrs, "count"))); break; + } case "preRequisiteSkill": + { skillLearn.addPreReqSkill(new SkillHolder(parseInteger(attrs, "id"), parseInteger(attrs, "lvl"))); break; + } case "race": + { skillLearn.addRace(Race.valueOf(b.getTextContent())); break; + } case "residenceId": + { skillLearn.addResidenceId(Integer.valueOf(b.getTextContent())); break; + } case "socialClass": + { skillLearn.setSocialClass(Enum.valueOf(SocialClass.class, b.getTextContent())); break; + } case "removeSkill": + { final int removeSkillId = parseInteger(attrs, "id"); skillLearn.addRemoveSkills(removeSkillId); _removeSkillCache.computeIfAbsent(classId, k -> new HashSet<>()).add(removeSkillId); break; + } } } diff --git a/trunk/java/com/l2jmobius/gameserver/network/clientpackets/RequestExEnchantSkill.java b/trunk/java/com/l2jmobius/gameserver/network/clientpackets/RequestExEnchantSkill.java index 6bf40dba47..5af437d9c7 100644 --- a/trunk/java/com/l2jmobius/gameserver/network/clientpackets/RequestExEnchantSkill.java +++ b/trunk/java/com/l2jmobius/gameserver/network/clientpackets/RequestExEnchantSkill.java @@ -16,6 +16,8 @@ */ package com.l2jmobius.gameserver.network.clientpackets; +import java.util.logging.Level; +import java.util.logging.LogRecord; import java.util.logging.Logger; import com.l2jmobius.Config; @@ -45,14 +47,26 @@ public final class RequestExEnchantSkill implements IClientIncomingPacket { private static final Logger _logEnchant = Logger.getLogger("enchant.skills"); + private int _type; // enchant type: 0 - normal, 1 - safe, 2 - untrain, 3 - change route, 4 - 100% + private int _skillId; private int _skillLvl; + private int _fullLvl; @Override public boolean read(L2GameClient client, PacketReader packet) { + _type = packet.readD(); _skillId = packet.readD(); - _skillLvl = packet.readD(); + _fullLvl = packet.readD(); + if (_fullLvl < 100) + { + _skillLvl = _fullLvl; + } + else + { + _skillLvl = _fullLvl >> 16; + } return true; } @@ -72,19 +86,19 @@ public final class RequestExEnchantSkill implements IClientIncomingPacket if (player.getClassId().level() < 3) // requires to have 3rd class quest completed { - client.sendPacket(SystemMessageId.YOU_CANNOT_USE_THE_SKILL_ENHANCING_FUNCTION_IN_THIS_CLASS_YOU_CAN_USE_CORRESPONDING_FUNCTION_WHEN_COMPLETING_THE_THIRD_CLASS_CHANGE); + player.sendPacket(SystemMessageId.YOU_CANNOT_USE_THE_SKILL_ENHANCING_FUNCTION_IN_THIS_CLASS_YOU_CAN_USE_CORRESPONDING_FUNCTION_WHEN_COMPLETING_THE_THIRD_CLASS_CHANGE); return; } if (player.getLevel() < 76) { - client.sendPacket(SystemMessageId.YOU_CANNOT_USE_THE_SKILL_ENHANCING_FUNCTION_ON_THIS_LEVEL_YOU_CAN_USE_THE_CORRESPONDING_FUNCTION_ON_LEVELS_HIGHER_THAN_LV_76); + player.sendPacket(SystemMessageId.YOU_CANNOT_USE_THE_SKILL_ENHANCING_FUNCTION_ON_THIS_LEVEL_YOU_CAN_USE_THE_CORRESPONDING_FUNCTION_ON_LEVELS_HIGHER_THAN_LV_76); return; } if (!player.isAllowedToEnchantSkills()) { - client.sendPacket(SystemMessageId.YOU_CANNOT_USE_THE_SKILL_ENHANCING_FUNCTION_IN_THIS_STATE_YOU_CAN_ENHANCE_SKILLS_WHEN_NOT_IN_BATTLE_AND_CANNOT_USE_THE_FUNCTION_WHILE_TRANSFORMED_IN_BATTLE_ON_A_MOUNT_OR_WHILE_THE_SKILL_IS_ON_COOLDOWN); + player.sendPacket(SystemMessageId.YOU_CANNOT_USE_THE_SKILL_ENHANCING_FUNCTION_IN_THIS_STATE_YOU_CAN_ENHANCE_SKILLS_WHEN_NOT_IN_BATTLE_AND_CANNOT_USE_THE_FUNCTION_WHILE_TRANSFORMED_IN_BATTLE_ON_A_MOUNT_OR_WHILE_THE_SKILL_IS_ON_COOLDOWN); return; } @@ -105,133 +119,452 @@ public final class RequestExEnchantSkill implements IClientIncomingPacket { return; } - final EnchantSkillHolder esd = s.getEnchantSkillHolder(_skillLvl); - final int beforeEnchantSkillLevel = player.getSkillLevel(_skillId); - if (beforeEnchantSkillLevel != s.getMinSkillLevel(_skillLvl)) + final int _elvl = ((_skillLvl % 100) - 1) / 10; + if (_type == 0) // enchant { - return; - } - - final int costMultiplier = Config.NORMAL_ENCHANT_COST_MULTIPLIER; - final int requiredSp = esd.getSpCost() * costMultiplier; - if (player.getSp() >= requiredSp) - { - // only first lvl requires book - final boolean usesBook = (_skillLvl % 100) == 1; // 101, 201, 301 ... - final int reqItemId = EnchantSkillGroupsData.NORMAL_ENCHANT_BOOK; - final L2ItemInstance spb = player.getInventory().getItemByItemId(reqItemId); - - if (Config.ES_SP_BOOK_NEEDED && usesBook && (spb == null)) // Haven't spellbook + final EnchantSkillHolder esd = s.getEnchantSkillHolder(_skillLvl); + final int beforeEnchantSkillLevel = player.getSkillLevel(_skillId); + if (beforeEnchantSkillLevel != s.getMinSkillLevel(_skillLvl)) { - client.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL); return; } - final int requiredAdena = (esd.getAdenaCost() * costMultiplier); - if (player.getInventory().getAdena() < requiredAdena) + final int costMultiplier = EnchantSkillGroupsData.NORMAL_ENCHANT_COST_MULTIPLIER; + final int requiredSp = esd.getSpCost() * costMultiplier; + if (player.getSp() >= requiredSp) { - client.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL); - return; - } - - boolean check = player.getStat().removeExpAndSp(0, requiredSp, false); - if (Config.ES_SP_BOOK_NEEDED && usesBook) - { - check &= player.destroyItem("Consume", spb.getObjectId(), 1, player, true); - } - - check &= player.destroyItemByItemId("Consume", Inventory.ADENA_ID, requiredAdena, player, true); - if (!check) - { - client.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL); - return; - } - - // ok. Destroy ONE copy of the book - final int rate = esd.getRate(player); - if (Rnd.get(100) <= rate) - { - if (Config.LOG_SKILL_ENCHANTS) + final boolean usesBook = true; + final int reqItemId; + if (player.getClassId().level() == 3) { - if (skill.getLevel() > 100) + reqItemId = EnchantSkillGroupsData.NORMAL_ENCHANT_BOOK_OLD; + } + else if (_elvl == 0) + { + reqItemId = EnchantSkillGroupsData.NORMAL_ENCHANT_BOOK; + } + else if (_elvl == 1) + { + reqItemId = EnchantSkillGroupsData.NORMAL_ENCHANT_BOOK_V2; + } + else + { + reqItemId = EnchantSkillGroupsData.NORMAL_ENCHANT_BOOK_V3; + } + final L2ItemInstance spb = player.getInventory().getItemByItemId(reqItemId); + + if (Config.ES_SP_BOOK_NEEDED && usesBook && (spb == null)) + { + player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL); + return; + } + + final int requiredAdena = esd.getAdenaCost() * costMultiplier; + if (player.getInventory().getAdena() < requiredAdena) + { + player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL); + return; + } + + boolean check = player.getStat().removeExpAndSp(0, requiredSp, false); + if (Config.ES_SP_BOOK_NEEDED && usesBook) + { + check &= player.destroyItem("Consume", spb.getObjectId(), 1, player, true); + } + + check &= player.destroyItemByItemId("Consume", Inventory.ADENA_ID, requiredAdena, player, true); + if (!check) + { + player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL); + return; + } + + // ok. Destroy ONE copy of the book + final int rate = esd.getRate(player); + if (Rnd.get(100) <= rate) + { + if (Config.LOG_SKILL_ENCHANTS) { - if (spb != null) + final LogRecord record = new LogRecord(Level.INFO, "Success"); + record.setParameters(new Object[] { - _logEnchant.info("Success, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", +" + (skill.getLevel() % 100) + " " + skill.getName() + "(" + skill.getId() + "), " + spb.getName() + "(" + spb.getCount() + ") [" + spb.getObjectId() + "], " + rate); - } - else - { - _logEnchant.info("Success, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", +" + (skill.getLevel() % 100) + " " + skill.getName() + "(" + skill.getId() + "), " + rate); - } + player, + skill, + spb, + rate + }); + record.setLoggerName("skill"); + _logEnchant.log(record); + } + + player.addSkill(skill, true); + player.sendPacket(ExEnchantSkillResult.valueOf(true)); + + final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.SKILL_ENCHANT_WAS_SUCCESSFUL_S1_HAS_BEEN_ENCHANTED); + sm.addSkillName(_skillId); + player.sendPacket(sm); + + if (Config.DEBUG) + { + _log.fine("Learned skill ID: " + _skillId + " Level: " + _skillLvl + " for " + requiredSp + " SP, " + requiredAdena + " Adena."); + } + } + else + { + if (player.getClassId().level() == 3) + { + player.addSkill(SkillData.getInstance().getSkill(_skillId, s.getBaseLevel()), true); } else { - if (spb != null) + final int _clvl = ((((_skillLvl % 100) - 1) / 10) * 10) + ((_skillLvl / 1000) * 1000); + player.addSkill(SkillData.getInstance().getSkill(_skillId, _clvl), true); + } + player.sendPacket(SystemMessageId.SKILL_ENCHANT_FAILED_THE_SKILL_WILL_BE_INITIALIZED); + player.sendPacket(ExEnchantSkillResult.valueOf(false)); + + if (Config.LOG_SKILL_ENCHANTS) + { + final LogRecord record = new LogRecord(Level.INFO, "Fail"); + record.setParameters(new Object[] { - _logEnchant.info("Success, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", " + skill.getName() + "(" + skill.getId() + "), " + spb.getName() + "(" + spb.getCount() + ") [" + spb.getObjectId() + "], " + rate); - } - else - { - _logEnchant.info("Success, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", " + skill.getName() + "(" + skill.getId() + "), " + rate); - } + player, + skill, + spb, + rate + }); + record.setLoggerName("skill"); + _logEnchant.log(record); } } - player.addSkill(skill, true); - client.sendPacket(ExEnchantSkillResult.valueOf(true)); - - final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.SKILL_ENCHANT_WAS_SUCCESSFUL_S1_HAS_BEEN_ENCHANTED); - sm.addSkillName(_skillId); - client.sendPacket(sm); - - if (Config.DEBUG) - { - _log.finer("Learned skill ID: " + _skillId + " Level: " + _skillLvl + " for " + requiredSp + " SP, " + requiredAdena + " Adena."); - } + player.sendPacket(new UserInfo(player)); + player.sendSkillList(); + final int afterEnchantSkillLevel = player.getSkillLevel(_skillId); + player.sendPacket(new ExEnchantSkillInfo(_skillId, afterEnchantSkillLevel)); + player.sendPacket(new ExEnchantSkillInfoDetail(0, _skillId, afterEnchantSkillLevel + 1, player)); + player.updateShortCuts(_skillId, afterEnchantSkillLevel); } else { - player.addSkill(SkillData.getInstance().getSkill(_skillId, s.getBaseLevel()), true); - client.sendPacket(SystemMessageId.SKILL_ENCHANT_FAILED_THE_SKILL_WILL_BE_INITIALIZED); - client.sendPacket(ExEnchantSkillResult.valueOf(false)); + player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_SP_TO_ENCHANT_THAT_SKILL); + } + } + else if (_type == 1) // safe enchant + { + final int costMultiplier = EnchantSkillGroupsData.SAFE_ENCHANT_COST_MULTIPLIER; + final int reqItemId; + if (player.getClassId().level() == 3) + { + reqItemId = EnchantSkillGroupsData.SAFE_ENCHANT_BOOK_OLD; + } + else if (_elvl == 0) + { + reqItemId = EnchantSkillGroupsData.SAFE_ENCHANT_BOOK; + } + else if (_elvl == 1) + { + reqItemId = EnchantSkillGroupsData.SAFE_ENCHANT_BOOK_V2; + } + else + { + reqItemId = EnchantSkillGroupsData.SAFE_ENCHANT_BOOK_V3; + } + final EnchantSkillHolder esd = s.getEnchantSkillHolder(_skillLvl); + final int beforeEnchantSkillLevel = player.getSkillLevel(_skillId); + if (beforeEnchantSkillLevel != s.getMinSkillLevel(_skillLvl)) + { + return; + } + + final int requiredSp = esd.getSpCost() * costMultiplier; + final int requireditems = esd.getAdenaCost() * costMultiplier; + final int rate = esd.getRate(player); + + if (player.getSp() >= requiredSp) + { + final L2ItemInstance spb = player.getInventory().getItemByItemId(reqItemId); + if (spb == null) + { + player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL); + return; + } + + if (player.getInventory().getAdena() < requireditems) + { + player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL); + return; + } + + boolean check = player.getStat().removeExpAndSp(0, requiredSp, false); + check &= player.destroyItem("Consume", spb.getObjectId(), 1, player, true); + + check &= player.destroyItemByItemId("Consume", Inventory.ADENA_ID, requireditems, player, true); + + if (!check) + { + player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL); + return; + } + + if (Rnd.get(100) <= rate) + { + if (Config.LOG_SKILL_ENCHANTS) + { + final LogRecord record = new LogRecord(Level.INFO, "Safe Success"); + record.setParameters(new Object[] + { + player, + skill, + spb, + rate + }); + record.setLoggerName("skill"); + _logEnchant.log(record); + } + + player.addSkill(skill, true); + + if (Config.DEBUG) + { + _log.fine("Learned skill ID: " + _skillId + " Level: " + _skillLvl + " for " + requiredSp + " SP, " + requireditems + " Adena."); + } + + player.sendPacket(ExEnchantSkillResult.valueOf(true)); + + final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.SKILL_ENCHANT_WAS_SUCCESSFUL_S1_HAS_BEEN_ENCHANTED); + sm.addSkillName(_skillId); + player.sendPacket(sm); + } + else + { + if (Config.LOG_SKILL_ENCHANTS) + { + final LogRecord record = new LogRecord(Level.INFO, "Safe Fail"); + record.setParameters(new Object[] + { + player, + skill, + spb, + rate + }); + record.setLoggerName("skill"); + _logEnchant.log(record); + } + + final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.SKILL_ENCHANT_FAILED_THE_SKILL_WILL_BE_INITIALIZED); + player.sendPacket(sm); + player.sendPacket(ExEnchantSkillResult.valueOf(false)); + } + + player.sendPacket(new UserInfo(player)); + player.sendSkillList(); + final int afterEnchantSkillLevel = player.getSkillLevel(_skillId); + player.sendPacket(new ExEnchantSkillInfo(_skillId, afterEnchantSkillLevel)); + player.sendPacket(new ExEnchantSkillInfoDetail(1, _skillId, afterEnchantSkillLevel + 1, player)); + player.updateShortCuts(_skillId, afterEnchantSkillLevel); + } + else + { + player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_SP_TO_ENCHANT_THAT_SKILL)); + } + } + else if (_type == 2) // untrain + { + return; + } + else if (_type == 3) // change route + { + final int reqItemId; + if (player.getClassId().level() == 3) + { + reqItemId = EnchantSkillGroupsData.CHANGE_ENCHANT_BOOK_OLD; + } + else if (_elvl == 0) + { + reqItemId = EnchantSkillGroupsData.CHANGE_ENCHANT_BOOK; + } + else if (_elvl == 1) + { + reqItemId = EnchantSkillGroupsData.CHANGE_ENCHANT_BOOK_V2; + } + else + { + reqItemId = EnchantSkillGroupsData.CHANGE_ENCHANT_BOOK_V3; + } + + final int beforeEnchantSkillLevel = player.getSkillLevel(_skillId); + if (beforeEnchantSkillLevel <= 1000) + { + return; + } + + final int currentEnchantLevel = beforeEnchantSkillLevel % 1000; + if (currentEnchantLevel != (_skillLvl % 1000)) + { + return; + } + final EnchantSkillHolder esd = s.getEnchantSkillHolder(_skillLvl); + + final int requiredSp = esd.getSpCost(); + final int requireditems = esd.getAdenaCost(); + + if (player.getSp() >= requiredSp) + { + final L2ItemInstance spb = player.getInventory().getItemByItemId(reqItemId); + if (Config.ES_SP_BOOK_NEEDED && (spb == null)) + { + player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_SKILL_ROUTE_CHANGE); + return; + } + + if (player.getInventory().getAdena() < requireditems) + { + player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL); + return; + } + + boolean check = player.getStat().removeExpAndSp(0, requiredSp, false); + if (Config.ES_SP_BOOK_NEEDED) + { + check &= player.destroyItem("Consume", spb.getObjectId(), 1, player, true); + } + + check &= player.destroyItemByItemId("Consume", Inventory.ADENA_ID, requireditems, player, true); + + if (!check) + { + player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL); + return; + } + + final int levelPenalty = Rnd.get(Math.min(4, currentEnchantLevel)); + _skillLvl -= levelPenalty; + if ((_skillLvl % 1000) == 0) + { + _skillLvl = s.getBaseLevel(); + } if (Config.LOG_SKILL_ENCHANTS) { - if (skill.getLevel() > 100) + final LogRecord record = new LogRecord(Level.INFO, "Route Change"); + record.setParameters(new Object[] { - if (spb != null) - { - _logEnchant.info("Fail, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", +" + (skill.getLevel() % 100) + " " + skill.getName() + "(" + skill.getId() + "), " + spb.getName() + "(" + spb.getCount() + ") [" + spb.getObjectId() + "], " + rate); - } - else - { - _logEnchant.info("Fail, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", +" + (skill.getLevel() % 100) + " " + skill.getName() + "(" + skill.getId() + "), " + rate); - } + player, + skill, + spb + }); + record.setLoggerName("skill"); + _logEnchant.log(record); + } + + player.addSkill(SkillData.getInstance().getSkill(_skillId, _skillLvl), true); + player.sendPacket(ExEnchantSkillResult.valueOf(true)); + + if (Config.DEBUG) + { + _log.fine("Learned skill ID: " + _skillId + " Level: " + _skillLvl + " for " + requiredSp + " SP, " + requireditems + " Adena."); + } + + player.sendPacket(new UserInfo(player)); + + final SystemMessage sm; + if (levelPenalty == 0) + { + sm = SystemMessage.getSystemMessage(SystemMessageId.ENCHANT_SKILL_ROUTE_CHANGE_WAS_SUCCESSFUL_LV_OF_ENCHANT_SKILL_S1_WILL_REMAIN); + sm.addSkillName(_skillId); + } + else + { + sm = SystemMessage.getSystemMessage(SystemMessageId.ENCHANT_SKILL_ROUTE_CHANGE_WAS_SUCCESSFUL_LV_OF_ENCHANT_SKILL_S1_HAS_BEEN_DECREASED_BY_S2); + sm.addSkillName(_skillId); + + if (_skillLvl > 1000) + { + sm.addInt(_skillLvl % 1000); } else { - if (spb != null) - { - _logEnchant.info("Fail, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", " + skill.getName() + "(" + skill.getId() + "), " + spb.getName() + "(" + spb.getCount() + ") [" + spb.getObjectId() + "], " + rate); - } - else - { - _logEnchant.info("Fail, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", " + skill.getName() + "(" + skill.getId() + "), " + rate); - } + sm.addInt(0); } } + player.sendPacket(sm); + player.sendSkillList(); + final int afterEnchantSkillLevel = player.getSkillLevel(_skillId); + player.sendPacket(new ExEnchantSkillInfo(_skillId, afterEnchantSkillLevel)); + player.sendPacket(new ExEnchantSkillInfoDetail(3, _skillId, afterEnchantSkillLevel, player)); + player.updateShortCuts(_skillId, afterEnchantSkillLevel); + } + else + { + player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_SP_TO_ENCHANT_THAT_SKILL)); + } + } + else if (_type == 4) // 100% enchant + { + final int reqItemId; + if (player.getClassId().level() == 3) + { + reqItemId = EnchantSkillGroupsData.IMMORTAL_SCROLL; + } + else if (_elvl == 0) + { + reqItemId = EnchantSkillGroupsData.IMMORTAL_SCROLL; + } + else if (_elvl == 1) + { + reqItemId = EnchantSkillGroupsData.IMMORTAL_SCROLL_V2; + } + else + { + reqItemId = EnchantSkillGroupsData.IMMORTAL_SCROLL_V3; + } + final int beforeEnchantSkillLevel = player.getSkillLevel(_skillId); + if (beforeEnchantSkillLevel != s.getMinSkillLevel(_skillLvl)) + { + return; } - client.sendPacket(new UserInfo(player)); + final L2ItemInstance spb = player.getInventory().getItemByItemId(reqItemId); + if (spb == null) + { + player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL); + return; + } + + player.destroyItem("Consume", spb.getObjectId(), 1, player, true); + + if (Config.LOG_SKILL_ENCHANTS) + { + final LogRecord record = new LogRecord(Level.INFO, "100% Success"); + record.setParameters(new Object[] + { + player, + skill, + spb, + 100 + }); + record.setLoggerName("skill"); + _logEnchant.log(record); + } + + player.addSkill(skill, true); + + if (Config.DEBUG) + { + _log.fine("Learned skill ID: " + _skillId + " Level: " + _skillLvl + "."); + } + + player.sendPacket(ExEnchantSkillResult.valueOf(true)); + final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.SKILL_ENCHANT_WAS_SUCCESSFUL_S1_HAS_BEEN_ENCHANTED); + sm.addSkillName(_skillId); + player.sendPacket(sm); + player.sendPacket(new UserInfo(player)); player.sendSkillList(); final int afterEnchantSkillLevel = player.getSkillLevel(_skillId); - client.sendPacket(new ExEnchantSkillInfo(_skillId, afterEnchantSkillLevel)); - client.sendPacket(new ExEnchantSkillInfoDetail(0, _skillId, afterEnchantSkillLevel + 1, player)); + player.sendPacket(new ExEnchantSkillInfo(_skillId, afterEnchantSkillLevel)); + player.sendPacket(new ExEnchantSkillInfoDetail(1, _skillId, afterEnchantSkillLevel + 1, player)); player.updateShortCuts(_skillId, afterEnchantSkillLevel); } - else - { - client.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_SP_TO_ENCHANT_THAT_SKILL); - } } } diff --git a/trunk/java/com/l2jmobius/gameserver/network/clientpackets/RequestExEnchantSkillInfo.java b/trunk/java/com/l2jmobius/gameserver/network/clientpackets/RequestExEnchantSkillInfo.java index 9508a654b4..e307558bca 100644 --- a/trunk/java/com/l2jmobius/gameserver/network/clientpackets/RequestExEnchantSkillInfo.java +++ b/trunk/java/com/l2jmobius/gameserver/network/clientpackets/RequestExEnchantSkillInfo.java @@ -32,12 +32,21 @@ public final class RequestExEnchantSkillInfo implements IClientIncomingPacket { private int _skillId; private int _skillLvl; + private int _fullLvl; @Override public boolean read(L2GameClient client, PacketReader packet) { _skillId = packet.readD(); - _skillLvl = packet.readD(); + _fullLvl = packet.readD(); + if (_fullLvl < 100) + { + _skillLvl = _fullLvl; + } + else + { + _skillLvl = _fullLvl >> 16; + } return true; } @@ -78,6 +87,6 @@ public final class RequestExEnchantSkillInfo implements IClientIncomingPacket return; } - client.sendPacket(new ExEnchantSkillInfo(_skillId, _skillLvl)); + activeChar.sendPacket(new ExEnchantSkillInfo(_skillId, _skillLvl)); } } \ No newline at end of file diff --git a/trunk/java/com/l2jmobius/gameserver/network/clientpackets/RequestExEnchantSkillInfoDetail.java b/trunk/java/com/l2jmobius/gameserver/network/clientpackets/RequestExEnchantSkillInfoDetail.java index 91e1e8fccc..d235f42da8 100644 --- a/trunk/java/com/l2jmobius/gameserver/network/clientpackets/RequestExEnchantSkillInfoDetail.java +++ b/trunk/java/com/l2jmobius/gameserver/network/clientpackets/RequestExEnchantSkillInfoDetail.java @@ -32,13 +32,22 @@ public final class RequestExEnchantSkillInfoDetail implements IClientIncomingPac private int _type; private int _skillId; private int _skillLvl; + private int _fullLvl; @Override public boolean read(L2GameClient client, PacketReader packet) { _type = packet.readD(); _skillId = packet.readD(); - _skillLvl = packet.readD(); + _fullLvl = packet.readD(); + if (_fullLvl < 100) + { + _skillLvl = _fullLvl; + } + else + { + _skillLvl = _fullLvl >> 16; + } return true; } @@ -65,7 +74,7 @@ public final class RequestExEnchantSkillInfoDetail implements IClientIncomingPac } else if (_type == 2) { - reqSkillLvl = _skillLvl + 1; // untrain + return; } else if (_type == 3) { @@ -81,7 +90,7 @@ public final class RequestExEnchantSkillInfoDetail implements IClientIncomingPac } // if reqlvl is 100,200,.. check base skill lvl enchant - if ((reqSkillLvl % 100) == 0) + if ((reqSkillLvl % 1000) == 0) { final L2EnchantSkillLearn esl = EnchantSkillGroupsData.getInstance().getSkillEnchantmentBySkillId(_skillId); if (esl != null) @@ -101,13 +110,14 @@ public final class RequestExEnchantSkillInfoDetail implements IClientIncomingPac else if (playerSkillLvl != reqSkillLvl) { // change route is different skill lvl but same enchant - if ((_type == 3) && ((playerSkillLvl % 100) != (_skillLvl % 100))) + if ((_type == 3) && ((playerSkillLvl % 1000) != (_skillLvl % 1000))) { return; } } // send skill enchantment detail - client.sendPacket(new ExEnchantSkillInfoDetail(_type, _skillId, _skillLvl, activeChar)); + final ExEnchantSkillInfoDetail esd = new ExEnchantSkillInfoDetail(_type, _skillId, _skillLvl, activeChar); + activeChar.sendPacket(esd); } } diff --git a/trunk/java/com/l2jmobius/gameserver/network/serverpackets/ExEnchantSkillInfo.java b/trunk/java/com/l2jmobius/gameserver/network/serverpackets/ExEnchantSkillInfo.java index 0bbf84d14f..96223bb70e 100644 --- a/trunk/java/com/l2jmobius/gameserver/network/serverpackets/ExEnchantSkillInfo.java +++ b/trunk/java/com/l2jmobius/gameserver/network/serverpackets/ExEnchantSkillInfo.java @@ -21,6 +21,7 @@ import java.util.List; import com.l2jmobius.commons.network.PacketWriter; import com.l2jmobius.gameserver.data.xml.impl.EnchantSkillGroupsData; +import com.l2jmobius.gameserver.data.xml.impl.SkillData; import com.l2jmobius.gameserver.model.L2EnchantSkillGroup.EnchantSkillHolder; import com.l2jmobius.gameserver.model.L2EnchantSkillLearn; import com.l2jmobius.gameserver.network.client.OutgoingPackets; @@ -31,19 +32,21 @@ public final class ExEnchantSkillInfo implements IClientOutgoingPacket private final int _id; private final int _lvl; + private final int _maxlvl; private boolean _maxEnchanted = false; public ExEnchantSkillInfo(int id, int lvl) { _id = id; _lvl = lvl; + _maxlvl = SkillData.getInstance().getMaxLevel(_id); final L2EnchantSkillLearn enchantLearn = EnchantSkillGroupsData.getInstance().getSkillEnchantmentBySkillId(_id); // do we have this skill? if (enchantLearn != null) { // skill already enchanted? - if (_lvl > 100) + if (_lvl > 1000) { _maxEnchanted = enchantLearn.isMaxEnchant(_lvl); @@ -51,24 +54,19 @@ public final class ExEnchantSkillInfo implements IClientOutgoingPacket final EnchantSkillHolder esd = enchantLearn.getEnchantSkillHolder(_lvl); // if it exists add it - if (esd != null) + if ((esd != null) && !_maxEnchanted) { - _routes.add(_lvl); // current enchant add firts + _routes.add(_lvl + 1); // current enchant add firts } - final int skillLvL = (_lvl % 100); - for (int route : enchantLearn.getAllRoutes()) { - if (((route * 100) + skillLvL) == _lvl) + if (((route * 1000) + (_lvl % 1000)) == _lvl) { continue; } - // add other levels of all routes - same lvl as enchanted - // lvl - _routes.add((route * 100) + skillLvL); + _routes.add((route * 1000) + (_lvl % 1000)); } - } else // not already enchanted @@ -76,7 +74,7 @@ public final class ExEnchantSkillInfo implements IClientOutgoingPacket for (int route : enchantLearn.getAllRoutes()) { // add first level (+1) of all routes - _routes.add((route * 100) + 1); + _routes.add((route * 1000) + 1); } } } @@ -88,11 +86,25 @@ public final class ExEnchantSkillInfo implements IClientOutgoingPacket OutgoingPackets.EX_ENCHANT_SKILL_INFO.writeId(packet); packet.writeD(_id); - packet.writeD(_lvl); + if (_lvl < 100) + { + packet.writeD(_lvl); + } + else + { + packet.writeH(_maxlvl); + packet.writeH(_lvl); + } packet.writeD(_maxEnchanted ? 0 : 1); - packet.writeD(_lvl > 100 ? 1 : 0); // enchanted? + packet.writeD(_lvl > 1000 ? 1 : 0); // enchanted? packet.writeD(_routes.size()); - _routes.forEach(packet::writeD); + + for (int level : _routes) + { + packet.writeH(_maxlvl); + packet.writeH(level); + } + return true; } } diff --git a/trunk/java/com/l2jmobius/gameserver/network/serverpackets/ExEnchantSkillInfoDetail.java b/trunk/java/com/l2jmobius/gameserver/network/serverpackets/ExEnchantSkillInfoDetail.java index d482b5c4ec..55f94efa55 100644 --- a/trunk/java/com/l2jmobius/gameserver/network/serverpackets/ExEnchantSkillInfoDetail.java +++ b/trunk/java/com/l2jmobius/gameserver/network/serverpackets/ExEnchantSkillInfoDetail.java @@ -19,6 +19,7 @@ package com.l2jmobius.gameserver.network.serverpackets; import com.l2jmobius.Config; import com.l2jmobius.commons.network.PacketWriter; import com.l2jmobius.gameserver.data.xml.impl.EnchantSkillGroupsData; +import com.l2jmobius.gameserver.data.xml.impl.SkillData; import com.l2jmobius.gameserver.model.L2EnchantSkillGroup.EnchantSkillHolder; import com.l2jmobius.gameserver.model.L2EnchantSkillLearn; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; @@ -34,6 +35,7 @@ public class ExEnchantSkillInfoDetail implements IClientOutgoingPacket private static final int TYPE_SAFE_ENCHANT = 1; private static final int TYPE_UNTRAIN_ENCHANT = 2; private static final int TYPE_CHANGE_ENCHANT = 3; + private static final int TYPE_IMMORTAL_ENCHANT = 4; private int bookId = 0; private int reqCount = 0; @@ -41,21 +43,26 @@ public class ExEnchantSkillInfoDetail implements IClientOutgoingPacket private final int _type; private final int _skillid; private final int _skilllvl; + private final int _maxlvl; private final int _chance; private int _sp; private final int _adenacount; public ExEnchantSkillInfoDetail(int type, int skillid, int skilllvl, L2PcInstance ply) { + _type = type; + _skillid = skillid; + _skilllvl = skilllvl; + _maxlvl = SkillData.getInstance().getMaxLevel(_skillid); final L2EnchantSkillLearn enchantLearn = EnchantSkillGroupsData.getInstance().getSkillEnchantmentBySkillId(skillid); EnchantSkillHolder esd = null; // do we have this skill? if (enchantLearn != null) { - if (skilllvl > 100) + if (_skilllvl > 1000) { - esd = enchantLearn.getEnchantSkillHolder(skilllvl); + esd = enchantLearn.getEnchantSkillHolder(_skilllvl); } else { @@ -65,48 +72,125 @@ public class ExEnchantSkillInfoDetail implements IClientOutgoingPacket if (esd == null) { - throw new IllegalArgumentException("Skill " + skillid + " dont have enchant data for level " + skilllvl); + throw new IllegalArgumentException("Skill " + skillid + " dont have enchant data for level " + _skilllvl); } if (type == 0) { - multi = Config.NORMAL_ENCHANT_COST_MULTIPLIER; + multi = EnchantSkillGroupsData.NORMAL_ENCHANT_COST_MULTIPLIER; } else if (type == 1) { - multi = Config.SAFE_ENCHANT_COST_MULTIPLIER; + multi = EnchantSkillGroupsData.SAFE_ENCHANT_COST_MULTIPLIER; } - _chance = esd.getRate(ply); - _sp = esd.getSpCost(); - if (type == TYPE_UNTRAIN_ENCHANT) + if (type != TYPE_IMMORTAL_ENCHANT) { - _sp = (int) (0.8 * _sp); + _chance = esd.getRate(ply); + _sp = esd.getSpCost(); + if (type == TYPE_UNTRAIN_ENCHANT) + { + _sp = (int) (0.8 * _sp); + } + _adenacount = esd.getAdenaCost() * multi; + } + else + { + _chance = 100; + _sp = 0; + _adenacount = 0; } - _adenacount = esd.getAdenaCost() * multi; - _type = type; - _skillid = skillid; - _skilllvl = skilllvl; + final int _elvl = ((_skilllvl % 100) - 1) / 10; switch (type) { case TYPE_NORMAL_ENCHANT: - bookId = EnchantSkillGroupsData.NORMAL_ENCHANT_BOOK; - reqCount = (((_skilllvl % 100) > 1) ? 0 : 1); + { + if (ply.getClassId().level() < 4) + { + bookId = EnchantSkillGroupsData.NORMAL_ENCHANT_BOOK_OLD; + } + else if (_elvl == 0) + { + bookId = EnchantSkillGroupsData.NORMAL_ENCHANT_BOOK; + } + else if (_elvl == 1) + { + bookId = EnchantSkillGroupsData.NORMAL_ENCHANT_BOOK_V2; + } + else + { + bookId = EnchantSkillGroupsData.NORMAL_ENCHANT_BOOK_V3; + } + reqCount = 1; break; + } case TYPE_SAFE_ENCHANT: - bookId = EnchantSkillGroupsData.SAFE_ENCHANT_BOOK; - reqCount = 1; - break; - case TYPE_UNTRAIN_ENCHANT: - bookId = EnchantSkillGroupsData.UNTRAIN_ENCHANT_BOOK; + { + if (ply.getClassId().level() < 4) + { + bookId = EnchantSkillGroupsData.SAFE_ENCHANT_BOOK_OLD; + } + else if (_elvl == 0) + { + bookId = EnchantSkillGroupsData.SAFE_ENCHANT_BOOK; + } + else if (_elvl == 1) + { + bookId = EnchantSkillGroupsData.SAFE_ENCHANT_BOOK_V2; + } + else + { + bookId = EnchantSkillGroupsData.SAFE_ENCHANT_BOOK_V3; + } reqCount = 1; break; + } case TYPE_CHANGE_ENCHANT: - bookId = EnchantSkillGroupsData.CHANGE_ENCHANT_BOOK; + { + if (ply.getClassId().level() < 4) + { + bookId = EnchantSkillGroupsData.CHANGE_ENCHANT_BOOK_OLD; + } + else if (_elvl == 0) + { + bookId = EnchantSkillGroupsData.CHANGE_ENCHANT_BOOK; + } + else if (_elvl == 1) + { + bookId = EnchantSkillGroupsData.CHANGE_ENCHANT_BOOK_V2; + } + else + { + bookId = EnchantSkillGroupsData.CHANGE_ENCHANT_BOOK_V3; + } reqCount = 1; break; + } + case TYPE_IMMORTAL_ENCHANT: + { + if (ply.getClassId().level() < 4) + { + bookId = EnchantSkillGroupsData.IMMORTAL_SCROLL; + } + else if (_elvl == 0) + { + bookId = EnchantSkillGroupsData.IMMORTAL_SCROLL; + } + else if (_elvl == 1) + { + bookId = EnchantSkillGroupsData.IMMORTAL_SCROLL_V2; + } + else + { + bookId = EnchantSkillGroupsData.IMMORTAL_SCROLL_V3; + } + reqCount = 1; + break; + } default: + { return; + } } if ((type != TYPE_SAFE_ENCHANT) && !Config.ES_SP_BOOK_NEEDED) @@ -122,7 +206,8 @@ public class ExEnchantSkillInfoDetail implements IClientOutgoingPacket packet.writeD(_type); packet.writeD(_skillid); - packet.writeD(_skilllvl); + packet.writeH(_maxlvl); + packet.writeH(_skilllvl); packet.writeQ(_sp * multi); // sp packet.writeD(_chance); // exp packet.writeD(0x02); // items count? diff --git a/trunk/java/com/l2jmobius/gameserver/network/serverpackets/ExEnchantSkillList.java b/trunk/java/com/l2jmobius/gameserver/network/serverpackets/ExEnchantSkillList.java index 55380fcb55..92fa6c02d9 100644 --- a/trunk/java/com/l2jmobius/gameserver/network/serverpackets/ExEnchantSkillList.java +++ b/trunk/java/com/l2jmobius/gameserver/network/serverpackets/ExEnchantSkillList.java @@ -16,11 +16,10 @@ */ package com.l2jmobius.gameserver.network.serverpackets; -import java.util.LinkedList; +import java.util.ArrayList; import java.util.List; import com.l2jmobius.commons.network.PacketWriter; -import com.l2jmobius.gameserver.model.skills.Skill; import com.l2jmobius.gameserver.network.client.OutgoingPackets; public class ExEnchantSkillList implements IClientOutgoingPacket @@ -34,16 +33,29 @@ public class ExEnchantSkillList implements IClientOutgoingPacket } private final EnchantSkillType _type; - private final List _skills = new LinkedList<>(); + private final List _skills; + + static class Skill + { + public int id; + public int nextLevel; + + Skill(int pId, int pNextLevel) + { + id = pId; + nextLevel = pNextLevel; + } + } + + public void addSkill(int id, int level) + { + _skills.add(new Skill(id, level)); + } public ExEnchantSkillList(EnchantSkillType type) { _type = type; - } - - public void addSkill(Skill skill) - { - _skills.add(skill); + _skills = new ArrayList<>(); } @Override @@ -53,10 +65,10 @@ public class ExEnchantSkillList implements IClientOutgoingPacket packet.writeD(_type.ordinal()); packet.writeD(_skills.size()); - for (Skill skill : _skills) + for (Skill sk : _skills) { - packet.writeD(skill.getId()); - packet.writeD(skill.getLevel()); + packet.writeD(sk.id); + packet.writeD(sk.nextLevel); } return true; }