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;
}