/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* L2J Server is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.gameserver.model.itemcontainer;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jserver.Config;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.data.xml.impl.ArmorSetsData;
import com.l2jserver.gameserver.datatables.ItemTable;
import com.l2jserver.gameserver.enums.ItemLocation;
import com.l2jserver.gameserver.enums.PrivateStoreType;
import com.l2jserver.gameserver.model.L2ArmorSet;
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.model.PcCondOverride;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.holders.ArmorsetSkillHolder;
import com.l2jserver.gameserver.model.holders.SkillHolder;
import com.l2jserver.gameserver.model.items.L2Item;
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
import com.l2jserver.gameserver.model.items.type.EtcItemType;
import com.l2jserver.gameserver.model.items.type.WeaponType;
import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.network.serverpackets.ExUserInfoEquipSlot;
import com.l2jserver.gameserver.network.serverpackets.SkillCoolTime;
import com.l2jserver.util.StringUtil;
/**
* This class manages inventory
* @version $Revision: 1.13.2.9.2.12 $ $Date: 2005/03/29 23:15:15 $ rewritten 23.2.2006 by Advi
*/
public abstract class Inventory extends ItemContainer
{
protected static final Logger _log = Logger.getLogger(Inventory.class.getName());
public interface PaperdollListener
{
public void notifyEquiped(int slot, L2ItemInstance inst, Inventory inventory);
public void notifyUnequiped(int slot, L2ItemInstance inst, Inventory inventory);
}
// Common Items
public static final int ADENA_ID = 57;
public static final int ANCIENT_ADENA_ID = 5575;
public static final int BEAUTY_TICKET_ID = 36308;
public static final long MAX_ADENA = Config.MAX_ADENA;
public static final int PAPERDOLL_UNDER = 0;
public static final int PAPERDOLL_HEAD = 1;
public static final int PAPERDOLL_HAIR = 2;
public static final int PAPERDOLL_HAIR2 = 3;
public static final int PAPERDOLL_NECK = 4;
public static final int PAPERDOLL_RHAND = 5;
public static final int PAPERDOLL_CHEST = 6;
public static final int PAPERDOLL_LHAND = 7;
public static final int PAPERDOLL_REAR = 8;
public static final int PAPERDOLL_LEAR = 9;
public static final int PAPERDOLL_GLOVES = 10;
public static final int PAPERDOLL_LEGS = 11;
public static final int PAPERDOLL_FEET = 12;
public static final int PAPERDOLL_RFINGER = 13;
public static final int PAPERDOLL_LFINGER = 14;
public static final int PAPERDOLL_LBRACELET = 15;
public static final int PAPERDOLL_RBRACELET = 16;
public static final int PAPERDOLL_DECO1 = 17;
public static final int PAPERDOLL_DECO2 = 18;
public static final int PAPERDOLL_DECO3 = 19;
public static final int PAPERDOLL_DECO4 = 20;
public static final int PAPERDOLL_DECO5 = 21;
public static final int PAPERDOLL_DECO6 = 22;
public static final int PAPERDOLL_CLOAK = 23;
public static final int PAPERDOLL_BELT = 24;
public static final int PAPERDOLL_BROOCH = 25;
public static final int PAPERDOLL_BROOCH_JEWEL1 = 26;
public static final int PAPERDOLL_BROOCH_JEWEL2 = 27;
public static final int PAPERDOLL_BROOCH_JEWEL3 = 28;
public static final int PAPERDOLL_BROOCH_JEWEL4 = 29;
public static final int PAPERDOLL_BROOCH_JEWEL5 = 30;
public static final int PAPERDOLL_BROOCH_JEWEL6 = 31;
public static final int PAPERDOLL_TOTALSLOTS = 32;
// Speed percentage mods
public static final double MAX_ARMOR_WEIGHT = 12000;
private final L2ItemInstance[] _paperdoll;
private final List<PaperdollListener> _paperdollListeners;
// protected to be accessed from child classes only
protected int _totalWeight;
// used to quickly check for using of items of special type
private int _wearedMask;
// Recorder of alterations in inventory
private static final class ChangeRecorder implements PaperdollListener
{
private final Inventory _inventory;
private final List<L2ItemInstance> _changed;
/**
* Constructor of the ChangeRecorder
* @param inventory
*/
ChangeRecorder(Inventory inventory)
{
_inventory = inventory;
_changed = new ArrayList<>();
_inventory.addPaperdollListener(this);
}
/**
* Add alteration in inventory when item equipped
* @param slot
* @param item
* @param inventory
*/
@Override
public void notifyEquiped(int slot, L2ItemInstance item, Inventory inventory)
{
if (!_changed.contains(item))
{
_changed.add(item);
}
}
/**
* Add alteration in inventory when item unequipped
* @param slot
* @param item
* @param inventory
*/
@Override
public void notifyUnequiped(int slot, L2ItemInstance item, Inventory inventory)
{
if (!_changed.contains(item))
{
_changed.add(item);
}
}
/**
* Returns alterations in inventory
* @return L2ItemInstance[] : array of altered items
*/
public L2ItemInstance[] getChangedItems()
{
return _changed.toArray(new L2ItemInstance[_changed.size()]);
}
}
private static final class BowCrossRodListener implements PaperdollListener
{
private static BowCrossRodListener instance = new BowCrossRodListener();
public static BowCrossRodListener getInstance()
{
return instance;
}
@Override
public void notifyUnequiped(int slot, L2ItemInstance item, Inventory inventory)
{
if (slot != PAPERDOLL_RHAND)
{
return;
}
if (item.getItemType() == WeaponType.BOW)
{
L2ItemInstance arrow = inventory.getPaperdollItem(PAPERDOLL_LHAND);
if (arrow != null)
{
inventory.setPaperdollItem(PAPERDOLL_LHAND, null);
}
}
else if (item.getItemType() == WeaponType.CROSSBOW)
{
L2ItemInstance bolts = inventory.getPaperdollItem(PAPERDOLL_LHAND);
if (bolts != null)
{
inventory.setPaperdollItem(PAPERDOLL_LHAND, null);
}
}
else if (item.getItemType() == WeaponType.FISHINGROD)
{
L2ItemInstance lure = inventory.getPaperdollItem(PAPERDOLL_LHAND);
if (lure != null)
{
inventory.setPaperdollItem(PAPERDOLL_LHAND, null);
}
}
}
@Override
public void notifyEquiped(int slot, L2ItemInstance item, Inventory inventory)
{
if (slot != PAPERDOLL_RHAND)
{
return;
}
if (item.getItemType() == WeaponType.BOW)
{
L2ItemInstance arrow = inventory.findArrowForBow(item.getItem());
if (arrow != null)
{
inventory.setPaperdollItem(PAPERDOLL_LHAND, arrow);
}
}
else if (item.getItemType() == WeaponType.CROSSBOW)
{
L2ItemInstance bolts = inventory.findBoltForCrossBow(item.getItem());
if (bolts != null)
{
inventory.setPaperdollItem(PAPERDOLL_LHAND, bolts);
}
}
}
}
private static final class StatsListener implements PaperdollListener
{
private static StatsListener instance = new StatsListener();
public static StatsListener getInstance()
{
return instance;
}
@Override
public void notifyUnequiped(int slot, L2ItemInstance item, Inventory inventory)
{
inventory.getOwner().removeStatsOwner(item);
}
@Override
public void notifyEquiped(int slot, L2ItemInstance item, Inventory inventory)
{
inventory.getOwner().addStatFuncs(item.getStatFuncs(inventory.getOwner()));
}
}
private static final class ItemSkillsListener implements PaperdollListener
{
private static ItemSkillsListener instance = new ItemSkillsListener();
public static ItemSkillsListener getInstance()
{
return instance;
}
@Override
public void notifyUnequiped(int slot, L2ItemInstance item, Inventory inventory)
{
if (!(inventory.getOwner() instanceof L2PcInstance))
{
return;
}
final L2PcInstance player = (L2PcInstance) inventory.getOwner();
Skill enchant4Skill, itemSkill;
L2Item it = item.getItem();
boolean update = false;
boolean updateTimeStamp = false;
// Remove augmentation bonuses on unequip
if (item.isAugmented())
{
item.getAugmentation().removeBonus(player);
}
item.removeElementAttrBonus(player);
// Remove skills bestowed from +4 armor
if (item.getEnchantLevel() >= 4)
{
enchant4Skill = it.getEnchant4Skill();
if (enchant4Skill != null)
{
player.removeSkill(enchant4Skill, false, enchant4Skill.isPassive());
update = true;
}
}
item.clearEnchantStats();
final SkillHolder[] skills = it.getSkills();
if (skills != null)
{
for (SkillHolder skillInfo : skills)
{
if (skillInfo == null)
{
continue;
}
itemSkill = skillInfo.getSkill();
if (itemSkill != null)
{
player.removeSkill(itemSkill, false, itemSkill.isPassive());
update = true;
}
else
{
_log.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + skillInfo + ".");
}
}
}
if (item.isArmor())
{
for (L2ItemInstance itm : inventory.getItems())
{
if (!itm.isEquipped() || (itm.getItem().getSkills() == null) || itm.equals(item))
{
continue;
}
for (SkillHolder sk : itm.getItem().getSkills())
{
if (player.getSkillLevel(sk.getSkillId()) != -1)
{
continue;
}
itemSkill = sk.getSkill();
if (itemSkill != null)
{
itemSkill.setReferenceItemId(item.getId());
player.addSkill(itemSkill, false);
if (itemSkill.isActive())
{
if (!player.hasSkillReuse(itemSkill.getReuseHashCode()))
{
int equipDelay = item.getEquipReuseDelay();
if (equipDelay > 0)
{
player.addTimeStamp(itemSkill, equipDelay);
player.disableSkill(itemSkill, equipDelay);
}
}
updateTimeStamp = true;
}
update = true;
}
}
}
}
// Apply skill, if weapon have "skills on unequip"
Skill unequipSkill = it.getUnequipSkill();
if (unequipSkill != null)
{
L2PcInstance[] targets =
{
player
};
unequipSkill.activateSkill(player, targets);
}
if (update)
{
player.sendSkillList();
if (updateTimeStamp)
{
player.sendPacket(new SkillCoolTime(player));
}
}
}
@Override
public void notifyEquiped(int slot, L2ItemInstance item, Inventory inventory)
{
if (!(inventory.getOwner() instanceof L2PcInstance))
{
return;
}
final L2PcInstance player = (L2PcInstance) inventory.getOwner();
Skill enchant4Skill, itemSkill;
L2Item it = item.getItem();
boolean update = false;
boolean updateTimeStamp = false;
// Apply augmentation bonuses on equip
if (item.isAugmented())
{
item.getAugmentation().applyBonus(player);
}
item.updateElementAttrBonus(player);
// Add skills bestowed from +4 armor
if (item.getEnchantLevel() >= 4)
{
enchant4Skill = it.getEnchant4Skill();
if (enchant4Skill != null)
{
player.addSkill(enchant4Skill, false);
update = true;
}
}
item.applyEnchantStats();
final SkillHolder[] skills = it.getSkills();
if (skills != null)
{
for (SkillHolder skillInfo : skills)
{
if (skillInfo == null)
{
continue;
}
itemSkill = skillInfo.getSkill();
if (itemSkill != null)
{
player.addSkill(itemSkill, false);
if (itemSkill.isActive())
{
if (!player.hasSkillReuse(itemSkill.getReuseHashCode()))
{
int equipDelay = item.getEquipReuseDelay();
if (equipDelay > 0)
{
player.addTimeStamp(itemSkill, equipDelay);
player.disableSkill(itemSkill, equipDelay);
}
}
updateTimeStamp = true;
}
update = true;
}
else
{
_log.warning("Inventory.ItemSkillsListener.Weapon: Incorrect skill: " + skillInfo + ".");
}
}
}
if (update)
{
player.sendSkillList();
if (updateTimeStamp)
{
player.sendPacket(new SkillCoolTime(player));
}
}
}
}
private static final class ArmorSetListener implements PaperdollListener
{
private static ArmorSetListener instance = new ArmorSetListener();
public static ArmorSetListener getInstance()
{
return instance;
}
private boolean addSkills(L2PcInstance player, L2ItemInstance item, List<ArmorsetSkillHolder> skills, int piecesCount)
{
boolean updateTimeStamp = false;
boolean update = false;
if (skills != null)
{
for (ArmorsetSkillHolder holder : skills)
{
final Skill itemSkill = holder.getSkill();
if (itemSkill != null)
{
if (holder.getMinimumPieces() > piecesCount)
{
continue;
}
player.addSkill(itemSkill, false);
if (itemSkill.isActive() && (item != null))
{
if (!player.hasSkillReuse(itemSkill.getReuseHashCode()))
{
int equipDelay = item.getEquipReuseDelay();
if (equipDelay > 0)
{
player.addTimeStamp(itemSkill, equipDelay);
player.disableSkill(itemSkill, equipDelay);
}
}
updateTimeStamp = true;
}
update = true;
}
else
{
_log.warning("Inventory.ArmorSetListener.addSkills: Incorrect skill: " + holder + ".");
}
}
}
if (updateTimeStamp)
{
player.sendPacket(new SkillCoolTime(player));
}
return update;
}
private boolean addShieldSkills(L2PcInstance player, List<SkillHolder> skills)
{
boolean update = false;
for (SkillHolder holder : skills)
{
if (holder.getSkill() != null)
{
player.addSkill(holder.getSkill(), false);
update = true;
}
else
{
_log.warning("Inventory.ArmorSetListener.addShieldSkills: Incorrect skill: " + holder + ".");
}
}
return update;
}
private boolean addEnchantSkills(L2PcInstance player, List<ArmorsetSkillHolder> skills, int lowestEnchantedItem)
{
boolean update = false;
for (ArmorsetSkillHolder holder : skills)
{
if (holder.getMinimumPieces() > lowestEnchantedItem)
{
continue;
}
if (holder.getSkill() != null)
{
player.addSkill(holder.getSkill(), false);
update = true;
}
else
{
_log.warning("Inventory.ArmorSetListener.addEnchantSkills: Incorrect skill: " + holder + ".");
}
}
return update;
}
@Override
public void notifyEquiped(int slot, L2ItemInstance item, Inventory inventory)
{
if (!(inventory.getOwner() instanceof L2PcInstance))
{
return;
}
// Checks if player is wearing a chest item
final L2ItemInstance chestItem = inventory.getPaperdollItem(PAPERDOLL_CHEST);
if (chestItem == null)
{
return;
}
final L2PcInstance player = (L2PcInstance) inventory.getOwner();
boolean update = false;
final L2ArmorSet armorSet = ArmorSetsData.getInstance().getSet(chestItem.getId());
if (armorSet != null)
{
// Checks if equipped item is part of set
if (armorSet.containItem(slot, item.getId()))
{
final int piecesCount = armorSet.getPiecesCount(player);
final int lowestEnchantedItem = armorSet.getLowestSetEnchant(player);
if (piecesCount >= armorSet.getMinimumPieces())
{
update = addSkills(player, item, armorSet.getSkills(), piecesCount);
if (armorSet.containShield(player)) // has shield from set
{
if (addShieldSkills(player, armorSet.getShieldSkills()))
{
update = true;
}
}
if (lowestEnchantedItem > 5) // has all parts of set enchanted to 6 or more
{
if (addEnchantSkills(player, armorSet.getEnchantSkills(), lowestEnchantedItem))
{
update = true;
}
}
}
}
else if (armorSet.containShield(item.getId()))
{
if (addShieldSkills(player, armorSet.getShieldSkills()))
{
update = true;
}
}
}
final L2ArmorSet visualArmorSet = ArmorSetsData.getInstance().getSet(chestItem.getVisualId());
if ((visualArmorSet != null) && visualArmorSet.isVisual())
{
int pieces = visualArmorSet.getVisualPiecesCount(player);
if (pieces >= visualArmorSet.getMinimumPieces())
{
addSkills(player, item, visualArmorSet.getSkills(), visualArmorSet.getPiecesCount(player));
}
}
if (update)
{
player.sendSkillList();
}
}
private boolean removeShieldSkills(L2PcInstance player, List<SkillHolder> shieldSkills)
{
if ((shieldSkills != null) && !shieldSkills.isEmpty())
{
for (SkillHolder holder : shieldSkills)
{
Skill itemSkill = holder.getSkill();
if (itemSkill != null)
{
player.removeSkill(itemSkill, false, itemSkill.isPassive());
}
else
{
_log.warning("Inventory.ArmorSetListener.removeShieldSkills: Incorrect skill: " + holder + ".");
}
}
return true;
}
return false;
}
@Override
public void notifyUnequiped(int slot, L2ItemInstance item, Inventory inventory)
{
if (!(inventory.getOwner() instanceof L2PcInstance))
{
return;
}
final L2PcInstance player = (L2PcInstance) inventory.getOwner();
boolean remove = false;
if (slot == PAPERDOLL_CHEST)
{
if (removeArmorsetBonus(player, ArmorSetsData.getInstance().getSet(item.getId())))
{
remove = true;
}
if (removeArmorsetBonus(player, ArmorSetsData.getInstance().getSet(item.getVisualId())))
{
remove = true;
}
}
else
{
final L2ItemInstance chestItem = inventory.getPaperdollItem(PAPERDOLL_CHEST);
if (chestItem == null)
{
return;
}
final L2ArmorSet armorSet = ArmorSetsData.getInstance().getSet(chestItem.getId());
if ((armorSet != null) && !armorSet.isVisual())
{
if (armorSet.containItem(slot, item.getId())) // removed part of set
{
if (removeArmorsetBonus(player, armorSet))
{
remove = true;
}
final int piecesCount = armorSet.getPiecesCount(player);
if (piecesCount > armorSet.getMinimumPieces())
{
addSkills(player, null, armorSet.getSkills(), piecesCount);
}
}
else if (armorSet.containShield(item.getId())) // removed shield
{
if (removeShieldSkills(player, armorSet.getShieldSkills()))
{
remove = true;
}
}
}
final L2ArmorSet visualArmorSet = ArmorSetsData.getInstance().getSet(chestItem.getVisualId());
if ((visualArmorSet != null) && visualArmorSet.isVisual())
{
if (visualArmorSet.containItem(slot, item.getVisualId())) // removed part of set
{
if (removeArmorsetBonus(player, visualArmorSet))
{
remove = true;
}
}
else if (visualArmorSet.containShield(item.getVisualId())) // removed shield
{
if (removeShieldSkills(player, visualArmorSet.getShieldSkills()))
{
remove = true;
}
}
}
}
if (remove)
{
player.checkItemRestriction();
player.sendSkillList();
}
}
}
protected static boolean removeArmorsetBonus(L2PcInstance player, L2ArmorSet armorSet)
{
boolean remove = armorSet != null;
final List<ArmorsetSkillHolder> skills = armorSet != null ? armorSet.getSkills() : null;
final List<SkillHolder> shieldSkill = armorSet != null ? armorSet.getShieldSkills() : null; // shield skill
final List<ArmorsetSkillHolder> enchantSkills = armorSet != null ? armorSet.getEnchantSkills() : null; // enchant +6 skill
Skill itemSkill;
if (skills != null)
{
for (SkillHolder holder : skills)
{
itemSkill = holder.getSkill();
if (itemSkill != null)
{
player.removeSkill(itemSkill, false, itemSkill.isPassive());
}
else
{
_log.warning("Inventory.ArmorSetListener: Incorrect skill: " + holder + ".");
}
}
}
if (shieldSkill != null)
{
for (SkillHolder holder : shieldSkill)
{
itemSkill = holder.getSkill();
if (itemSkill != null)
{
player.removeSkill(itemSkill, false, itemSkill.isPassive());
}
else
{
_log.warning("Inventory.ArmorSetListener: Incorrect skill: " + holder + ".");
}
}
}
if (enchantSkills != null)
{
for (SkillHolder holder : enchantSkills)
{
itemSkill = holder.getSkill();
if (itemSkill != null)
{
player.removeSkill(itemSkill, false, itemSkill.isPassive());
}
else
{
_log.warning("Inventory.ArmorSetListener: Incorrect skill: " + holder + ".");
}
}
}
return remove;
}
private static final class BraceletListener implements PaperdollListener
{
private static BraceletListener instance = new BraceletListener();
public static BraceletListener getInstance()
{
return instance;
}
@Override
public void notifyUnequiped(int slot, L2ItemInstance item, Inventory inventory)
{
if (item.getItem().getBodyPart() == L2Item.SLOT_R_BRACELET)
{
inventory.unEquipItemInSlot(PAPERDOLL_DECO1);
inventory.unEquipItemInSlot(PAPERDOLL_DECO2);
inventory.unEquipItemInSlot(PAPERDOLL_DECO3);
inventory.unEquipItemInSlot(PAPERDOLL_DECO4);
inventory.unEquipItemInSlot(PAPERDOLL_DECO5);
inventory.unEquipItemInSlot(PAPERDOLL_DECO6);
}
}
// Note (April 3, 2009): Currently on equip, talismans do not display properly, do we need checks here to fix this?
@Override
public void notifyEquiped(int slot, L2ItemInstance item, Inventory inventory)
{
}
}
private static final class BroochListener implements PaperdollListener
{
private static BroochListener instance = new BroochListener();
public static BroochListener getInstance()
{
return instance;
}
@Override
public void notifyUnequiped(int slot, L2ItemInstance item, Inventory inventory)
{
if (item.getItem().getBodyPart() == L2Item.SLOT_BROOCH)
{
inventory.unEquipItemInSlot(PAPERDOLL_BROOCH_JEWEL1);
inventory.unEquipItemInSlot(PAPERDOLL_BROOCH_JEWEL2);
inventory.unEquipItemInSlot(PAPERDOLL_BROOCH_JEWEL3);
inventory.unEquipItemInSlot(PAPERDOLL_BROOCH_JEWEL4);
inventory.unEquipItemInSlot(PAPERDOLL_BROOCH_JEWEL5);
inventory.unEquipItemInSlot(PAPERDOLL_BROOCH_JEWEL6);
}
}
// Note (April 3, 2009): Currently on equip, talismans do not display properly, do we need checks here to fix this?
@Override
public void notifyEquiped(int slot, L2ItemInstance item, Inventory inventory)
{
}
}
/**
* Constructor of the inventory
*/
protected Inventory()
{
_paperdoll = new L2ItemInstance[PAPERDOLL_TOTALSLOTS];
_paperdollListeners = new ArrayList<>();
if (this instanceof PcInventory)
{
addPaperdollListener(ArmorSetListener.getInstance());
addPaperdollListener(BowCrossRodListener.getInstance());
addPaperdollListener(ItemSkillsListener.getInstance());
addPaperdollListener(BraceletListener.getInstance());
addPaperdollListener(BroochListener.getInstance());
}
// common
addPaperdollListener(StatsListener.getInstance());
}
protected abstract ItemLocation getEquipLocation();
/**
* Returns the instance of new ChangeRecorder
* @return ChangeRecorder
*/
private ChangeRecorder newRecorder()
{
return new ChangeRecorder(this);
}
/**
* Drop item from inventory and updates database
* @param process : String Identifier of process triggering this action
* @param item : L2ItemInstance to be dropped
* @param actor : L2PcInstance Player requesting the item drop
* @param reference : Object Object referencing current action like NPC selling item or previous item in transformation
* @return L2ItemInstance corresponding to the destroyed item or the updated item in inventory
*/
public L2ItemInstance dropItem(String process, L2ItemInstance item, L2PcInstance actor, Object reference)
{
if (item == null)
{
return null;
}
synchronized (item)
{
if (!_items.contains(item))
{
return null;
}
removeItem(item);
item.setOwnerId(process, 0, actor, reference);
item.setItemLocation(ItemLocation.VOID);
item.setLastChange(L2ItemInstance.REMOVED);
item.updateDatabase();
refreshWeight();
}
return item;
}
/**
* Drop item from inventory by using its <B>objectID</B> and updates database
* @param process : String Identifier of process triggering this action
* @param objectId : int Item Instance identifier of the item to be dropped
* @param count : int Quantity of items to be dropped
* @param actor : L2PcInstance Player requesting the item drop
* @param reference : Object Object referencing current action like NPC selling item or previous item in transformation
* @return L2ItemInstance corresponding to the destroyed item or the updated item in inventory
*/
public L2ItemInstance dropItem(String process, int objectId, long count, L2PcInstance actor, Object reference)
{
L2ItemInstance item = getItemByObjectId(objectId);
if (item == null)
{
return null;
}
synchronized (item)
{
if (!_items.contains(item))
{
return null;
}
// Adjust item quantity and create new instance to drop
// Directly drop entire item
if (item.getCount() > count)
{
item.changeCount(process, -count, actor, reference);
item.setLastChange(L2ItemInstance.MODIFIED);
item.updateDatabase();
item = ItemTable.getInstance().createItem(process, item.getId(), count, actor, reference);
item.updateDatabase();
refreshWeight();
return item;
}
}
return dropItem(process, item, actor, reference);
}
/**
* Adds item to inventory for further adjustments and Equip it if necessary (itemlocation defined)
* @param item : L2ItemInstance to be added from inventory
*/
@Override
protected void addItem(L2ItemInstance item)
{
super.addItem(item);
if (item.isEquipped())
{
equipItem(item);
}
}
/**
* Removes item from inventory for further adjustments.
* @param item : L2ItemInstance to be removed from inventory
*/
@Override
protected boolean removeItem(L2ItemInstance item)
{
// Unequip item if equiped
for (int i = 0; i < _paperdoll.length; i++)
{
if (_paperdoll[i] == item)
{
unEquipItemInSlot(i);
}
}
return super.removeItem(item);
}
/**
* @param slot the slot.
* @return the item in the paperdoll slot
*/
public L2ItemInstance getPaperdollItem(int slot)
{
return _paperdoll[slot];
}
/**
* @param slot the slot.
* @return {@code true} if specified paperdoll slot is empty, {@code false} otherwise
*/
public boolean isPaperdollSlotEmpty(int slot)
{
return _paperdoll[slot] == null;
}
public static int getPaperdollIndex(int slot)
{
switch (slot)
{
case L2Item.SLOT_UNDERWEAR:
return PAPERDOLL_UNDER;
case L2Item.SLOT_R_EAR:
return PAPERDOLL_REAR;
case L2Item.SLOT_LR_EAR:
case L2Item.SLOT_L_EAR:
return PAPERDOLL_LEAR;
case L2Item.SLOT_NECK:
return PAPERDOLL_NECK;
case L2Item.SLOT_R_FINGER:
case L2Item.SLOT_LR_FINGER:
return PAPERDOLL_RFINGER;
case L2Item.SLOT_L_FINGER:
return PAPERDOLL_LFINGER;
case L2Item.SLOT_HEAD:
return PAPERDOLL_HEAD;
case L2Item.SLOT_R_HAND:
case L2Item.SLOT_LR_HAND:
return PAPERDOLL_RHAND;
case L2Item.SLOT_L_HAND:
return PAPERDOLL_LHAND;
case L2Item.SLOT_GLOVES:
return PAPERDOLL_GLOVES;
case L2Item.SLOT_CHEST:
case L2Item.SLOT_FULL_ARMOR:
case L2Item.SLOT_ALLDRESS:
return PAPERDOLL_CHEST;
case L2Item.SLOT_LEGS:
return PAPERDOLL_LEGS;
case L2Item.SLOT_FEET:
return PAPERDOLL_FEET;
case L2Item.SLOT_BACK:
return PAPERDOLL_CLOAK;
case L2Item.SLOT_HAIR:
case L2Item.SLOT_HAIRALL:
return PAPERDOLL_HAIR;
case L2Item.SLOT_HAIR2:
return PAPERDOLL_HAIR2;
case L2Item.SLOT_R_BRACELET:
return PAPERDOLL_RBRACELET;
case L2Item.SLOT_L_BRACELET:
return PAPERDOLL_LBRACELET;
case L2Item.SLOT_DECO:
return PAPERDOLL_DECO1; // return first we deal with it later
case L2Item.SLOT_BELT:
return PAPERDOLL_BELT;
case L2Item.SLOT_BROOCH:
return PAPERDOLL_BROOCH;
case L2Item.SLOT_BROOCH_JEWEL:
return PAPERDOLL_BROOCH_JEWEL1;
}
return -1;
}
/**
* Returns the item in the paperdoll L2Item slot
* @param slot identifier
* @return L2ItemInstance
*/
public L2ItemInstance getPaperdollItemByL2ItemId(int slot)
{
int index = getPaperdollIndex(slot);
if (index == -1)
{
return null;
}
return _paperdoll[index];
}
/**
* Returns the ID of the item in the paperdoll slot
* @param slot : int designating the slot
* @return int designating the ID of the item
*/
public int getPaperdollItemId(int slot)
{
L2ItemInstance item = _paperdoll[slot];
if (item != null)
{
return item.getId();
}
return 0;
}
/**
* Returns the ID of the item in the paperdoll slot
* @param slot : int designating the slot
* @return int designating the ID of the item
*/
public int getPaperdollItemDisplayId(int slot)
{
final L2ItemInstance item = _paperdoll[slot];
return (item != null) ? item.getDisplayId() : 0;
}
/**
* Returns the visual id of the item in the paperdoll slot
* @param slot : int designating the slot
* @return int designating the ID of the item
*/
public int getPaperdollItemVisualId(int slot)
{
final L2ItemInstance item = _paperdoll[slot];
return (item != null) ? item.getVisualId() : 0;
}
public int getPaperdollAugmentationId(int slot)
{
final L2ItemInstance item = _paperdoll[slot];
return ((item != null) && (item.getAugmentation() != null)) ? item.getAugmentation().getAugmentationId() : 0;
}
/**
* Returns the objectID associated to the item in the paperdoll slot
* @param slot : int pointing out the slot
* @return int designating the objectID
*/
public int getPaperdollObjectId(int slot)
{
final L2ItemInstance item = _paperdoll[slot];
return (item != null) ? item.getObjectId() : 0;
}
/**
* Adds new inventory's paperdoll listener.
* @param listener the new listener
*/
public synchronized void addPaperdollListener(PaperdollListener listener)
{
assert !_paperdollListeners.contains(listener);
_paperdollListeners.add(listener);
}
/**
* Removes a paperdoll listener.
* @param listener the listener to be deleted
*/
public synchronized void removePaperdollListener(PaperdollListener listener)
{
_paperdollListeners.remove(listener);
}
/**
* Equips an item in the given slot of the paperdoll.<br>
* <U><I>Remark :</I></U> The item <B>must be</B> in the inventory already.
* @param slot : int pointing out the slot of the paperdoll
* @param item : L2ItemInstance pointing out the item to add in slot
* @return L2ItemInstance designating the item placed in the slot before
*/
public synchronized L2ItemInstance setPaperdollItem(int slot, L2ItemInstance item)
{
L2ItemInstance old = _paperdoll[slot];
if (old != item)
{
if (old != null)
{
_paperdoll[slot] = null;
// Put old item from paperdoll slot to base location
old.setItemLocation(getBaseLocation());
old.setLastChange(L2ItemInstance.MODIFIED);
// Get the mask for paperdoll
int mask = 0;
for (int i = 0; i < PAPERDOLL_TOTALSLOTS; i++)
{
L2ItemInstance pi = _paperdoll[i];
if (pi != null)
{
mask |= pi.getItem().getItemMask();
}
}
_wearedMask = mask;
// Notify all paperdoll listener in order to unequip old item in slot
for (PaperdollListener listener : _paperdollListeners)
{
if (listener == null)
{
continue;
}
listener.notifyUnequiped(slot, old, this);
}
old.updateDatabase();
if (getOwner().isPlayer())
{
getOwner().sendPacket(new ExUserInfoEquipSlot(getOwner().getActingPlayer()));
}
}
// Add new item in slot of paperdoll
if (item != null)
{
_paperdoll[slot] = item;
item.setItemLocation(getEquipLocation(), slot);
item.setLastChange(L2ItemInstance.MODIFIED);
_wearedMask |= item.getItem().getItemMask();
for (PaperdollListener listener : _paperdollListeners)
{
if (listener == null)
{
continue;
}
listener.notifyEquiped(slot, item, this);
}
item.updateDatabase();
if (getOwner().isPlayer())
{
getOwner().sendPacket(new ExUserInfoEquipSlot(getOwner().getActingPlayer()));
}
}
}
return old;
}
/**
* @return the mask of wore item
*/
public int getWearedMask()
{
return _wearedMask;
}
public int getSlotFromItem(L2ItemInstance item)
{
int slot = -1;
final int location = item.getLocationSlot();
switch (location)
{
case PAPERDOLL_UNDER:
slot = L2Item.SLOT_UNDERWEAR;
break;
case PAPERDOLL_LEAR:
slot = L2Item.SLOT_L_EAR;
break;
case PAPERDOLL_REAR:
slot = L2Item.SLOT_R_EAR;
break;
case PAPERDOLL_NECK:
slot = L2Item.SLOT_NECK;
break;
case PAPERDOLL_RFINGER:
slot = L2Item.SLOT_R_FINGER;
break;
case PAPERDOLL_LFINGER:
slot = L2Item.SLOT_L_FINGER;
break;
case PAPERDOLL_HAIR:
slot = L2Item.SLOT_HAIR;
break;
case PAPERDOLL_HAIR2:
slot = L2Item.SLOT_HAIR2;
break;
case PAPERDOLL_HEAD:
slot = L2Item.SLOT_HEAD;
break;
case PAPERDOLL_RHAND:
slot = L2Item.SLOT_R_HAND;
break;
case PAPERDOLL_LHAND:
slot = L2Item.SLOT_L_HAND;
break;
case PAPERDOLL_GLOVES:
slot = L2Item.SLOT_GLOVES;
break;
case PAPERDOLL_CHEST:
slot = item.getItem().getBodyPart();
break;
case PAPERDOLL_LEGS:
slot = L2Item.SLOT_LEGS;
break;
case PAPERDOLL_CLOAK:
slot = L2Item.SLOT_BACK;
break;
case PAPERDOLL_FEET:
slot = L2Item.SLOT_FEET;
break;
case PAPERDOLL_LBRACELET:
slot = L2Item.SLOT_L_BRACELET;
break;
case PAPERDOLL_RBRACELET:
slot = L2Item.SLOT_R_BRACELET;
break;
case PAPERDOLL_DECO1:
case PAPERDOLL_DECO2:
case PAPERDOLL_DECO3:
case PAPERDOLL_DECO4:
case PAPERDOLL_DECO5:
case PAPERDOLL_DECO6:
slot = L2Item.SLOT_DECO;
break;
case PAPERDOLL_BELT:
slot = L2Item.SLOT_BELT;
break;
case PAPERDOLL_BROOCH:
slot = L2Item.SLOT_BROOCH;
break;
case PAPERDOLL_BROOCH_JEWEL1:
case PAPERDOLL_BROOCH_JEWEL2:
case PAPERDOLL_BROOCH_JEWEL3:
case PAPERDOLL_BROOCH_JEWEL4:
case PAPERDOLL_BROOCH_JEWEL5:
case PAPERDOLL_BROOCH_JEWEL6:
slot = L2Item.SLOT_BROOCH_JEWEL;
break;
}
return slot;
}
/**
* Unequips item in body slot and returns alterations.<BR>
* <B>If you dont need return value use {@link Inventory#unEquipItemInBodySlot(int)} instead</B>
* @param slot : int designating the slot of the paperdoll
* @return L2ItemInstance[] : list of changes
*/
public L2ItemInstance[] unEquipItemInBodySlotAndRecord(int slot)
{
Inventory.ChangeRecorder recorder = newRecorder();
try
{
unEquipItemInBodySlot(slot);
}
finally
{
removePaperdollListener(recorder);
}
return recorder.getChangedItems();
}
/**
* Sets item in slot of the paperdoll to null value
* @param pdollSlot : int designating the slot
* @return L2ItemInstance designating the item in slot before change
*/
public L2ItemInstance unEquipItemInSlot(int pdollSlot)
{
return setPaperdollItem(pdollSlot, null);
}
/**
* Unequips item in slot and returns alterations<BR>
* <B>If you dont need return value use {@link Inventory#unEquipItemInSlot(int)} instead</B>
* @param slot : int designating the slot
* @return L2ItemInstance[] : list of items altered
*/
public L2ItemInstance[] unEquipItemInSlotAndRecord(int slot)
{
Inventory.ChangeRecorder recorder = newRecorder();
try
{
unEquipItemInSlot(slot);
if (getOwner() instanceof L2PcInstance)
{
((L2PcInstance) getOwner()).refreshExpertisePenalty();
}
}
finally
{
removePaperdollListener(recorder);
}
return recorder.getChangedItems();
}
/**
* Unequips item in slot (i.e. equips with default value)
* @param slot : int designating the slot
* @return {@link L2ItemInstance} designating the item placed in the slot
*/
public L2ItemInstance unEquipItemInBodySlot(int slot)
{
if (Config.DEBUG)
{
_log.info(Inventory.class.getSimpleName() + ": Unequip body slot:" + slot);
}
int pdollSlot = -1;
switch (slot)
{
case L2Item.SLOT_L_EAR:
pdollSlot = PAPERDOLL_LEAR;
break;
case L2Item.SLOT_R_EAR:
pdollSlot = PAPERDOLL_REAR;
break;
case L2Item.SLOT_NECK:
pdollSlot = PAPERDOLL_NECK;
break;
case L2Item.SLOT_R_FINGER:
pdollSlot = PAPERDOLL_RFINGER;
break;
case L2Item.SLOT_L_FINGER:
pdollSlot = PAPERDOLL_LFINGER;
break;
case L2Item.SLOT_HAIR:
pdollSlot = PAPERDOLL_HAIR;
break;
case L2Item.SLOT_HAIR2:
pdollSlot = PAPERDOLL_HAIR2;
break;
case L2Item.SLOT_HAIRALL:
setPaperdollItem(PAPERDOLL_HAIR, null);
pdollSlot = PAPERDOLL_HAIR;
break;
case L2Item.SLOT_HEAD:
pdollSlot = PAPERDOLL_HEAD;
break;
case L2Item.SLOT_R_HAND:
case L2Item.SLOT_LR_HAND:
pdollSlot = PAPERDOLL_RHAND;
break;
case L2Item.SLOT_L_HAND:
pdollSlot = PAPERDOLL_LHAND;
break;
case L2Item.SLOT_GLOVES:
pdollSlot = PAPERDOLL_GLOVES;
break;
case L2Item.SLOT_CHEST:
case L2Item.SLOT_ALLDRESS:
case L2Item.SLOT_FULL_ARMOR:
pdollSlot = PAPERDOLL_CHEST;
break;
case L2Item.SLOT_LEGS:
pdollSlot = PAPERDOLL_LEGS;
break;
case L2Item.SLOT_BACK:
pdollSlot = PAPERDOLL_CLOAK;
break;
case L2Item.SLOT_FEET:
pdollSlot = PAPERDOLL_FEET;
break;
case L2Item.SLOT_UNDERWEAR:
pdollSlot = PAPERDOLL_UNDER;
break;
case L2Item.SLOT_L_BRACELET:
pdollSlot = PAPERDOLL_LBRACELET;
break;
case L2Item.SLOT_R_BRACELET:
pdollSlot = PAPERDOLL_RBRACELET;
break;
case L2Item.SLOT_DECO:
pdollSlot = PAPERDOLL_DECO1;
break;
case L2Item.SLOT_BELT:
pdollSlot = PAPERDOLL_BELT;
break;
case L2Item.SLOT_BROOCH:
pdollSlot = PAPERDOLL_BROOCH;
break;
case L2Item.SLOT_BROOCH_JEWEL:
pdollSlot = PAPERDOLL_BROOCH_JEWEL1;
break;
default:
_log.info("Unhandled slot type: " + slot);
_log.info(StringUtil.getTraceString(Thread.currentThread().getStackTrace()));
}
if (pdollSlot >= 0)
{
L2ItemInstance old = setPaperdollItem(pdollSlot, null);
if (old != null)
{
if (getOwner() instanceof L2PcInstance)
{
((L2PcInstance) getOwner()).refreshExpertisePenalty();
}
}
return old;
}
return null;
}
/**
* Equips item and returns list of alterations<BR>
* <B>If you don't need return value use {@link Inventory#equipItem(L2ItemInstance)} instead</B>
* @param item : L2ItemInstance corresponding to the item
* @return L2ItemInstance[] : list of alterations
*/
public L2ItemInstance[] equipItemAndRecord(L2ItemInstance item)
{
Inventory.ChangeRecorder recorder = newRecorder();
try
{
equipItem(item);
}
finally
{
removePaperdollListener(recorder);
}
return recorder.getChangedItems();
}
/**
* Equips item in slot of paperdoll.
* @param item : L2ItemInstance designating the item and slot used.
*/
public void equipItem(L2ItemInstance item)
{
if ((getOwner() instanceof L2PcInstance) && (((L2PcInstance) getOwner()).getPrivateStoreType() != PrivateStoreType.NONE))
{
return;
}
if (getOwner() instanceof L2PcInstance)
{
L2PcInstance player = (L2PcInstance) getOwner();
if (!player.canOverrideCond(PcCondOverride.ITEM_CONDITIONS) && !player.isHero() && item.isHeroItem())
{
return;
}
}
int targetSlot = item.getItem().getBodyPart();
// Check if player is using Formal Wear and item isn't Wedding Bouquet.
L2ItemInstance formal = getPaperdollItem(PAPERDOLL_CHEST);
if ((item.getId() != 21163) && (formal != null) && (formal.getItem().getBodyPart() == L2Item.SLOT_ALLDRESS))
{
// only chest target can pass this
switch (targetSlot)
{
case L2Item.SLOT_LR_HAND:
case L2Item.SLOT_L_HAND:
case L2Item.SLOT_R_HAND:
case L2Item.SLOT_LEGS:
case L2Item.SLOT_FEET:
case L2Item.SLOT_GLOVES:
case L2Item.SLOT_HEAD:
return;
}
}
switch (targetSlot)
{
case L2Item.SLOT_LR_HAND:
{
setPaperdollItem(PAPERDOLL_LHAND, null);
setPaperdollItem(PAPERDOLL_RHAND, item);
break;
}
case L2Item.SLOT_L_HAND:
{
L2ItemInstance rh = getPaperdollItem(PAPERDOLL_RHAND);
if ((rh != null) && (rh.getItem().getBodyPart() == L2Item.SLOT_LR_HAND) && !(((rh.getItemType() == WeaponType.BOW) && (item.getItemType() == EtcItemType.ARROW)) || ((rh.getItemType() == WeaponType.CROSSBOW) && (item.getItemType() == EtcItemType.BOLT)) || ((rh.getItemType() == WeaponType.FISHINGROD) && (item.getItemType() == EtcItemType.LURE))))
{
setPaperdollItem(PAPERDOLL_RHAND, null);
}
setPaperdollItem(PAPERDOLL_LHAND, item);
break;
}
case L2Item.SLOT_R_HAND:
{
// don't care about arrows, listener will unequip them (hopefully)
setPaperdollItem(PAPERDOLL_RHAND, item);
break;
}
case L2Item.SLOT_L_EAR:
case L2Item.SLOT_R_EAR:
case L2Item.SLOT_LR_EAR:
{
if (_paperdoll[PAPERDOLL_LEAR] == null)
{
setPaperdollItem(PAPERDOLL_LEAR, item);
}
else if (_paperdoll[PAPERDOLL_REAR] == null)
{
setPaperdollItem(PAPERDOLL_REAR, item);
}
else
{
setPaperdollItem(PAPERDOLL_LEAR, item);
}
break;
}
case L2Item.SLOT_L_FINGER:
case L2Item.SLOT_R_FINGER:
case L2Item.SLOT_LR_FINGER:
{
if (_paperdoll[PAPERDOLL_LFINGER] == null)
{
setPaperdollItem(PAPERDOLL_LFINGER, item);
}
else if (_paperdoll[PAPERDOLL_RFINGER] == null)
{
setPaperdollItem(PAPERDOLL_RFINGER, item);
}
else
{
setPaperdollItem(PAPERDOLL_LFINGER, item);
}
break;
}
case L2Item.SLOT_NECK:
setPaperdollItem(PAPERDOLL_NECK, item);
break;
case L2Item.SLOT_FULL_ARMOR:
setPaperdollItem(PAPERDOLL_LEGS, null);
setPaperdollItem(PAPERDOLL_CHEST, item);
break;
case L2Item.SLOT_CHEST:
setPaperdollItem(PAPERDOLL_CHEST, item);
break;
case L2Item.SLOT_LEGS:
{
// handle full armor
L2ItemInstance chest = getPaperdollItem(PAPERDOLL_CHEST);
if ((chest != null) && (chest.getItem().getBodyPart() == L2Item.SLOT_FULL_ARMOR))
{
setPaperdollItem(PAPERDOLL_CHEST, null);
}
setPaperdollItem(PAPERDOLL_LEGS, item);
break;
}
case L2Item.SLOT_FEET:
setPaperdollItem(PAPERDOLL_FEET, item);
break;
case L2Item.SLOT_GLOVES:
setPaperdollItem(PAPERDOLL_GLOVES, item);
break;
case L2Item.SLOT_HEAD:
setPaperdollItem(PAPERDOLL_HEAD, item);
break;
case L2Item.SLOT_HAIR:
L2ItemInstance hair = getPaperdollItem(PAPERDOLL_HAIR);
if ((hair != null) && (hair.getItem().getBodyPart() == L2Item.SLOT_HAIRALL))
{
setPaperdollItem(PAPERDOLL_HAIR2, null);
}
else
{
setPaperdollItem(PAPERDOLL_HAIR, null);
}
setPaperdollItem(PAPERDOLL_HAIR, item);
break;
case L2Item.SLOT_HAIR2:
L2ItemInstance hair2 = getPaperdollItem(PAPERDOLL_HAIR);
if ((hair2 != null) && (hair2.getItem().getBodyPart() == L2Item.SLOT_HAIRALL))
{
setPaperdollItem(PAPERDOLL_HAIR, null);
}
else
{
setPaperdollItem(PAPERDOLL_HAIR2, null);
}
setPaperdollItem(PAPERDOLL_HAIR2, item);
break;
case L2Item.SLOT_HAIRALL:
setPaperdollItem(PAPERDOLL_HAIR2, null);
setPaperdollItem(PAPERDOLL_HAIR, item);
break;
case L2Item.SLOT_UNDERWEAR:
setPaperdollItem(PAPERDOLL_UNDER, item);
break;
case L2Item.SLOT_BACK:
setPaperdollItem(PAPERDOLL_CLOAK, item);
break;
case L2Item.SLOT_L_BRACELET:
setPaperdollItem(PAPERDOLL_LBRACELET, item);
break;
case L2Item.SLOT_R_BRACELET:
setPaperdollItem(PAPERDOLL_RBRACELET, item);
break;
case L2Item.SLOT_DECO:
equipTalisman(item);
break;
case L2Item.SLOT_BELT:
setPaperdollItem(PAPERDOLL_BELT, item);
break;
case L2Item.SLOT_ALLDRESS:
// formal dress
setPaperdollItem(PAPERDOLL_LEGS, null);
setPaperdollItem(PAPERDOLL_LHAND, null);
setPaperdollItem(PAPERDOLL_RHAND, null);
setPaperdollItem(PAPERDOLL_RHAND, null);
setPaperdollItem(PAPERDOLL_LHAND, null);
setPaperdollItem(PAPERDOLL_HEAD, null);
setPaperdollItem(PAPERDOLL_FEET, null);
setPaperdollItem(PAPERDOLL_GLOVES, null);
setPaperdollItem(PAPERDOLL_CHEST, item);
break;
case L2Item.SLOT_BROOCH:
setPaperdollItem(PAPERDOLL_BROOCH, item);
break;
case L2Item.SLOT_BROOCH_JEWEL:
equipBroochJewel(item);
break;
default:
_log.warning("Unknown body slot " + targetSlot + " for Item ID:" + item.getId());
}
}
/**
* Refresh the weight of equipment loaded
*/
@Override
protected void refreshWeight()
{
long weight = 0;
for (L2ItemInstance item : _items)
{
if ((item != null) && (item.getItem() != null))
{
weight += item.getItem().getWeight() * item.getCount();
}
}
_totalWeight = (int) Math.min(weight, Integer.MAX_VALUE);
}
/**
* @return the totalWeight.
*/
public int getTotalWeight()
{
return _totalWeight;
}
/**
* Return the L2ItemInstance of the arrows needed for this bow.
* @param bow : L2Item designating the bow
* @return L2ItemInstance pointing out arrows for bow
*/
public L2ItemInstance findArrowForBow(L2Item bow)
{
if (bow == null)
{
return null;
}
L2ItemInstance arrow = null;
for (L2ItemInstance item : getItems())
{
if (item.isEtcItem() && (item.getItem().getCrystalTypePlus() == bow.getCrystalTypePlus()) && (item.getEtcItem().getItemType() == EtcItemType.ARROW))
{
arrow = item;
break;
}
}
// Get the L2ItemInstance corresponding to the item identifier and return it
return arrow;
}
/**
* Return the L2ItemInstance of the bolts needed for this crossbow.
* @param crossbow : L2Item designating the crossbow
* @return L2ItemInstance pointing out bolts for crossbow
*/
public L2ItemInstance findBoltForCrossBow(L2Item crossbow)
{
L2ItemInstance bolt = null;
for (L2ItemInstance item : getItems())
{
if (item.isEtcItem() && (item.getItem().getCrystalTypePlus() == crossbow.getCrystalTypePlus()) && (item.getEtcItem().getItemType() == EtcItemType.BOLT))
{
bolt = item;
break;
}
}
// Get the L2ItemInstance corresponding to the item identifier and return it
return bolt;
}
/**
* Get back items in inventory from database
*/
@Override
public void restore()
{
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("SELECT object_id, item_id, count, enchant_level, loc, loc_data, custom_type1, custom_type2, mana_left, time FROM items WHERE owner_id=? AND (loc=? OR loc=?) ORDER BY loc_data"))
{
statement.setInt(1, getOwnerId());
statement.setString(2, getBaseLocation().name());
statement.setString(3, getEquipLocation().name());
try (ResultSet inv = statement.executeQuery())
{
L2ItemInstance item;
while (inv.next())
{
item = L2ItemInstance.restoreFromDb(getOwnerId(), inv);
if (item == null)
{
continue;
}
if (getOwner() instanceof L2PcInstance)
{
L2PcInstance player = (L2PcInstance) getOwner();
if (!player.canOverrideCond(PcCondOverride.ITEM_CONDITIONS) && !player.isHero() && item.isHeroItem())
{
item.setItemLocation(ItemLocation.INVENTORY);
}
}
L2World.getInstance().storeObject(item);
// If stackable item is found in inventory just add to current quantity
if (item.isStackable() && (getItemByItemId(item.getId()) != null))
{
addItem("Restore", item, getOwner().getActingPlayer(), null);
}
else
{
addItem(item);
}
}
}
refreshWeight();
}
catch (Exception e)
{
_log.log(Level.WARNING, "Could not restore inventory: " + e.getMessage(), e);
}
}
public int getTalismanSlots()
{
return getOwner().getActingPlayer().getStat().getTalismanSlots();
}
private void equipTalisman(L2ItemInstance item)
{
if (getTalismanSlots() == 0)
{
return;
}
// find same (or incompatible) talisman type
for (int i = PAPERDOLL_DECO1; i < (PAPERDOLL_DECO1 + getTalismanSlots()); i++)
{
if (_paperdoll[i] != null)
{
if (getPaperdollItemId(i) == item.getId())
{
// overwtite
setPaperdollItem(i, item);
return;
}
}
}
// no free slot found - put on first free
for (int i = PAPERDOLL_DECO1; i < (PAPERDOLL_DECO1 + getTalismanSlots()); i++)
{
if (_paperdoll[i] == null)
{
setPaperdollItem(i, item);
return;
}
}
// no free slots - put on first
setPaperdollItem(PAPERDOLL_DECO1, item);
}
public int getBroochJewelSlots()
{
return getOwner().getActingPlayer().getStat().getBroochJewelSlots();
}
private void equipBroochJewel(L2ItemInstance item)
{
if (getBroochJewelSlots() == 0)
{
return;
}
// find same (or incompatible) brooch jewel type
for (int i = PAPERDOLL_BROOCH_JEWEL1; i < (PAPERDOLL_BROOCH_JEWEL1 + getBroochJewelSlots()); i++)
{
if (_paperdoll[i] != null)
{
if (getPaperdollItemId(i) == item.getId())
{
// overwtite
setPaperdollItem(i, item);
return;
}
}
}
// no free slot found - put on first free
for (int i = PAPERDOLL_BROOCH_JEWEL1; i < (PAPERDOLL_BROOCH_JEWEL1 + getBroochJewelSlots()); i++)
{
if (_paperdoll[i] == null)
{
setPaperdollItem(i, item);
return;
}
}
// no free slots - put on first
setPaperdollItem(PAPERDOLL_BROOCH_JEWEL1, item);
}
public boolean canEquipCloak()
{
return getOwner().getActingPlayer().getStat().canEquipCloak();
}
/**
* Re-notify to paperdoll listeners every equipped item
*/
public void reloadEquippedItems()
{
int slot;
for (L2ItemInstance item : _paperdoll)
{
if (item == null)
{
continue;
}
slot = item.getLocationSlot();
for (PaperdollListener listener : _paperdollListeners)
{
if (listener == null)
{
continue;
}
listener.notifyUnequiped(slot, item, this);
listener.notifyEquiped(slot, item, this);
}
}
if (getOwner().isPlayer())
{
getOwner().sendPacket(new ExUserInfoEquipSlot(getOwner().getActingPlayer()));
}
}
public int getArmorMinEnchant()
{
if ((getOwner() == null) || !getOwner().isPlayer())
{
return 0;
}
final L2PcInstance player = getOwner().getActingPlayer();
final L2ItemInstance chest = getPaperdollItem(PAPERDOLL_CHEST);
final L2ArmorSet set = chest != null ? ArmorSetsData.getInstance().getSet(chest.getId()) : null;
// No Chest - No Bonus
if ((chest == null) || (set == null))
{
return 0;
}
return set.getLowestSetEnchant(player);
}
public int getWeaponEnchant()
{
final L2ItemInstance item = getPaperdollItem(Inventory.PAPERDOLL_RHAND);
return item != null ? item.getEnchantLevel() : 0;
}
}