/* * 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 3 of the License, 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, see . */ package net.sf.l2j.gameserver.model; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.List; import javolution.util.FastList; import net.sf.l2j.Config; import net.sf.l2j.L2DatabaseFactory; import net.sf.l2j.gameserver.datatables.ArmorSetsTable; import net.sf.l2j.gameserver.datatables.ItemTable; import net.sf.l2j.gameserver.datatables.SkillTable; import net.sf.l2j.gameserver.model.L2ItemInstance.ItemLocation; import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance; import net.sf.l2j.gameserver.network.SystemMessageId; import net.sf.l2j.gameserver.network.serverpackets.SystemMessage; import net.sf.l2j.gameserver.templates.L2Armor; import net.sf.l2j.gameserver.templates.L2EtcItem; import net.sf.l2j.gameserver.templates.L2EtcItemType; import net.sf.l2j.gameserver.templates.L2Item; import net.sf.l2j.gameserver.templates.L2Weapon; import net.sf.l2j.gameserver.templates.L2WeaponType; /** * 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_REAR = 1; public static final int PAPERDOLL_LEAR = 2; public static final int PAPERDOLL_LREAR = 3; public static final int PAPERDOLL_NECK = 4; public static final int PAPERDOLL_LFINGER = 5; public static final int PAPERDOLL_RFINGER = 6; public static final int PAPERDOLL_LRFINGER = 7; public static final int PAPERDOLL_HEAD = 8; public static final int PAPERDOLL_RHAND = 9; public static final int PAPERDOLL_LHAND = 10; public static final int PAPERDOLL_GLOVES = 11; public static final int PAPERDOLL_CHEST = 12; public static final int PAPERDOLL_LEGS = 13; public static final int PAPERDOLL_FEET = 14; public static final int PAPERDOLL_BACK = 15; public static final int PAPERDOLL_LRHAND = 16; public static final int PAPERDOLL_FULLARMOR = 17; public static final int PAPERDOLL_HAIR = 18; public static final int PAPERDOLL_ALLDRESS = 19; public static final int PAPERDOLL_HAIR2 = 20; public static final int PAPERDOLL_HAIRALL = 21; public static final int PAPERDOLL_RBRACELET = 22; public static final int PAPERDOLL_LBRACELET = 23; public static final int PAPERDOLL_DECO = 24; //Speed percentage mods public static final double MAX_ARMOR_WEIGHT = 12000; private final L2ItemInstance[] _paperdoll; private final List _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 { 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); } else { if (!owner.isWearingFormalWear()) return; } } } /** * Recorder of alterations in inventory */ public static final class ChangeRecorder implements PaperdollListener { private final Inventory _inventory; private final List _changed; /** * Constructor of the ChangeRecorder * @param inventory */ ChangeRecorder(Inventory inventory) { _inventory = inventory; _changed = new FastList(); _inventory.addPaperdollListener(this); } /** * Add alteration in inventory when item equiped */ public void notifyEquiped(int slot, L2ItemInstance item) { if (!_changed.contains(item)) _changed.add(item); } /** * Add alteration in inventory when item unequiped */ 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 CrossBowListener implements PaperdollListener { public void notifyUnequiped(int slot, L2ItemInstance item) { if (slot != PAPERDOLL_LRHAND) return; if (Config.ASSERT) assert null == getPaperdollItem(PAPERDOLL_LRHAND); if (item.getItemType() == L2WeaponType.CROSSBOW) { L2ItemInstance bolts = getPaperdollItem(PAPERDOLL_LHAND); if (bolts != null) setPaperdollItem(PAPERDOLL_LHAND, null); } } public void notifyEquiped(int slot, L2ItemInstance item) { if (slot != PAPERDOLL_LRHAND) return; if (Config.ASSERT) assert item == getPaperdollItem(PAPERDOLL_LRHAND); if (item.getItemType() == L2WeaponType.CROSSBOW) { L2ItemInstance bolts = findBoltForCrossBow(item.getItem()); if (bolts != null) setPaperdollItem(PAPERDOLL_LHAND, bolts); } } } final class BowListener implements PaperdollListener { 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); } } 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); } } } final class StatsListener implements PaperdollListener { public void notifyUnequiped(int slot, L2ItemInstance item) { if (slot == PAPERDOLL_LRHAND) return; getOwner().removeStatsOwner(item); } public void notifyEquiped(int slot, L2ItemInstance item) { if (slot == PAPERDOLL_LRHAND) return; getOwner().addStatFuncs(item.getStatFuncs(getOwner())); } } final class ItemSkillsListener implements PaperdollListener { public void notifyUnequiped(int slot, L2ItemInstance item) { L2PcInstance player; if(getOwner() instanceof L2PcInstance) { player = (L2PcInstance)getOwner(); } else return; L2Skill _itemSkill = null; int skill_Id = 0; int skillLvl = 0; L2Item it = item.getItem(); if(it instanceof L2Weapon) { // Remove augmentation bonuses on unequip if (item.isAugmented() && getOwner() instanceof L2PcInstance) item.getAugmentation().removeBonus((L2PcInstance)getOwner()); final String[] _skill = ((L2Weapon)it).getSkills(); if (_skill != null) { for (String skillInfo : _skill) { String[] skill = skillInfo.split("-"); if (skill != null && skill.length == 2) { skill_Id = Integer.parseInt(skill[0]); skillLvl = Integer.parseInt(skill[1]); if (skill_Id > 0 && skillLvl > 0) _itemSkill = SkillTable.getInstance().getInfo(skill_Id, skillLvl); if (_itemSkill != null) { player.removeSkill(_itemSkill, false); player.sendSkillList(); } } } } } else if(it instanceof L2Armor) { final String[] _skill = ((L2Armor)it).getSkills(); if (_skill != null) { for (String skillInfo : _skill) { String[] skill = skillInfo.split("-"); if (skill != null && skill.length == 2) { skill_Id = Integer.parseInt(skill[0]); skillLvl = Integer.parseInt(skill[1]); if (skill_Id > 0 && skillLvl > 0) _itemSkill = SkillTable.getInstance().getInfo(skill_Id, skillLvl); if (_itemSkill != null) { player.removeSkill(_itemSkill, false); player.sendSkillList(); } } } } } } public void notifyEquiped(int slot, L2ItemInstance item) { L2PcInstance player; if(getOwner() instanceof L2PcInstance) { player = (L2PcInstance)getOwner(); } else return; L2Skill enchant4Skill = null; L2Skill _itemSkill = null; int skill_Id = 0; int skillLvl = 0; L2Item it = item.getItem(); if(it instanceof L2Weapon) { // Apply augmentation bonuses on equip if (item.isAugmented() && getOwner() instanceof L2PcInstance) item.getAugmentation().applyBonus((L2PcInstance)getOwner()); final String[] _skill = ((L2Weapon)it).getSkills(); if (_skill != null) { for (String skillInfo : _skill) { String[] skill = skillInfo.split("-"); if (skill != null && skill.length == 2) { skill_Id = Integer.parseInt(skill[0]); skillLvl = Integer.parseInt(skill[1]); if (skill_Id > 0 && skillLvl > 0) _itemSkill = SkillTable.getInstance().getInfo(skill_Id, skillLvl); if (_itemSkill != null) { player.addSkill(_itemSkill, false); player.sendSkillList(); } } } } if(item.getEnchantLevel() >= 4) enchant4Skill= ((L2Weapon)it).getEnchant4Skill(); if(enchant4Skill != null) { player.addSkill(enchant4Skill, false); player.sendSkillList(); } } else if(it instanceof L2Armor) { final String[] _skill = ((L2Armor)it).getSkills(); if (_skill != null) { for (String skillInfo : _skill) { String[] skill = skillInfo.split("-"); if (skill != null && skill.length == 2) { skill_Id = Integer.parseInt(skill[0]); skillLvl = Integer.parseInt(skill[1]); if (skill_Id > 0 && skillLvl > 0) _itemSkill = SkillTable.getInstance().getInfo(skill_Id, skillLvl); if (_itemSkill != null) { player.addSkill(_itemSkill, false); player.sendSkillList(); } } } } } } } final class ArmorSetListener implements PaperdollListener { 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(),armorSet.getSkillLvl()); 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()+"."); } if(armorSet.isEnchanted6(player)) // has all parts of set enchanted to 6 or more { final 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()+"."); } } } } 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()+"."); } } } 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 removeSkillLvl1 = 1; // set skillLvl 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(); removeSkillLvl1 = armorSet.getSkillLvl(); removeSkillId2 = armorSet.getShieldSkillId(); removeSkillId3 = armorSet.getEnchant6skillId(); } 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(); removeSkillLvl1 = armorSet.getSkillLvl(); removeSkillId2 = armorSet.getShieldSkillId(); removeSkillId3 = armorSet.getEnchant6skillId(); } else if(armorSet.containShield(item.getItemId())) // removed shield { remove = true; removeSkillId2 = armorSet.getShieldSkillId(); } } if(remove) { if(removeSkillId1 != 0) { L2Skill skill = SkillTable.getInstance().getInfo(removeSkillId1,removeSkillLvl1); if(skill != null) player.removeSkill(skill); else _log.warning("Inventory.ArmorSetListener: Incorrect skill: "+removeSkillId1+"."); } if(removeSkillId2 != 0) { L2Skill skill = SkillTable.getInstance().getInfo(removeSkillId2,1); if(skill != null) player.removeSkill(skill); else _log.warning("Inventory.ArmorSetListener: Incorrect skill: "+removeSkillId2+"."); } if(removeSkillId3 != 0) { L2Skill skill = SkillTable.getInstance().getInfo(removeSkillId3,1); if(skill != null) player.removeSkill(skill); else _log.warning("Inventory.ArmorSetListener: Incorrect skill: "+removeSkillId3+"."); } player.sendSkillList(); } } } /* 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[25]; _paperdollListeners = new FastList(); addPaperdollListener(new ArmorSetListener()); addPaperdollListener(new CrossBowListener()); addPaperdollListener(new BowListener()); addPaperdollListener(new ItemSkillsListener()); 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) { if (item == null) return null; 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 objectID 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 else 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 // if (item.isEquipped()) unEquipItemInSlotAndRecord(item.getEquipSlot()); for (int i = 0; i < _paperdoll.length; i++) if (_paperdoll[i] == item) unEquipItemInSlot(i); return super.removeItem(item); } /** * Returns the item in the paperdoll slot * @return L2ItemInstance */ public L2ItemInstance getPaperdollItem(int slot) { return _paperdoll[slot]; } /** * Returns the item in the paperdoll L2Item slot * @param L2Item slot identifier * @return L2ItemInstance */ public L2ItemInstance getPaperdollItemByL2ItemId(int slot) { switch (slot) { case 0x01: return _paperdoll[0]; case 0x02: return _paperdoll[1]; case 0x04: return _paperdoll[2]; case 0x06: return _paperdoll[3]; case 0x08: return _paperdoll[4]; case 0x10: return _paperdoll[5]; case 0x20: return _paperdoll[6]; case 0x30: return _paperdoll[7]; case 0x040: return _paperdoll[8]; case 0x080: return _paperdoll[9]; case 0x0100: return _paperdoll[10]; case 0x0200: return _paperdoll[11]; case 0x0400: return _paperdoll[12]; case 0x0800: return _paperdoll[13]; case 0x1000: return _paperdoll[14]; case 0x2000: return _paperdoll[15]; case 0x4000: return _paperdoll[16]; case 0x8000: return _paperdoll[17]; case 0x010000: return _paperdoll[18]; case 0x020000: return _paperdoll[19]; case 0x040000: return _paperdoll[20]; case 0x080000: return _paperdoll[21]; case 0x100000: return _paperdoll[22]; case 0x200000: return _paperdoll[23]; case 0x400000: return _paperdoll[24]; } 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_HAIRALL]; 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(); } else { 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_HAIRALL]; if (item != null) return item.getObjectId(); } return 0; } /** * Adds new inventory's paperdoll listener * @param PaperdollListener pointing out the listener */ public synchronized void addPaperdollListener(PaperdollListener listener) { if (Config.ASSERT) assert !_paperdollListeners.contains(listener); _paperdollListeners.add(listener); } /** * Removes a paperdoll listener * @param PaperdollListener pointing out the listener to be deleted */ public synchronized void removePaperdollListener(PaperdollListener listener) { _paperdollListeners.remove(listener); } /** * Equips an item in the given slot of the paperdoll. * Remark : The item HAS TO BE 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(); } _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); } 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.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_HAIRALL: slot = L2Item.SLOT_HAIRALL; 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_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; case PAPERDOLL_LBRACELET: slot = L2Item.SLOT_L_BRACELET; break; case PAPERDOLL_RBRACELET: slot = L2Item.SLOT_R_BRACELET; 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) { Inventory.ChangeRecorder recorder = newRecorder(); try { unEquipItemInBodySlot(slot); if (getOwner() instanceof L2PcInstance) ((L2PcInstance)getOwner()).refreshExpertisePenalty(); } 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) { 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) { 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 */ 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_HAIR2: pdollSlot = PAPERDOLL_HAIR2; break; case L2Item.SLOT_HAIRALL: setPaperdollItem(PAPERDOLL_HAIR, null); setPaperdollItem(PAPERDOLL_HAIR2, null);// this should be the same as in DHAIR pdollSlot = PAPERDOLL_HAIRALL; 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: // fall through 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; case L2Item.SLOT_L_BRACELET: pdollSlot = PAPERDOLL_LBRACELET; break; case L2Item.SLOT_R_BRACELET: pdollSlot = PAPERDOLL_RBRACELET; 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(); if(player.getPkKills() > 0 && item.getItemId() >= 7816 && item.getItemId() <= 7831) { player.sendPacket(new SystemMessage(SystemMessageId.YOU_ARE_UNABLE_TO_EQUIP_THIS_ITEM_WHEN_YOUR_PK_COUNT_IS_GREATER_THAN_OR_EQUAL_TO_ONE)); return; } if(!player.isGM()) if (!player.isHero()) { if (item.isHeroItem()) 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); 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_HAIRALL, null) != null) { setPaperdollItem(PAPERDOLL_HAIRALL, null); setPaperdollItem(PAPERDOLL_HAIR, null); setPaperdollItem(PAPERDOLL_HAIR2, null); } else setPaperdollItem(PAPERDOLL_HAIR, null); setPaperdollItem(PAPERDOLL_HAIR, item); break; case L2Item.SLOT_HAIR2: if (setPaperdollItem(PAPERDOLL_HAIRALL, null) != null) { setPaperdollItem(PAPERDOLL_HAIRALL, null); setPaperdollItem(PAPERDOLL_HAIR, null); setPaperdollItem(PAPERDOLL_HAIR2, null); } else setPaperdollItem(PAPERDOLL_HAIR2, null); setPaperdollItem(PAPERDOLL_HAIR2, item); break; case L2Item.SLOT_HAIRALL: if (setPaperdollItem(PAPERDOLL_HAIR, null) != null) { setPaperdollItem(PAPERDOLL_HAIR, null); setPaperdollItem(PAPERDOLL_HAIR2, null); } else { setPaperdollItem(PAPERDOLL_HAIR2, null); } setPaperdollItem(PAPERDOLL_HAIRALL, item); break; case L2Item.SLOT_UNDERWEAR: setPaperdollItem(PAPERDOLL_UNDER, item); break; case L2Item.SLOT_BACK: setPaperdollItem(PAPERDOLL_BACK, item); break; case L2Item.SLOT_L_BRACELET: setPaperdollItem(PAPERDOLL_LBRACELET, item); break; case L2Item.SLOT_R_BRACELET: setPaperdollItem(PAPERDOLL_RBRACELET, 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.

* @param bow : L2Item designating the bow * @return L2ItemInstance pointing out arrows for bow */ public L2ItemInstance findArrowForBow(L2Item bow) { 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: case L2Item.CRYSTAL_S80: arrowsId = 1345; break; // Shining arrow } // Get the L2ItemInstance corresponding to the item identifier and return it return getItemByItemId(arrowsId); } /** * 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) { int boltsId = 0; switch (crossbow.getCrystalType()) { default: case L2Item.CRYSTAL_NONE: boltsId = 9632; break; // Wooden Bolt case L2Item.CRYSTAL_D: boltsId = 9633; break; // Bone Bolt case L2Item.CRYSTAL_C: boltsId = 9634; break; // Steel Bolt case L2Item.CRYSTAL_B: boltsId = 9635; break; // Silver Bolt case L2Item.CRYSTAL_A: boltsId = 9636; break; // Mithril Bolt case L2Item.CRYSTAL_S: case L2Item.CRYSTAL_S80: boltsId = 9637; break; // Shining Bolt } // Get the L2ItemInstance corresponding to the item identifier and return it return getItemByItemId(boltsId); } /** * Get back items in inventory from database */ @Override public void restore() { java.sql.Connection con = null; try { 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 FROM items WHERE owner_id=? AND (loc=? OR loc=?) "); statement.setInt(1, getOwner().getObjectId()); statement.setString(2, getBaseLocation().name()); statement.setString(3, getEquipLocation().name()); ResultSet inv = statement.executeQuery(); L2ItemInstance item; while (inv.next()) { item = L2ItemInstance.restoreFromDb(getOwner().getObjectId(), inv); if (item == null) continue; if(getOwner() instanceof L2PcInstance) { L2PcInstance player = (L2PcInstance)getOwner(); if(player.getPkKills() > 0 && item.getItemId() >= 7816 && item.getItemId() <= 7831) { item.setLocation(ItemLocation.INVENTORY); } if(!player.isGM()) if (!player.isHero()) { if (item.isHeroItem()) item.setLocation(ItemLocation.INVENTORY); } } 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(); } catch (Exception e) { _log.warning("Could not restore inventory : " + e); } finally { try { con.close(); } catch (Exception e) {} } } /** * Re-notify to paperdoll listeners every equipped item */ public void reloadEquippedItems() { L2ItemInstance item; int slot; for (int i = 0; i < _paperdoll.length; i++) { item = _paperdoll[i]; if (item == null) continue; slot = item.getLocationSlot(); for (PaperdollListener listener : _paperdollListeners) { if (listener == null) continue; listener.notifyUnequiped(slot, item); listener.notifyEquiped(slot, item); } } } }