diff --git a/trunk/dist/game/data/multisell/documentation.txt b/trunk/dist/game/data/multisell/documentation.txt index c2df8c126c..b5affb1192 100644 --- a/trunk/dist/game/data/multisell/documentation.txt +++ b/trunk/dist/game/data/multisell/documentation.txt @@ -37,7 +37,9 @@ TAGS: : start and end the list : start and end a single entry within the list : add a product for the entry - : add an ingredient for the entry. + : add an ingredient for the entry +enchantmentLevel : add item enchantment level + Sample: @@ -48,7 +50,7 @@ Sample: - + \ No newline at end of file diff --git a/trunk/dist/game/data/xsd/multisell.xsd b/trunk/dist/game/data/xsd/multisell.xsd index 0a582d9ba9..089fd5b89c 100644 --- a/trunk/dist/game/data/xsd/multisell.xsd +++ b/trunk/dist/game/data/xsd/multisell.xsd @@ -20,6 +20,7 @@ + @@ -27,6 +28,7 @@ + diff --git a/trunk/java/com/l2jmobius/gameserver/model/multisell/Ingredient.java b/trunk/java/com/l2jmobius/gameserver/model/multisell/Ingredient.java index 499e08a1e6..dcb12ddab5 100644 --- a/trunk/java/com/l2jmobius/gameserver/model/multisell/Ingredient.java +++ b/trunk/java/com/l2jmobius/gameserver/model/multisell/Ingredient.java @@ -30,6 +30,7 @@ public class Ingredient { private int _itemId; private long _itemCount; + private final int _enchantmentLevel; private boolean _isTaxIngredient; private boolean _maintainIngredient; private L2Item _template = null; @@ -38,13 +39,14 @@ public class Ingredient public Ingredient(StatsSet set) { - this(set.getInt("id"), set.getLong("count"), set.getInt("chance", 0), set.getBoolean("isTaxIngredient", false), set.getBoolean("maintainIngredient", false)); + this(set.getInt("id"), set.getLong("count"), set.getInt("enchantmentLevel", 0), set.getInt("chance", 0), set.getBoolean("isTaxIngredient", false), set.getBoolean("maintainIngredient", false)); } - public Ingredient(int itemId, long itemCount, int chance, boolean isTaxIngredient, boolean maintainIngredient) + public Ingredient(int itemId, long itemCount, int enchantmentLevel, int chance, boolean isTaxIngredient, boolean maintainIngredient) { _itemId = itemId; _itemCount = itemCount; + _enchantmentLevel = enchantmentLevel; _chance = chance; _isTaxIngredient = isTaxIngredient; _maintainIngredient = maintainIngredient; @@ -59,7 +61,7 @@ public class Ingredient */ public Ingredient getCopy() { - return new Ingredient(_itemId, _itemCount, _chance, _isTaxIngredient, _maintainIngredient); + return new Ingredient(_itemId, _itemCount, _enchantmentLevel, _chance, _isTaxIngredient, _maintainIngredient); } public final L2Item getTemplate() @@ -84,7 +86,7 @@ public class Ingredient public final int getEnchantLevel() { - return _itemInfo != null ? _itemInfo.getEnchantLevel() : 0; + return _itemInfo == null ? _enchantmentLevel : _itemInfo.getEnchantLevel(); } public final void setItemId(int itemId) diff --git a/trunk/java/com/l2jmobius/gameserver/model/multisell/PreparedEntry.java b/trunk/java/com/l2jmobius/gameserver/model/multisell/PreparedEntry.java index 70b9f7e054..46f4aac588 100644 --- a/trunk/java/com/l2jmobius/gameserver/model/multisell/PreparedEntry.java +++ b/trunk/java/com/l2jmobius/gameserver/model/multisell/PreparedEntry.java @@ -61,7 +61,7 @@ public class PreparedEntry extends Entry // do not yet add this adena amount to the list as non-taxIngredient adena might be entered later (order not guaranteed) continue; } - else if (maintainEnchantment && (item != null) && ing.isArmorOrWeapon()) + if (maintainEnchantment && (item != null) && ing.isArmorOrWeapon()) { info = new ItemInfo(item); final Ingredient newIngredient = ing.getCopy(); @@ -70,8 +70,7 @@ public class PreparedEntry extends Entry } else { - final Ingredient newIngredient = ing.getCopy(); - _ingredients.add(newIngredient); + _ingredients.add(ing.getCopy()); } } @@ -79,7 +78,7 @@ public class PreparedEntry extends Entry adenaAmount += _taxAmount; // do not forget tax if (adenaAmount > 0) { - _ingredients.add(new Ingredient(ADENA_ID, adenaAmount, 0, false, false)); + _ingredients.add(new Ingredient(ADENA_ID, adenaAmount, 0, 0, false, false)); } // now copy products diff --git a/trunk/java/com/l2jmobius/gameserver/network/clientpackets/MultiSellChoose.java b/trunk/java/com/l2jmobius/gameserver/network/clientpackets/MultiSellChoose.java index c72235d99f..f54e973849 100644 --- a/trunk/java/com/l2jmobius/gameserver/network/clientpackets/MultiSellChoose.java +++ b/trunk/java/com/l2jmobius/gameserver/network/clientpackets/MultiSellChoose.java @@ -152,8 +152,7 @@ public class MultiSellChoose implements IClientIncomingPacket } final ArrayList ingredientsList = new ArrayList<>(entry.getIngredients().size()); - // Generate a list of distinct ingredients and counts in order to check if the correct item-counts - // are possessed by the player + // Generate a list of distinct ingredients and counts in order to check if the correct item-counts are possessed by the player boolean newIng; for (Ingredient e : entry.getIngredients()) { @@ -187,7 +186,7 @@ public class MultiSellChoose implements IClientIncomingPacket } } - // now check if the player has sufficient items in the inventory to cover the ingredients' expences + // now check if the player has sufficient items in the inventory to cover the ingredient expenses for (Ingredient e : ingredientsList) { if ((e.getItemCount() * _amount) > Integer.MAX_VALUE) @@ -206,13 +205,23 @@ public class MultiSellChoose implements IClientIncomingPacket { // if this is not a list that maintains enchantment, check the count of all items that have the given id. // otherwise, check only the count of items with exactly the needed enchantment level - final long required = ((Config.ALT_BLACKSMITH_USE_RECIPES || !e.getMaintainIngredient()) ? (e.getItemCount() * _amount) : e.getItemCount()); - if (inv.getInventoryItemCount(e.getItemId(), list.getMaintainEnchantment() ? e.getEnchantLevel() : -1, false) < required) + final long required = (Config.ALT_BLACKSMITH_USE_RECIPES || !e.getMaintainIngredient()) ? (e.getItemCount() * _amount) : e.getItemCount(); + if (inv.getInventoryItemCount(e.getItemId(), (list.getMaintainEnchantment() || (e.getEnchantLevel() > 0)) ? e.getEnchantLevel() : -1, false) < required) { - final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_S2_S1_S); - sm.addItemName(e.getTemplate()); - sm.addLong(required); - player.sendPacket(sm); + if (e.getEnchantLevel() > 0) + { + final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_S2_S1_S); + sm.addString("+" + e.getEnchantLevel() + " " + e.getTemplate().getName()); + sm.addLong(required); + player.sendPacket(sm); + } + else + { + final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_S2_S1_S); + sm.addItemName(e.getTemplate()); + sm.addLong(required); + player.sendPacket(sm); + } return; } } @@ -253,7 +262,7 @@ public class MultiSellChoose implements IClientIncomingPacket // if it's a stackable item, just reduce the amount from the first (only) instance that is found in the inventory if (itemToTake.isStackable()) { - if (!player.destroyItem("Multisell", itemToTake.getObjectId(), (e.getItemCount() * _amount), player.getTarget(), true)) + if (!player.destroyItem("Multisell", itemToTake.getObjectId(), e.getItemCount() * _amount, player.getTarget(), true)) { player.setMultiSell(null); return; @@ -266,7 +275,7 @@ public class MultiSellChoose implements IClientIncomingPacket // b) list does not maintain enchantment: get the instances with the LOWEST enchantment level // a) if enchantment is maintained, then get a list of items that exactly match this enchantment - if (list.getMaintainEnchantment()) + if (list.getMaintainEnchantment() || (e.getEnchantLevel() > 0)) { // loop through this list and remove (one by one) each item until the required amount is taken. final L2ItemInstance[] inventoryContents = inv.getAllItemsByItemId(e.getItemId(), e.getEnchantLevel(), false).toArray(new L2ItemInstance[0]); @@ -329,7 +338,7 @@ public class MultiSellChoose implements IClientIncomingPacket { for (L2ItemInstance item : inventoryContents) { - if (item.getEnchantLevel() < itemToTake.getEnchantLevel()) + if ((item.getEnchantLevel() < itemToTake.getEnchantLevel()) && (item.getEnchantLevel() >= e.getEnchantLevel())) { itemToTake = item; // nothing will have enchantment less than 0. If a zero-enchanted @@ -369,7 +378,7 @@ public class MultiSellChoose implements IClientIncomingPacket } // Calculate chance - matched = (itemRandom < (cumulativeChance += e.getChance())); + matched = itemRandom < (cumulativeChance += e.getChance()); if (!matched) { continue; @@ -388,47 +397,51 @@ public class MultiSellChoose implements IClientIncomingPacket } else { + L2ItemInstance product = null; for (int i = 0; i < (e.getItemCount() * _amount); i++) { - final L2ItemInstance product = inv.addItem("Multisell", e.getItemId(), 1, player, player.getTarget()); - if ((product != null) && list.getMaintainEnchantment()) + product = inv.addItem("Multisell", e.getItemId(), 1, player, player.getTarget()); + if ((product != null) && (list.getMaintainEnchantment() || (e.getEnchantLevel() > 0))) { final ItemInfo info = originalInfos.get(i); - if (info.getAugmentId() > 0) + if (info != null) { - product.setAugmentation(new L2Augmentation(info.getAugmentId())); - } - if (info.getElementals().length > 0) - { - Arrays.stream(info.getElementals()).filter(Objects::nonNull).forEach(product::setAttribute); - } - if (info.getVisualId() > 0) - { - product.setVisualId(info.getVisualId()); - if (info.getVisualStoneId() > 0) + if (info.getAugmentId() > 0) { - product.getVariables().set(ItemVariables.VISUAL_APPEARANCE_STONE_ID, info.getVisualStoneId()); + product.setAugmentation(new L2Augmentation(info.getAugmentId())); } - if (info.getVisualIdLifeTime() > 0) + if (info.getElementals().length > 0) { - product.getVariables().set(ItemVariables.VISUAL_APPEARANCE_LIFE_TIME, info.getVisualIdLifeTime()); - product.scheduleVisualLifeTime(); + Arrays.stream(info.getElementals()).filter(Objects::nonNull).forEach(product::setAttribute); } - } - if (!info.getSpecialAbilities().isEmpty()) - { - int position = 0; - for (EnsoulOption option : info.getSpecialAbilities()) + if (info.getVisualId() > 0) { - product.addSpecialAbility(option, position++, 1, true); + product.setVisualId(info.getVisualId()); + if (info.getVisualStoneId() > 0) + { + product.getVariables().set(ItemVariables.VISUAL_APPEARANCE_STONE_ID, info.getVisualStoneId()); + } + if (info.getVisualIdLifeTime() > 0) + { + product.getVariables().set(ItemVariables.VISUAL_APPEARANCE_LIFE_TIME, info.getVisualIdLifeTime()); + product.scheduleVisualLifeTime(); + } } - } - if (!info.getAdditionalSpecialAbilities().isEmpty()) - { - int position = 0; - for (EnsoulOption option : info.getAdditionalSpecialAbilities()) + if (!info.getSpecialAbilities().isEmpty()) { - product.addSpecialAbility(option, position++, 2, true); + int position = 0; + for (EnsoulOption option : info.getSpecialAbilities()) + { + product.addSpecialAbility(option, position++, 1, true); + } + } + if (!info.getAdditionalSpecialAbilities().isEmpty()) + { + int position = 0; + for (EnsoulOption option : info.getAdditionalSpecialAbilities()) + { + product.addSpecialAbility(option, position++, 2, true); + } } } product.setEnchantLevel(e.getEnchantLevel()); diff --git a/trunk/java/com/l2jmobius/gameserver/network/serverpackets/MultiSellList.java b/trunk/java/com/l2jmobius/gameserver/network/serverpackets/MultiSellList.java index 560b713f48..f3e5788121 100644 --- a/trunk/java/com/l2jmobius/gameserver/network/serverpackets/MultiSellList.java +++ b/trunk/java/com/l2jmobius/gameserver/network/serverpackets/MultiSellList.java @@ -138,7 +138,7 @@ public final class MultiSellList implements IClientOutgoingPacket } else { - packet.writeH(0x00); // enchant level + packet.writeH(ing.getEnchantLevel()); // enchant level packet.writeD(ing.getChance()); // augment id packet.writeD(0x00); // mana packet.writeD(0x00); // time ? @@ -196,7 +196,7 @@ public final class MultiSellList implements IClientOutgoingPacket } else { - packet.writeH(0x00); // enchant level + packet.writeH(ing.getEnchantLevel()); // enchant level packet.writeD(ing.getChance()); // augment id packet.writeD(0x00); // mana packet.writeH(0x00); // attack element