Multisell enchanted items support.
This commit is contained in:
parent
6382642e1a
commit
1db5262d58
@ -88,7 +88,7 @@ public final class MultisellData implements IGameXmlReader
|
||||
{
|
||||
if ("item".equalsIgnoreCase(itemNode.getNodeName()))
|
||||
{
|
||||
final List<ItemHolder> ingredients = new ArrayList<>(1);
|
||||
final List<ItemChanceHolder> ingredients = new ArrayList<>(1);
|
||||
final List<ItemChanceHolder> products = new ArrayList<>(1);
|
||||
final MultisellEntryHolder entry = new MultisellEntryHolder(ingredients, products);
|
||||
|
||||
@ -98,7 +98,8 @@ public final class MultisellData implements IGameXmlReader
|
||||
{
|
||||
final int id = parseInteger(d.getAttributes(), "id");
|
||||
final long count = parseLong(d.getAttributes(), "count");
|
||||
final ItemHolder ingredient = new ItemHolder(id, count);
|
||||
final byte enchantmentLevel = parseByte(d.getAttributes(), "enchantmentLevel", (byte) 0);
|
||||
final ItemChanceHolder ingredient = new ItemChanceHolder(id, 0, count, enchantmentLevel);
|
||||
|
||||
if (itemExists(ingredient))
|
||||
{
|
||||
@ -115,7 +116,8 @@ public final class MultisellData implements IGameXmlReader
|
||||
final int id = parseInteger(d.getAttributes(), "id");
|
||||
final long count = parseLong(d.getAttributes(), "count");
|
||||
final double chance = parseDouble(d.getAttributes(), "chance", Double.NaN);
|
||||
final ItemChanceHolder product = new ItemChanceHolder(id, chance, count);
|
||||
final byte enchantmentLevel = parseByte(d.getAttributes(), "enchantmentLevel", (byte) 0);
|
||||
final ItemChanceHolder product = new ItemChanceHolder(id, chance, count, enchantmentLevel);
|
||||
|
||||
if (itemExists(product))
|
||||
{
|
||||
|
@ -28,6 +28,7 @@ import com.l2jmobius.commons.util.Rnd;
|
||||
public class ItemChanceHolder extends ItemHolder
|
||||
{
|
||||
private final double _chance;
|
||||
private final byte _enchantmentLevel;
|
||||
|
||||
public ItemChanceHolder(int id, double chance)
|
||||
{
|
||||
@ -38,6 +39,14 @@ public class ItemChanceHolder extends ItemHolder
|
||||
{
|
||||
super(id, count);
|
||||
_chance = chance;
|
||||
_enchantmentLevel = 0;
|
||||
}
|
||||
|
||||
public ItemChanceHolder(int id, double chance, long count, byte enchantmentLevel)
|
||||
{
|
||||
super(id, count);
|
||||
_chance = chance;
|
||||
_enchantmentLevel = enchantmentLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -49,6 +58,15 @@ public class ItemChanceHolder extends ItemHolder
|
||||
return _chance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the enchant level.
|
||||
* @return the enchant level of the item contained in this object
|
||||
*/
|
||||
public byte getEnchantmentLevel()
|
||||
{
|
||||
return _enchantmentLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a cumulative chance of all given holders. If all holders' chance sum up to 100% or above, there is 100% guarantee a holder will be selected.
|
||||
* @param holders list of holders to calculate chance from.
|
||||
|
@ -29,17 +29,17 @@ import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
public class MultisellEntryHolder
|
||||
{
|
||||
private final boolean _stackable;
|
||||
private final List<ItemHolder> _ingredients;
|
||||
private final List<ItemChanceHolder> _ingredients;
|
||||
private final List<ItemChanceHolder> _products;
|
||||
|
||||
public MultisellEntryHolder(List<ItemHolder> ingredients, List<ItemChanceHolder> products)
|
||||
public MultisellEntryHolder(List<ItemChanceHolder> ingredients, List<ItemChanceHolder> products)
|
||||
{
|
||||
_ingredients = Collections.unmodifiableList(ingredients);
|
||||
_products = Collections.unmodifiableList(products);
|
||||
_stackable = products.stream().map(i -> ItemTable.getInstance().getTemplate(i.getId())).filter(Objects::nonNull).allMatch(L2Item::isStackable);
|
||||
}
|
||||
|
||||
public final List<ItemHolder> getIngredients()
|
||||
public final List<ItemChanceHolder> getIngredients()
|
||||
{
|
||||
return _ingredients;
|
||||
}
|
||||
|
@ -435,6 +435,21 @@ public class PcInventory extends Inventory
|
||||
*/
|
||||
@Override
|
||||
public L2ItemInstance addItem(String process, int itemId, long count, L2PcInstance actor, Object reference)
|
||||
{
|
||||
return addItem(process, itemId, count, actor, reference, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds item in inventory and checks _adena and _ancientAdena
|
||||
* @param process : String Identifier of process triggering this action
|
||||
* @param itemId : int Item Identifier of the item to be added
|
||||
* @param count : int Quantity of items to be added
|
||||
* @param actor : L2PcInstance Player requesting the item creation
|
||||
* @param reference : Object Object referencing current action like NPC selling item or previous item in transformation
|
||||
* @param update : Update inventory (not used by MultiSellChoose packet / it sends update after finish)
|
||||
* @return L2ItemInstance corresponding to the new item or the updated item in inventory
|
||||
*/
|
||||
public L2ItemInstance addItem(String process, int itemId, long count, L2PcInstance actor, Object reference, boolean update)
|
||||
{
|
||||
final L2ItemInstance item = super.addItem(process, itemId, count, actor, reference);
|
||||
if (item != null)
|
||||
@ -456,15 +471,18 @@ public class PcInventory extends Inventory
|
||||
if ((item != null) && (actor != null))
|
||||
{
|
||||
// Send inventory update packet
|
||||
if (!Config.FORCE_INVENTORY_UPDATE)
|
||||
if (update)
|
||||
{
|
||||
final InventoryUpdate playerIU = new InventoryUpdate();
|
||||
playerIU.addItem(item);
|
||||
actor.sendInventoryUpdate(playerIU);
|
||||
}
|
||||
else
|
||||
{
|
||||
actor.sendItemList(false);
|
||||
if (!Config.FORCE_INVENTORY_UPDATE)
|
||||
{
|
||||
final InventoryUpdate playerIU = new InventoryUpdate();
|
||||
playerIU.addItem(item);
|
||||
actor.sendInventoryUpdate(playerIU);
|
||||
}
|
||||
else
|
||||
{
|
||||
actor.sendItemList(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Notify to scripts
|
||||
|
@ -33,7 +33,6 @@ import com.l2jmobius.gameserver.model.L2Clan;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemChanceHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.MultisellEntryHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.PreparedMultisellListHolder;
|
||||
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||
@ -243,6 +242,33 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
// Summarize all item counts into one map. That would include non-stackable items under 1 id and multiple count.
|
||||
final Map<Integer, Long> itemIdCount = entry.getIngredients().stream().collect(Collectors.toMap(i -> i.getId(), i -> list.getIngredientCount(i), (k1, k2) -> Math.addExact(k1, k2)));
|
||||
|
||||
// Check for enchanted level requirements.
|
||||
for (ItemChanceHolder ingredient : entry.getIngredients())
|
||||
{
|
||||
if (ingredient.getEnchantmentLevel() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int found = 0;
|
||||
for (L2ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
|
||||
{
|
||||
if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
|
||||
{
|
||||
found++;
|
||||
}
|
||||
}
|
||||
|
||||
if (found < ingredient.getCount())
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
|
||||
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
|
||||
player.sendPacket(sm);
|
||||
return;
|
||||
}
|
||||
|
||||
itemIdCount.remove(ingredient.getId()); // Since we check now.
|
||||
}
|
||||
|
||||
// Now check if the player has sufficient items in the inventory to cover the ingredients' expences. Take care for non-stackable items like 2 swords to dual.
|
||||
boolean allOk = true;
|
||||
for (Entry<Integer, Long> idCount : itemIdCount.entrySet())
|
||||
@ -260,7 +286,7 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
boolean itemEnchantmentProcessed = (itemEnchantment == null);
|
||||
|
||||
// Take all ingredients
|
||||
for (ItemHolder ingredient : entry.getIngredients())
|
||||
for (ItemChanceHolder ingredient : entry.getIngredients())
|
||||
{
|
||||
final long totalCount = Math.multiplyExact(list.getIngredientCount(ingredient), _amount);
|
||||
final SpecialItemType specialItem = SpecialItemType.getByClientId(ingredient.getId());
|
||||
@ -306,6 +332,23 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ingredient.getEnchantmentLevel() > 0)
|
||||
{
|
||||
// Take the enchanted item.
|
||||
final L2ItemInstance destroyedItem = inventory.destroyItem("Multisell", inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()).iterator().next(), totalCount, player, npc);
|
||||
if (destroyedItem != null)
|
||||
{
|
||||
itemEnchantmentProcessed = true;
|
||||
iu.addItem(destroyedItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
|
||||
sm.addItemName(ingredient.getId());
|
||||
player.sendPacket(sm);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!itemEnchantmentProcessed && (itemEnchantment != null) && (itemEnchantment.getItem().getId() == ingredient.getId()))
|
||||
{
|
||||
// Take the enchanted item.
|
||||
@ -390,8 +433,7 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
else
|
||||
{
|
||||
// Give item.
|
||||
final L2ItemInstance addedItem = inventory.addItem("Multisell", product.getId(), totalCount, player, npc);
|
||||
iu.addItem(addedItem);
|
||||
final L2ItemInstance addedItem = inventory.addItem("Multisell", product.getId(), totalCount, player, npc, false);
|
||||
|
||||
// Check if the newly given item should be enchanted.
|
||||
if (itemEnchantmentProcessed && list.isMaintainEnchantment() && (itemEnchantment != null) && addedItem.isEquipable() && addedItem.getItem().getClass().equals(itemEnchantment.getItem().getClass()))
|
||||
@ -405,12 +447,15 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
addedItem.setAttribute(new AttributeHolder(AttributeType.EARTH, itemEnchantment.getAttributeDefence(AttributeType.EARTH)), false);
|
||||
addedItem.setAttribute(new AttributeHolder(AttributeType.HOLY, itemEnchantment.getAttributeDefence(AttributeType.HOLY)), false);
|
||||
addedItem.setAttribute(new AttributeHolder(AttributeType.DARK, itemEnchantment.getAttributeDefence(AttributeType.DARK)), false);
|
||||
|
||||
addedItem.updateDatabase();
|
||||
|
||||
// Mark that we have already upgraded the item.
|
||||
itemEnchantmentProcessed = false;
|
||||
}
|
||||
if (product.getEnchantmentLevel() > 0)
|
||||
{
|
||||
addedItem.setEnchantLevel(product.getEnchantmentLevel());
|
||||
addedItem.updateDatabase();
|
||||
}
|
||||
|
||||
if (addedItem.getCount() > 1)
|
||||
{
|
||||
@ -432,6 +477,9 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
sm.addItemName(addedItem);
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
|
||||
// Inventory update.
|
||||
iu.addItem(addedItem);
|
||||
}
|
||||
}
|
||||
|
||||
@ -470,7 +518,7 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
* @param totalCount
|
||||
* @return {@code false} if ingredient amount is not enough, {@code true} otherwise.
|
||||
*/
|
||||
private boolean checkIngredients(final L2PcInstance player, PreparedMultisellListHolder list, final PcInventory inventory, final L2Clan clan, final int ingredientId, final long totalCount)
|
||||
private boolean checkIngredients(L2PcInstance player, PreparedMultisellListHolder list, PcInventory inventory, L2Clan clan, int ingredientId, long totalCount)
|
||||
{
|
||||
final SpecialItemType specialItem = SpecialItemType.getByClientId(ingredientId);
|
||||
if (specialItem != null)
|
||||
|
@ -22,7 +22,6 @@ import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.model.ItemInfo;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemChanceHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.MultisellEntryHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.PreparedMultisellListHolder;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
@ -96,13 +95,13 @@ public final class MultiSellList extends AbstractItemPacket
|
||||
packet.writeH(65535);
|
||||
}
|
||||
packet.writeQ(_list.getProductCount(product));
|
||||
packet.writeH(displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
packet.writeH(product.getEnchantmentLevel() > 0 ? product.getEnchantmentLevel() : displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
packet.writeD((int) Math.ceil(product.getChance())); // chance
|
||||
writeItemAugment(packet, displayItemEnchantment);
|
||||
writeItemElemental(packet, displayItemEnchantment);
|
||||
}
|
||||
|
||||
for (ItemHolder ingredient : entry.getIngredients())
|
||||
for (ItemChanceHolder ingredient : entry.getIngredients())
|
||||
{
|
||||
final L2Item template = ItemTable.getInstance().getTemplate(ingredient.getId());
|
||||
final ItemInfo displayItemEnchantment = ((itemEnchantment != null) && (itemEnchantment.getItem().getId() == ingredient.getId())) ? itemEnchantment : null;
|
||||
@ -110,7 +109,7 @@ public final class MultiSellList extends AbstractItemPacket
|
||||
packet.writeD(ingredient.getId());
|
||||
packet.writeH(template != null ? template.getType2() : 65535);
|
||||
packet.writeQ(_list.getIngredientCount(ingredient));
|
||||
packet.writeH(displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
packet.writeH(ingredient.getEnchantmentLevel() > 0 ? ingredient.getEnchantmentLevel() : displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
writeItemAugment(packet, displayItemEnchantment);
|
||||
writeItemElemental(packet, displayItemEnchantment);
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ public final class MultisellData implements IGameXmlReader
|
||||
{
|
||||
if ("item".equalsIgnoreCase(itemNode.getNodeName()))
|
||||
{
|
||||
final List<ItemHolder> ingredients = new ArrayList<>(1);
|
||||
final List<ItemChanceHolder> ingredients = new ArrayList<>(1);
|
||||
final List<ItemChanceHolder> products = new ArrayList<>(1);
|
||||
final MultisellEntryHolder entry = new MultisellEntryHolder(ingredients, products);
|
||||
|
||||
@ -98,7 +98,8 @@ public final class MultisellData implements IGameXmlReader
|
||||
{
|
||||
final int id = parseInteger(d.getAttributes(), "id");
|
||||
final long count = parseLong(d.getAttributes(), "count");
|
||||
final ItemHolder ingredient = new ItemHolder(id, count);
|
||||
final byte enchantmentLevel = parseByte(d.getAttributes(), "enchantmentLevel", (byte) 0);
|
||||
final ItemChanceHolder ingredient = new ItemChanceHolder(id, 0, count, enchantmentLevel);
|
||||
|
||||
if (itemExists(ingredient))
|
||||
{
|
||||
@ -115,7 +116,8 @@ public final class MultisellData implements IGameXmlReader
|
||||
final int id = parseInteger(d.getAttributes(), "id");
|
||||
final long count = parseLong(d.getAttributes(), "count");
|
||||
final double chance = parseDouble(d.getAttributes(), "chance", Double.NaN);
|
||||
final ItemChanceHolder product = new ItemChanceHolder(id, chance, count);
|
||||
final byte enchantmentLevel = parseByte(d.getAttributes(), "enchantmentLevel", (byte) 0);
|
||||
final ItemChanceHolder product = new ItemChanceHolder(id, chance, count, enchantmentLevel);
|
||||
|
||||
if (itemExists(product))
|
||||
{
|
||||
|
@ -28,6 +28,7 @@ import com.l2jmobius.commons.util.Rnd;
|
||||
public class ItemChanceHolder extends ItemHolder
|
||||
{
|
||||
private final double _chance;
|
||||
private final byte _enchantmentLevel;
|
||||
|
||||
public ItemChanceHolder(int id, double chance)
|
||||
{
|
||||
@ -38,6 +39,14 @@ public class ItemChanceHolder extends ItemHolder
|
||||
{
|
||||
super(id, count);
|
||||
_chance = chance;
|
||||
_enchantmentLevel = 0;
|
||||
}
|
||||
|
||||
public ItemChanceHolder(int id, double chance, long count, byte enchantmentLevel)
|
||||
{
|
||||
super(id, count);
|
||||
_chance = chance;
|
||||
_enchantmentLevel = enchantmentLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -49,6 +58,15 @@ public class ItemChanceHolder extends ItemHolder
|
||||
return _chance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the enchant level.
|
||||
* @return the enchant level of the item contained in this object
|
||||
*/
|
||||
public byte getEnchantmentLevel()
|
||||
{
|
||||
return _enchantmentLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a cumulative chance of all given holders. If all holders' chance sum up to 100% or above, there is 100% guarantee a holder will be selected.
|
||||
* @param holders list of holders to calculate chance from.
|
||||
|
@ -29,17 +29,17 @@ import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
public class MultisellEntryHolder
|
||||
{
|
||||
private final boolean _stackable;
|
||||
private final List<ItemHolder> _ingredients;
|
||||
private final List<ItemChanceHolder> _ingredients;
|
||||
private final List<ItemChanceHolder> _products;
|
||||
|
||||
public MultisellEntryHolder(List<ItemHolder> ingredients, List<ItemChanceHolder> products)
|
||||
public MultisellEntryHolder(List<ItemChanceHolder> ingredients, List<ItemChanceHolder> products)
|
||||
{
|
||||
_ingredients = Collections.unmodifiableList(ingredients);
|
||||
_products = Collections.unmodifiableList(products);
|
||||
_stackable = products.stream().map(i -> ItemTable.getInstance().getTemplate(i.getId())).filter(Objects::nonNull).allMatch(L2Item::isStackable);
|
||||
}
|
||||
|
||||
public final List<ItemHolder> getIngredients()
|
||||
public final List<ItemChanceHolder> getIngredients()
|
||||
{
|
||||
return _ingredients;
|
||||
}
|
||||
|
@ -435,6 +435,21 @@ public class PcInventory extends Inventory
|
||||
*/
|
||||
@Override
|
||||
public L2ItemInstance addItem(String process, int itemId, long count, L2PcInstance actor, Object reference)
|
||||
{
|
||||
return addItem(process, itemId, count, actor, reference, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds item in inventory and checks _adena and _ancientAdena
|
||||
* @param process : String Identifier of process triggering this action
|
||||
* @param itemId : int Item Identifier of the item to be added
|
||||
* @param count : int Quantity of items to be added
|
||||
* @param actor : L2PcInstance Player requesting the item creation
|
||||
* @param reference : Object Object referencing current action like NPC selling item or previous item in transformation
|
||||
* @param update : Update inventory (not used by MultiSellChoose packet / it sends update after finish)
|
||||
* @return L2ItemInstance corresponding to the new item or the updated item in inventory
|
||||
*/
|
||||
public L2ItemInstance addItem(String process, int itemId, long count, L2PcInstance actor, Object reference, boolean update)
|
||||
{
|
||||
final L2ItemInstance item = super.addItem(process, itemId, count, actor, reference);
|
||||
if (item != null)
|
||||
@ -456,15 +471,18 @@ public class PcInventory extends Inventory
|
||||
if ((item != null) && (actor != null))
|
||||
{
|
||||
// Send inventory update packet
|
||||
if (!Config.FORCE_INVENTORY_UPDATE)
|
||||
if (update)
|
||||
{
|
||||
final InventoryUpdate playerIU = new InventoryUpdate();
|
||||
playerIU.addItem(item);
|
||||
actor.sendInventoryUpdate(playerIU);
|
||||
}
|
||||
else
|
||||
{
|
||||
actor.sendItemList(false);
|
||||
if (!Config.FORCE_INVENTORY_UPDATE)
|
||||
{
|
||||
final InventoryUpdate playerIU = new InventoryUpdate();
|
||||
playerIU.addItem(item);
|
||||
actor.sendInventoryUpdate(playerIU);
|
||||
}
|
||||
else
|
||||
{
|
||||
actor.sendItemList(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Notify to scripts
|
||||
|
@ -36,7 +36,6 @@ import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.ensoul.EnsoulOption;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemChanceHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.MultisellEntryHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.PreparedMultisellListHolder;
|
||||
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||
@ -271,6 +270,33 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
// Summarize all item counts into one map. That would include non-stackable items under 1 id and multiple count.
|
||||
final Map<Integer, Long> itemIdCount = entry.getIngredients().stream().collect(Collectors.toMap(i -> i.getId(), i -> list.getIngredientCount(i), (k1, k2) -> Math.addExact(k1, k2)));
|
||||
|
||||
// Check for enchanted level requirements.
|
||||
for (ItemChanceHolder ingredient : entry.getIngredients())
|
||||
{
|
||||
if (ingredient.getEnchantmentLevel() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int found = 0;
|
||||
for (L2ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
|
||||
{
|
||||
if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
|
||||
{
|
||||
found++;
|
||||
}
|
||||
}
|
||||
|
||||
if (found < ingredient.getCount())
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
|
||||
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
|
||||
player.sendPacket(sm);
|
||||
return;
|
||||
}
|
||||
|
||||
itemIdCount.remove(ingredient.getId()); // Since we check now.
|
||||
}
|
||||
|
||||
// Now check if the player has sufficient items in the inventory to cover the ingredients' expences. Take care for non-stackable items like 2 swords to dual.
|
||||
boolean allOk = true;
|
||||
for (Entry<Integer, Long> idCount : itemIdCount.entrySet())
|
||||
@ -288,7 +314,7 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
boolean itemEnchantmentProcessed = (itemEnchantment == null);
|
||||
|
||||
// Take all ingredients
|
||||
for (ItemHolder ingredient : entry.getIngredients())
|
||||
for (ItemChanceHolder ingredient : entry.getIngredients())
|
||||
{
|
||||
final long totalCount = Math.multiplyExact(list.getIngredientCount(ingredient), _amount);
|
||||
final SpecialItemType specialItem = SpecialItemType.getByClientId(ingredient.getId());
|
||||
@ -334,6 +360,23 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ingredient.getEnchantmentLevel() > 0)
|
||||
{
|
||||
// Take the enchanted item.
|
||||
final L2ItemInstance destroyedItem = inventory.destroyItem("Multisell", inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()).iterator().next(), totalCount, player, npc);
|
||||
if (destroyedItem != null)
|
||||
{
|
||||
itemEnchantmentProcessed = true;
|
||||
iu.addItem(destroyedItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
|
||||
sm.addItemName(ingredient.getId());
|
||||
player.sendPacket(sm);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!itemEnchantmentProcessed && (itemEnchantment != null) && (itemEnchantment.getItem().getId() == ingredient.getId()))
|
||||
{
|
||||
// Take the enchanted item.
|
||||
@ -418,8 +461,7 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
else
|
||||
{
|
||||
// Give item.
|
||||
final L2ItemInstance addedItem = inventory.addItem("Multisell", product.getId(), totalCount, player, npc);
|
||||
iu.addItem(addedItem);
|
||||
final L2ItemInstance addedItem = inventory.addItem("Multisell", product.getId(), totalCount, player, npc, false);
|
||||
|
||||
// Check if the newly given item should be enchanted.
|
||||
if (itemEnchantmentProcessed && list.isMaintainEnchantment() && (itemEnchantment != null) && addedItem.isEquipable() && addedItem.getItem().getClass().equals(itemEnchantment.getItem().getClass()))
|
||||
@ -447,12 +489,15 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
addedItem.addSpecialAbility(_soulCrystalSpecialOptions[i], i + 1, 2, false);
|
||||
}
|
||||
}
|
||||
|
||||
addedItem.updateDatabase();
|
||||
|
||||
// Mark that we have already upgraded the item.
|
||||
itemEnchantmentProcessed = false;
|
||||
}
|
||||
if (product.getEnchantmentLevel() > 0)
|
||||
{
|
||||
addedItem.setEnchantLevel(product.getEnchantmentLevel());
|
||||
addedItem.updateDatabase();
|
||||
}
|
||||
|
||||
if (addedItem.getCount() > 1)
|
||||
{
|
||||
@ -474,6 +519,9 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
sm.addItemName(addedItem);
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
|
||||
// Inventory update.
|
||||
iu.addItem(addedItem);
|
||||
}
|
||||
}
|
||||
|
||||
@ -512,7 +560,7 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
* @param totalCount
|
||||
* @return {@code false} if ingredient amount is not enough, {@code true} otherwise.
|
||||
*/
|
||||
private boolean checkIngredients(final L2PcInstance player, PreparedMultisellListHolder list, final PcInventory inventory, final L2Clan clan, final int ingredientId, final long totalCount)
|
||||
private boolean checkIngredients(L2PcInstance player, PreparedMultisellListHolder list, PcInventory inventory, L2Clan clan, int ingredientId, long totalCount)
|
||||
{
|
||||
final SpecialItemType specialItem = SpecialItemType.getByClientId(ingredientId);
|
||||
if (specialItem != null)
|
||||
|
@ -22,7 +22,6 @@ import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.model.ItemInfo;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemChanceHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.MultisellEntryHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.PreparedMultisellListHolder;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
@ -97,14 +96,14 @@ public final class MultiSellList extends AbstractItemPacket
|
||||
packet.writeH(65535);
|
||||
}
|
||||
packet.writeQ(_list.getProductCount(product));
|
||||
packet.writeH(displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
packet.writeH(product.getEnchantmentLevel() > 0 ? product.getEnchantmentLevel() : displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
packet.writeD((int) Math.ceil(product.getChance())); // chance
|
||||
writeItemAugment(packet, displayItemEnchantment);
|
||||
writeItemElemental(packet, displayItemEnchantment);
|
||||
writeItemEnsoulOptions(packet, displayItemEnchantment);
|
||||
}
|
||||
|
||||
for (ItemHolder ingredient : entry.getIngredients())
|
||||
for (ItemChanceHolder ingredient : entry.getIngredients())
|
||||
{
|
||||
final L2Item template = ItemTable.getInstance().getTemplate(ingredient.getId());
|
||||
final ItemInfo displayItemEnchantment = ((itemEnchantment != null) && (itemEnchantment.getItem().getId() == ingredient.getId())) ? itemEnchantment : null;
|
||||
@ -112,7 +111,7 @@ public final class MultiSellList extends AbstractItemPacket
|
||||
packet.writeD(ingredient.getId());
|
||||
packet.writeH(template != null ? template.getType2() : 65535);
|
||||
packet.writeQ(_list.getIngredientCount(ingredient));
|
||||
packet.writeH(displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
packet.writeH(ingredient.getEnchantmentLevel() > 0 ? ingredient.getEnchantmentLevel() : displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
writeItemAugment(packet, displayItemEnchantment);
|
||||
writeItemElemental(packet, displayItemEnchantment);
|
||||
writeItemEnsoulOptions(packet, displayItemEnchantment);
|
||||
|
@ -88,7 +88,7 @@ public final class MultisellData implements IGameXmlReader
|
||||
{
|
||||
if ("item".equalsIgnoreCase(itemNode.getNodeName()))
|
||||
{
|
||||
final List<ItemHolder> ingredients = new ArrayList<>(1);
|
||||
final List<ItemChanceHolder> ingredients = new ArrayList<>(1);
|
||||
final List<ItemChanceHolder> products = new ArrayList<>(1);
|
||||
final MultisellEntryHolder entry = new MultisellEntryHolder(ingredients, products);
|
||||
|
||||
@ -98,7 +98,8 @@ public final class MultisellData implements IGameXmlReader
|
||||
{
|
||||
final int id = parseInteger(d.getAttributes(), "id");
|
||||
final long count = parseLong(d.getAttributes(), "count");
|
||||
final ItemHolder ingredient = new ItemHolder(id, count);
|
||||
final byte enchantmentLevel = parseByte(d.getAttributes(), "enchantmentLevel", (byte) 0);
|
||||
final ItemChanceHolder ingredient = new ItemChanceHolder(id, 0, count, enchantmentLevel);
|
||||
|
||||
if (itemExists(ingredient))
|
||||
{
|
||||
@ -115,7 +116,8 @@ public final class MultisellData implements IGameXmlReader
|
||||
final int id = parseInteger(d.getAttributes(), "id");
|
||||
final long count = parseLong(d.getAttributes(), "count");
|
||||
final double chance = parseDouble(d.getAttributes(), "chance", Double.NaN);
|
||||
final ItemChanceHolder product = new ItemChanceHolder(id, chance, count);
|
||||
final byte enchantmentLevel = parseByte(d.getAttributes(), "enchantmentLevel", (byte) 0);
|
||||
final ItemChanceHolder product = new ItemChanceHolder(id, chance, count, enchantmentLevel);
|
||||
|
||||
if (itemExists(product))
|
||||
{
|
||||
|
@ -28,6 +28,7 @@ import com.l2jmobius.commons.util.Rnd;
|
||||
public class ItemChanceHolder extends ItemHolder
|
||||
{
|
||||
private final double _chance;
|
||||
private final byte _enchantmentLevel;
|
||||
|
||||
public ItemChanceHolder(int id, double chance)
|
||||
{
|
||||
@ -38,6 +39,14 @@ public class ItemChanceHolder extends ItemHolder
|
||||
{
|
||||
super(id, count);
|
||||
_chance = chance;
|
||||
_enchantmentLevel = 0;
|
||||
}
|
||||
|
||||
public ItemChanceHolder(int id, double chance, long count, byte enchantmentLevel)
|
||||
{
|
||||
super(id, count);
|
||||
_chance = chance;
|
||||
_enchantmentLevel = enchantmentLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -49,6 +58,15 @@ public class ItemChanceHolder extends ItemHolder
|
||||
return _chance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the enchant level.
|
||||
* @return the enchant level of the item contained in this object
|
||||
*/
|
||||
public byte getEnchantmentLevel()
|
||||
{
|
||||
return _enchantmentLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a cumulative chance of all given holders. If all holders' chance sum up to 100% or above, there is 100% guarantee a holder will be selected.
|
||||
* @param holders list of holders to calculate chance from.
|
||||
|
@ -29,17 +29,17 @@ import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
public class MultisellEntryHolder
|
||||
{
|
||||
private final boolean _stackable;
|
||||
private final List<ItemHolder> _ingredients;
|
||||
private final List<ItemChanceHolder> _ingredients;
|
||||
private final List<ItemChanceHolder> _products;
|
||||
|
||||
public MultisellEntryHolder(List<ItemHolder> ingredients, List<ItemChanceHolder> products)
|
||||
public MultisellEntryHolder(List<ItemChanceHolder> ingredients, List<ItemChanceHolder> products)
|
||||
{
|
||||
_ingredients = Collections.unmodifiableList(ingredients);
|
||||
_products = Collections.unmodifiableList(products);
|
||||
_stackable = products.stream().map(i -> ItemTable.getInstance().getTemplate(i.getId())).filter(Objects::nonNull).allMatch(L2Item::isStackable);
|
||||
}
|
||||
|
||||
public final List<ItemHolder> getIngredients()
|
||||
public final List<ItemChanceHolder> getIngredients()
|
||||
{
|
||||
return _ingredients;
|
||||
}
|
||||
|
@ -435,6 +435,21 @@ public class PcInventory extends Inventory
|
||||
*/
|
||||
@Override
|
||||
public L2ItemInstance addItem(String process, int itemId, long count, L2PcInstance actor, Object reference)
|
||||
{
|
||||
return addItem(process, itemId, count, actor, reference, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds item in inventory and checks _adena and _ancientAdena
|
||||
* @param process : String Identifier of process triggering this action
|
||||
* @param itemId : int Item Identifier of the item to be added
|
||||
* @param count : int Quantity of items to be added
|
||||
* @param actor : L2PcInstance Player requesting the item creation
|
||||
* @param reference : Object Object referencing current action like NPC selling item or previous item in transformation
|
||||
* @param update : Update inventory (not used by MultiSellChoose packet / it sends update after finish)
|
||||
* @return L2ItemInstance corresponding to the new item or the updated item in inventory
|
||||
*/
|
||||
public L2ItemInstance addItem(String process, int itemId, long count, L2PcInstance actor, Object reference, boolean update)
|
||||
{
|
||||
final L2ItemInstance item = super.addItem(process, itemId, count, actor, reference);
|
||||
if (item != null)
|
||||
@ -456,15 +471,18 @@ public class PcInventory extends Inventory
|
||||
if ((item != null) && (actor != null))
|
||||
{
|
||||
// Send inventory update packet
|
||||
if (!Config.FORCE_INVENTORY_UPDATE)
|
||||
if (update)
|
||||
{
|
||||
final InventoryUpdate playerIU = new InventoryUpdate();
|
||||
playerIU.addItem(item);
|
||||
actor.sendInventoryUpdate(playerIU);
|
||||
}
|
||||
else
|
||||
{
|
||||
actor.sendItemList(false);
|
||||
if (!Config.FORCE_INVENTORY_UPDATE)
|
||||
{
|
||||
final InventoryUpdate playerIU = new InventoryUpdate();
|
||||
playerIU.addItem(item);
|
||||
actor.sendInventoryUpdate(playerIU);
|
||||
}
|
||||
else
|
||||
{
|
||||
actor.sendItemList(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Notify to scripts
|
||||
|
@ -36,7 +36,6 @@ import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.ensoul.EnsoulOption;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemChanceHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.MultisellEntryHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.PreparedMultisellListHolder;
|
||||
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||
@ -271,6 +270,33 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
// Summarize all item counts into one map. That would include non-stackable items under 1 id and multiple count.
|
||||
final Map<Integer, Long> itemIdCount = entry.getIngredients().stream().collect(Collectors.toMap(i -> i.getId(), i -> list.getIngredientCount(i), (k1, k2) -> Math.addExact(k1, k2)));
|
||||
|
||||
// Check for enchanted level requirements.
|
||||
for (ItemChanceHolder ingredient : entry.getIngredients())
|
||||
{
|
||||
if (ingredient.getEnchantmentLevel() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int found = 0;
|
||||
for (L2ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
|
||||
{
|
||||
if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
|
||||
{
|
||||
found++;
|
||||
}
|
||||
}
|
||||
|
||||
if (found < ingredient.getCount())
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
|
||||
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
|
||||
player.sendPacket(sm);
|
||||
return;
|
||||
}
|
||||
|
||||
itemIdCount.remove(ingredient.getId()); // Since we check now.
|
||||
}
|
||||
|
||||
// Now check if the player has sufficient items in the inventory to cover the ingredients' expences. Take care for non-stackable items like 2 swords to dual.
|
||||
boolean allOk = true;
|
||||
for (Entry<Integer, Long> idCount : itemIdCount.entrySet())
|
||||
@ -288,7 +314,7 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
boolean itemEnchantmentProcessed = (itemEnchantment == null);
|
||||
|
||||
// Take all ingredients
|
||||
for (ItemHolder ingredient : entry.getIngredients())
|
||||
for (ItemChanceHolder ingredient : entry.getIngredients())
|
||||
{
|
||||
final long totalCount = Math.multiplyExact(list.getIngredientCount(ingredient), _amount);
|
||||
final SpecialItemType specialItem = SpecialItemType.getByClientId(ingredient.getId());
|
||||
@ -334,6 +360,23 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ingredient.getEnchantmentLevel() > 0)
|
||||
{
|
||||
// Take the enchanted item.
|
||||
final L2ItemInstance destroyedItem = inventory.destroyItem("Multisell", inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()).iterator().next(), totalCount, player, npc);
|
||||
if (destroyedItem != null)
|
||||
{
|
||||
itemEnchantmentProcessed = true;
|
||||
iu.addItem(destroyedItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
|
||||
sm.addItemName(ingredient.getId());
|
||||
player.sendPacket(sm);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!itemEnchantmentProcessed && (itemEnchantment != null) && (itemEnchantment.getItem().getId() == ingredient.getId()))
|
||||
{
|
||||
// Take the enchanted item.
|
||||
@ -418,8 +461,7 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
else
|
||||
{
|
||||
// Give item.
|
||||
final L2ItemInstance addedItem = inventory.addItem("Multisell", product.getId(), totalCount, player, npc);
|
||||
iu.addItem(addedItem);
|
||||
final L2ItemInstance addedItem = inventory.addItem("Multisell", product.getId(), totalCount, player, npc, false);
|
||||
|
||||
// Check if the newly given item should be enchanted.
|
||||
if (itemEnchantmentProcessed && list.isMaintainEnchantment() && (itemEnchantment != null) && addedItem.isEquipable() && addedItem.getItem().getClass().equals(itemEnchantment.getItem().getClass()))
|
||||
@ -447,12 +489,15 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
addedItem.addSpecialAbility(_soulCrystalSpecialOptions[i], i + 1, 2, false);
|
||||
}
|
||||
}
|
||||
|
||||
addedItem.updateDatabase();
|
||||
|
||||
// Mark that we have already upgraded the item.
|
||||
itemEnchantmentProcessed = false;
|
||||
}
|
||||
if (product.getEnchantmentLevel() > 0)
|
||||
{
|
||||
addedItem.setEnchantLevel(product.getEnchantmentLevel());
|
||||
addedItem.updateDatabase();
|
||||
}
|
||||
|
||||
if (addedItem.getCount() > 1)
|
||||
{
|
||||
@ -474,6 +519,9 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
sm.addItemName(addedItem);
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
|
||||
// Inventory update.
|
||||
iu.addItem(addedItem);
|
||||
}
|
||||
}
|
||||
|
||||
@ -512,7 +560,7 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
* @param totalCount
|
||||
* @return {@code false} if ingredient amount is not enough, {@code true} otherwise.
|
||||
*/
|
||||
private boolean checkIngredients(final L2PcInstance player, PreparedMultisellListHolder list, final PcInventory inventory, final L2Clan clan, final int ingredientId, final long totalCount)
|
||||
private boolean checkIngredients(L2PcInstance player, PreparedMultisellListHolder list, PcInventory inventory, L2Clan clan, int ingredientId, long totalCount)
|
||||
{
|
||||
final SpecialItemType specialItem = SpecialItemType.getByClientId(ingredientId);
|
||||
if (specialItem != null)
|
||||
|
@ -22,7 +22,6 @@ import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.model.ItemInfo;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemChanceHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.MultisellEntryHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.PreparedMultisellListHolder;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
@ -99,14 +98,14 @@ public final class MultiSellList extends AbstractItemPacket
|
||||
packet.writeH(65535);
|
||||
}
|
||||
packet.writeQ(_list.getProductCount(product));
|
||||
packet.writeH(displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
packet.writeH(product.getEnchantmentLevel() > 0 ? product.getEnchantmentLevel() : displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
packet.writeD((int) Math.ceil(product.getChance())); // chance
|
||||
writeItemAugment(packet, displayItemEnchantment);
|
||||
writeItemElemental(packet, displayItemEnchantment);
|
||||
writeItemEnsoulOptions(packet, displayItemEnchantment);
|
||||
}
|
||||
|
||||
for (ItemHolder ingredient : entry.getIngredients())
|
||||
for (ItemChanceHolder ingredient : entry.getIngredients())
|
||||
{
|
||||
final L2Item template = ItemTable.getInstance().getTemplate(ingredient.getId());
|
||||
final ItemInfo displayItemEnchantment = ((itemEnchantment != null) && (itemEnchantment.getItem().getId() == ingredient.getId())) ? itemEnchantment : null;
|
||||
@ -114,7 +113,7 @@ public final class MultiSellList extends AbstractItemPacket
|
||||
packet.writeD(ingredient.getId());
|
||||
packet.writeH(template != null ? template.getType2() : 65535);
|
||||
packet.writeQ(_list.getIngredientCount(ingredient));
|
||||
packet.writeH(displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
packet.writeH(ingredient.getEnchantmentLevel() > 0 ? ingredient.getEnchantmentLevel() : displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
writeItemAugment(packet, displayItemEnchantment);
|
||||
writeItemElemental(packet, displayItemEnchantment);
|
||||
writeItemEnsoulOptions(packet, displayItemEnchantment);
|
||||
|
@ -88,7 +88,7 @@ public final class MultisellData implements IGameXmlReader
|
||||
{
|
||||
if ("item".equalsIgnoreCase(itemNode.getNodeName()))
|
||||
{
|
||||
final List<ItemHolder> ingredients = new ArrayList<>(1);
|
||||
final List<ItemChanceHolder> ingredients = new ArrayList<>(1);
|
||||
final List<ItemChanceHolder> products = new ArrayList<>(1);
|
||||
final MultisellEntryHolder entry = new MultisellEntryHolder(ingredients, products);
|
||||
|
||||
@ -98,7 +98,8 @@ public final class MultisellData implements IGameXmlReader
|
||||
{
|
||||
final int id = parseInteger(d.getAttributes(), "id");
|
||||
final long count = parseLong(d.getAttributes(), "count");
|
||||
final ItemHolder ingredient = new ItemHolder(id, count);
|
||||
final byte enchantmentLevel = parseByte(d.getAttributes(), "enchantmentLevel", (byte) 0);
|
||||
final ItemChanceHolder ingredient = new ItemChanceHolder(id, 0, count, enchantmentLevel);
|
||||
|
||||
if (itemExists(ingredient))
|
||||
{
|
||||
@ -115,7 +116,8 @@ public final class MultisellData implements IGameXmlReader
|
||||
final int id = parseInteger(d.getAttributes(), "id");
|
||||
final long count = parseLong(d.getAttributes(), "count");
|
||||
final double chance = parseDouble(d.getAttributes(), "chance", Double.NaN);
|
||||
final ItemChanceHolder product = new ItemChanceHolder(id, chance, count);
|
||||
final byte enchantmentLevel = parseByte(d.getAttributes(), "enchantmentLevel", (byte) 0);
|
||||
final ItemChanceHolder product = new ItemChanceHolder(id, chance, count, enchantmentLevel);
|
||||
|
||||
if (itemExists(product))
|
||||
{
|
||||
|
@ -28,6 +28,7 @@ import com.l2jmobius.commons.util.Rnd;
|
||||
public class ItemChanceHolder extends ItemHolder
|
||||
{
|
||||
private final double _chance;
|
||||
private final byte _enchantmentLevel;
|
||||
|
||||
public ItemChanceHolder(int id, double chance)
|
||||
{
|
||||
@ -38,6 +39,14 @@ public class ItemChanceHolder extends ItemHolder
|
||||
{
|
||||
super(id, count);
|
||||
_chance = chance;
|
||||
_enchantmentLevel = 0;
|
||||
}
|
||||
|
||||
public ItemChanceHolder(int id, double chance, long count, byte enchantmentLevel)
|
||||
{
|
||||
super(id, count);
|
||||
_chance = chance;
|
||||
_enchantmentLevel = enchantmentLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -49,6 +58,15 @@ public class ItemChanceHolder extends ItemHolder
|
||||
return _chance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the enchant level.
|
||||
* @return the enchant level of the item contained in this object
|
||||
*/
|
||||
public byte getEnchantmentLevel()
|
||||
{
|
||||
return _enchantmentLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a cumulative chance of all given holders. If all holders' chance sum up to 100% or above, there is 100% guarantee a holder will be selected.
|
||||
* @param holders list of holders to calculate chance from.
|
||||
|
@ -29,17 +29,17 @@ import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
public class MultisellEntryHolder
|
||||
{
|
||||
private final boolean _stackable;
|
||||
private final List<ItemHolder> _ingredients;
|
||||
private final List<ItemChanceHolder> _ingredients;
|
||||
private final List<ItemChanceHolder> _products;
|
||||
|
||||
public MultisellEntryHolder(List<ItemHolder> ingredients, List<ItemChanceHolder> products)
|
||||
public MultisellEntryHolder(List<ItemChanceHolder> ingredients, List<ItemChanceHolder> products)
|
||||
{
|
||||
_ingredients = Collections.unmodifiableList(ingredients);
|
||||
_products = Collections.unmodifiableList(products);
|
||||
_stackable = products.stream().map(i -> ItemTable.getInstance().getTemplate(i.getId())).filter(Objects::nonNull).allMatch(L2Item::isStackable);
|
||||
}
|
||||
|
||||
public final List<ItemHolder> getIngredients()
|
||||
public final List<ItemChanceHolder> getIngredients()
|
||||
{
|
||||
return _ingredients;
|
||||
}
|
||||
|
@ -435,6 +435,21 @@ public class PcInventory extends Inventory
|
||||
*/
|
||||
@Override
|
||||
public L2ItemInstance addItem(String process, int itemId, long count, L2PcInstance actor, Object reference)
|
||||
{
|
||||
return addItem(process, itemId, count, actor, reference, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds item in inventory and checks _adena and _ancientAdena
|
||||
* @param process : String Identifier of process triggering this action
|
||||
* @param itemId : int Item Identifier of the item to be added
|
||||
* @param count : int Quantity of items to be added
|
||||
* @param actor : L2PcInstance Player requesting the item creation
|
||||
* @param reference : Object Object referencing current action like NPC selling item or previous item in transformation
|
||||
* @param update : Update inventory (not used by MultiSellChoose packet / it sends update after finish)
|
||||
* @return L2ItemInstance corresponding to the new item or the updated item in inventory
|
||||
*/
|
||||
public L2ItemInstance addItem(String process, int itemId, long count, L2PcInstance actor, Object reference, boolean update)
|
||||
{
|
||||
final L2ItemInstance item = super.addItem(process, itemId, count, actor, reference);
|
||||
if (item != null)
|
||||
@ -456,15 +471,18 @@ public class PcInventory extends Inventory
|
||||
if ((item != null) && (actor != null))
|
||||
{
|
||||
// Send inventory update packet
|
||||
if (!Config.FORCE_INVENTORY_UPDATE)
|
||||
if (update)
|
||||
{
|
||||
final InventoryUpdate playerIU = new InventoryUpdate();
|
||||
playerIU.addItem(item);
|
||||
actor.sendInventoryUpdate(playerIU);
|
||||
}
|
||||
else
|
||||
{
|
||||
actor.sendItemList(false);
|
||||
if (!Config.FORCE_INVENTORY_UPDATE)
|
||||
{
|
||||
final InventoryUpdate playerIU = new InventoryUpdate();
|
||||
playerIU.addItem(item);
|
||||
actor.sendInventoryUpdate(playerIU);
|
||||
}
|
||||
else
|
||||
{
|
||||
actor.sendItemList(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Notify to scripts
|
||||
|
@ -36,7 +36,6 @@ import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.ensoul.EnsoulOption;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemChanceHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.MultisellEntryHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.PreparedMultisellListHolder;
|
||||
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||
@ -271,6 +270,33 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
// Summarize all item counts into one map. That would include non-stackable items under 1 id and multiple count.
|
||||
final Map<Integer, Long> itemIdCount = entry.getIngredients().stream().collect(Collectors.toMap(i -> i.getId(), i -> list.getIngredientCount(i), (k1, k2) -> Math.addExact(k1, k2)));
|
||||
|
||||
// Check for enchanted level requirements.
|
||||
for (ItemChanceHolder ingredient : entry.getIngredients())
|
||||
{
|
||||
if (ingredient.getEnchantmentLevel() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int found = 0;
|
||||
for (L2ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
|
||||
{
|
||||
if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
|
||||
{
|
||||
found++;
|
||||
}
|
||||
}
|
||||
|
||||
if (found < ingredient.getCount())
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
|
||||
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
|
||||
player.sendPacket(sm);
|
||||
return;
|
||||
}
|
||||
|
||||
itemIdCount.remove(ingredient.getId()); // Since we check now.
|
||||
}
|
||||
|
||||
// Now check if the player has sufficient items in the inventory to cover the ingredients' expences. Take care for non-stackable items like 2 swords to dual.
|
||||
boolean allOk = true;
|
||||
for (Entry<Integer, Long> idCount : itemIdCount.entrySet())
|
||||
@ -288,7 +314,7 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
boolean itemEnchantmentProcessed = (itemEnchantment == null);
|
||||
|
||||
// Take all ingredients
|
||||
for (ItemHolder ingredient : entry.getIngredients())
|
||||
for (ItemChanceHolder ingredient : entry.getIngredients())
|
||||
{
|
||||
final long totalCount = Math.multiplyExact(list.getIngredientCount(ingredient), _amount);
|
||||
final SpecialItemType specialItem = SpecialItemType.getByClientId(ingredient.getId());
|
||||
@ -334,6 +360,23 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ingredient.getEnchantmentLevel() > 0)
|
||||
{
|
||||
// Take the enchanted item.
|
||||
final L2ItemInstance destroyedItem = inventory.destroyItem("Multisell", inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()).iterator().next(), totalCount, player, npc);
|
||||
if (destroyedItem != null)
|
||||
{
|
||||
itemEnchantmentProcessed = true;
|
||||
iu.addItem(destroyedItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
|
||||
sm.addItemName(ingredient.getId());
|
||||
player.sendPacket(sm);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!itemEnchantmentProcessed && (itemEnchantment != null) && (itemEnchantment.getItem().getId() == ingredient.getId()))
|
||||
{
|
||||
// Take the enchanted item.
|
||||
@ -418,8 +461,7 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
else
|
||||
{
|
||||
// Give item.
|
||||
final L2ItemInstance addedItem = inventory.addItem("Multisell", product.getId(), totalCount, player, npc);
|
||||
iu.addItem(addedItem);
|
||||
final L2ItemInstance addedItem = inventory.addItem("Multisell", product.getId(), totalCount, player, npc, false);
|
||||
|
||||
// Check if the newly given item should be enchanted.
|
||||
if (itemEnchantmentProcessed && list.isMaintainEnchantment() && (itemEnchantment != null) && addedItem.isEquipable() && addedItem.getItem().getClass().equals(itemEnchantment.getItem().getClass()))
|
||||
@ -447,12 +489,15 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
addedItem.addSpecialAbility(_soulCrystalSpecialOptions[i], i + 1, 2, false);
|
||||
}
|
||||
}
|
||||
|
||||
addedItem.updateDatabase();
|
||||
|
||||
// Mark that we have already upgraded the item.
|
||||
itemEnchantmentProcessed = false;
|
||||
}
|
||||
if (product.getEnchantmentLevel() > 0)
|
||||
{
|
||||
addedItem.setEnchantLevel(product.getEnchantmentLevel());
|
||||
addedItem.updateDatabase();
|
||||
}
|
||||
|
||||
if (addedItem.getCount() > 1)
|
||||
{
|
||||
@ -474,6 +519,9 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
sm.addItemName(addedItem);
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
|
||||
// Inventory update.
|
||||
iu.addItem(addedItem);
|
||||
}
|
||||
}
|
||||
|
||||
@ -512,7 +560,7 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
* @param totalCount
|
||||
* @return {@code false} if ingredient amount is not enough, {@code true} otherwise.
|
||||
*/
|
||||
private boolean checkIngredients(final L2PcInstance player, PreparedMultisellListHolder list, final PcInventory inventory, final L2Clan clan, final int ingredientId, final long totalCount)
|
||||
private boolean checkIngredients(L2PcInstance player, PreparedMultisellListHolder list, PcInventory inventory, L2Clan clan, int ingredientId, long totalCount)
|
||||
{
|
||||
final SpecialItemType specialItem = SpecialItemType.getByClientId(ingredientId);
|
||||
if (specialItem != null)
|
||||
|
@ -22,7 +22,6 @@ import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.model.ItemInfo;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemChanceHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.MultisellEntryHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.PreparedMultisellListHolder;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
@ -100,14 +99,14 @@ public final class MultiSellList extends AbstractItemPacket
|
||||
packet.writeH(65535);
|
||||
}
|
||||
packet.writeQ(_list.getProductCount(product));
|
||||
packet.writeH(displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
packet.writeH(product.getEnchantmentLevel() > 0 ? product.getEnchantmentLevel() : displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
packet.writeD((int) Math.ceil(product.getChance())); // chance
|
||||
writeItemAugment(packet, displayItemEnchantment);
|
||||
writeItemElemental(packet, displayItemEnchantment);
|
||||
writeItemEnsoulOptions(packet, displayItemEnchantment);
|
||||
}
|
||||
|
||||
for (ItemHolder ingredient : entry.getIngredients())
|
||||
for (ItemChanceHolder ingredient : entry.getIngredients())
|
||||
{
|
||||
final L2Item template = ItemTable.getInstance().getTemplate(ingredient.getId());
|
||||
final ItemInfo displayItemEnchantment = ((itemEnchantment != null) && (itemEnchantment.getItem().getId() == ingredient.getId())) ? itemEnchantment : null;
|
||||
@ -115,7 +114,7 @@ public final class MultiSellList extends AbstractItemPacket
|
||||
packet.writeD(ingredient.getId());
|
||||
packet.writeH(template != null ? template.getType2() : 65535);
|
||||
packet.writeQ(_list.getIngredientCount(ingredient));
|
||||
packet.writeH(displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
packet.writeH(ingredient.getEnchantmentLevel() > 0 ? ingredient.getEnchantmentLevel() : displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
writeItemAugment(packet, displayItemEnchantment);
|
||||
writeItemElemental(packet, displayItemEnchantment);
|
||||
writeItemEnsoulOptions(packet, displayItemEnchantment);
|
||||
|
@ -88,7 +88,7 @@ public final class MultisellData implements IGameXmlReader
|
||||
{
|
||||
if ("item".equalsIgnoreCase(itemNode.getNodeName()))
|
||||
{
|
||||
final List<ItemHolder> ingredients = new ArrayList<>(1);
|
||||
final List<ItemChanceHolder> ingredients = new ArrayList<>(1);
|
||||
final List<ItemChanceHolder> products = new ArrayList<>(1);
|
||||
final MultisellEntryHolder entry = new MultisellEntryHolder(ingredients, products);
|
||||
|
||||
@ -98,7 +98,8 @@ public final class MultisellData implements IGameXmlReader
|
||||
{
|
||||
final int id = parseInteger(d.getAttributes(), "id");
|
||||
final long count = parseLong(d.getAttributes(), "count");
|
||||
final ItemHolder ingredient = new ItemHolder(id, count);
|
||||
final byte enchantmentLevel = parseByte(d.getAttributes(), "enchantmentLevel", (byte) 0);
|
||||
final ItemChanceHolder ingredient = new ItemChanceHolder(id, 0, count, enchantmentLevel);
|
||||
|
||||
if (itemExists(ingredient))
|
||||
{
|
||||
@ -115,7 +116,8 @@ public final class MultisellData implements IGameXmlReader
|
||||
final int id = parseInteger(d.getAttributes(), "id");
|
||||
final long count = parseLong(d.getAttributes(), "count");
|
||||
final double chance = parseDouble(d.getAttributes(), "chance", Double.NaN);
|
||||
final ItemChanceHolder product = new ItemChanceHolder(id, chance, count);
|
||||
final byte enchantmentLevel = parseByte(d.getAttributes(), "enchantmentLevel", (byte) 0);
|
||||
final ItemChanceHolder product = new ItemChanceHolder(id, chance, count, enchantmentLevel);
|
||||
|
||||
if (itemExists(product))
|
||||
{
|
||||
|
@ -28,6 +28,7 @@ import com.l2jmobius.commons.util.Rnd;
|
||||
public class ItemChanceHolder extends ItemHolder
|
||||
{
|
||||
private final double _chance;
|
||||
private final byte _enchantmentLevel;
|
||||
|
||||
public ItemChanceHolder(int id, double chance)
|
||||
{
|
||||
@ -38,6 +39,14 @@ public class ItemChanceHolder extends ItemHolder
|
||||
{
|
||||
super(id, count);
|
||||
_chance = chance;
|
||||
_enchantmentLevel = 0;
|
||||
}
|
||||
|
||||
public ItemChanceHolder(int id, double chance, long count, byte enchantmentLevel)
|
||||
{
|
||||
super(id, count);
|
||||
_chance = chance;
|
||||
_enchantmentLevel = enchantmentLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -49,6 +58,15 @@ public class ItemChanceHolder extends ItemHolder
|
||||
return _chance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the enchant level.
|
||||
* @return the enchant level of the item contained in this object
|
||||
*/
|
||||
public byte getEnchantmentLevel()
|
||||
{
|
||||
return _enchantmentLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a cumulative chance of all given holders. If all holders' chance sum up to 100% or above, there is 100% guarantee a holder will be selected.
|
||||
* @param holders list of holders to calculate chance from.
|
||||
|
@ -29,17 +29,17 @@ import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
public class MultisellEntryHolder
|
||||
{
|
||||
private final boolean _stackable;
|
||||
private final List<ItemHolder> _ingredients;
|
||||
private final List<ItemChanceHolder> _ingredients;
|
||||
private final List<ItemChanceHolder> _products;
|
||||
|
||||
public MultisellEntryHolder(List<ItemHolder> ingredients, List<ItemChanceHolder> products)
|
||||
public MultisellEntryHolder(List<ItemChanceHolder> ingredients, List<ItemChanceHolder> products)
|
||||
{
|
||||
_ingredients = Collections.unmodifiableList(ingredients);
|
||||
_products = Collections.unmodifiableList(products);
|
||||
_stackable = products.stream().map(i -> ItemTable.getInstance().getTemplate(i.getId())).filter(Objects::nonNull).allMatch(L2Item::isStackable);
|
||||
}
|
||||
|
||||
public final List<ItemHolder> getIngredients()
|
||||
public final List<ItemChanceHolder> getIngredients()
|
||||
{
|
||||
return _ingredients;
|
||||
}
|
||||
|
@ -435,6 +435,21 @@ public class PcInventory extends Inventory
|
||||
*/
|
||||
@Override
|
||||
public L2ItemInstance addItem(String process, int itemId, long count, L2PcInstance actor, Object reference)
|
||||
{
|
||||
return addItem(process, itemId, count, actor, reference, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds item in inventory and checks _adena and _ancientAdena
|
||||
* @param process : String Identifier of process triggering this action
|
||||
* @param itemId : int Item Identifier of the item to be added
|
||||
* @param count : int Quantity of items to be added
|
||||
* @param actor : L2PcInstance Player requesting the item creation
|
||||
* @param reference : Object Object referencing current action like NPC selling item or previous item in transformation
|
||||
* @param update : Update inventory (not used by MultiSellChoose packet / it sends update after finish)
|
||||
* @return L2ItemInstance corresponding to the new item or the updated item in inventory
|
||||
*/
|
||||
public L2ItemInstance addItem(String process, int itemId, long count, L2PcInstance actor, Object reference, boolean update)
|
||||
{
|
||||
final L2ItemInstance item = super.addItem(process, itemId, count, actor, reference);
|
||||
if (item != null)
|
||||
@ -456,15 +471,18 @@ public class PcInventory extends Inventory
|
||||
if ((item != null) && (actor != null))
|
||||
{
|
||||
// Send inventory update packet
|
||||
if (!Config.FORCE_INVENTORY_UPDATE)
|
||||
if (update)
|
||||
{
|
||||
final InventoryUpdate playerIU = new InventoryUpdate();
|
||||
playerIU.addItem(item);
|
||||
actor.sendInventoryUpdate(playerIU);
|
||||
}
|
||||
else
|
||||
{
|
||||
actor.sendItemList(false);
|
||||
if (!Config.FORCE_INVENTORY_UPDATE)
|
||||
{
|
||||
final InventoryUpdate playerIU = new InventoryUpdate();
|
||||
playerIU.addItem(item);
|
||||
actor.sendInventoryUpdate(playerIU);
|
||||
}
|
||||
else
|
||||
{
|
||||
actor.sendItemList(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Notify to scripts
|
||||
|
@ -36,7 +36,6 @@ import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.ensoul.EnsoulOption;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemChanceHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.MultisellEntryHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.PreparedMultisellListHolder;
|
||||
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||
@ -271,6 +270,33 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
// Summarize all item counts into one map. That would include non-stackable items under 1 id and multiple count.
|
||||
final Map<Integer, Long> itemIdCount = entry.getIngredients().stream().collect(Collectors.toMap(i -> i.getId(), i -> list.getIngredientCount(i), (k1, k2) -> Math.addExact(k1, k2)));
|
||||
|
||||
// Check for enchanted level requirements.
|
||||
for (ItemChanceHolder ingredient : entry.getIngredients())
|
||||
{
|
||||
if (ingredient.getEnchantmentLevel() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int found = 0;
|
||||
for (L2ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
|
||||
{
|
||||
if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
|
||||
{
|
||||
found++;
|
||||
}
|
||||
}
|
||||
|
||||
if (found < ingredient.getCount())
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
|
||||
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
|
||||
player.sendPacket(sm);
|
||||
return;
|
||||
}
|
||||
|
||||
itemIdCount.remove(ingredient.getId()); // Since we check now.
|
||||
}
|
||||
|
||||
// Now check if the player has sufficient items in the inventory to cover the ingredients' expences. Take care for non-stackable items like 2 swords to dual.
|
||||
boolean allOk = true;
|
||||
for (Entry<Integer, Long> idCount : itemIdCount.entrySet())
|
||||
@ -288,7 +314,7 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
boolean itemEnchantmentProcessed = (itemEnchantment == null);
|
||||
|
||||
// Take all ingredients
|
||||
for (ItemHolder ingredient : entry.getIngredients())
|
||||
for (ItemChanceHolder ingredient : entry.getIngredients())
|
||||
{
|
||||
final long totalCount = Math.multiplyExact(list.getIngredientCount(ingredient), _amount);
|
||||
final SpecialItemType specialItem = SpecialItemType.getByClientId(ingredient.getId());
|
||||
@ -334,6 +360,23 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ingredient.getEnchantmentLevel() > 0)
|
||||
{
|
||||
// Take the enchanted item.
|
||||
final L2ItemInstance destroyedItem = inventory.destroyItem("Multisell", inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()).iterator().next(), totalCount, player, npc);
|
||||
if (destroyedItem != null)
|
||||
{
|
||||
itemEnchantmentProcessed = true;
|
||||
iu.addItem(destroyedItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
|
||||
sm.addItemName(ingredient.getId());
|
||||
player.sendPacket(sm);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!itemEnchantmentProcessed && (itemEnchantment != null) && (itemEnchantment.getItem().getId() == ingredient.getId()))
|
||||
{
|
||||
// Take the enchanted item.
|
||||
@ -418,8 +461,7 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
else
|
||||
{
|
||||
// Give item.
|
||||
final L2ItemInstance addedItem = inventory.addItem("Multisell", product.getId(), totalCount, player, npc);
|
||||
iu.addItem(addedItem);
|
||||
final L2ItemInstance addedItem = inventory.addItem("Multisell", product.getId(), totalCount, player, npc, false);
|
||||
|
||||
// Check if the newly given item should be enchanted.
|
||||
if (itemEnchantmentProcessed && list.isMaintainEnchantment() && (itemEnchantment != null) && addedItem.isEquipable() && addedItem.getItem().getClass().equals(itemEnchantment.getItem().getClass()))
|
||||
@ -447,12 +489,15 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
addedItem.addSpecialAbility(_soulCrystalSpecialOptions[i], i + 1, 2, false);
|
||||
}
|
||||
}
|
||||
|
||||
addedItem.updateDatabase();
|
||||
|
||||
// Mark that we have already upgraded the item.
|
||||
itemEnchantmentProcessed = false;
|
||||
}
|
||||
if (product.getEnchantmentLevel() > 0)
|
||||
{
|
||||
addedItem.setEnchantLevel(product.getEnchantmentLevel());
|
||||
addedItem.updateDatabase();
|
||||
}
|
||||
|
||||
if (addedItem.getCount() > 1)
|
||||
{
|
||||
@ -474,6 +519,9 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
sm.addItemName(addedItem);
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
|
||||
// Inventory update.
|
||||
iu.addItem(addedItem);
|
||||
}
|
||||
}
|
||||
|
||||
@ -512,7 +560,7 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
* @param totalCount
|
||||
* @return {@code false} if ingredient amount is not enough, {@code true} otherwise.
|
||||
*/
|
||||
private boolean checkIngredients(final L2PcInstance player, PreparedMultisellListHolder list, final PcInventory inventory, final L2Clan clan, final int ingredientId, final long totalCount)
|
||||
private boolean checkIngredients(L2PcInstance player, PreparedMultisellListHolder list, PcInventory inventory, L2Clan clan, int ingredientId, long totalCount)
|
||||
{
|
||||
final SpecialItemType specialItem = SpecialItemType.getByClientId(ingredientId);
|
||||
if (specialItem != null)
|
||||
|
@ -22,7 +22,6 @@ import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.model.ItemInfo;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemChanceHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.MultisellEntryHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.PreparedMultisellListHolder;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
@ -99,14 +98,14 @@ public final class MultiSellList extends AbstractItemPacket
|
||||
packet.writeH(65535);
|
||||
}
|
||||
packet.writeQ(_list.getProductCount(product));
|
||||
packet.writeH(displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
packet.writeH(product.getEnchantmentLevel() > 0 ? product.getEnchantmentLevel() : displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
packet.writeD((int) Math.ceil(product.getChance())); // chance
|
||||
writeItemAugment(packet, displayItemEnchantment);
|
||||
writeItemElemental(packet, displayItemEnchantment);
|
||||
writeItemEnsoulOptions(packet, displayItemEnchantment);
|
||||
}
|
||||
|
||||
for (ItemHolder ingredient : entry.getIngredients())
|
||||
for (ItemChanceHolder ingredient : entry.getIngredients())
|
||||
{
|
||||
final L2Item template = ItemTable.getInstance().getTemplate(ingredient.getId());
|
||||
final ItemInfo displayItemEnchantment = ((itemEnchantment != null) && (itemEnchantment.getItem().getId() == ingredient.getId())) ? itemEnchantment : null;
|
||||
@ -114,7 +113,7 @@ public final class MultiSellList extends AbstractItemPacket
|
||||
packet.writeD(ingredient.getId());
|
||||
packet.writeH(template != null ? template.getType2() : 65535);
|
||||
packet.writeQ(_list.getIngredientCount(ingredient));
|
||||
packet.writeH(displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
packet.writeH(ingredient.getEnchantmentLevel() > 0 ? ingredient.getEnchantmentLevel() : displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
writeItemAugment(packet, displayItemEnchantment);
|
||||
writeItemElemental(packet, displayItemEnchantment);
|
||||
writeItemEnsoulOptions(packet, displayItemEnchantment);
|
||||
|
@ -88,7 +88,7 @@ public final class MultisellData implements IGameXmlReader
|
||||
{
|
||||
if ("item".equalsIgnoreCase(itemNode.getNodeName()))
|
||||
{
|
||||
final List<ItemHolder> ingredients = new ArrayList<>(1);
|
||||
final List<ItemChanceHolder> ingredients = new ArrayList<>(1);
|
||||
final List<ItemChanceHolder> products = new ArrayList<>(1);
|
||||
final MultisellEntryHolder entry = new MultisellEntryHolder(ingredients, products);
|
||||
|
||||
@ -98,7 +98,8 @@ public final class MultisellData implements IGameXmlReader
|
||||
{
|
||||
final int id = parseInteger(d.getAttributes(), "id");
|
||||
final long count = parseLong(d.getAttributes(), "count");
|
||||
final ItemHolder ingredient = new ItemHolder(id, count);
|
||||
final byte enchantmentLevel = parseByte(d.getAttributes(), "enchantmentLevel", (byte) 0);
|
||||
final ItemChanceHolder ingredient = new ItemChanceHolder(id, 0, count, enchantmentLevel);
|
||||
|
||||
if (itemExists(ingredient))
|
||||
{
|
||||
@ -115,7 +116,8 @@ public final class MultisellData implements IGameXmlReader
|
||||
final int id = parseInteger(d.getAttributes(), "id");
|
||||
final long count = parseLong(d.getAttributes(), "count");
|
||||
final double chance = parseDouble(d.getAttributes(), "chance", Double.NaN);
|
||||
final ItemChanceHolder product = new ItemChanceHolder(id, chance, count);
|
||||
final byte enchantmentLevel = parseByte(d.getAttributes(), "enchantmentLevel", (byte) 0);
|
||||
final ItemChanceHolder product = new ItemChanceHolder(id, chance, count, enchantmentLevel);
|
||||
|
||||
if (itemExists(product))
|
||||
{
|
||||
|
@ -28,6 +28,7 @@ import com.l2jmobius.commons.util.Rnd;
|
||||
public class ItemChanceHolder extends ItemHolder
|
||||
{
|
||||
private final double _chance;
|
||||
private final byte _enchantmentLevel;
|
||||
|
||||
public ItemChanceHolder(int id, double chance)
|
||||
{
|
||||
@ -38,6 +39,14 @@ public class ItemChanceHolder extends ItemHolder
|
||||
{
|
||||
super(id, count);
|
||||
_chance = chance;
|
||||
_enchantmentLevel = 0;
|
||||
}
|
||||
|
||||
public ItemChanceHolder(int id, double chance, long count, byte enchantmentLevel)
|
||||
{
|
||||
super(id, count);
|
||||
_chance = chance;
|
||||
_enchantmentLevel = enchantmentLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -49,6 +58,15 @@ public class ItemChanceHolder extends ItemHolder
|
||||
return _chance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the enchant level.
|
||||
* @return the enchant level of the item contained in this object
|
||||
*/
|
||||
public byte getEnchantmentLevel()
|
||||
{
|
||||
return _enchantmentLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a cumulative chance of all given holders. If all holders' chance sum up to 100% or above, there is 100% guarantee a holder will be selected.
|
||||
* @param holders list of holders to calculate chance from.
|
||||
|
@ -29,17 +29,17 @@ import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
public class MultisellEntryHolder
|
||||
{
|
||||
private final boolean _stackable;
|
||||
private final List<ItemHolder> _ingredients;
|
||||
private final List<ItemChanceHolder> _ingredients;
|
||||
private final List<ItemChanceHolder> _products;
|
||||
|
||||
public MultisellEntryHolder(List<ItemHolder> ingredients, List<ItemChanceHolder> products)
|
||||
public MultisellEntryHolder(List<ItemChanceHolder> ingredients, List<ItemChanceHolder> products)
|
||||
{
|
||||
_ingredients = Collections.unmodifiableList(ingredients);
|
||||
_products = Collections.unmodifiableList(products);
|
||||
_stackable = products.stream().map(i -> ItemTable.getInstance().getTemplate(i.getId())).filter(Objects::nonNull).allMatch(L2Item::isStackable);
|
||||
}
|
||||
|
||||
public final List<ItemHolder> getIngredients()
|
||||
public final List<ItemChanceHolder> getIngredients()
|
||||
{
|
||||
return _ingredients;
|
||||
}
|
||||
|
@ -435,6 +435,21 @@ public class PcInventory extends Inventory
|
||||
*/
|
||||
@Override
|
||||
public L2ItemInstance addItem(String process, int itemId, long count, L2PcInstance actor, Object reference)
|
||||
{
|
||||
return addItem(process, itemId, count, actor, reference, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds item in inventory and checks _adena and _ancientAdena
|
||||
* @param process : String Identifier of process triggering this action
|
||||
* @param itemId : int Item Identifier of the item to be added
|
||||
* @param count : int Quantity of items to be added
|
||||
* @param actor : L2PcInstance Player requesting the item creation
|
||||
* @param reference : Object Object referencing current action like NPC selling item or previous item in transformation
|
||||
* @param update : Update inventory (not used by MultiSellChoose packet / it sends update after finish)
|
||||
* @return L2ItemInstance corresponding to the new item or the updated item in inventory
|
||||
*/
|
||||
public L2ItemInstance addItem(String process, int itemId, long count, L2PcInstance actor, Object reference, boolean update)
|
||||
{
|
||||
final L2ItemInstance item = super.addItem(process, itemId, count, actor, reference);
|
||||
if (item != null)
|
||||
@ -456,15 +471,18 @@ public class PcInventory extends Inventory
|
||||
if ((item != null) && (actor != null))
|
||||
{
|
||||
// Send inventory update packet
|
||||
if (!Config.FORCE_INVENTORY_UPDATE)
|
||||
if (update)
|
||||
{
|
||||
final InventoryUpdate playerIU = new InventoryUpdate();
|
||||
playerIU.addItem(item);
|
||||
actor.sendInventoryUpdate(playerIU);
|
||||
}
|
||||
else
|
||||
{
|
||||
actor.sendItemList(false);
|
||||
if (!Config.FORCE_INVENTORY_UPDATE)
|
||||
{
|
||||
final InventoryUpdate playerIU = new InventoryUpdate();
|
||||
playerIU.addItem(item);
|
||||
actor.sendInventoryUpdate(playerIU);
|
||||
}
|
||||
else
|
||||
{
|
||||
actor.sendItemList(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Notify to scripts
|
||||
|
@ -36,7 +36,6 @@ import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.ensoul.EnsoulOption;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemChanceHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.MultisellEntryHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.PreparedMultisellListHolder;
|
||||
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||
@ -271,6 +270,33 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
// Summarize all item counts into one map. That would include non-stackable items under 1 id and multiple count.
|
||||
final Map<Integer, Long> itemIdCount = entry.getIngredients().stream().collect(Collectors.toMap(i -> i.getId(), i -> list.getIngredientCount(i), (k1, k2) -> Math.addExact(k1, k2)));
|
||||
|
||||
// Check for enchanted level requirements.
|
||||
for (ItemChanceHolder ingredient : entry.getIngredients())
|
||||
{
|
||||
if (ingredient.getEnchantmentLevel() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int found = 0;
|
||||
for (L2ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
|
||||
{
|
||||
if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
|
||||
{
|
||||
found++;
|
||||
}
|
||||
}
|
||||
|
||||
if (found < ingredient.getCount())
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
|
||||
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
|
||||
player.sendPacket(sm);
|
||||
return;
|
||||
}
|
||||
|
||||
itemIdCount.remove(ingredient.getId()); // Since we check now.
|
||||
}
|
||||
|
||||
// Now check if the player has sufficient items in the inventory to cover the ingredients' expences. Take care for non-stackable items like 2 swords to dual.
|
||||
boolean allOk = true;
|
||||
for (Entry<Integer, Long> idCount : itemIdCount.entrySet())
|
||||
@ -288,7 +314,7 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
boolean itemEnchantmentProcessed = (itemEnchantment == null);
|
||||
|
||||
// Take all ingredients
|
||||
for (ItemHolder ingredient : entry.getIngredients())
|
||||
for (ItemChanceHolder ingredient : entry.getIngredients())
|
||||
{
|
||||
final long totalCount = Math.multiplyExact(list.getIngredientCount(ingredient), _amount);
|
||||
final SpecialItemType specialItem = SpecialItemType.getByClientId(ingredient.getId());
|
||||
@ -334,6 +360,23 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ingredient.getEnchantmentLevel() > 0)
|
||||
{
|
||||
// Take the enchanted item.
|
||||
final L2ItemInstance destroyedItem = inventory.destroyItem("Multisell", inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()).iterator().next(), totalCount, player, npc);
|
||||
if (destroyedItem != null)
|
||||
{
|
||||
itemEnchantmentProcessed = true;
|
||||
iu.addItem(destroyedItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
|
||||
sm.addItemName(ingredient.getId());
|
||||
player.sendPacket(sm);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!itemEnchantmentProcessed && (itemEnchantment != null) && (itemEnchantment.getItem().getId() == ingredient.getId()))
|
||||
{
|
||||
// Take the enchanted item.
|
||||
@ -418,8 +461,7 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
else
|
||||
{
|
||||
// Give item.
|
||||
final L2ItemInstance addedItem = inventory.addItem("Multisell", product.getId(), totalCount, player, npc);
|
||||
iu.addItem(addedItem);
|
||||
final L2ItemInstance addedItem = inventory.addItem("Multisell", product.getId(), totalCount, player, npc, false);
|
||||
|
||||
// Check if the newly given item should be enchanted.
|
||||
if (itemEnchantmentProcessed && list.isMaintainEnchantment() && (itemEnchantment != null) && addedItem.isEquipable() && addedItem.getItem().getClass().equals(itemEnchantment.getItem().getClass()))
|
||||
@ -447,12 +489,15 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
addedItem.addSpecialAbility(_soulCrystalSpecialOptions[i], i + 1, 2, false);
|
||||
}
|
||||
}
|
||||
|
||||
addedItem.updateDatabase();
|
||||
|
||||
// Mark that we have already upgraded the item.
|
||||
itemEnchantmentProcessed = false;
|
||||
}
|
||||
if (product.getEnchantmentLevel() > 0)
|
||||
{
|
||||
addedItem.setEnchantLevel(product.getEnchantmentLevel());
|
||||
addedItem.updateDatabase();
|
||||
}
|
||||
|
||||
if (addedItem.getCount() > 1)
|
||||
{
|
||||
@ -474,6 +519,9 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
sm.addItemName(addedItem);
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
|
||||
// Inventory update.
|
||||
iu.addItem(addedItem);
|
||||
}
|
||||
}
|
||||
|
||||
@ -512,7 +560,7 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
* @param totalCount
|
||||
* @return {@code false} if ingredient amount is not enough, {@code true} otherwise.
|
||||
*/
|
||||
private boolean checkIngredients(final L2PcInstance player, PreparedMultisellListHolder list, final PcInventory inventory, final L2Clan clan, final int ingredientId, final long totalCount)
|
||||
private boolean checkIngredients(L2PcInstance player, PreparedMultisellListHolder list, PcInventory inventory, L2Clan clan, int ingredientId, long totalCount)
|
||||
{
|
||||
final SpecialItemType specialItem = SpecialItemType.getByClientId(ingredientId);
|
||||
if (specialItem != null)
|
||||
|
@ -22,7 +22,6 @@ import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.model.ItemInfo;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemChanceHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.MultisellEntryHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.PreparedMultisellListHolder;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
@ -100,14 +99,14 @@ public final class MultiSellList extends AbstractItemPacket
|
||||
packet.writeH(65535);
|
||||
}
|
||||
packet.writeQ(_list.getProductCount(product));
|
||||
packet.writeH(displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
packet.writeH(product.getEnchantmentLevel() > 0 ? product.getEnchantmentLevel() : displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
packet.writeD((int) Math.ceil(product.getChance())); // chance
|
||||
writeItemAugment(packet, displayItemEnchantment);
|
||||
writeItemElemental(packet, displayItemEnchantment);
|
||||
writeItemEnsoulOptions(packet, displayItemEnchantment);
|
||||
}
|
||||
|
||||
for (ItemHolder ingredient : entry.getIngredients())
|
||||
for (ItemChanceHolder ingredient : entry.getIngredients())
|
||||
{
|
||||
final L2Item template = ItemTable.getInstance().getTemplate(ingredient.getId());
|
||||
final ItemInfo displayItemEnchantment = ((itemEnchantment != null) && (itemEnchantment.getItem().getId() == ingredient.getId())) ? itemEnchantment : null;
|
||||
@ -115,7 +114,7 @@ public final class MultiSellList extends AbstractItemPacket
|
||||
packet.writeD(ingredient.getId());
|
||||
packet.writeH(template != null ? template.getType2() : 65535);
|
||||
packet.writeQ(_list.getIngredientCount(ingredient));
|
||||
packet.writeH(displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
packet.writeH(ingredient.getEnchantmentLevel() > 0 ? ingredient.getEnchantmentLevel() : displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
writeItemAugment(packet, displayItemEnchantment);
|
||||
writeItemElemental(packet, displayItemEnchantment);
|
||||
writeItemEnsoulOptions(packet, displayItemEnchantment);
|
||||
|
Loading…
Reference in New Issue
Block a user