/*
* This program 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 2, or (at your option)
* any later version.
*
* This program 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* http://www.gnu.org/copyleft/gpl.html
*/
package com.l2jfrozen.gameserver.model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.List;
import javolution.util.FastList;
import com.l2jfrozen.Config;
import com.l2jfrozen.gameserver.datatables.SkillTable;
import com.l2jfrozen.gameserver.datatables.sql.ArmorSetsTable;
import com.l2jfrozen.gameserver.datatables.sql.ItemTable;
import com.l2jfrozen.gameserver.model.actor.instance.L2ItemInstance;
import com.l2jfrozen.gameserver.model.actor.instance.L2ItemInstance.ItemLocation;
import com.l2jfrozen.gameserver.model.actor.instance.L2PcInstance;
import com.l2jfrozen.gameserver.templates.L2Armor;
import com.l2jfrozen.gameserver.templates.L2EtcItem;
import com.l2jfrozen.gameserver.templates.L2EtcItemType;
import com.l2jfrozen.gameserver.templates.L2Item;
import com.l2jfrozen.gameserver.templates.L2Weapon;
import com.l2jfrozen.gameserver.templates.L2WeaponType;
import com.l2jfrozen.util.CloseUtil;
import com.l2jfrozen.util.database.L2DatabaseFactory;
/**
* 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);
public void notifyUnequiped(int slot, L2ItemInstance inst);
}
public static final int PAPERDOLL_UNDER = 0;
public static final int PAPERDOLL_LEAR = 1;
public static final int PAPERDOLL_REAR = 2;
public static final int PAPERDOLL_NECK = 3;
public static final int PAPERDOLL_LFINGER = 4;
public static final int PAPERDOLL_RFINGER = 5;
public static final int PAPERDOLL_HEAD = 6;
public static final int PAPERDOLL_RHAND = 7;
public static final int PAPERDOLL_LHAND = 8;
public static final int PAPERDOLL_GLOVES = 9;
public static final int PAPERDOLL_CHEST = 10;
public static final int PAPERDOLL_LEGS = 11;
public static final int PAPERDOLL_FEET = 12;
public static final int PAPERDOLL_BACK = 13;
public static final int PAPERDOLL_LRHAND = 14;
public static final int PAPERDOLL_FACE = 15;
public static final int PAPERDOLL_HAIR = 16;
public static final int PAPERDOLL_DHAIR = 17;
public static final int PAPERDOLL_TOTALSLOTS = 18;
//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;
final class FormalWearListener implements PaperdollListener
{
@Override
public void notifyUnequiped(int slot, L2ItemInstance item)
{
if(!(getOwner() != null && getOwner() instanceof L2PcInstance))
return;
L2PcInstance owner = (L2PcInstance) getOwner();
if(item.getItemId() == 6408)
{
owner.setIsWearingFormalWear(false);
}
owner = null;
}
@Override
public void notifyEquiped(int slot, L2ItemInstance item)
{
if(!(getOwner() != null && getOwner() instanceof L2PcInstance))
return;
L2PcInstance owner = (L2PcInstance) getOwner();
// If player equip Formal Wear unequip weapons and abort cast/attack
if(item.getItemId() == 6408)
{
owner.setIsWearingFormalWear(true);
if(owner.isCastingNow())
{
owner.abortCast();
}
if(owner.isAttackingNow())
{
owner.abortAttack();
}
unEquipItemInSlot(PAPERDOLL_RHAND);
unEquipItemInSlot(PAPERDOLL_LHAND);
unEquipItemInSlot(PAPERDOLL_LRHAND);
}
else
{
if(!owner.isWearingFormalWear())
return;
}
owner = null;
}
}
/**
* Recorder of alterations in inventory
*/
public 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 FastList<L2ItemInstance>();
_inventory.addPaperdollListener(this);
}
/**
* Add alteration in inventory when item equiped
*/
@Override
public void notifyEquiped(int slot, L2ItemInstance item)
{
if(!_changed.contains(item))
{
_changed.add(item);
}
}
/**
* Add alteration in inventory when item unequiped
*/
@Override
public void notifyUnequiped(int slot, L2ItemInstance item)
{
if(!_changed.contains(item))
{
_changed.add(item);
}
}
/**
* Returns alterations in inventory
*
* @return L2ItemInstance[] : array of alterated items
*/
public L2ItemInstance[] getChangedItems()
{
return _changed.toArray(new L2ItemInstance[_changed.size()]);
}
}
final class BowListener implements PaperdollListener
{
@Override
public void notifyUnequiped(int slot, L2ItemInstance item)
{
if(slot != PAPERDOLL_LRHAND)
return;
if(Config.ASSERT)
{
assert null == getPaperdollItem(PAPERDOLL_LRHAND);
}
if(item.getItemType() == L2WeaponType.BOW)
{
L2ItemInstance arrow = getPaperdollItem(PAPERDOLL_LHAND);
if(arrow != null)
{
setPaperdollItem(PAPERDOLL_LHAND, null);
}
L2PcInstance player = null;
L2Skill skill = null;
if(item.getItemId() == 9140)
{
if(getOwner() instanceof L2PcInstance)
{
player = (L2PcInstance) getOwner();
skill = SkillTable.getInstance().getInfo(3261, 1);
player.removeSkill(skill);
player.sendSkillList();
skill = null;
}
}
arrow = null;
}
}
/**
* private void InventoryUpdate() { // TODO Auto-generated method stub }
**/
@Override
public void notifyEquiped(int slot, L2ItemInstance item)
{
if(slot != PAPERDOLL_LRHAND)
return;
if(Config.ASSERT)
{
assert item == getPaperdollItem(PAPERDOLL_LRHAND);
}
if(item.getItemType() == L2WeaponType.BOW)
{
L2ItemInstance arrow = findArrowForBow(item.getItem());
if(arrow != null)
{
setPaperdollItem(PAPERDOLL_LHAND, arrow);
//InventoryUpdate();
}
L2PcInstance player = null;
L2Skill skill = null;
if(item.getItemId() == 9140)
{
if(getOwner() instanceof L2PcInstance)
{
player = (L2PcInstance) getOwner();
skill = SkillTable.getInstance().getInfo(3261, 1);
player.addSkill(skill, false);
player.sendSkillList();
skill = null;
}
}
arrow = null;
}
}
}
final class StatsListener implements PaperdollListener
{
@Override
public void notifyUnequiped(int slot, L2ItemInstance item)
{
if(slot == PAPERDOLL_LRHAND)
return;
getOwner().removeStatsOwner(item);
}
@Override
public void notifyEquiped(int slot, L2ItemInstance item)
{
if(slot == PAPERDOLL_LRHAND)
return;
getOwner().addStatFuncs(item.getStatFuncs(getOwner()));
}
}
final class ItemPassiveSkillsListener implements PaperdollListener
{
@Override
public void notifyUnequiped(int slot, L2ItemInstance item)
{
L2PcInstance player;
if(getOwner() instanceof L2PcInstance)
{
player = (L2PcInstance) getOwner();
}
else
return;
L2Skill passiveSkill = null;
L2Skill enchant4Skill = null;
L2Item it = item.getItem();
if(it instanceof L2Weapon)
{
passiveSkill = ((L2Weapon) it).getSkill();
enchant4Skill = ((L2Weapon) it).getEnchant4Skill();
}
else if(it instanceof L2Armor)
{
passiveSkill = ((L2Armor) it).getSkill();
}
if(!player.isItemEquippedByItemId(item.getItemId())){
if(passiveSkill != null)
{
player.removeSkill(passiveSkill, false);
player.sendSkillList();
}
if(enchant4Skill != null)
{
player.removeSkill(enchant4Skill, false);
player.sendSkillList();
}
}
player = null;
passiveSkill = null;
enchant4Skill = null;
}
@Override
public void notifyEquiped(int slot, L2ItemInstance item)
{
L2PcInstance player;
if(getOwner() instanceof L2PcInstance)
{
player = (L2PcInstance) getOwner();
}
else
return;
L2Skill passiveSkill = null;
L2Skill enchant4Skill = null;
L2Item it = item.getItem();
if(it instanceof L2Weapon)
{
// Check for Penality
player.refreshExpertisePenalty();
player.refreshMasteryWeapPenality();
// If player get penality he will not recive SA bonus like retail
if (player.getExpertisePenalty() == 0)
{
// Passive skills from Weapon (SA)
passiveSkill = ((L2Weapon) it).getSkill();
}
if(item.getEnchantLevel() >= 4)
{
enchant4Skill = ((L2Weapon) it).getEnchant4Skill();
}
}
else if(it instanceof L2Armor)
{
// Check for Penality
player.refreshExpertisePenalty();
player.refreshMasteryPenality();
// Passive skills from Armor
passiveSkill = ((L2Armor) it).getSkill();
}
if(passiveSkill != null)
{
if(!passiveSkill.is_singleEffect()
|| player.getInventory().checkHowManyEquipped(item.getItemId())==1){
player.addSkill(passiveSkill, false);
player.sendSkillList();
}
}
if(enchant4Skill != null)
{
if(!enchant4Skill.is_singleEffect()
|| player.getInventory().checkHowManyEquipped(item.getItemId())==1){
player.addSkill(enchant4Skill, false);
player.sendSkillList();
}
}
passiveSkill = null;
enchant4Skill = null;
player = null;
}
}
final class ArmorSetListener implements PaperdollListener
{
@Override
public void notifyEquiped(int slot, L2ItemInstance item)
{
if(!(getOwner() instanceof L2PcInstance))
return;
L2PcInstance player = (L2PcInstance) getOwner();
// checks if player worns chest item
L2ItemInstance chestItem = getPaperdollItem(PAPERDOLL_CHEST);
if(chestItem == null)
return;
// checks if there is armorset for chest item that player worns
L2ArmorSet armorSet = ArmorSetsTable.getInstance().getSet(chestItem.getItemId());
if(armorSet == null)
return;
// checks if equiped item is part of set
if(armorSet.containItem(slot, item.getItemId()))
{
if(armorSet.containAll(player))
{
L2Skill skill = SkillTable.getInstance().getInfo(armorSet.getSkillId(), 1);
if(skill != null)
{
player.addSkill(skill, false);
player.sendSkillList();
}
else
{
_log.warning("Inventory.ArmorSetListener: Incorrect skill: " + armorSet.getSkillId() + ".");
}
if(armorSet.containShield(player)) // has shield from set
{
L2Skill skills = SkillTable.getInstance().getInfo(armorSet.getShieldSkillId(), 1);
if(skills != null)
{
player.addSkill(skills, false);
player.sendSkillList();
}
else
{
_log.warning("Inventory.ArmorSetListener: Incorrect skill: " + armorSet.getShieldSkillId() + ".");
}
skills = null;
}
if(armorSet.isEnchanted6(player)) // has all parts of set enchanted to 6 or more
{
int skillId = armorSet.getEnchant6skillId();
if(skillId > 0)
{
L2Skill skille = SkillTable.getInstance().getInfo(skillId, 1);
if(skille != null)
{
player.addSkill(skille, false);
player.sendSkillList();
}
else
{
_log.warning("Inventory.ArmorSetListener: Incorrect skill: " + armorSet.getEnchant6skillId() + ".");
}
skille = null;
}
}
skill = null;
}
}
else if(armorSet.containShield(item.getItemId()))
{
if(armorSet.containAll(player))
{
L2Skill skills = SkillTable.getInstance().getInfo(armorSet.getShieldSkillId(), 1);
if(skills != null)
{
player.addSkill(skills, false);
player.sendSkillList();
}
else
{
_log.warning("Inventory.ArmorSetListener: Incorrect skill: " + armorSet.getShieldSkillId() + ".");
}
skills = null;
}
}
}
@Override
public void notifyUnequiped(int slot, L2ItemInstance item)
{
if(!(getOwner() instanceof L2PcInstance))
return;
L2PcInstance player = (L2PcInstance) getOwner();
boolean remove = false;
int removeSkillId1 = 0; // set skill
int removeSkillId2 = 0; // shield skill
int removeSkillId3 = 0; // enchant +6 skill
if(slot == PAPERDOLL_CHEST)
{
L2ArmorSet armorSet = ArmorSetsTable.getInstance().getSet(item.getItemId());
if(armorSet == null)
return;
remove = true;
removeSkillId1 = armorSet.getSkillId();
removeSkillId2 = armorSet.getShieldSkillId();
removeSkillId3 = armorSet.getEnchant6skillId();
armorSet = null;
}
else
{
L2ItemInstance chestItem = getPaperdollItem(PAPERDOLL_CHEST);
if(chestItem == null)
return;
L2ArmorSet armorSet = ArmorSetsTable.getInstance().getSet(chestItem.getItemId());
if(armorSet == null)
return;
if(armorSet.containItem(slot, item.getItemId())) // removed part of set
{
remove = true;
removeSkillId1 = armorSet.getSkillId();
removeSkillId2 = armorSet.getShieldSkillId();
removeSkillId3 = armorSet.getEnchant6skillId();
}
else if(armorSet.containShield(item.getItemId())) // removed shield
{
remove = true;
removeSkillId2 = armorSet.getShieldSkillId();
}
armorSet = null;
chestItem = null;
}
if(remove)
{
if(removeSkillId1 != 0)
{
L2Skill skill = SkillTable.getInstance().getInfo(removeSkillId1, 1);
if(skill != null)
{
player.removeSkill(skill);
}
else
{
_log.warning("Inventory.ArmorSetListener: Incorrect skill: " + removeSkillId1 + ".");
}
skill = null;
}
if(removeSkillId2 != 0)
{
L2Skill skill = SkillTable.getInstance().getInfo(removeSkillId2, 1);
if(skill != null)
{
player.removeSkill(skill);
}
else
{
_log.warning("Inventory.ArmorSetListener: Incorrect skill: " + removeSkillId2 + ".");
}
skill = null;
}
if(removeSkillId3 != 0)
{
L2Skill skill = SkillTable.getInstance().getInfo(removeSkillId3, 1);
if(skill != null)
{
player.removeSkill(skill);
}
else
{
_log.warning("Inventory.ArmorSetListener: Incorrect skill: " + removeSkillId3 + ".");
}
skill = null;
}
player.sendSkillList();
}
player = null;
}
}
/*
final class FormalWearListener implements PaperdollListener
{
public void notifyUnequiped(int slot, L2ItemInstance item)
{
if (!(getOwner() != null
&& getOwner() instanceof L2PcInstance))
return;
L2PcInstance owner = (L2PcInstance)getOwner();
if (item.getItemId() == 6408)
owner.setIsWearingFormalWear(false);
}
public void notifyEquiped(int slot, L2ItemInstance item)
{
if (!(getOwner() != null
&& getOwner() instanceof L2PcInstance))
return;
L2PcInstance owner = (L2PcInstance)getOwner();
// If player equip Formal Wear unequip weapons and abort cast/attack
if (item.getItemId() == 6408)
{
owner.setIsWearingFormalWear(true);
if (owner.isCastingNow())
owner.abortCast();
if (owner.isAttackingNow())
owner.abortAttack();
setPaperdollItem(PAPERDOLL_LHAND, null);
setPaperdollItem(PAPERDOLL_RHAND, null);
setPaperdollItem(PAPERDOLL_LRHAND, null);
}
else
{
if (!owner.isWearingFormalWear())
return;
// Don't let weapons be equipped if player is wearing Formal Wear
if (slot == PAPERDOLL_LHAND
|| slot == PAPERDOLL_RHAND
|| slot == PAPERDOLL_LRHAND)
{
setPaperdollItem(slot, null);
}
}
}
}
*/
/**
* Constructor of the inventory
*/
protected Inventory()
{
_paperdoll = new L2ItemInstance[0x12];
_paperdollListeners = new FastList<PaperdollListener>();
addPaperdollListener(new ArmorSetListener());
addPaperdollListener(new BowListener());
addPaperdollListener(new ItemPassiveSkillsListener());
addPaperdollListener(new StatsListener());
addPaperdollListener(new FormalWearListener());
}
protected abstract ItemLocation getEquipLocation();
/**
* Returns the instance of new ChangeRecorder
*
* @return ChangeRecorder
*/
public 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 : L2Object 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, L2Object reference)
{
synchronized (item)
{
if(!_items.contains(item))
return null;
removeItem(item);
item.setOwnerId(process, 0, actor, reference);
item.setLocation(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 : L2Object 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, int count, L2PcInstance actor, L2Object reference)
{
L2ItemInstance item = getItemByObjectId(objectId);
if(item == null)
return null;
// Adjust item quantity and create new instance to drop
if(item.getCount() > count)
{
item.changeCount(process, -count, actor, reference);
item.setLastChange(L2ItemInstance.MODIFIED);
item.updateDatabase();
item = ItemTable.getInstance().createItem(process, item.getItemId(), count, actor, reference);
item.updateDatabase();
refreshWeight();
return item;
}
// Directly drop entire item
return dropItem(process, item, actor, reference);
}
/**
* Adds item to inventory for further adjustments and Equip it if necessary (itemlocation defined)<BR>
* <BR>
*
* @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 void removeItem(L2ItemInstance item)
{
// Unequip item if equiped
// if (item.isEquipped()) unEquipItemInSlotAndRecord(item.getEquipSlot());
for(int i = 0; i < _paperdoll.length; i++)
if(_paperdoll[i] == item)
{
unEquipItemInSlot(i);
}
super.removeItem(item);
}
/**
* Returns the item in the paperdoll slot
* @param slot
*
* @return L2ItemInstance
*/
public L2ItemInstance getPaperdollItem(int slot)
{
return _paperdoll[slot];
}
/**
* Returns the item in the paperdoll L2Item slot
* @param slot
* @return L2ItemInstance
*/
public L2ItemInstance getPaperdollItemByL2ItemId(int slot)
{
switch(slot)
{
case 0x01:
return _paperdoll[0];
case 0x04:
return _paperdoll[1];
case 0x02:
return _paperdoll[2];
case 0x08:
return _paperdoll[3];
case 0x20:
return _paperdoll[4];
case 0x10:
return _paperdoll[5];
case 0x40:
return _paperdoll[6];
case 0x80:
return _paperdoll[7];
case 0x0100:
return _paperdoll[8];
case 0x0200:
return _paperdoll[9];
case 0x0400:
return _paperdoll[10];
case 0x0800:
return _paperdoll[11];
case 0x1000:
return _paperdoll[12];
case 0x2000:
return _paperdoll[13];
case 0x4000:
return _paperdoll[14];
case 0x040000:
return _paperdoll[15];
case 0x010000:
return _paperdoll[16];
case 0x080000:
return _paperdoll[17];
}
return null;
}
/**
* Returns the ID of the item in the paperdol 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.getItemId();
else if(slot == PAPERDOLL_HAIR)
{
item = _paperdoll[PAPERDOLL_DHAIR];
if(item != null)
return item.getItemId();
}
return 0;
}
public int getPaperdollAugmentationId(int slot)
{
L2ItemInstance item = _paperdoll[slot];
if(item != null)
{
if(item.getAugmentation() != null)
return item.getAugmentation().getAugmentationId();
return 0;
}
return 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)
{
L2ItemInstance item = _paperdoll[slot];
if(item != null)
return item.getObjectId();
else if(slot == PAPERDOLL_HAIR)
{
item = _paperdoll[PAPERDOLL_DHAIR];
if(item != null)
return item.getObjectId();
}
return 0;
}
/**
* Adds new inventory's paperdoll listener
*
* @param listener
*/
public synchronized void addPaperdollListener(PaperdollListener listener)
{
if(Config.ASSERT)
{
assert !_paperdollListeners.contains(listener);
}
_paperdollListeners.add(listener);
}
/**
* Removes a paperdoll listener
*
* @param listener to be deleted
*/
public synchronized void removePaperdollListener(PaperdollListener listener)
{
_paperdollListeners.remove(listener);
}
/**
* Equips an item in the given slot of the paperdoll. <U><I>Remark :</I></U> The item <B>HAS TO BE</B> already in
* the inventory
*
* @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 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.setLocation(getBaseLocation());
old.setLastChange(L2ItemInstance.MODIFIED);
// Get the mask for paperdoll
int mask = 0;
for(int i = 0; i < PAPERDOLL_LRHAND; i++)
{
L2ItemInstance pi = _paperdoll[i];
if(pi != null)
{
mask |= pi.getItem().getItemMask();
}
pi = null;
}
_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);
}
if(old.isAugmented())
{
if(getOwner() != null && getOwner() instanceof L2PcInstance)
old.getAugmentation().removeBoni((L2PcInstance)getOwner());
}
old.updateDatabase();
}
// Add new item in slot of paperdoll
if(item != null)
{
_paperdoll[slot] = item;
item.setLocation(getEquipLocation(), slot);
item.setLastChange(L2ItemInstance.MODIFIED);
_wearedMask |= item.getItem().getItemMask();
for(PaperdollListener listener : _paperdollListeners)
{
listener.notifyEquiped(slot, item);
}
item.updateDatabase();
}
}
return old;
}
/**
* Return the mask of weared item
*
* @return int
*/
public int getWearedMask()
{
return _wearedMask;
}
public int getSlotFromItem(L2ItemInstance item)
{
int slot = -1;
int location = item.getEquipSlot();
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_FACE:
slot = L2Item.SLOT_FACE;
break;
case PAPERDOLL_DHAIR:
slot = L2Item.SLOT_DHAIR;
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;// fall through
case PAPERDOLL_CHEST:
slot = L2Item.SLOT_CHEST;
break; //TODO
case PAPERDOLL_LEGS:
slot = L2Item.SLOT_LEGS;
break;
case PAPERDOLL_BACK:
slot = L2Item.SLOT_BACK;
break;
case PAPERDOLL_FEET:
slot = L2Item.SLOT_FEET;
break;
case PAPERDOLL_LRHAND:
slot = L2Item.SLOT_LR_HAND;
break;
}
return slot;
}
/**
* Unequips item in body slot and returns alterations.
*
* @param slot : int designating the slot of the paperdoll
* @return L2ItemInstance[] : list of changes
*/
//public synchronized L2ItemInstance[] unEquipItemInBodySlotAndRecord(int slot)
public L2ItemInstance[] unEquipItemInBodySlotAndRecord(int slot)
{
Inventory.ChangeRecorder recorder = newRecorder();
try
{
unEquipItemInBodySlot(slot);
if(getOwner() instanceof L2PcInstance)
{
((L2PcInstance) getOwner()).refreshExpertisePenalty();
((L2PcInstance) getOwner()).refreshMasteryPenality();
((L2PcInstance) getOwner()).refreshMasteryWeapPenality();
}
}
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 synchronized L2ItemInstance unEquipItemInSlot(int pdollSlot)
public L2ItemInstance unEquipItemInSlot(int pdollSlot)
{
return setPaperdollItem(pdollSlot, null);
}
/**
* Unepquips item in slot and returns alterations
*
* @param slot : int designating the slot
* @return L2ItemInstance[] : list of items altered
*/
//public synchronized L2ItemInstance[] unEquipItemInSlotAndRecord(int slot)
public L2ItemInstance[] unEquipItemInSlotAndRecord(int slot)
{
Inventory.ChangeRecorder recorder = newRecorder();
try
{
unEquipItemInSlot(slot);
if(getOwner() instanceof L2PcInstance)
{
((L2PcInstance) getOwner()).refreshExpertisePenalty();
((L2PcInstance) getOwner()).refreshMasteryPenality();
}
}
finally
{
removePaperdollListener(recorder);
}
return recorder.getChangedItems();
}
/**
* Unequips item in slot (i.e. equips with default value)
*
* @param slot : int designating the slot
*/
private void unEquipItemInBodySlot(int slot)
{
if(Config.DEBUG)
{
_log.fine("--- 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_FACE:
pdollSlot = PAPERDOLL_FACE;
break;
case L2Item.SLOT_DHAIR:
setPaperdollItem(PAPERDOLL_HAIR, null);
setPaperdollItem(PAPERDOLL_FACE, null);// this should be the same as in DHAIR
pdollSlot = PAPERDOLL_DHAIR;
break;
case L2Item.SLOT_HEAD:
pdollSlot = PAPERDOLL_HEAD;
break;
case L2Item.SLOT_R_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:
pdollSlot = PAPERDOLL_CHEST;
break; //TODO: пїЅпїЅпїЅпїЅ "пїЅпїЅпїЅпїЅпїЅ"
case L2Item.SLOT_FULL_ARMOR:
pdollSlot = PAPERDOLL_CHEST;
break;
case L2Item.SLOT_LEGS:
pdollSlot = PAPERDOLL_LEGS;
break;
case L2Item.SLOT_BACK:
pdollSlot = PAPERDOLL_BACK;
break;
case L2Item.SLOT_FEET:
pdollSlot = PAPERDOLL_FEET;
break;
case L2Item.SLOT_UNDERWEAR:
pdollSlot = PAPERDOLL_UNDER;
break;
case L2Item.SLOT_LR_HAND:
setPaperdollItem(PAPERDOLL_LHAND, null);
setPaperdollItem(PAPERDOLL_RHAND, null);// this should be the same as in LRHAND
pdollSlot = PAPERDOLL_LRHAND;
break;
}
if(pdollSlot >= 0)
{
setPaperdollItem(pdollSlot, null);
}
}
/**
* Equips item and returns list of alterations
*
* @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 synchronized void equipItem(L2ItemInstance item)
{
if(getOwner() instanceof L2PcInstance && ((L2PcInstance) getOwner()).getPrivateStoreType() != 0)
return;
if(getOwner() instanceof L2PcInstance)
{
L2PcInstance player = (L2PcInstance) getOwner();
// Like L2OFF weapon hero and crown aren't removed after restart
if(!player.isGM())
if(!player.isHero())
{
int itemId = item.getItemId();
if(itemId >= 6611 && itemId <= 6621 || itemId == 6842)
return;
}
}
int targetSlot = item.getItem().getBodyPart();
switch(targetSlot)
{
case L2Item.SLOT_LR_HAND:
{
if(setPaperdollItem(PAPERDOLL_LHAND, null) != null)
{
// exchange 2h for 2h
setPaperdollItem(PAPERDOLL_RHAND, null);
setPaperdollItem(PAPERDOLL_LHAND, null);
}
else
{
setPaperdollItem(PAPERDOLL_RHAND, null);
}
setPaperdollItem(PAPERDOLL_RHAND, item);
setPaperdollItem(PAPERDOLL_LRHAND, item);
break;
}
case L2Item.SLOT_L_HAND:
{
if(!(item.getItem() instanceof L2EtcItem) || item.getItem().getItemType() != L2EtcItemType.ARROW)
{
L2ItemInstance old1 = setPaperdollItem(PAPERDOLL_LRHAND, null);
if(old1 != null)
{
setPaperdollItem(PAPERDOLL_RHAND, null);
}
}
setPaperdollItem(PAPERDOLL_LHAND, null);
setPaperdollItem(PAPERDOLL_LHAND, item);
break;
}
case L2Item.SLOT_R_HAND:
{
if(_paperdoll[PAPERDOLL_LRHAND] != null)
{
setPaperdollItem(PAPERDOLL_LRHAND, null);
setPaperdollItem(PAPERDOLL_LHAND, null);
setPaperdollItem(PAPERDOLL_RHAND, null);
}
else
{
setPaperdollItem(PAPERDOLL_RHAND, null);
}
setPaperdollItem(PAPERDOLL_RHAND, item);
break;
}
case L2Item.SLOT_L_EAR:
case L2Item.SLOT_R_EAR:
case L2Item.SLOT_L_EAR | L2Item.SLOT_R_EAR:
{
if(_paperdoll[PAPERDOLL_LEAR] == null)
{
setPaperdollItem(PAPERDOLL_LEAR, item);
}
else if(_paperdoll[PAPERDOLL_REAR] == null)
{
setPaperdollItem(PAPERDOLL_REAR, item);
}
else
{
setPaperdollItem(PAPERDOLL_LEAR, null);
setPaperdollItem(PAPERDOLL_LEAR, item);
}
break;
}
case L2Item.SLOT_L_FINGER:
case L2Item.SLOT_R_FINGER:
case L2Item.SLOT_L_FINGER | L2Item.SLOT_R_FINGER:
{
if(_paperdoll[PAPERDOLL_LFINGER] == null)
{
setPaperdollItem(PAPERDOLL_LFINGER, item);
}
else if(_paperdoll[PAPERDOLL_RFINGER] == null)
{
setPaperdollItem(PAPERDOLL_RFINGER, item);
}
else
{
setPaperdollItem(PAPERDOLL_LFINGER, null);
setPaperdollItem(PAPERDOLL_LFINGER, item);
}
break;
}
case L2Item.SLOT_NECK:
setPaperdollItem(PAPERDOLL_NECK, item);
break;
case L2Item.SLOT_FULL_ARMOR:
setPaperdollItem(PAPERDOLL_CHEST, null);
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, null);
setPaperdollItem(PAPERDOLL_LEGS, item);
chest = null;
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:
if(setPaperdollItem(PAPERDOLL_DHAIR, null) != null)
{
setPaperdollItem(PAPERDOLL_DHAIR, null);
setPaperdollItem(PAPERDOLL_HAIR, null);
setPaperdollItem(PAPERDOLL_FACE, null);
}
else
{
setPaperdollItem(PAPERDOLL_HAIR, null);
}
setPaperdollItem(PAPERDOLL_HAIR, item);
break;
case L2Item.SLOT_FACE:
if(setPaperdollItem(PAPERDOLL_DHAIR, null) != null)
{
setPaperdollItem(PAPERDOLL_DHAIR, null);
setPaperdollItem(PAPERDOLL_HAIR, null);
setPaperdollItem(PAPERDOLL_FACE, null);
}
else
{
setPaperdollItem(PAPERDOLL_FACE, null);
}
setPaperdollItem(PAPERDOLL_FACE, item);
break;
case L2Item.SLOT_DHAIR:
if(setPaperdollItem(PAPERDOLL_HAIR, null) != null)
{
setPaperdollItem(PAPERDOLL_HAIR, null);
setPaperdollItem(PAPERDOLL_FACE, null);
}
else
{
setPaperdollItem(PAPERDOLL_FACE, null);
}
setPaperdollItem(PAPERDOLL_DHAIR, item);
break;
case L2Item.SLOT_UNDERWEAR:
setPaperdollItem(PAPERDOLL_UNDER, item);
break;
case L2Item.SLOT_BACK:
setPaperdollItem(PAPERDOLL_BACK, item);
break;
default:
_log.warning("unknown body slot:" + targetSlot);
}
}
/**
* Refresh the weight of equipment loaded
*/
@Override
protected void refreshWeight()
{
int weight = 0;
for(L2ItemInstance item : _items)
{
if(item != null && item.getItem() != null)
{
weight += item.getItem().getWeight() * item.getCount();
}
}
_totalWeight = weight;
}
/**
* Returns the totalWeight.
*
* @return int
*/
public int getTotalWeight()
{
return _totalWeight;
}
/**
* Return the L2ItemInstance of the arrows needed for this bow.<BR>
* <BR>
*
* @param bow : L2Item designating the bow
* @return L2ItemInstance pointing out arrows for bow
*/
public L2ItemInstance findArrowForBow(L2Item bow)
{
if(bow == null)
return null;
// Check if char has the bow equiped
if(bow.getItemType() != L2WeaponType.BOW)
return null;
int arrowsId = 0;
switch(bow.getCrystalType())
{
default: // broken weapon.csv ??
case L2Item.CRYSTAL_NONE:
arrowsId = 17;
break; // Wooden arrow
case L2Item.CRYSTAL_D:
arrowsId = 1341;
break; // Bone arrow
case L2Item.CRYSTAL_C:
arrowsId = 1342;
break; // Fine steel arrow
case L2Item.CRYSTAL_B:
arrowsId = 1343;
break; // Silver arrow
case L2Item.CRYSTAL_A:
arrowsId = 1344;
break; // Mithril arrow
case L2Item.CRYSTAL_S:
arrowsId = 1345;
break; // Shining arrow
}
// Get the L2ItemInstance corresponding to the item identifier and return it
return getItemByItemId(arrowsId);
}
/**
* Get back items in inventory from database
*/
@Override
public void restore()
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = con.prepareStatement("SELECT object_id FROM items WHERE owner_id=? AND (loc=? OR loc=?) " + "ORDER BY object_id DESC");
statement.setInt(1, getOwner().getObjectId());
statement.setString(2, getBaseLocation().name());
statement.setString(3, getEquipLocation().name());
ResultSet inv = statement.executeQuery();
L2ItemInstance item;
while(inv.next())
{
int objectId = inv.getInt(1);
item = L2ItemInstance.restoreFromDb(objectId);
if(item == null)
{
continue;
}
if(getOwner() instanceof L2PcInstance)
{
L2PcInstance player = (L2PcInstance) getOwner();
if(!player.isGM())
if(!player.isHero())
{
int itemId = item.getItemId();
if(itemId >= 6611 && itemId <= 6621 || itemId == 6842)
{
item.setLocation(ItemLocation.INVENTORY);
}
}
player = null;
}
L2World.getInstance().storeObject(item);
// If stackable item is found in inventory just add to current quantity
if(item.isStackable() && getItemByItemId(item.getItemId()) != null)
{
addItem("Restore", item, null, getOwner());
}
else
{
addItem(item);
}
}
inv.close();
statement.close();
refreshWeight();
statement = null;
inv = null;
item = null;
}
catch(Exception e)
{
_log.warning("Could not restore inventory : ");
e.printStackTrace();
}
finally
{
CloseUtil.close(con);
con = null;
}
}
/**
* Re-notify to paperdoll listeners every equipped item
*/
public void reloadEquippedItems()
{
L2ItemInstance item;
int slot;
for(L2ItemInstance element : _paperdoll)
{
item = element;
if(item == null)
{
continue;
}
slot = item.getEquipSlot();
for(PaperdollListener listener : _paperdollListeners)
{
if(listener == null)
{
continue;
}
listener.notifyUnequiped(slot, item);
listener.notifyEquiped(slot, item);
}
}
item = null;
}
}