/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* L2J Server is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.gameserver.model;
import static com.l2jserver.gameserver.model.itemcontainer.Inventory.MAX_ADENA;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.logging.Logger;
import com.l2jserver.Config;
import com.l2jserver.gameserver.datatables.ItemTable;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.itemcontainer.Inventory;
import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
import com.l2jserver.gameserver.model.items.L2Item;
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.ExAdenaInvenCount;
import com.l2jserver.gameserver.network.serverpackets.ExUserInfoInvenWeight;
import com.l2jserver.gameserver.network.serverpackets.InventoryUpdate;
import com.l2jserver.gameserver.network.serverpackets.ItemList;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
import com.l2jserver.gameserver.util.Util;
/**
* @author Advi
*/
public class TradeList
{
private static final Logger _log = Logger.getLogger(TradeList.class.getName());
private final L2PcInstance _owner;
private L2PcInstance _partner;
private final List<TradeItem> _items;
private String _title;
private boolean _packaged;
private boolean _confirmed = false;
private boolean _locked = false;
public TradeList(L2PcInstance owner)
{
_items = new ArrayList<>();
_owner = owner;
}
public L2PcInstance getOwner()
{
return _owner;
}
public void setPartner(L2PcInstance partner)
{
_partner = partner;
}
public L2PcInstance getPartner()
{
return _partner;
}
public void setTitle(String title)
{
_title = title;
}
public String getTitle()
{
return _title;
}
public boolean isLocked()
{
return _locked;
}
public boolean isConfirmed()
{
return _confirmed;
}
public boolean isPackaged()
{
return _packaged;
}
public void setPackaged(boolean value)
{
_packaged = value;
}
/**
* @return all items from TradeList
*/
public TradeItem[] getItems()
{
return _items.toArray(new TradeItem[_items.size()]);
}
/**
* Returns the list of items in inventory available for transaction
* @param inventory
* @return L2ItemInstance : items in inventory
*/
public TradeItem[] getAvailableItems(PcInventory inventory)
{
final ArrayList<TradeItem> list = new ArrayList<>();
for (TradeItem item : _items)
{
int el[] = new int[6];
for (int i = 0; i < 6; i++)
{
el[i] = item.getElementDefAttr((byte) i);
}
item = new TradeItem(item, item.getCount(), item.getPrice(), item.getEnchant(), item.getAttackElementType(), item.getAttackElementPower(), el, item.getVisualId());
inventory.adjustAvailableItem(item);
list.add(item);
}
return list.toArray(new TradeItem[list.size()]);
}
/**
* @return Item List size
*/
public int getItemCount()
{
return _items.size();
}
/**
* Adjust available item from Inventory by the one in this list
* @param item : L2ItemInstance to be adjusted
* @return TradeItem representing adjusted item
*/
public TradeItem adjustAvailableItem(L2ItemInstance item)
{
if (item.isStackable())
{
for (TradeItem exclItem : _items)
{
if (exclItem.getItem().getId() == item.getId())
{
if (item.getCount() <= exclItem.getCount())
{
return null;
}
return new TradeItem(item, item.getCount() - exclItem.getCount(), item.getReferencePrice());
}
}
}
return new TradeItem(item, item.getCount(), item.getReferencePrice());
}
/**
* Adjust ItemRequest by corresponding item in this list using its <b>ObjectId</b>
* @param item : ItemRequest to be adjusted
*/
public void adjustItemRequest(ItemRequest item)
{
for (TradeItem filtItem : _items)
{
if (filtItem.getObjectId() == item.getObjectId())
{
if (filtItem.getCount() < item.getCount())
{
item.setCount(filtItem.getCount());
}
return;
}
}
item.setCount(0);
}
/**
* Add simplified item to TradeList
* @param objectId : int
* @param count : int
* @return
*/
public TradeItem addItem(int objectId, long count)
{
return addItem(objectId, count, 0);
}
/**
* Add item to TradeList
* @param objectId : int
* @param count : long
* @param price : long
* @return
*/
public synchronized TradeItem addItem(int objectId, long count, long price)
{
if (isLocked())
{
_log.warning(_owner.getName() + ": Attempt to modify locked TradeList!");
return null;
}
L2Object o = L2World.getInstance().findObject(objectId);
if (!(o instanceof L2ItemInstance))
{
_log.warning(_owner.getName() + ": Trying to add something other than an item!");
return null;
}
L2ItemInstance item = (L2ItemInstance) o;
if (!(item.isTradeable() || (getOwner().isGM() && Config.GM_TRADE_RESTRICTED_ITEMS)) || item.isQuestItem())
{
_log.warning(_owner.getName() + ": Attempt to add a restricted item!");
return null;
}
if (!getOwner().getInventory().canManipulateWithItemId(item.getId()))
{
_log.warning(_owner.getName() + ": Attempt to add an item that can't manipualte!");
return null;
}
if ((count <= 0) || (count > item.getCount()))
{
_log.warning(_owner.getName() + ": Attempt to add an item with invalid item count!");
return null;
}
if (!item.isStackable() && (count > 1))
{
_log.warning(_owner.getName() + ": Attempt to add non-stackable item to TradeList with count > 1!");
return null;
}
if ((Inventory.MAX_ADENA / count) < price)
{
_log.warning(_owner.getName() + ": Attempt to overflow adena !");
return null;
}
for (TradeItem checkitem : _items)
{
if (checkitem.getObjectId() == objectId)
{
_log.warning(_owner.getName() + ": Attempt to add an item that is already present!");
return null;
}
}
TradeItem titem = new TradeItem(item, count, price);
_items.add(titem);
// If Player has already confirmed this trade, invalidate the confirmation
invalidateConfirmation();
return titem;
}
/**
* Add item to TradeList
* @param itemId
* @param count
* @param price
* @param enchantLevel
* @param attackAttribute
* @param attackAttributeValue
* @param defenseAttributes
* @param appearanceId
* @return
*/
public synchronized TradeItem addItemByItemId(int itemId, long count, long price, int enchantLevel, int attackAttribute, int attackAttributeValue, int defenseAttributes[], int appearanceId)
{
if (isLocked())
{
_log.warning(_owner.getName() + ": Attempt to modify locked TradeList!");
return null;
}
L2Item item = ItemTable.getInstance().getTemplate(itemId);
if (item == null)
{
_log.warning(_owner.getName() + ": Attempt to add invalid item to TradeList!");
return null;
}
if (!item.isTradeable() || item.isQuestItem())
{
return null;
}
if (!item.isStackable() && (count > 1))
{
_log.warning(_owner.getName() + ": Attempt to add non-stackable item to TradeList with count > 1!");
return null;
}
if ((Inventory.MAX_ADENA / count) < price)
{
_log.warning(_owner.getName() + ": Attempt to overflow adena !");
return null;
}
TradeItem titem = new TradeItem(item, count, price, enchantLevel, attackAttribute, attackAttributeValue, defenseAttributes, appearanceId);
_items.add(titem);
// If Player has already confirmed this trade, invalidate the confirmation
invalidateConfirmation();
return titem;
}
/**
* Remove item from TradeList
* @param objectId : int
* @param itemId
* @param count : int
* @return
*/
public synchronized TradeItem removeItem(int objectId, int itemId, long count)
{
if (isLocked())
{
_log.warning(_owner.getName() + ": Attempt to modify locked TradeList!");
return null;
}
for (TradeItem titem : _items)
{
if ((titem.getObjectId() == objectId) || (titem.getItem().getId() == itemId))
{
// If Partner has already confirmed this trade, invalidate the confirmation
if (_partner != null)
{
TradeList partnerList = _partner.getActiveTradeList();
if (partnerList == null)
{
_log.warning(_partner.getName() + ": Trading partner (" + _partner.getName() + ") is invalid in this trade!");
return null;
}
partnerList.invalidateConfirmation();
}
// Reduce item count or complete item
if ((count != -1) && (titem.getCount() > count))
{
titem.setCount(titem.getCount() - count);
}
else
{
_items.remove(titem);
}
return titem;
}
}
return null;
}
/**
* Update items in TradeList according their quantity in owner inventory
*/
public synchronized void updateItems()
{
for (TradeItem titem : _items)
{
L2ItemInstance item = _owner.getInventory().getItemByObjectId(titem.getObjectId());
if ((item == null) || (titem.getCount() < 1))
{
removeItem(titem.getObjectId(), -1, -1);
}
else if (item.getCount() < titem.getCount())
{
titem.setCount(item.getCount());
}
}
}
/**
* Lockes TradeList, no further changes are allowed
*/
public void lock()
{
_locked = true;
}
/**
* Clears item list
*/
public synchronized void clear()
{
_items.clear();
_locked = false;
}
/**
* Confirms TradeList
* @return : boolean
*/
public boolean confirm()
{
if (_confirmed)
{
return true; // Already confirmed
}
// If Partner has already confirmed this trade, proceed exchange
if (_partner != null)
{
TradeList partnerList = _partner.getActiveTradeList();
if (partnerList == null)
{
_log.warning(_partner.getName() + ": Trading partner (" + _partner.getName() + ") is invalid in this trade!");
return false;
}
// Synchronization order to avoid deadlock
TradeList sync1, sync2;
if (getOwner().getObjectId() > partnerList.getOwner().getObjectId())
{
sync1 = partnerList;
sync2 = this;
}
else
{
sync1 = this;
sync2 = partnerList;
}
synchronized (sync1)
{
synchronized (sync2)
{
_confirmed = true;
if (partnerList.isConfirmed())
{
partnerList.lock();
lock();
if (!partnerList.validate())
{
return false;
}
if (!validate())
{
return false;
}
doExchange(partnerList);
}
else
{
_partner.onTradeConfirm(_owner);
}
}
}
}
else
{
_confirmed = true;
}
return _confirmed;
}
/**
* Cancels TradeList confirmation
*/
public void invalidateConfirmation()
{
_confirmed = false;
}
/**
* Validates TradeList with owner inventory
* @return
*/
private boolean validate()
{
// Check for Owner validity
if ((_owner == null) || (L2World.getInstance().getPlayer(_owner.getObjectId()) == null))
{
_log.warning("Invalid owner of TradeList");
return false;
}
// Check for Item validity
for (TradeItem titem : _items)
{
L2ItemInstance item = _owner.checkItemManipulation(titem.getObjectId(), titem.getCount(), "transfer");
if ((item == null) || (item.getCount() < 1))
{
_log.warning(_owner.getName() + ": Invalid Item in TradeList");
return false;
}
}
return true;
}
/**
* Transfers all TradeItems from inventory to partner
* @param partner
* @param ownerIU
* @param partnerIU
* @return
*/
private boolean TransferItems(L2PcInstance partner, InventoryUpdate ownerIU, InventoryUpdate partnerIU)
{
for (TradeItem titem : _items)
{
L2ItemInstance oldItem = _owner.getInventory().getItemByObjectId(titem.getObjectId());
if (oldItem == null)
{
return false;
}
L2ItemInstance newItem = _owner.getInventory().transferItem("Trade", titem.getObjectId(), titem.getCount(), partner.getInventory(), _owner, _partner);
if (newItem == null)
{
return false;
}
// Add changes to inventory update packets
if (ownerIU != null)
{
if ((oldItem.getCount() > 0) && (oldItem != newItem))
{
ownerIU.addModifiedItem(oldItem);
}
else
{
ownerIU.addRemovedItem(oldItem);
}
}
if (partnerIU != null)
{
if (newItem.getCount() > titem.getCount())
{
partnerIU.addModifiedItem(newItem);
}
else
{
partnerIU.addNewItem(newItem);
}
}
}
return true;
}
/**
* @param partner
* @return items slots count
*/
public int countItemsSlots(L2PcInstance partner)
{
int slots = 0;
for (TradeItem item : _items)
{
if (item == null)
{
continue;
}
L2Item template = ItemTable.getInstance().getTemplate(item.getItem().getId());
if (template == null)
{
continue;
}
if (!template.isStackable())
{
slots += item.getCount();
}
else if (partner.getInventory().getItemByItemId(item.getItem().getId()) == null)
{
slots++;
}
}
return slots;
}
/**
* @return the weight of items in tradeList
*/
public int calcItemsWeight()
{
long weight = 0;
for (TradeItem item : _items)
{
if (item == null)
{
continue;
}
L2Item template = ItemTable.getInstance().getTemplate(item.getItem().getId());
if (template == null)
{
continue;
}
weight += item.getCount() * template.getWeight();
}
return (int) Math.min(weight, Integer.MAX_VALUE);
}
/**
* Proceeds with trade
* @param partnerList
*/
private void doExchange(TradeList partnerList)
{
boolean success = false;
// check weight and slots
if ((!getOwner().getInventory().validateWeight(partnerList.calcItemsWeight())) || !(partnerList.getOwner().getInventory().validateWeight(calcItemsWeight())))
{
partnerList.getOwner().sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_WEIGHT_LIMIT);
getOwner().sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_WEIGHT_LIMIT);
}
else if ((!getOwner().getInventory().validateCapacity(partnerList.countItemsSlots(getOwner()))) || (!partnerList.getOwner().getInventory().validateCapacity(countItemsSlots(partnerList.getOwner()))))
{
partnerList.getOwner().sendPacket(SystemMessageId.YOUR_INVENTORY_IS_FULL);
getOwner().sendPacket(SystemMessageId.YOUR_INVENTORY_IS_FULL);
}
else
{
// Prepare inventory update packet
InventoryUpdate ownerIU = Config.FORCE_INVENTORY_UPDATE ? null : new InventoryUpdate();
InventoryUpdate partnerIU = Config.FORCE_INVENTORY_UPDATE ? null : new InventoryUpdate();
// Transfer items
partnerList.TransferItems(getOwner(), partnerIU, ownerIU);
TransferItems(partnerList.getOwner(), ownerIU, partnerIU);
// Send inventory update packet
if (ownerIU != null)
{
_owner.sendPacket(ownerIU);
}
else
{
_owner.sendPacket(new ItemList(_owner, false));
}
if (partnerIU != null)
{
_partner.sendPacket(partnerIU);
}
else
{
_partner.sendPacket(new ItemList(_partner, false));
}
// Update current load as well
_owner.sendPacket(new ExUserInfoInvenWeight(_owner));
_owner.sendPacket(new ExAdenaInvenCount(_owner));
_partner.sendPacket(new ExUserInfoInvenWeight(_partner));
_partner.sendPacket(new ExAdenaInvenCount(_partner));
success = true;
}
// Finish the trade
partnerList.getOwner().onTradeFinish(success);
getOwner().onTradeFinish(success);
}
/**
* Buy items from this PrivateStore list
* @param player
* @param items
* @return int: result of trading. 0 - ok, 1 - canceled (no adena), 2 - failed (item error)
*/
public synchronized int privateStoreBuy(L2PcInstance player, HashSet<ItemRequest> items)
{
if (_locked)
{
return 1;
}
if (!validate())
{
lock();
return 1;
}
if (!_owner.isOnline() || !player.isOnline())
{
return 1;
}
int slots = 0;
int weight = 0;
long totalPrice = 0;
final PcInventory ownerInventory = _owner.getInventory();
final PcInventory playerInventory = player.getInventory();
for (ItemRequest item : items)
{
boolean found = false;
for (TradeItem ti : _items)
{
if (ti.getObjectId() == item.getObjectId())
{
if (ti.getPrice() == item.getPrice())
{
if (ti.getCount() < item.getCount())
{
item.setCount(ti.getCount());
}
found = true;
}
break;
}
}
// item with this objectId and price not found in tradelist
if (!found)
{
if (isPackaged())
{
Util.handleIllegalPlayerAction(player, "[TradeList.privateStoreBuy()] Player " + player.getName() + " tried to cheat the package sell and buy only a part of the package! Ban this player for bot usage!", Config.DEFAULT_PUNISH);
return 2;
}
item.setCount(0);
continue;
}
// check for overflow in the single item
if ((MAX_ADENA / item.getCount()) < item.getPrice())
{
// private store attempting to overflow - disable it
lock();
return 1;
}
totalPrice += item.getCount() * item.getPrice();
// check for overflow of the total price
if ((MAX_ADENA < totalPrice) || (totalPrice < 0))
{
// private store attempting to overflow - disable it
lock();
return 1;
}
// Check if requested item is available for manipulation
L2ItemInstance oldItem = _owner.checkItemManipulation(item.getObjectId(), item.getCount(), "sell");
if ((oldItem == null) || !oldItem.isTradeable())
{
// private store sell invalid item - disable it
lock();
return 2;
}
L2Item template = ItemTable.getInstance().getTemplate(item.getItemId());
if (template == null)
{
continue;
}
weight += item.getCount() * template.getWeight();
if (!template.isStackable())
{
slots += item.getCount();
}
else if (playerInventory.getItemByItemId(item.getItemId()) == null)
{
slots++;
}
}
if (totalPrice > playerInventory.getAdena())
{
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_ADENA);
return 1;
}
if (!playerInventory.validateWeight(weight))
{
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_WEIGHT_LIMIT);
return 1;
}
if (!playerInventory.validateCapacity(slots))
{
player.sendPacket(SystemMessageId.YOUR_INVENTORY_IS_FULL);
return 1;
}
// Prepare inventory update packets
final InventoryUpdate ownerIU = new InventoryUpdate();
final InventoryUpdate playerIU = new InventoryUpdate();
final L2ItemInstance adenaItem = playerInventory.getAdenaInstance();
if (!playerInventory.reduceAdena("PrivateStore", totalPrice, player, _owner))
{
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_ADENA);
return 1;
}
playerIU.addItem(adenaItem);
ownerInventory.addAdena("PrivateStore", totalPrice, _owner, player);
// ownerIU.addItem(ownerInventory.getAdenaInstance());
boolean ok = true;
// Transfer items
for (ItemRequest item : items)
{
if (item.getCount() == 0)
{
continue;
}
// Check if requested item is available for manipulation
L2ItemInstance oldItem = _owner.checkItemManipulation(item.getObjectId(), item.getCount(), "sell");
if (oldItem == null)
{
// should not happens - validation already done
lock();
ok = false;
break;
}
// Proceed with item transfer
L2ItemInstance newItem = ownerInventory.transferItem("PrivateStore", item.getObjectId(), item.getCount(), playerInventory, _owner, player);
if (newItem == null)
{
ok = false;
break;
}
removeItem(item.getObjectId(), -1, item.getCount());
// Add changes to inventory update packets
if ((oldItem.getCount() > 0) && (oldItem != newItem))
{
ownerIU.addModifiedItem(oldItem);
}
else
{
ownerIU.addRemovedItem(oldItem);
}
if (newItem.getCount() > item.getCount())
{
playerIU.addModifiedItem(newItem);
}
else
{
playerIU.addNewItem(newItem);
}
// Send messages about the transaction to both players
if (newItem.isStackable())
{
SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.C1_PURCHASED_S3_S2_S);
msg.addString(player.getName());
msg.addItemName(newItem);
msg.addLong(item.getCount());
_owner.sendPacket(msg);
msg = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_PURCHASED_S3_S2_S_FROM_C1);
msg.addString(_owner.getName());
msg.addItemName(newItem);
msg.addLong(item.getCount());
player.sendPacket(msg);
}
else
{
SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.C1_PURCHASED_S2);
msg.addString(player.getName());
msg.addItemName(newItem);
_owner.sendPacket(msg);
msg = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_PURCHASED_S2_FROM_C1);
msg.addString(_owner.getName());
msg.addItemName(newItem);
player.sendPacket(msg);
}
}
// Send inventory update packet
_owner.sendPacket(ownerIU);
player.sendPacket(playerIU);
if (ok)
{
return 0;
}
return 2;
}
/**
* Sell items to this PrivateStore list
* @param player
* @param items
* @return : boolean true if success
*/
public synchronized boolean privateStoreSell(L2PcInstance player, ItemRequest[] items)
{
if (_locked)
{
return false;
}
if (!_owner.isOnline() || !player.isOnline())
{
return false;
}
boolean ok = false;
final PcInventory ownerInventory = _owner.getInventory();
final PcInventory playerInventory = player.getInventory();
// Prepare inventory update packet
final InventoryUpdate ownerIU = new InventoryUpdate();
final InventoryUpdate playerIU = new InventoryUpdate();
long totalPrice = 0;
for (ItemRequest item : items)
{
// searching item in tradelist using itemId
boolean found = false;
for (TradeItem ti : _items)
{
if (ti.getItem().getId() == item.getItemId())
{
// price should be the same
if (ti.getPrice() == item.getPrice())
{
// if requesting more than available - decrease count
if (ti.getCount() < item.getCount())
{
item.setCount(ti.getCount());
}
found = item.getCount() > 0;
}
break;
}
}
// not found any item in the tradelist with same itemId and price
// maybe another player already sold this item ?
if (!found)
{
continue;
}
// check for overflow in the single item
if ((MAX_ADENA / item.getCount()) < item.getPrice())
{
lock();
break;
}
long _totalPrice = totalPrice + (item.getCount() * item.getPrice());
// check for overflow of the total price
if ((MAX_ADENA < _totalPrice) || (_totalPrice < 0))
{
lock();
break;
}
if (ownerInventory.getAdena() < _totalPrice)
{
continue;
}
// Check if requested item is available for manipulation
int objectId = item.getObjectId();
L2ItemInstance oldItem = player.checkItemManipulation(objectId, item.getCount(), "sell");
// private store - buy use same objectId for buying several non-stackable items
if (oldItem == null)
{
// searching other items using same itemId
oldItem = playerInventory.getItemByItemId(item.getItemId());
if (oldItem == null)
{
continue;
}
objectId = oldItem.getObjectId();
oldItem = player.checkItemManipulation(objectId, item.getCount(), "sell");
if (oldItem == null)
{
continue;
}
}
if (oldItem.getId() != item.getItemId())
{
Util.handleIllegalPlayerAction(player, player + " is cheating with sell items", Config.DEFAULT_PUNISH);
return false;
}
if (!oldItem.isTradeable())
{
continue;
}
// Proceed with item transfer
L2ItemInstance newItem = playerInventory.transferItem("PrivateStore", objectId, item.getCount(), ownerInventory, player, _owner);
if (newItem == null)
{
continue;
}
removeItem(-1, item.getItemId(), item.getCount());
ok = true;
// increase total price only after successful transaction
totalPrice = _totalPrice;
// Add changes to inventory update packets
if ((oldItem.getCount() > 0) && (oldItem != newItem))
{
playerIU.addModifiedItem(oldItem);
}
else
{
playerIU.addRemovedItem(oldItem);
}
if (newItem.getCount() > item.getCount())
{
ownerIU.addModifiedItem(newItem);
}
else
{
ownerIU.addNewItem(newItem);
}
// Send messages about the transaction to both players
if (newItem.isStackable())
{
SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_PURCHASED_S3_S2_S_FROM_C1);
msg.addString(player.getName());
msg.addItemName(newItem);
msg.addLong(item.getCount());
_owner.sendPacket(msg);
msg = SystemMessage.getSystemMessage(SystemMessageId.C1_PURCHASED_S3_S2_S);
msg.addString(_owner.getName());
msg.addItemName(newItem);
msg.addLong(item.getCount());
player.sendPacket(msg);
}
else
{
SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_PURCHASED_S2_FROM_C1);
msg.addString(player.getName());
msg.addItemName(newItem);
_owner.sendPacket(msg);
msg = SystemMessage.getSystemMessage(SystemMessageId.C1_PURCHASED_S2);
msg.addString(_owner.getName());
msg.addItemName(newItem);
player.sendPacket(msg);
}
}
if (totalPrice > 0)
{
// Transfer adena
if (totalPrice > ownerInventory.getAdena())
{
// should not happens, just a precaution
return false;
}
final L2ItemInstance adenaItem = ownerInventory.getAdenaInstance();
ownerInventory.reduceAdena("PrivateStore", totalPrice, _owner, player);
ownerIU.addItem(adenaItem);
playerInventory.addAdena("PrivateStore", totalPrice, player, _owner);
playerIU.addItem(playerInventory.getAdenaInstance());
}
if (ok)
{
// Send inventory update packet
_owner.sendPacket(ownerIU);
player.sendPacket(playerIU);
}
return ok;
}
}