/*
OrpheusMS: MapleStory Private Server based on OdinMS
Copyright (C) 2012 Aaron Weiss <aaron@deviant-core.net>
Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package server;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import client.IItem;
import client.MapleCharacter;
import client.MapleClient;
import net.MaplePacket;
import net.SendOpcode;
import server.maps.AbstractMapleMapObject;
import server.maps.MapleMapObjectType;
import tools.MaplePacketCreator;
import tools.data.output.MaplePacketLittleEndianWriter;
/**
*
* @author Matze
*/
public class MaplePlayerShop extends AbstractMapleMapObject {
private MapleCharacter owner;
private MapleCharacter[] visitors = new MapleCharacter[3];
private List<MaplePlayerShopItem> items = new ArrayList<MaplePlayerShopItem>();
private MapleCharacter[] slot = {null, null, null};
private String description;
private int boughtnumber = 0;
private List<String> bannedList = new ArrayList<String>();
public MaplePlayerShop(MapleCharacter owner, String description) {
this.setPosition(owner.getPosition());
this.owner = owner;
this.description = description;
}
public boolean hasFreeSlot() {
return visitors[0] == null || visitors[1] == null || visitors[2] == null;
}
public boolean isOwner(MapleCharacter c) {
return owner.equals(c);
}
public void addVisitor(MapleCharacter visitor) {
for (int i = 0; i < 3; i++) {
if (visitors[i] == null) {
visitors[i] = visitor;
if (this.getSlot(0) == null) {
this.setSlot(visitor, 0);
this.broadcast(MaplePacketCreator.getPlayerShopNewVisitor(visitor, 1));
} else if (this.getSlot(1) == null) {
this.setSlot(visitor, 1);
this.broadcast(MaplePacketCreator.getPlayerShopNewVisitor(visitor, 2));
} else if (this.getSlot(2) == null) {
this.setSlot(visitor, 2);
this.broadcast(MaplePacketCreator.getPlayerShopNewVisitor(visitor, 3));
visitor.getMap().broadcastMessage(MaplePacketCreator.addCharBox(this.getOwner(), 1));
}
break;
}
}
}
public void removeVisitor(MapleCharacter visitor) {
if (visitor == owner) {
owner.getMap().removeMapObject(this);
owner.setPlayerShop(null);
}
for (int i = 0; i < 3; i++) {
if (visitors[i] != null && visitors[i].getId() == visitor.getId()) {
int slot_ = visitor.getSlot();
visitors[i] = null;
this.setSlot(null, i);
visitor.setSlot(-1);
this.broadcast(MaplePacketCreator.getPlayerShopRemoveVisitor(slot_ + 1));
return;
}
}
}
public boolean isVisitor(MapleCharacter visitor) {
return visitors[0] == visitor || visitors[1] == visitor || visitors[2] == visitor;
}
public void addItem(MaplePlayerShopItem item) {
items.add(item);
}
public void removeItem(int item) {
items.remove(item);
}
/**
* no warnings for now o.op
*
* @param c
* @param item
* @param quantity
*/
public void buy(MapleClient c, int item, short quantity) {
if (isVisitor(c.getPlayer())) {
MaplePlayerShopItem pItem = items.get(item);
IItem newItem = pItem.getItem().copy();
newItem.setQuantity(newItem.getQuantity());
if (quantity < 1 || pItem.getBundles() < 1 || newItem.getQuantity() > pItem.getBundles() || !pItem.isExist()) {
return;
} else if (newItem.getType() == 1 && newItem.getQuantity() > 1) {
return;
}
synchronized (c.getPlayer()) {
if (c.getPlayer().getMeso() >= (long) pItem.getPrice() * quantity) {
if (MapleInventoryManipulator.addFromDrop(c, newItem, false)) {
c.getPlayer().gainMeso(-pItem.getPrice() * quantity, true);
owner.gainMeso(pItem.getPrice() * quantity, true);
pItem.setBundles((short) (pItem.getBundles() - quantity));
if (pItem.getBundles() < 1) {
pItem.setDoesExist(false);
if (++boughtnumber == items.size()) {
owner.setPlayerShop(null);
owner.getMap().broadcastMessage(MaplePacketCreator.removeCharBox(owner));
this.removeVisitors();
owner.dropMessage(1, "Your items are sold out, and therefore your shop is closed.");
}
}
} else {
c.getPlayer().dropMessage(1, "Your inventory is full. Please clean a slot before buying this item.");
}
}
}
}
}
public void broadcastToVisitors(MaplePacket packet) {
for (int i = 0; i < 3; i++) {
if (visitors[i] != null) {
visitors[i].getClient().getSession().write(packet);
}
}
}
public void removeVisitors() {
try {
for (int i = 0; i < 3; i++) {
if (visitors[i] != null) {
visitors[i].getClient().getSession().write(MaplePacketCreator.shopErrorMessage(10, 1));
removeVisitor(visitors[i]);
}
}
} catch (Exception e) {
e.printStackTrace();
}
if (owner != null) {
removeVisitor(getOwner());
}
}
public static MaplePacket shopErrorMessage(int error, int type) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendOpcode.PLAYER_INTERACTION.getValue());
mplew.write(0x0A);
mplew.write(type);
mplew.write(error);
return mplew.getPacket();
}
public void broadcast(MaplePacket packet) {
if (owner.getClient() != null && owner.getClient().getSession() != null) {
owner.getClient().getSession().write(packet);
}
broadcastToVisitors(packet);
}
public void chat(MapleClient c, String chat) {
byte s = 0;
for (MapleCharacter mc : getVisitors()) {
s++;
if (mc != null) {
if (mc.getName().equalsIgnoreCase(c.getPlayer().getName())) {
break;
}
} else if (s == 3) {
s = 0;
}
}
broadcast(MaplePacketCreator.getPlayerShopChat(c.getPlayer(), chat, s));
}
public void sendShop(MapleClient c) {
c.getSession().write(MaplePacketCreator.getPlayerShop(c, this, isOwner(c.getPlayer())));
}
public MapleCharacter getOwner() {
return owner;
}
public MapleCharacter[] getVisitors() {
return visitors;
}
public MapleCharacter getSlot(int s) {
return slot[s];
}
private void setSlot(MapleCharacter person, int s) {
slot[s] = person;
if (person != null) {
person.setSlot(s);
}
}
public List<MaplePlayerShopItem> getItems() {
return Collections.unmodifiableList(items);
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@SuppressWarnings("unused")
public void banPlayer(String name) {
if (!bannedList.contains(name)) {
bannedList.add(name);
}
for (int i = 0; i < 3; i++) {
if (visitors[i] != null && visitors[i].getName().equals(name)) {
visitors[i].getClient().getSession().write(MaplePacketCreator.shopErrorMessage(5, 1));
removeVisitor(visitors[i]);
}
return;
}
}
public boolean isBanned(String name) {
return bannedList.contains(name);
}
@Override
public void sendDestroyData(MapleClient client) {
client.getSession().write(MaplePacketCreator.removeCharBox(this.getOwner()));
}
@Override
public void sendSpawnData(MapleClient client) {
client.getSession().write(MaplePacketCreator.addCharBox(this.getOwner(), 4));
}
@Override
public MapleMapObjectType getType() {
return MapleMapObjectType.SHOP;
}
}