package org.reunionemu.jreunion.game;
import java.util.List;
import java.util.Vector;
import org.reunionemu.jreunion.server.Session;
import org.reunionemu.jreunion.server.SessionList;
import org.reunionemu.jreunion.server.PacketFactory.Type;
import org.slf4j.LoggerFactory;
/**
* @author Aidamina
* @license http://reunion.googlecode.com/svn/trunk/license.txt
*/
public class Shop {
private Player Owner;
private List<ShopItem> itemList = new Vector<ShopItem>();
private long lime;
private String description;
private int tabs;
//list of players buying from this shop
private List<Shop> playersBuying = new Vector<Shop>();
public Shop() {
}
public Shop(Player owner, int tabs) {
setOwner(owner);
setTabs(tabs);
}
public Player getOwner() {
return Owner;
}
public void setOwner(Player owner) {
Owner = owner;
}
public void addItem(ShopItem item){
if (itemList.contains(item)) {
return;
}
itemList.add(item);
}
public List<ShopItem> getItemList() {
return itemList;
}
public int listSize() {
return itemList.size();
}
public void removeItem(ShopItem item) {
if (!itemList.contains(item)) {
return;
}
itemList.remove(item);
}
public long getLime() {
return lime;
}
public void setLime(long lime) {
this.lime = lime;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getTabs() {
return tabs;
}
public void setTabs(int tabs) {
this.tabs = tabs;
}
public List<Shop> getPlayersBuying() {
return playersBuying;
//return new Vector<Shop>(playersBuying);
}
public void addPlayerBuying(Shop shop){
if(!getPlayersBuying().contains(shop)){
getPlayersBuying().add(shop);
}
}
public void removePlayerBuying(Shop shop){
if(getPlayersBuying().contains(shop)){
getPlayersBuying().remove(shop);
}
}
public int getPlayersBuyingSize(){
return getPlayersBuying().size();
}
public int getItemAmount(int position){
int count = 0;
for(ShopItem item : itemList){
if(item.getShopPosition().getSlot() == position)
count++;
}
return count;
}
public ShopItem getItem(ShopPosition position){
for(ShopItem item : itemList){
if(item.getShopPosition().getSlot() == position.getSlot())
return item;
}
return null;
}
public ShopItem getItem(int itemTypeId){
for(ShopItem item : itemList){
if(item.getItem().getType().getTypeId() == itemTypeId)
return item;
}
return null;
}
public ShopItem getIdenticalItem(int itemTypeId, long price, int goldBars, int silverBars, int bronzeBars){
for(ShopItem item : itemList){
if(item.getItem().getType().getTypeId() == itemTypeId &&
item.getPrice() == price &&
item.getGoldBars() == goldBars &&
item.getSilverBars() == silverBars &&
item.getBronzeBars() == bronzeBars &&
getItemAmount(item.getShopPosition().getSlot()) < 100) {
return item;
}
}
return null;
}
public int getFreePosition(){
for(int pos=0; pos<36; pos++){
if(getItem(new ShopPosition(pos)) == null)
return pos;
}
return -1;
}
public void close(){
for(Shop shop : getPlayersBuying()){
shop.getOwner().getClient().sendPacket(Type.MSG, getOwner().getName()+" closed shop.");
shop.close();
}
//getPlayersBuying().clear();
if(listSize() > 0){
unRegAll();
}
getOwner().setLime(getOwner().getLime() + getLime());
getOwner().getPosition().getLocalMap().removeShop(this);
getOwner().setShop(null);
getOwner().getClient().sendPacket(Type.U_SHOP, "close");
getOwner().getClient().sendPacket(Type.U_SHOP, "out", getOwner());
SessionList<Session> sessionList = getOwner().getInterested().getSessions();
sessionList.sendPacket(Type.U_SHOP, "out", getOwner());
LoggerFactory.getLogger(this.getClass()).info(getOwner().getName()+" personal shop closed.");
}
public void regItem(int position, int invTab, int goldBars, int silverBars, int bronzeBars, long price, int invPosX, int invPosY){
ShopItem shopItem = null;
List<ShopItem> newShopItems = new Vector<ShopItem>();
//ShopPosition shopPosition = new ShopPosition(position);
int[] invItemsPosition; //[tab][x1][y1][x2][y2]...[x10][y10]
if(invTab == -1){ //add single item to shop
shopItem = getItem(new ShopPosition(position));
//if the requested position already contains a item, and the new item
//is different from the existing item, then return error message.
if(shopItem != null && shopItem.getPrice() != price){
getOwner().getClient().sendPacket(Type.U_SHOP, "reg", 0, -4, 1);
return;
}
HandPosition holdingItem = getOwner().getInventory().getHoldingItem();
if(holdingItem==null){
return;
} else {
Item<?> item = holdingItem.getItem();
shopItem = new ShopItem(new ShopPosition(position), goldBars, silverBars, bronzeBars, price, item);
newShopItems.add(shopItem);
getOwner().getInventory().setHoldingItem(null);
invItemsPosition = new int[3];
invItemsPosition[0] = -1;
invItemsPosition[1] = -1;
invItemsPosition[2] = -1;
}
} else { //add multiple items to shop
InventoryItem invItem = getOwner().getInventory().getItem(invTab, invPosX, invPosY);
shopItem = getIdenticalItem(invItem.getItem().getType().getTypeId(), price, goldBars, silverBars, bronzeBars);
//if already exist a shop position with the same item requested, select it,
//else get the first free position.
ShopPosition shopPosition = (shopItem==null ? new ShopPosition(getFreePosition()) : shopItem.getShopPosition());
position = shopPosition.getSlot();
//if adding the max multiple amount (10) is above the position limit amount (100),
//then calculate the available position amount, else set it to the max amount(10).
int itemAmount = ((getItemAmount(shopPosition.getSlot())+10) > 100 ?
100-getItemAmount(shopPosition.getSlot()) : 9);
List<InventoryItem> invItemList = new Vector<InventoryItem>();
invItemList.add(invItem);
int itemTypeId = invItem.getItem().getType().getTypeId();
getOwner().getInventory().deleteInventoryItem(invItem);
//get/remove all inventory items available, equal to the requested item type.
do {
invItem = getOwner().getInventory().getItem(invTab, itemTypeId);
if(invItem != null) {
invItemList.add(invItem);
getOwner().getInventory().deleteInventoryItem(invItem);
}
} while(invItem != null && itemAmount-- > 1);
invItemsPosition = new int[(invItemList.size()*2)+1];
invItemsPosition[0] = invTab;
int index = 1;
//get/store inventory items positions and create/add shop items.
for(InventoryItem item : invItemList){
shopItem = new ShopItem(new ShopPosition(position), goldBars, silverBars, bronzeBars, price, item.getItem());
newShopItems.add(shopItem);
invItemsPosition[index++] = item.getPosition().getPosX();
invItemsPosition[index++] = item.getPosition().getPosY();
}
}
for(ShopItem newShopItem : newShopItems){
addItem(newShopItem);
LoggerFactory.getLogger(this.getClass()).info("Player "+getOwner()+" added item "+newShopItem.getItem()+" to shop.");
}
getOwner().getClient().sendPacket(Type.U_SHOP, "reg", 1, position, newShopItems.size(), shopItem, invItemsPosition );
}
public void unRegItem(int position, int amountRequested){
ShopItem shopItem = getItem(new ShopPosition(position));
if(shopItem == null)
return;
if(amountRequested == 1){ //removing a single items from shop.
removeItem(shopItem);
getOwner().getInventory().setHoldingItem(new HandPosition(shopItem.getItem()));
getOwner().getClient().sendPacket(Type.U_SHOP, "unreg", 1, position, amountRequested);
getOwner().getClient().sendPacket(Type.PICK_EXTRA, shopItem.getItem());
LoggerFactory.getLogger(this.getClass()).info("Player "+getOwner()+" removed item "+shopItem.getItem()+" from shop.");
} else if(amountRequested > 1) { //removing multiple items from shop.
int existingAmount = getItemAmount(position);
getOwner().getClient().sendPacket(Type.U_SHOP, "unreg", 1, position, existingAmount);
do {
InventoryItem invItem = getOwner().getInventory().storeItem(shopItem.getItem(), -1);
getOwner().getClient().sendPacket(Type.INVEN, invItem, getOwner().getClient().getVersion());
removeItem(shopItem);
shopItem = getItem(new ShopPosition(position));
} while(existingAmount-- > 1);
}
}
public void unRegAll(){
//List<Integer> processedPositions = new Vector<Integer>();
for(ShopItem shopItem : itemList){
//TODO: process more then one item at the same time.
/*
int position = shopItem.getShopPosition().getSlot();
if(processedPositions.contains(position))
continue;
processedPositions.add(position);
int amount = getItemAmount(position);
*/
int amount = 1;
getOwner().getClient().sendPacket(Type.U_SHOP, "unreg", 1, shopItem.getShopPosition().getSlot(), amount);
//int[] freePosition = getOwner().getInventory().getFreeSlots(shopItem.getItem(), -1);
//InventoryPosition inventoryPosition = new InventoryPosition(freePosition[1],freePosition[2],freePosition[0]);
//InventoryItem inventoryItem = new InventoryItem(shopItem.getItem(), inventoryPosition);
//getOwner().getInventory().addInventoryItem(inventoryItem);
InventoryItem inventoryItem = getOwner().getInventory().storeItem(shopItem.getItem(), -1);
getOwner().getClient().sendPacket(Type.INVEN, inventoryItem, getOwner().getClient().getVersion());
}
itemList.clear();
}
public void start(String[] args){
String shopDescription = "";
for(int i=2; i<args.length; i++){
shopDescription += args[i];
if(i < args.length-1)
shopDescription += " ";
}
setDescription(shopDescription);
SessionList<Session> sessions = getOwner().getInterested().getSessions();
sessions.sendPacket(Type.U_SHOP, "in", getOwner(), shopDescription);
getOwner().getClient().sendPacket(Type.U_SHOP, "start");
}
public void modify(){
getOwner().getClient().sendPacket(Type.U_SHOP, "out", getOwner());
SessionList<Session> sessionList = getOwner().getInterested().getSessions();
sessionList.sendPacket(Type.U_SHOP, "out", getOwner());
getOwner().getClient().sendPacket(Type.U_SHOP, "modify");
}
public void open(Player buyer){
buyer.setShop(new Shop(buyer, getTabs()));
buyer.getClient().sendPacket(Type.U_SHOP, "open", getOwner(), getTabs()-1);
buyer.getClient().sendPacket(Type.U_SHOP, "list_start");
for(ShopItem shopItem : getItemList()){
buyer.getClient().sendPacket(Type.U_SHOP, "list", shopItem, getItemAmount(shopItem.getShopPosition().getSlot()));
}
buyer.getClient().sendPacket(Type.U_SHOP, "list_end");
addPlayerBuying(buyer.getShop());
}
public void buy(int position, int requestedAmount){
Shop sellerShop = getOwner().getPosition().getLocalMap().getShopBuying(getOwner());
ShopItem shopItem = sellerShop.getItem(new ShopPosition(position));
int availableAmount = sellerShop.getItemAmount(position);
if(getOwner().getLime() - (shopItem.getPrice()*availableAmount) < 0){
getOwner().getClient().sendPacket(Type.MSG, "You don't have enough lime to buy this item.");
return;
}
if(shopItem.getGoldBars()>0 || shopItem.getSilverBars()>0 || shopItem.getBronzeBars()>0){
getOwner().getClient().sendPacket(Type.SAY, "The amount of bars (gold, silver, bronze) will be ignored.");
sellerShop.getOwner().getClient().sendPacket(Type.SAY, "The amount of bars (gold, silver, bronze) will be ignored.");
}
getOwner().setLime(getOwner().getLime() - (shopItem.getPrice()*availableAmount));
//buy command to the player who is buying.
getOwner().getClient().sendPacket(Type.U_SHOP, "buy", 1, position, availableAmount);
//buy command to other players that are viewing the shop.
for(Shop shop : sellerShop.getPlayersBuying()){
if(getOwner() != shop.getOwner()){
shop.getOwner().getClient().sendPacket(Type.U_SHOP, "buy", 2, position, availableAmount);
}
}
List<ShopItem> shopItems = new Vector<ShopItem>();
while(availableAmount-- > 0){
shopItem = sellerShop.getItem(new ShopPosition(position));
//int[] freePosition = getOwner().getInventory().getFreeSlots(shopItem.getItem(), -1);
//InventoryPosition inventoryPosition = new InventoryPosition(freePosition[1],freePosition[2],freePosition[0]);
//InventoryItem inventoryItem = new InventoryItem(shopItem.getItem(), inventoryPosition);
//getOwner().getInventory().addInventoryItem(inventoryItem);
InventoryItem inventoryItem = getOwner().getInventory().storeItem(shopItem.getItem(), -1);
getOwner().getClient().sendPacket(Type.INVEN, inventoryItem, getOwner().getClient().getVersion());
shopItems.add(shopItem);
sellerShop.removeItem(shopItem);
}
getOwner().getClient().sendPacket(Type.SAY, "The item as been bought: "+shopItem.getItem().getType().getName()+
" ("+shopItems.size()+")");
LoggerFactory.getLogger(this.getClass()).info("Player "+getOwner()+" bought "+shopItems.size()+" item(s) "
+shopItem.getItem()+" from player "+sellerShop.getOwner());
sellerShop.sell(getOwner(), shopItems);
}
public void sell(Player buyer, List<ShopItem> shopItems){
if(buyer==null || shopItems==null)
return;
int saleLime = 0;
ShopItem sItem = null;
for(ShopItem shopItem : shopItems){
sItem = shopItem;
saleLime += shopItem.getPrice();
//removeItem(shopItem);
}
setLime(getLime() + saleLime);
getOwner().getClient().sendPacket(Type.U_SHOP, "sell", 1, sItem.getShopPosition().getSlot(), shopItems.size(),
sItem, getLime());
getOwner().getClient().sendPacket(Type.SAY, buyer.getName()+" bought item: "+sItem.getItem().getType().getName()+
" ("+shopItems.size()+")");
}
}