Package l2p.gameserver.model.items

Source Code of l2p.gameserver.model.items.Inventory

package l2p.gameserver.model.items;

import java.sql.ResultSet;
import java.util.Arrays;
import java.util.Comparator;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

import l2p.database.DatabaseUtils;
import l2p.database.FiltredPreparedStatement;
import l2p.database.L2DatabaseFactory;
import l2p.database.ThreadConnection;
import l2p.extensions.multilang.CustomMessage;
import l2p.gameserver.cache.Msg;
import l2p.gameserver.instancemanager.CastleManager;
import l2p.gameserver.instancemanager.CursedWeaponsManager;
import l2p.gameserver.model.L2Character;
import l2p.gameserver.model.L2Clan;
import l2p.gameserver.model.L2Player;
import l2p.gameserver.model.L2Skill;
import l2p.gameserver.model.base.ClassType;
import l2p.gameserver.model.base.PlayerClass;
import l2p.gameserver.model.base.Race;
import l2p.gameserver.model.entity.vehicle.L2AirShip;
import l2p.gameserver.model.items.L2ItemInstance.ItemLocation;
import l2p.gameserver.model.items.listeners.ArmorSetListener;
import l2p.gameserver.model.items.listeners.BowListener;
import l2p.gameserver.model.items.listeners.BraceletListener;
import l2p.gameserver.model.items.listeners.ChangeRecorder;
import l2p.gameserver.model.items.listeners.ItemAugmentationListener;
import l2p.gameserver.model.items.listeners.ItemSkillsListener;
import l2p.gameserver.model.items.listeners.PaperdollListener;
import l2p.gameserver.model.items.listeners.StatsListener;
import l2p.gameserver.model.items.listeners.WeaponListener;
import l2p.gameserver.serverpackets.InventoryUpdate;
import l2p.gameserver.serverpackets.PetInventoryUpdate;
import l2p.gameserver.serverpackets.SystemMessage;
import l2p.gameserver.skills.Stats;
import l2p.gameserver.tables.ItemTable;
import l2p.gameserver.tables.PetDataTable;
import l2p.gameserver.templates.L2Armor;
import l2p.gameserver.templates.L2Armor.ArmorType;
import l2p.gameserver.templates.L2EtcItem;
import l2p.gameserver.templates.L2EtcItem.EtcItemType;
import l2p.gameserver.templates.L2Item;
import l2p.gameserver.templates.L2Weapon.WeaponType;
import l2p.util.GArray;
import l2p.util.GCSArray;
import l2p.util.Log;
import l2p.util.Util;

public abstract class Inventory
{
  protected static final Logger _log = Logger.getLogger(Inventory.class.getName());
  public static final byte PAPERDOLL_UNDER = 0;
  public static final byte PAPERDOLL_REAR = 1;
  public static final byte PAPERDOLL_LEAR = 2;
  public static final byte PAPERDOLL_NECK = 3;
  public static final byte PAPERDOLL_RFINGER = 4;
  public static final byte PAPERDOLL_LFINGER = 5;
  public static final byte PAPERDOLL_HEAD = 6;
  public static final byte PAPERDOLL_RHAND = 7;
  public static final byte PAPERDOLL_LHAND = 8;
  public static final byte PAPERDOLL_GLOVES = 9;
  public static final byte PAPERDOLL_CHEST = 10;
  public static final byte PAPERDOLL_LEGS = 11;
  public static final byte PAPERDOLL_FEET = 12;
  public static final byte PAPERDOLL_BACK = 13;
  public static final byte PAPERDOLL_LRHAND = 14;
  public static final byte PAPERDOLL_HAIR = 15;
  public static final byte PAPERDOLL_DHAIR = 16;
  public static final byte PAPERDOLL_RBRACELET = 17;
  public static final byte PAPERDOLL_LBRACELET = 18;
  public static final byte PAPERDOLL_DECO1 = 19;
  public static final byte PAPERDOLL_DECO2 = 20;
  public static final byte PAPERDOLL_DECO3 = 21;
  public static final byte PAPERDOLL_DECO4 = 22;
  public static final byte PAPERDOLL_DECO5 = 23;
  public static final byte PAPERDOLL_DECO6 = 24;
  public static final byte PAPERDOLL_BELT = 25;
  public static final byte PAPERDOLL_MAX = 26;
  private final L2ItemInstance[] _paperdoll;
  private final CopyOnWriteArrayList<PaperdollListener> _paperdollListeners;
  private GCSArray<L2ItemInstance> _listenedItems;
  // protected to be accessed from child classes only
  // Отдельно синхронизировать этот список не надо, ибо ConcurrentLinkedQueue уже синхронизирован
  protected final ConcurrentLinkedQueue<L2ItemInstance> _items;
  protected final ConcurrentLinkedQueue<L2ItemInstance> _refundItems;
  private int _totalWeight;
  private boolean _refreshingListeners;
  // used to quickly check for using of items of special type
  private long _wearedMask;
  // Castle circlets, WARNING: position == castle.id !
  public static final Integer[] _castleCirclets = {0, // no castle - no circlet.. :)
    6838, // Circlet of Gludio
    6835, // Circlet of Dion
    6839, // Circlet of Giran
    6837, // Circlet of Oren
    6840, // Circlet of Aden
    6834, // Circlet of Innadril
    6836, // Circlet of Goddard
    8182, // Circlet of Rune
    8183, // Circlet of Schuttgart
  };
  public static final int FORMAL_WEAR_ID = 6408;

  protected Inventory()
  {
    _paperdoll = new L2ItemInstance[PAPERDOLL_MAX];
    _items = new ConcurrentLinkedQueue<L2ItemInstance>();
    _refundItems = new ConcurrentLinkedQueue<L2ItemInstance>();
    _paperdollListeners = new CopyOnWriteArrayList<PaperdollListener>();
    addPaperdollListener(new BraceletListener(this));
    addPaperdollListener(new BowListener(this));
    addPaperdollListener(new ArmorSetListener(this));
    addPaperdollListener(new StatsListener(this));
    addPaperdollListener(new ItemSkillsListener(this));
    addPaperdollListener(new ItemAugmentationListener(this));
    addPaperdollListener(new WeaponListener(this));
  }

  public abstract L2Character getOwner();

  protected abstract ItemLocation getBaseLocation();

  protected abstract ItemLocation getEquipLocation();

  public int getOwnerId()
  {
    L2Character owner = getOwner();
    return owner == null ? 0 : owner.getObjectId();
  }

  public ChangeRecorder newRecorder()
  {
    return new ChangeRecorder(this);
  }

  public int getSize()
  {
    return getItemsList().size();
  }

  public L2ItemInstance[] getItems()
  {
    return getItemsList().toArray(new L2ItemInstance[getItemsList().size()]);
  }

  public ConcurrentLinkedQueue<L2ItemInstance> getItemsList()
  {
    return _items;
  }

  public ConcurrentLinkedQueue<L2ItemInstance> getRefundItemsList()
  {
    return _refundItems;
  }

  public L2ItemInstance addItem(int id, long count)
  {
    L2ItemInstance newItem = ItemTable.getInstance().createItem(id);
    newItem.setCount(count);
    return addItem(newItem);
  }

  public L2ItemInstance addItem(L2ItemInstance newItem)
  {
    return addItem(newItem, true, true);
  }

  private L2ItemInstance addItem(L2ItemInstance newItem, boolean dbUpdate, boolean log)
  {
    L2Character owner = getOwner();
    if(owner == null || newItem == null)
    {
      return null;
    }
    if(newItem.isHerb() && !owner.getPlayer().isGM())
    {
      Util.handleIllegalPlayerAction(owner.getPlayer(), "tried to pickup herb into inventory", "Inventory[179]", 1);
      return null;
    }
    if(newItem.getCount() < 0)
    {
      _log.warning("AddItem: count < 0 owner:" + owner.getName());
      Thread.dumpStack();
      return null;
    }
    L2ItemInstance result = newItem;
    boolean stackableFound = false;
    if(log)
    {
      Log.add("Inventory|" + owner.getName() + "|Get item|" + result.getItemId() + "|" + result.getCount() + "|" + result.getObjectId(), "items");
    }
    // If stackable, search item in inventory in order to add to current quantity
    if(newItem.isStackable())
    {
      int itemId = newItem.getItemId();
      L2ItemInstance old = getItemByItemId(itemId);
      if(old != null)
      {
        // add new item quantity to existing stack
        old.setCount(old.getCount() + newItem.getCount());
        // reset new item to null
        if(log)
        {
          Log.add("Inventory|" + owner.getName() + "|join item from-to|" + result.getItemId() + "|" + newItem.getObjectId() + "|" + old.getObjectId(), "items");
        }
        newItem.setCount(0);
        newItem.setOwnerId(0);
        newItem.setLocation(ItemLocation.VOID);
        newItem.removeFromDb(true);
        newItem.deleteMe();
        stackableFound = true;
        sendModifyItem(old);
        // update old item in inventory and destroy new item
        old.updateDatabase();
        result = old;
      }
    }
    // If item hasn't be found in inventory
    if(!stackableFound)
    {
      // Add item in inventory
      if(getItemByObjectId(newItem.getObjectId()) == null)
      {
        getItemsList().add(newItem);
        if(!newItem.isEquipable() && newItem.getItem() instanceof L2EtcItem && !newItem.isStackable() && (newItem.getStatFuncs() != null || newItem.getItem().getAttachedSkills() != null))
        {
          if(_listenedItems == null)
          {
            _listenedItems = new GCSArray<L2ItemInstance>();
          }
          _listenedItems.add(newItem);
          for(PaperdollListener listener : _paperdollListeners)
          {
            listener.notifyEquipped(-1, newItem);
          }
        }
      }
      else if(log)
      {
        Log.add("Inventory|" + owner.getName() + "|add double link to item in inventory list!|" + newItem.getItemId() + "|" + newItem.getObjectId(), "items");
      }
      if(newItem.getOwnerId() != owner.getPlayer().getObjectId() || dbUpdate)
      {
        newItem.setOwnerId(owner.getPlayer().getObjectId());
        newItem.setLocation(getBaseLocation(), findSlot(0));
        sendNewItem(newItem);
      }
      // If database wanted to be updated, update item
      if(dbUpdate)
      {
        newItem.updateDatabase();
      }
    }
    if(dbUpdate && result.isCursed() && owner.isPlayer())
    {
      CursedWeaponsManager.getInstance().checkPlayer((L2Player) owner, result);
    }
    refreshWeight();
    return result;
  }

  public void restoreCursedWeapon()
  {
    L2Character owner = getOwner();
    if(owner == null || !owner.isPlayer())
    {
      return;
    }
    for(L2ItemInstance i : getItemsList())
    {
      if(i.isCursed())
      {
        CursedWeaponsManager.getInstance().checkPlayer((L2Player) owner, i);
        _log.info("Restored CursedWeapon [" + i + "] for: " + owner);
        break;
      }
    }
  }

  /**
   * Находит и возвращает пустой слот в инвентаре. Вызывается с параметром 0, рекурсивно вызывает себя увеличивая номер слота пока не найдет свободный.
   */
  public int findSlot(int slot)
  {
    for(L2ItemInstance i : _items)
    {
      if(i.isEquipped() || i.getItem().getType2() == L2Item.TYPE2_QUEST) // игнорируем надетое и квестовые вещи
      {
        continue;
      }
      if(i.getEquipSlot() == slot) // слот занят?
      {
        return findSlot(++slot);
      } // пробуем следующий
    }
    return slot; // слот не занят, возвращаем
  }

  public L2ItemInstance getPaperdollItem(int slot)
  {
    return _paperdoll[slot];
  }

  public L2ItemInstance[] getPaperdollItems()
  {
    return _paperdoll;
  }

  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();
      }
    }
    else if(slot == PAPERDOLL_RHAND && getOwner().isPlayer())
    {
      L2Player player = getOwner().getPlayer();
      if(player.getVehicle() == null || !player.getVehicle().isAirShip())
      {
        return 0;
      }
      L2AirShip airship = (L2AirShip) player.getVehicle();
      if(airship.getDriver() == player)
      {
        return 13556;
      } // Затычка на отображение штурвала - Airship Helm
    }
    return 0;
  }

  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;
  }

  public synchronized void addPaperdollListener(PaperdollListener listener)
  {
    _paperdollListeners.add(listener);
  }

  public synchronized void removePaperdollListener(PaperdollListener listener)
  {
    _paperdollListeners.remove(listener);
  }

  public L2ItemInstance setPaperdollItem(int slot, L2ItemInstance item)
  {
    L2ItemInstance old = _paperdoll[slot];
    if(old != item)
    {
      if(old != null)
      {
        _paperdoll[slot] = null;
        old.setLocation(getBaseLocation(), findSlot(0));
        sendModifyItem(old);
        long mask = 0;
        for(int i = 0; i < PAPERDOLL_MAX; i++)
        {
          L2ItemInstance pi = _paperdoll[i];
          if(pi != null)
          {
            mask |= pi.getItem().getItemMask();
          }
        }
        _wearedMask = mask;
        old.updateDatabase();
        for(PaperdollListener listener : _paperdollListeners)
        {
          listener.notifyUnequipped(slot, old);
        }
        old.shadowNotify(false);
      }
      if(item != null)
      {
        _paperdoll[slot] = item;
        item.setLocation(getEquipLocation(), slot);
        sendModifyItem(item);
        _wearedMask |= item.getItem().getItemMask();
        item.updateDatabase();
        for(PaperdollListener listener : _paperdollListeners)
        {
          listener.notifyEquipped(slot, item);
        }
        item.shadowNotify(true);
      }
    }
    return old;
  }

  public long getWearedMask()
  {
    return _wearedMask;
  }

  public void unEquipItem(L2ItemInstance item)
  {
    if(item.isEquipped())
    {
      unEquipItemInBodySlot(item.getBodyPart(), item);
    }
  }

  /**
   * Снимает предмет, и все зависимые от него, и возвращает отличия.
   */
  public L2ItemInstance[] unEquipItemInBodySlotAndRecord(int slot, L2ItemInstance item)
  {
    ChangeRecorder recorder = newRecorder();
    try
    {
      unEquipItemInBodySlot(slot, item);
    }
    finally
    {
      removePaperdollListener(recorder);
    }
    return recorder.getChangedItems();
  }

  /**
   * Снимет вещь, записывает это в базу, шлет все нужные пакеты и перепроверяет пенальти
   *
   * @param slot L2Item.SLOT_
   * @param item
   */
  public void unEquipItemInBodySlotAndNotify(int slot, L2ItemInstance item)
  {
    L2Player cha = getOwner().getPlayer();
    if(cha == null)
    {
      return;
    }
    L2ItemInstance[] unequipped = unEquipItemInBodySlotAndRecord(slot, item);
    if(unequipped == null || unequipped.length == 0)
    {
      return;
    }
    L2ItemInstance weapon = cha.getActiveWeaponInstance();
    for(L2ItemInstance uneq : unequipped)
    {
      if(uneq == null || uneq.isWear())
      {
        continue;
      }
      cha.sendDisarmMessage(uneq);
      if(weapon != null && uneq == weapon)
      {
        uneq.setChargedSpiritshot(L2ItemInstance.CHARGED_NONE);
        uneq.setChargedSoulshot(L2ItemInstance.CHARGED_NONE);
        cha.abortAttack(true, true);
        cha.abortCast(true);
      }
    }
    cha.refreshExpertisePenalty();
    cha.broadcastUserInfo(true);
  }

  public L2ItemInstance unEquipItemInSlot(int pdollSlot)
  {
    return setPaperdollItem(pdollSlot, null);
  }

  /**
   * Unequips item in slot (i.e. equips with default value)
   *
   * @param slot : int designating the slot
   */
  public void unEquipItemInBodySlot(int slot, L2ItemInstance item)
  {
    byte pdollSlot = -1;
    switch(slot)
    {
      case L2Item.SLOT_NECK:
        pdollSlot = PAPERDOLL_NECK;
        break;
      case L2Item.SLOT_L_EAR:
        pdollSlot = PAPERDOLL_LEAR;
        break;
      case L2Item.SLOT_R_EAR:
        pdollSlot = PAPERDOLL_REAR;
        break;
      case L2Item.SLOT_L_FINGER:
        pdollSlot = PAPERDOLL_LFINGER;
        break;
      case L2Item.SLOT_R_FINGER:
        pdollSlot = PAPERDOLL_RFINGER;
        break;
      case L2Item.SLOT_HAIR:
        pdollSlot = PAPERDOLL_HAIR;
        break;
      case L2Item.SLOT_DHAIR:
        pdollSlot = PAPERDOLL_DHAIR;
        break;
      case L2Item.SLOT_HAIRALL:
        setPaperdollItem(PAPERDOLL_HAIR, null);
        setPaperdollItem(PAPERDOLL_DHAIR, null); // This should be the same as in DHAIR
        pdollSlot = PAPERDOLL_HAIR;
        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_LEGS:
        pdollSlot = PAPERDOLL_LEGS;
        break;
      case L2Item.SLOT_CHEST:
      case L2Item.SLOT_FULL_ARMOR:
      case L2Item.SLOT_FORMAL_WEAR:
        pdollSlot = PAPERDOLL_CHEST;
        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_BELT:
        pdollSlot = PAPERDOLL_BELT;
        break;
      case L2Item.SLOT_LR_HAND:
        setPaperdollItem(PAPERDOLL_LHAND, null);
        setPaperdollItem(PAPERDOLL_RHAND, null); // this should be the same as in LRHAND
        pdollSlot = PAPERDOLL_RHAND;
        break;
      case L2Item.SLOT_L_BRACELET:
        pdollSlot = PAPERDOLL_LBRACELET;
        break;
      case L2Item.SLOT_R_BRACELET:
        pdollSlot = PAPERDOLL_RBRACELET;
        break;
      case L2Item.SLOT_DECO:
        if(item == null)
        {
          return;
        }
        else if(getPaperdollObjectId(PAPERDOLL_DECO1) == item.getObjectId())
        {
          pdollSlot = PAPERDOLL_DECO1;
        }
        else if(getPaperdollObjectId(PAPERDOLL_DECO2) == item.getObjectId())
        {
          pdollSlot = PAPERDOLL_DECO2;
        }
        else if(getPaperdollObjectId(PAPERDOLL_DECO3) == item.getObjectId())
        {
          pdollSlot = PAPERDOLL_DECO3;
        }
        else if(getPaperdollObjectId(PAPERDOLL_DECO4) == item.getObjectId())
        {
          pdollSlot = PAPERDOLL_DECO4;
        }
        else if(getPaperdollObjectId(PAPERDOLL_DECO5) == item.getObjectId())
        {
          pdollSlot = PAPERDOLL_DECO5;
        }
        else if(getPaperdollObjectId(PAPERDOLL_DECO6) == item.getObjectId())
        {
          pdollSlot = PAPERDOLL_DECO6;
        }
        break;
    }
    if(pdollSlot >= 0)
    {
      setPaperdollItem(pdollSlot, null);
    }
  }

  /**
   * Одевает предмет
   *
   * @param item
   * @param checks false при восстановлении инвентаря
   */
  public synchronized void equipItem(L2ItemInstance item, boolean checks)
  {
    int targetSlot = item.getItem().getBodyPart();
    if(checks)
    {
      L2Character owner = getOwner();
      if(owner.isPlayer() && owner.getName() != null)
      {
        SystemMessage msg = checkConditions(item);
        if(msg != null)
        {
          owner.sendPacket(msg);
          return;
        }
      }
    }
    double mp = 0; // при смене робы ману не сбрасываем
    switch(targetSlot)
    {
      case L2Item.SLOT_LR_HAND:
      {
        setPaperdollItem(PAPERDOLL_LHAND, null);
        setPaperdollItem(PAPERDOLL_RHAND, null);
        setPaperdollItem(PAPERDOLL_RHAND, item);
        break;
      }
      case L2Item.SLOT_L_HAND:
      {
        L2ItemInstance slot = getPaperdollItem(PAPERDOLL_RHAND);
        L2Item oldItem = slot == null ? null : slot.getItem();
        L2Item newItem = item.getItem();
        if(oldItem != null && newItem.getItemType() == EtcItemType.ARROW && oldItem.getItemType() == WeaponType.BOW && oldItem.getCrystalType() != newItem.getCrystalType())
        {
          return;
        }
        if(oldItem != null && newItem.getItemType() == EtcItemType.BOLT && oldItem.getItemType() == WeaponType.CROSSBOW && oldItem.getCrystalType() != newItem.getCrystalType())
        {
          return;
        }
        if(newItem.getItemType() != EtcItemType.ARROW && newItem.getItemType() != EtcItemType.BOLT && newItem.getItemType() != EtcItemType.BAIT)
        {
          if(oldItem != null && oldItem.getBodyPart() == L2Item.SLOT_LR_HAND)
          {
            setPaperdollItem(PAPERDOLL_RHAND, null);
            setPaperdollItem(PAPERDOLL_LHAND, null);
          }
          else
          {
            setPaperdollItem(PAPERDOLL_LHAND, null);
          }
          setPaperdollItem(PAPERDOLL_LHAND, item);
        }
        else if(oldItem != null && (newItem.getItemType() == EtcItemType.ARROW && oldItem.getItemType() == WeaponType.BOW || newItem.getItemType() == EtcItemType.BOLT && oldItem.getItemType() == WeaponType.CROSSBOW || newItem.getItemType() == EtcItemType.BAIT && oldItem.getItemType() == WeaponType.ROD))
        {
          setPaperdollItem(PAPERDOLL_LHAND, item);
          if(newItem.getItemType() == EtcItemType.BAIT && getOwner().isPlayer())
          {
            L2Player owner = (L2Player) getOwner();
            owner.setVar("LastLure", String.valueOf(item.getObjectId()));
          }
        }
        break;
      }
      case L2Item.SLOT_R_HAND:
      {
        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)
        {
          item.setBodyPart(L2Item.SLOT_L_EAR);
          setPaperdollItem(PAPERDOLL_LEAR, item);
        }
        else if(_paperdoll[PAPERDOLL_REAR] == null)
        {
          item.setBodyPart(L2Item.SLOT_R_EAR);
          setPaperdollItem(PAPERDOLL_REAR, item);
        }
        else
        {
          item.setBodyPart(L2Item.SLOT_L_EAR);
          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)
        {
          item.setBodyPart(L2Item.SLOT_L_FINGER);
          setPaperdollItem(PAPERDOLL_LFINGER, item);
        }
        else if(_paperdoll[PAPERDOLL_RFINGER] == null)
        {
          item.setBodyPart(L2Item.SLOT_R_FINGER);
          setPaperdollItem(PAPERDOLL_RFINGER, item);
        }
        else
        {
          item.setBodyPart(L2Item.SLOT_L_FINGER);
          setPaperdollItem(PAPERDOLL_LFINGER, null);
          setPaperdollItem(PAPERDOLL_LFINGER, item);
        }
        break;
      }
      case L2Item.SLOT_NECK:
        setPaperdollItem(PAPERDOLL_NECK, item);
        break;
      case L2Item.SLOT_FULL_ARMOR:
        if(getOwner() != null)
        {
          mp = getOwner().getCurrentMp();
        }
        setPaperdollItem(PAPERDOLL_CHEST, null);
        setPaperdollItem(PAPERDOLL_LEGS, null);
        setPaperdollItem(PAPERDOLL_CHEST, item);
        if(mp > getOwner().getCurrentMp())
        {
          getOwner().setCurrentMp(mp);
        }
        break;
      case L2Item.SLOT_CHEST:
        if(getOwner() != null)
        {
          mp = getOwner().getCurrentMp();
        }
        setPaperdollItem(PAPERDOLL_CHEST, item);
        if(mp > getOwner().getCurrentMp())
        {
          getOwner().setCurrentMp(mp);
        }
        break;
      case L2Item.SLOT_LEGS:
      {
        // handle full armor
        L2ItemInstance chest = getPaperdollItem(PAPERDOLL_CHEST);
        if(chest != null && chest.getBodyPart() == L2Item.SLOT_FULL_ARMOR)
        {
          setPaperdollItem(PAPERDOLL_CHEST, null);
        }
        if(getPaperdollItemId(PAPERDOLL_CHEST) == FORMAL_WEAR_ID)
        {
          setPaperdollItem(PAPERDOLL_CHEST, null);
        }
        if(getOwner() != null)
        {
          mp = getOwner().getCurrentMp();
        }
        setPaperdollItem(PAPERDOLL_LEGS, null);
        setPaperdollItem(PAPERDOLL_LEGS, item);
        if(mp > getOwner().getCurrentMp())
        {
          getOwner().setCurrentMp(mp);
        }
        break;
      }
      case L2Item.SLOT_FEET:
        if(getPaperdollItemId(PAPERDOLL_CHEST) == FORMAL_WEAR_ID)
        {
          setPaperdollItem(PAPERDOLL_CHEST, null);
        }
        setPaperdollItem(PAPERDOLL_FEET, item);
        break;
      case L2Item.SLOT_GLOVES:
        if(getPaperdollItemId(PAPERDOLL_CHEST) == FORMAL_WEAR_ID)
        {
          setPaperdollItem(PAPERDOLL_CHEST, null);
        }
        setPaperdollItem(PAPERDOLL_GLOVES, item);
        break;
      case L2Item.SLOT_HEAD:
        if(getPaperdollItemId(PAPERDOLL_CHEST) == FORMAL_WEAR_ID)
        {
          setPaperdollItem(PAPERDOLL_CHEST, null);
        }
        setPaperdollItem(PAPERDOLL_HEAD, item);
        break;
      case L2Item.SLOT_HAIR:
        L2ItemInstance slot = getPaperdollItem(PAPERDOLL_DHAIR);
        if(slot != null && slot.getItem().getBodyPart() == L2Item.SLOT_HAIRALL)
        {
          setPaperdollItem(PAPERDOLL_HAIR, null);
          setPaperdollItem(PAPERDOLL_DHAIR, null);
        }
        setPaperdollItem(PAPERDOLL_HAIR, item);
        break;
      case L2Item.SLOT_DHAIR:
        L2ItemInstance slot2 = getPaperdollItem(PAPERDOLL_DHAIR);
        if(slot2 != null && slot2.getItem().getBodyPart() == L2Item.SLOT_HAIRALL)
        {
          setPaperdollItem(PAPERDOLL_HAIR, null);
          setPaperdollItem(PAPERDOLL_DHAIR, null);
        }
        setPaperdollItem(PAPERDOLL_DHAIR, item);
        break;
      case L2Item.SLOT_HAIRALL:
        setPaperdollItem(PAPERDOLL_HAIR, null);
        setPaperdollItem(PAPERDOLL_DHAIR, null);
        setPaperdollItem(PAPERDOLL_DHAIR, item);
        break;
      case L2Item.SLOT_R_BRACELET:
        setPaperdollItem(PAPERDOLL_RBRACELET, null);
        setPaperdollItem(PAPERDOLL_RBRACELET, item);
        break;
      case L2Item.SLOT_L_BRACELET:
        setPaperdollItem(PAPERDOLL_LBRACELET, null);
        setPaperdollItem(PAPERDOLL_LBRACELET, item);
        break;
      case L2Item.SLOT_UNDERWEAR:
        setPaperdollItem(PAPERDOLL_UNDER, item);
        break;
      case L2Item.SLOT_BACK:
        setPaperdollItem(PAPERDOLL_BACK, item);
        break;
      case L2Item.SLOT_BELT:
        setPaperdollItem(PAPERDOLL_BELT, item);
        break;
      case L2Item.SLOT_DECO:
        if(_paperdoll[PAPERDOLL_DECO1] == null)
        {
          setPaperdollItem(PAPERDOLL_DECO1, item);
          break;
        }
        if(_paperdoll[PAPERDOLL_DECO2] == null)
        {
          setPaperdollItem(PAPERDOLL_DECO2, item);
          break;
        }
        if(_paperdoll[PAPERDOLL_DECO3] == null)
        {
          setPaperdollItem(PAPERDOLL_DECO3, item);
          break;
        }
        if(_paperdoll[PAPERDOLL_DECO4] == null)
        {
          setPaperdollItem(PAPERDOLL_DECO4, item);
          break;
        }
        if(_paperdoll[PAPERDOLL_DECO5] == null)
        {
          setPaperdollItem(PAPERDOLL_DECO5, item);
          break;
        }
        if(_paperdoll[PAPERDOLL_DECO6] == null)
        {
          setPaperdollItem(PAPERDOLL_DECO6, item);
        }
        else
        {
          setPaperdollItem(PAPERDOLL_DECO1, item);
        }
        break;
      case L2Item.SLOT_FORMAL_WEAR:
        // При одевании свадебного платья руки не трогаем
        setPaperdollItem(PAPERDOLL_LEGS, null);
        setPaperdollItem(PAPERDOLL_CHEST, null);
        setPaperdollItem(PAPERDOLL_HEAD, null);
        setPaperdollItem(PAPERDOLL_FEET, null);
        setPaperdollItem(PAPERDOLL_GLOVES, null);
        setPaperdollItem(PAPERDOLL_CHEST, item);
        break;
      default:
        _log.warning("unknown body slot:" + targetSlot + " for item id: " + item.getItemId());
    }
    if(getOwner().isPlayer())
    {
      ((L2Player) getOwner()).AutoShot();
    }
  }

  public L2ItemInstance getItemByItemId(int itemId)
  {
    for(L2ItemInstance temp : getItemsList())
    {
      if(temp.getItemId() == itemId)
      {
        return temp;
      }
    }
    return null;
  }

  public L2ItemInstance[] getAllItemsById(int itemId)
  {
    GArray<L2ItemInstance> ar = new GArray<L2ItemInstance>();
    for(L2ItemInstance i : getItemsList())
    {
      if(i.getItemId() == itemId)
      {
        ar.add(i);
      }
    }
    return ar.toArray(new L2ItemInstance[ar.size()]);
  }

  public int getPaperdollAugmentationId(int slot)
  {
    L2ItemInstance item = _paperdoll[slot];
    if(item != null && item.getAugmentation() != null)
    {
      return item.getAugmentation().getAugmentationId();
    }
    return 0;
  }

  public L2ItemInstance getItemByObjectId(Integer objectId)
  {
    for(L2ItemInstance temp : getItemsList())
    {
      if(temp.getObjectId() == objectId)
      {
        return temp;
      }
    }
    return null;
  }

  public L2ItemInstance destroyItem(int objectId, long count, boolean toLog)
  {
    L2ItemInstance item = getItemByObjectId(objectId);
    return destroyItem(item, count, toLog);
  }

  /**
   * Destroy item from inventory and updates database
   */
  public L2ItemInstance destroyItem(L2ItemInstance item, long count, boolean toLog)
  {
    if(getOwner() == null || item == null)
    {
      return null;
    }
    if(count < 0)
    {
      _log.warning("DestroyItem: count < 0 owner:" + getOwner().getName());
      Thread.dumpStack();
      return null;
    }
    if(toLog)
    {
      Log.LogItem(getOwner(), null, Log.DeleteItem, item, count);
      Log.add("Inventory|" + getOwner().getName() + "|Destroys item|" + item.getItemId() + "|" + count + "|" + item.getObjectId(), "items");
    }
    if(item.getCount() <= count)
    {
      if(item.getCount() < count && toLog)
      {
        Log.add("!Inventory|" + getOwner().getName() + "|Destroys item|" + item.getItemId() + "|" + count + " but item count " + item.getCount() + "|" + item.getObjectId(), "items");
      }
      removeItemFromInventory(item, true, true);
      // При удалении ошейника, удалить пета
      if(PetDataTable.isPetControlItem(item))
      {
        PetDataTable.deletePet(item, getOwner());
      }
    }
    else
    {
      item.setCount(item.getCount() - count);
      sendModifyItem(item);
      item.updateDatabase();
    }
    refreshWeight();
    return item;
  }

  private void sendModifyItem(L2ItemInstance item)
  {
    if(getOwner().isPet())
    {
      getOwner().getPlayer().sendPacket(new PetInventoryUpdate().addModifiedItem(item));
    }
    else
    {
      getOwner().sendPacket(new InventoryUpdate().addModifiedItem(item));
    }
  }

  private void sendRemoveItem(L2ItemInstance item)
  {
    if(getOwner().isPet())
    {
      getOwner().getPlayer().sendPacket(new PetInventoryUpdate().addRemovedItem(item));
    }
    else
    {
      getOwner().sendPacket(new InventoryUpdate().addRemovedItem(item));
    }
  }

  private void sendNewItem(L2ItemInstance item)
  {
    if(getOwner().isPet())
    {
      getOwner().getPlayer().sendPacket(new PetInventoryUpdate().addNewItem(item));
    }
    else
    {
      getOwner().sendPacket(new InventoryUpdate().addNewItem(item));
    }
  }
  // we need this one cuz warehouses send itemId only

  /**
   * Destroy item from inventory by using its <B>itemID</B> and updates
   * database
   *
   * @param itemId : int pointing out the itemID of the item
   * @param count  : long designating the quantity of item to destroy
   * @return L2ItemInstance designating the item up-to-date
   */
  public L2ItemInstance destroyItemByItemId(int itemId, long count, boolean toLog)
  {
    L2ItemInstance item = getItemByItemId(itemId);
    Log.LogItem(getOwner(), Log.Sys_DeleteItem, item, count);
    return destroyItem(item, count, toLog);
  }

  /**
   * Destroy item from inventory and from database.
   *
   * @param item       : L2ItemInstance designating the item to remove from inventory
   * @param clearCount : boolean : if true, set the item quantity to 0
   */
  private void removeItemFromInventory(L2ItemInstance item, boolean clearCount, boolean AllowRemoveAttributes)
  {
    if(getOwner() == null)
    {
      return;
    }
    if(getOwner().isPlayer())
    {
      L2Player player = (L2Player) getOwner();
      player.removeItemFromShortCut(item.getObjectId());
      if(item.isEquipped())
      {
        unEquipItem(item);
      }
    }
    getItemsList().remove(item);
    item.shadowNotify(false);
    if(!item.isEquipable() && item.getItem() instanceof L2EtcItem && !item.isStackable() && (item.getStatFuncs() != null || item.getItem().getAttachedSkills() != null))
    {
      if(_listenedItems != null)
      {
        _listenedItems.remove(item);
        if(_listenedItems.isEmpty())
        {
          _listenedItems = null;
        }
      }
      for(PaperdollListener listener : _paperdollListeners)
      {
        listener.notifyUnequipped(-1, item);
      }
    }
    if(clearCount)
    {
      item.setCount(0);
    }
    item.setOwnerId(0);
    item.setLocation(ItemLocation.VOID);
    sendRemoveItem(item);
    item.updateDatabase(true, AllowRemoveAttributes);
    item.deleteMe();
  }

  public L2ItemInstance dropItem(int objectId, long count, boolean allowRemoveAttributes)
  {
    L2ItemInstance item = getItemByObjectId(objectId);
    if(item == null)
    {
      _log.warning("DropItem: item objectId: " + objectId + " does not exist in inventory");
      Thread.dumpStack();
      return null;
    }
    return dropItem(item, count, allowRemoveAttributes);
  }

  /**
   * Drop item from inventory by using <B>object L2ItemInstance</B><BR>
   * <BR>
   * <U><I>Concept :</I></U><BR>
   * item equipped are unequipped
   * <LI>If quantity of items in inventory after drop is negative or null,
   * change location of item</LI>
   * <LI>Otherwise, change quantity in inventory and create new object with
   * quantity dropped</LI>
   *
   * @param oldItem : L2ItemInstance designating the item to drop
   * @param count   : int designating the quantity of item to drop
   * @return L2ItemInstance designating the item dropped
   */
  public L2ItemInstance dropItem(L2ItemInstance oldItem, long count, boolean AllowRemoveAttributes)
  {
    if(getOwner() == null)
    {
      return null;
    }
    if(getOwner().isPlayer() && ((L2Player) getOwner()).getPlayerAccess() != null && ((L2Player) getOwner()).getPlayerAccess().BlockInventory)
    {
      return null;
    }
    if(count < 0)
    {
      _log.warning("DropItem: count < 0 owner:" + getOwner().getName());
      return null;
    }
    if(oldItem == null)
    {
      _log.warning("DropItem: item id does not exist in inventory");
      return null;
    }
    Log.LogItem(getOwner(), null, Log.Drop, oldItem, count);
    if(oldItem.getCount() <= count || oldItem.getCount() <= 1)
    {
      Log.add("Inventory|" + getOwner().getName() + "|Drop item|" + oldItem.getItemId() + "|" + count + "|" + oldItem.getObjectId(), "items");
      removeItemFromInventory(oldItem, false, AllowRemoveAttributes);
      refreshWeight();
      // check drop pet controls items
      if(PetDataTable.isPetControlItem(oldItem))
      {
        PetDataTable.unSummonPet(oldItem, getOwner());
      }
      return oldItem;
    }
    oldItem.setCount(oldItem.getCount() - count);
    sendModifyItem(oldItem);
    L2ItemInstance newItem = ItemTable.getInstance().createItem(oldItem.getItemId());
    newItem.setCount(count);
    oldItem.updateDatabase();
    refreshWeight();
    Log.add("Inventory|" + getOwner().getName() + "|Split item from-to|" + oldItem.getItemId() + "|" + oldItem.getObjectId() + "|" + newItem.getObjectId(), "items");
    Log.add("Inventory|" + getOwner().getName() + "|Drop item|" + newItem.getItemId() + "|" + count + "|" + newItem.getObjectId(), "items");
    return newItem;
  }

  /**
   * Refresh the weight of equipment loaded
   */
  private void refreshWeight()
  {
    int weight = 0;
    for(L2ItemInstance element : getItemsList())
    {
      weight += element.getItem().getWeight() * element.getCount();
    }
    _totalWeight = weight;
    // notify char for overload checking
    if(getOwner().isPlayer())
    {
      ((L2Player) getOwner()).refreshOverloaded();
    }
    // Отключено, иначе во время автоматического кормления, мешает писать в чат.
    // При передаче вещей, шлется в другом месте
    //else if(getOwner().isPet)
    //  ((L2PetInstance) getOwner()).sendPetInfo();
  }

  public int getTotalWeight()
  {
    return _totalWeight;
  }

  private static final int[][] arrows = {
    //
    {17}, // NG
    {1341, 22067}, // D
    {1342, 22068}, // C
    {1343, 22069}, // B
    {1344, 22070}, // A
    {1345, 22071}, // S
  };

  public L2ItemInstance findArrowForBow(L2Item bow)
  {
    int[] arrowsId = arrows[bow.getCrystalType().externalOrdinal];
    L2ItemInstance ret;
    for(int id : arrowsId)
    {
      if((ret = getItemByItemId(id)) != null)
      {
        return ret;
      }
    }
    return null;
  }

  private static final int[][] bolts = {
    //
    {9632}, // NG
    {9633, 22144}, // D
    {9634, 22145}, // C
    {9635, 22146}, // B
    {9636, 22147}, // A
    {9637, 22148}, // S
  };

  public L2ItemInstance findArrowForCrossbow(L2Item xbow)
  {
    int[] boltsId = bolts[xbow.getCrystalType().externalOrdinal];
    L2ItemInstance ret;
    for(int id : boltsId)
    {
      if((ret = getItemByItemId(id)) != null)
      {
        return ret;
      }
    }
    return null;
  }

  public L2ItemInstance findEquippedLure()
  {
    L2ItemInstance res = null;
    int last_lure = 0;
    if(getOwner() != null && getOwner().isPlayer())
    {
      try
      {
        L2Player owner = (L2Player) getOwner();
        String LastLure = owner.getVar("LastLure");
        if(LastLure != null && !LastLure.isEmpty())
        {
          last_lure = Integer.valueOf(LastLure);
        }
      }
      catch(Exception e)
      {
        e.printStackTrace();
      }
    }
    for(L2ItemInstance temp : getItemsList())
    {
      if(temp.getItemType() == EtcItemType.BAIT)
      {
        if(temp.getLocation() == ItemLocation.PAPERDOLL && temp.getEquipSlot() == PAPERDOLL_LHAND)
        {
          return temp;
        }
        else if(last_lure > 0 && res == null && temp.getObjectId() == last_lure)
        {
          res = temp;
        }
      }
    }
    return res;
  }

  /**
   * Delete item object from world
   */
  public synchronized void deleteMe()
  {
    for(L2ItemInstance inst : getItemsList())
    {
      inst.updateInDb();
      inst.deleteMe();
    }
    getItemsList().clear();
  }

  public void updateDatabase(boolean commit)
  {
    updateDatabase(getItemsList(), commit);
  }

  private void updateDatabase(ConcurrentLinkedQueue<L2ItemInstance> items, boolean commit)
  {
    if(getOwner() != null)
    {
      for(L2ItemInstance inst : items)
      {
        inst.updateDatabase(commit, true);
      }
    }
  }

  /**
   * Функция для валидации вещей в инвентаре. Вызывается при загрузке персонажа.
   */
  public void validateItems()
  {
    for(L2ItemInstance item : getItemsList())
    {
      if(!getOwner().isPlayer())
      {
        continue;
      }
      L2Player player = getOwner().getPlayer();
      // Clan Apella armor
      if(item.isClanApellaItem() && player.getPledgeClass() < L2Player.RANK_WISEMAN)
      {
        unEquipItem(item);
      }
      else if(item.getItem().isCloak() && item.getName().contains("Knight") && player.getPledgeClass() < L2Player.RANK_KNIGHT)
      {
        unEquipItem(item);
      }
      // Clan Oath Armor
      else if(item.getItemId() >= 7850 && item.getItemId() <= 7859 && player.getLvlJoinedAcademy() == 0)
      {
        unEquipItem(item);
      }
      // Hero Weapons
      else if(item.isHeroWeapon() && !getOwner().isHero())
      {
        unEquipItem(item);
        destroyItem(item, 1, false);
      }
      // Wings of Destiny Circlet
      else if(item.getItemId() == 6842 && !getOwner().isHero())
      {
        unEquipItem(item);
      }
    }
  }

  public void restore()
  {
    final int OWNER = getOwner().getObjectId();
    ThreadConnection con = null;
    FiltredPreparedStatement statement = null;
    ResultSet rset = null;
    try
    {
      con = L2DatabaseFactory.getInstance().getConnection();
      statement = con.prepareStatement("SELECT * FROM items WHERE owner_id=? AND (loc=? OR loc=?) ORDER BY object_id DESC");
      statement.setInt(1, OWNER);
      statement.setString(2, getBaseLocation().name());
      statement.setString(3, getEquipLocation().name());
      rset = statement.executeQuery();
      L2ItemInstance item, newItem;
      while(rset.next())
      {
        if((item = L2ItemInstance.restoreFromDb(rset, con, true)) == null)
        {
          continue;
        }
        newItem = addItem(item, false, false);
        if(newItem == null)
        {
          continue;
        }
        if(item.isEquipped())
        {
          equipItem(item, false);
        }
      }
    }
    catch(Exception e)
    {
      _log.log(Level.WARNING, "could not restore inventory for player " + getOwner().getName() + ":", e);
    }
    finally
    {
      DatabaseUtils.closeDatabaseCSR(con, statement, rset);
    }
  }

  /**
   * Refresh all listeners
   * дергать осторожно, если какой-то предмет дает хп/мп то текущее значение будет сброшено
   */
  public void refreshListeners()
  {
    setRefreshingListeners(true);
    for(int i = 0; i < _paperdoll.length; i++)
    {
      L2ItemInstance item = getPaperdollItem(i);
      if(item == null)
      {
        continue;
      }
      for(PaperdollListener listener : _paperdollListeners)
      {
        listener.notifyUnequipped(i, item);
        listener.notifyEquipped(i, item);
      }
    }
    if(_listenedItems != null)
    {
      for(L2ItemInstance item : _listenedItems)
      {
        for(PaperdollListener listener : _paperdollListeners)
        {
          listener.notifyUnequipped(-1, item);
          listener.notifyEquipped(-1, item);
        }
      }
    }
    setRefreshingListeners(false);
  }

  public boolean isRefreshingListeners()
  {
    return _refreshingListeners;
  }

  public void setRefreshingListeners(boolean refreshingListeners)
  {
    _refreshingListeners = refreshingListeners;
  }

  /**
   * Вызывается из RequestSaveInventoryOrder
   */
  public void sort(int[][] order)
  {
    L2ItemInstance _item;
    ItemLocation _itemloc;
    for(int[] element : order)
    {
      _item = getItemByObjectId(element[0]);
      if(_item == null)
      {
        continue;
      }
      _itemloc = _item.getLocation();
      if(_itemloc != ItemLocation.INVENTORY)
      {
        continue;
      }
      _item.setLocation(_itemloc, element[1]);
    }
  }

  public long getCountOf(int itemId)
  {
    long result = 0;
    for(L2ItemInstance item : getItemsList())
    {
      if(item != null && item.getItemId() == itemId)
      {
        result += item.getCount();
      }
    }
    return result;
  }

  /**
   * Снимает все вещи, которые нельзя носить.
   * Применяется при смене саба, захвате замка, выходе из клана.
   */
  public void checkAllConditions()
  {
    for(L2ItemInstance item : _paperdoll)
    {
      if(item != null && checkConditions(item) != null)
      {
        unEquipItem(item);
        getOwner().getPlayer().sendDisarmMessage(item);
      }
    }
  }

  /**
   * Проверяет возможность носить эту вещь.
   */
  private SystemMessage checkConditions(L2ItemInstance item)
  {
    L2Player owner = getOwner().getPlayer();
    int itemId = item.getItemId();
    int targetSlot = item.getItem().getBodyPart();
    L2Clan ownersClan = owner.getClan();
    // Hero items
    if((item.isHeroWeapon() || item.getItemId() == 6842) && !owner.isHero())
    {
      return Msg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM;
    }
    // камаэли и хеви/робы/щиты/сигилы
    if(owner.getRace() == Race.kamael && (item.getItemType() == ArmorType.HEAVY || item.getItemType() == ArmorType.MAGIC || item.getItemType() == ArmorType.SIGIL || item.getItemType() == WeaponType.NONE && !item.getItem().isCombatFlag()))
    {
      return Msg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM;
    }
    // не камаэли и рапиры/арбалеты/древние мечи
    if(owner.getRace() != Race.kamael && (item.getItemType() == WeaponType.CROSSBOW || item.getItemType() == WeaponType.RAPIER || item.getItemType() == WeaponType.ANCIENTSWORD))
    {
      return Msg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM;
    }
    if(itemId >= 7850 && itemId <= 7859 && owner.getLvlJoinedAcademy() == 0) // Clan Oath Armor
    {
      return Msg.THIS_ITEM_CAN_ONLY_BE_WORN_BY_A_MEMBER_OF_THE_CLAN_ACADEMY;
    }
    if(item.isClanApellaItem() && owner.getPledgeClass() < L2Player.RANK_WISEMAN)
    {
      return Msg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM;
    }
    if(item.getItemType() == WeaponType.DUALDAGGER && !PlayerClass.values()[owner.getActiveClassId()].isOfType(ClassType.DaggerMaster))
    {
      return Msg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM;
    }
    if(item.getItem() instanceof L2Armor && ((L2Armor) item.getItem()).getClassType() != null && !PlayerClass.values()[owner.getActiveClassId()].isOfType(((L2Armor) item.getItem()).getClassType()))
    {
      return Msg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM;
    }
    // Замковые короны, доступные для всех членов клана
    if(Arrays.asList(_castleCirclets).contains(itemId) && (ownersClan == null || itemId != _castleCirclets[ownersClan.getHasCastle()]))
    {
      return new SystemMessage(new CustomMessage("l2p.gameserver.model.Inventory.CircletWorn", owner).addString(CastleManager.getInstance().getCastleByIndex(Arrays.asList(_castleCirclets).indexOf(itemId)).getName()));
    }
    // Корона лидера клана, владеющего замком
    if(itemId == 6841 && (ownersClan == null || !owner.isClanLeader() || ownersClan.getHasCastle() == 0))
    {
      return Msg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM;
    }
    // Нельзя одевать оружие, если уже одето проклятое оружие. Проверка двумя способами, для надежности.
    if(targetSlot == L2Item.SLOT_LR_HAND || targetSlot == L2Item.SLOT_L_HAND || targetSlot == L2Item.SLOT_R_HAND)
    {
      if(itemId != getPaperdollItemId(PAPERDOLL_RHAND) && CursedWeaponsManager.getInstance().isCursed(getPaperdollItemId(PAPERDOLL_RHAND)))
      {
        return Msg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM;
      }
      if(owner.isCursedWeaponEquipped() && itemId != owner.getCursedWeaponEquippedId())
      {
        return Msg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM;
      }
    }
    // Плащи
    if(item.getItem().isCloak())
    {
      // Can be worn by Knights or higher ranks who own castle
      if(item.getName().contains("Knight") && (owner.getPledgeClass() < L2Player.RANK_KNIGHT || owner.getCastle() == null))
      {
        return Msg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM;
      }
      // Плащи для камаэлей
      if(item.getName().contains("Kamael") && owner.getRace() != Race.kamael)
      {
        return Msg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM;
      }
      // Плащи можно носить только с S80 или S84 сетом
      boolean cloack_usable = false;
      for(int skill : L2Skill.SKILLS_S80_AND_S84_SETS)
      {
        if(owner.getSkillLevel(skill) > 0)
        {
          cloack_usable = true;
        }
      }
      if(!cloack_usable)
      {
        return Msg.THE_CLOAK_CANNOT_BE_EQUIPPED_BECAUSE_A_NECESSARY_ITEM_IS_NOT_EQUIPPED;
      }
    }
    if(targetSlot == L2Item.SLOT_R_BRACELET)
    {
      // Agathion Seal Bracelet - %Castle%
      if(itemId >= 9607 && itemId <= 9615 && (ownersClan == null || itemId - 9606 != ownersClan.getHasCastle()))
      {
        return Msg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM;
      }
      // Agathion Seal Bracelet - Fortress
      if(itemId == 10018 && (ownersClan == null || ownersClan.getHasFortress() == 0))
      {
        return Msg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM;
      }
      //TODO: Agathion Seal Bracelet - Rudolph
      //if((itemId == 10606 || itemId == 10607) && !Chrismas:))
      //{}
      //TODO: 9605/9606 - для нереализованых КХ
    }
    // Для квеста _128_PailakaSongofIceandFire
    // SpritesSword = 13034; EnhancedSpritesSword = 13035; SwordofIceandFire = 13036;
    if((itemId == 13034 || itemId == 13035 || itemId == 13036) && !owner.getReflection().getName().equalsIgnoreCase("Pailaka Song of Ice and Fire"))
    {
      return Msg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM;
    }
    // Для квеста _129_PailakaDevilsLegacy
    // SWORD = 13042; ENCHSWORD = 13043; LASTSWORD = 13044;
    if((itemId == 13042 || itemId == 13043 || itemId == 13044) && !owner.getReflection().getName().equalsIgnoreCase("Pailaka Devils Legacy"))
    {
      return Msg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM;
    }
    // Для квеста _144_PailakaInjuredDragon
    // SPEAR = 13052; ENCHSPEAR = 13053; LASTSPEAR = 13054;
    if((itemId == 13052 || itemId == 13053 || itemId == 13054) && !owner.getReflection().getName().equalsIgnoreCase("Pailaka Injured Dragon"))
    {
      return Msg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM;
    }
    if(targetSlot == L2Item.SLOT_DECO)
    {
      // Нельзя одевать талисманы без правого браслета
      if(_paperdoll[PAPERDOLL_RBRACELET] == null)
      {
        return Msg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM;
      }
      // Проверяем на количество слотов и одинаковые талисманы
      int talismans_count = 0;
      int max = (int) owner.calcStat(Stats.TALISMANS_LIMIT, 0, null, null);
      for(int slot = PAPERDOLL_DECO1; slot <= PAPERDOLL_DECO6; slot++)
      {
        if(_paperdoll[slot] != null && (_paperdoll[slot].getItemId() == itemId || ++talismans_count >= max))
        {
          return Msg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM;
        }
      }
    }
    return null;
  }

  private static class ItemOrderComparator implements Comparator<L2ItemInstance>
  {
    public int compare(L2ItemInstance o1, L2ItemInstance o2)
    {
      if(o1 == null || o2 == null)
      {
        return 0;
      }
      return o1.getEquipSlot() - o2.getEquipSlot();
    }
  }

  public static ItemOrderComparator OrderComparator = new ItemOrderComparator();
}
TOP

Related Classes of l2p.gameserver.model.items.Inventory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.