/*
* This file is part of aion-unique <aion-unique.org>.
*
* aion-unique 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.
*
* aion-unique 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 aion-unique. If not, see <http://www.gnu.org/licenses/>.
*/
package com.aionemu.gameserver.services;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import com.aionemu.gameserver.model.gameobjects.Item;
import com.aionemu.gameserver.model.gameobjects.player.Player;
import com.aionemu.gameserver.model.gameobjects.player.PrivateStore;
import com.aionemu.gameserver.model.gameobjects.player.Storage;
import com.aionemu.gameserver.model.gameobjects.state.CreatureState;
import com.aionemu.gameserver.model.items.GodStone;
import com.aionemu.gameserver.model.items.ManaStone;
import com.aionemu.gameserver.model.trade.TradeItem;
import com.aionemu.gameserver.model.trade.TradeList;
import com.aionemu.gameserver.model.trade.TradePSItem;
import com.aionemu.gameserver.network.aion.serverpackets.SM_EMOTION;
import com.aionemu.gameserver.network.aion.serverpackets.SM_INVENTORY_UPDATE;
import com.aionemu.gameserver.network.aion.serverpackets.SM_PRIVATE_STORE_NAME;
import com.aionemu.gameserver.network.aion.serverpackets.SM_UPDATE_ITEM;
import com.aionemu.gameserver.utils.PacketSendUtility;
import com.google.inject.Inject;
/**
* @author Simple
*
*/
public class PrivateStoreService
{
@Inject
ItemService itemService;
/**
* @param activePlayer
* @param itemObjId
* @param itemId
* @param itemAmount
* @param itemPrice
*/
public void addItem(Player activePlayer, TradePSItem[] tradePSItems)
{
/**
* Check if player already has a store, if not create one
*/
if(activePlayer.getStore() == null)
createStore(activePlayer);
/**
* Define store to make things easier
*/
PrivateStore store = activePlayer.getStore();
/**
* Check if player owns itemObjId else don't add item
*/
for(int i = 0; i < tradePSItems.length; i++)
{
Item item = getItemByObjId(activePlayer, tradePSItems[i].getItemObjId());
if(item != null)
{
if(!validateItem(item, tradePSItems[i].getItemId(), tradePSItems[i].getCount()))
return;
/**
* Add item to private store
*/
store.addItemToSell(tradePSItems[i].getItemObjId(), tradePSItems[i]);
}
}
}
/**
* A check isn't really needed.....
*
* @return
*/
private boolean validateItem(Item item, int itemId, int itemAmount)
{
return !(item.getItemTemplate().getTemplateId() != itemId || itemAmount > item.getItemCount());
}
/**
* This method will create the player's store
*
* @param activePlayer
*/
private void createStore(Player activePlayer)
{
activePlayer.setStore(new PrivateStore(activePlayer));
activePlayer.setState(CreatureState.PRIVATE_SHOP);
PacketSendUtility.broadcastPacket(activePlayer, new SM_EMOTION(activePlayer, 28, 0, 0), true);
}
/**
* This method will destroy the player's store
*
* @param activePlayer
*/
public void closePrivateStore(Player activePlayer)
{
activePlayer.setStore(null);
activePlayer.unsetState(CreatureState.PRIVATE_SHOP);
PacketSendUtility.broadcastPacket(activePlayer, new SM_EMOTION(activePlayer, 29, 0, 0), true);
}
/**
* This method will move the item to the new player and move kinah to item owner
*/
public void sellStoreItem(Player seller, Player buyer, TradeList tradeList)
{
/**
* 1. Check if we are busy with two valid participants
*/
if(!validateParticipants(seller, buyer))
return;
/**
* Define store to make life easier
*/
PrivateStore store = seller.getStore();
/**
* 2. Load all item object id's and validate if seller really owns them
*/
tradeList = loadObjIds(seller, tradeList);
if(tradeList == null)
return; // Invalid items found or store was empty
/**
* 3. Check free slots
*/
Storage inventory = buyer.getInventory();
int freeSlots = inventory.getLimit() - inventory.getAllItems().size() + 1;
if(freeSlots < tradeList.size())
return; // TODO message
/**
* Create total price and items
*/
int price = getTotalPrice(store, tradeList);
/**
* Check if player has enough kinah and remove it
*/
if(getKinahAmount(buyer) > price)
{
/**
* Decrease kinah for buyer and Increase kinah for seller
*/
decreaseKinahAmount(buyer, price);
increaseKinahAmount(seller, price);
List<Item> newItems = new ArrayList<Item>();
for(TradeItem tradeItem : tradeList.getTradeItems())
{
Item item = getItemByObjId(seller, tradeItem.getItemId());
if(item != null)
{
TradePSItem storeItem = store.getTradeItemById(tradeItem.getItemId());
Set<ManaStone> manaStones = null;
if(item.hasManaStones())
manaStones = item.getItemStones();
GodStone godStone = item.getGodStone();
decreaseItemFromPlayer(seller, item, tradeItem);
itemService.addItemWithStones(buyer, item.getItemTemplate().getTemplateId(), tradeItem.getCount(), manaStones, godStone);
if(storeItem.getCount() == tradeItem.getCount())
store.removeItem(storeItem.getItemObjId());
}
}
/**
* Add item to buyer's inventory
*/
if(newItems.size() > 0)
PacketSendUtility.sendPacket(buyer, new SM_INVENTORY_UPDATE(newItems));
/**
* Remove item from store and check if last item
*/
if(store.getSoldItems().size() == 0)
closePrivateStore(seller);
return;
}
}
/**
* Decrease item count and update inventory
*
* @param seller
* @param item
*/
private void decreaseItemFromPlayer(Player seller, Item item, TradeItem tradeItem)
{
seller.getInventory().decreaseItemCount(item, tradeItem.getCount());
PacketSendUtility.sendPacket(seller, new SM_UPDATE_ITEM(item));
PrivateStore store = seller.getStore();
store.getTradeItemById(item.getObjectId()).decreaseCount(tradeItem.getCount());
}
/**
* @param seller
* @param tradeList
* @return
*/
private TradeList loadObjIds(Player seller, TradeList tradeList)
{
PrivateStore store = seller.getStore();
TradeList newTradeList = new TradeList();
for(TradeItem tradeItem : tradeList.getTradeItems())
{
int i = 0;
for(int itemObjId : store.getSoldItems().keySet())
{
if(i == tradeItem.getItemId())
newTradeList.addPSItem(itemObjId, tradeItem.getCount());
i++;
}
}
/**
* Check if player still owns items
*/
if(!validateBuyItems(seller, newTradeList))
return null;
return newTradeList;
}
/**
* @param player1
* @param player2
*/
private boolean validateParticipants(Player itemOwner, Player newOwner)
{
return itemOwner != null && newOwner != null && itemOwner.isOnline() && newOwner.isOnline();
}
/**
* @param tradeList
*/
private boolean validateBuyItems(Player seller, TradeList tradeList)
{
for(TradeItem tradeItem : tradeList.getTradeItems())
{
Item item = seller.getInventory().getItemByObjId(tradeItem.getItemId());
// 1) don't allow to sell fake items;
if(item == null)
return false;
}
return true;
}
/**
* This method will return the amount of kinah of a player
*
* @param newOwner
* @return
*/
private int getKinahAmount(Player player)
{
return player.getInventory().getKinahItem().getItemCount();
}
/**
* This method will decrease the kinah amount of a player
*
* @param player
* @param price
*/
private void decreaseKinahAmount(Player player, int price)
{
player.getInventory().decreaseKinah(price);
}
/**
* This method will increase the kinah amount of a player
*
* @param player
* @param price
*/
private void increaseKinahAmount(Player player, int price)
{
player.getInventory().increaseKinah(price);
}
/**
* This method will return the item in a inventory by object id
*
* @param player
* @param tradePSItems
* @return
*/
private Item getItemByObjId(Player seller, int itemObjId)
{
return seller.getInventory().getItemByObjId(itemObjId);
}
/**
* This method will return the total price of the tradelist
*
* @param store
* @param tradeList
* @return
*/
private int getTotalPrice(PrivateStore store, TradeList tradeList)
{
int totalprice = 0;
for(TradeItem tradeItem : tradeList.getTradeItems())
{
TradePSItem item = store.getTradeItemById(tradeItem.getItemId());
totalprice += item.getPrice() * tradeItem.getCount();
}
return totalprice;
}
/**
* @param activePlayer
*/
public void openPrivateStore(Player activePlayer, String name)
{
if(name != null)
{
activePlayer.getStore().setStoreMessage(name);
PacketSendUtility.broadcastPacket(activePlayer,
new SM_PRIVATE_STORE_NAME(activePlayer.getObjectId(), name), true);
}
else
{
PacketSendUtility.broadcastPacket(activePlayer, new SM_PRIVATE_STORE_NAME(activePlayer.getObjectId(), ""),
true);
}
}
}