/* $Id: Locker.cpp 182 2010-01-08 10:35:27Z sausage $
* EOSERV is released under the zlib license.
* See LICENSE.txt for more info.
*/
#include "handlers.h"
#include "npc.hpp"
#include "map.hpp"
static void add_common(PacketBuilder &reply, Character *character, short item, int amount)
{
character->DelItem(item, amount);
character->CalculateStats();
reply.SetID(PACKET_LOCKER, PACKET_REPLY);
reply.AddShort(item);
reply.AddInt(character->HasItem(item));
reply.AddChar(character->weight);
reply.AddChar(character->maxweight);
UTIL_PTR_LIST_FOREACH(character->bank, Character_Item, item)
{
reply.AddShort(item->id);
reply.AddThree(item->amount);
}
}
CLIENT_F_FUNC(Locker)
{
PacketBuilder reply;
switch (action)
{
case PACKET_ADD: // Placing an item in a bank locker
{
if (this->state < EOClient::Playing) return false;
unsigned char x = reader.GetChar();
unsigned char y = reader.GetChar();
short item = reader.GetShort();
int amount = reader.GetThree();
if (item == 1) return true;
if (amount <= 0) return true;
if (this->player->character->HasItem(item) < amount) return true;
std::size_t lockermax = static_cast<int>(this->server->world->config["BaseBankSize"]) + this->player->character->bankmax * static_cast<int>(this->server->world->config["BankSizeStep"]);
if (util::path_length(this->player->character->x, this->player->character->y, x, y) <= 1)
{
if (this->player->character->map->GetSpec(x, y) == Map_Tile::BankVault || (this->player->character->x == x && this->player->character->y == y))
{
UTIL_PTR_LIST_FOREACH(this->player->character->bank, Character_Item, it)
{
if (it->id == item)
{
if (it->amount + amount < 0)
{
return true;
}
amount = std::min<int>(amount, static_cast<int>(this->server->world->config["MaxBank"]) - it->amount);
it->amount += amount;
add_common(reply, this->player->character, item, amount);
CLIENT_SEND(reply);
return true;
}
}
if (this->player->character->bank.size() >= lockermax)
{
return true;
}
amount = std::min<int>(amount, static_cast<int>(this->server->world->config["MaxBank"]));
Character_Item *newitem(new Character_Item);
newitem->id = item;
newitem->amount = amount;
this->player->character->bank.push_back(newitem);
newitem->Release();
add_common(reply, this->player->character, item, amount);
CLIENT_SEND(reply);
}
}
}
break;
case PACKET_TAKE: // Taking an item from a bank locker
{
if (this->state < EOClient::Playing) return false;
unsigned char x = reader.GetChar();
unsigned char y = reader.GetChar();
short item = reader.GetShort();
if (util::path_length(this->player->character->x, this->player->character->y, x, y) <= 1)
{
if (this->player->character->map->GetSpec(x, y) == Map_Tile::BankVault || (this->player->character->x == x && this->player->character->y == y))
{
UTIL_PTR_LIST_FOREACH(this->player->character->bank, Character_Item, it)
{
if (it->id == item)
{
this->player->character->AddItem(item, it->amount);
this->player->character->CalculateStats();
reply.SetID(PACKET_LOCKER, PACKET_GET);
reply.AddShort(item);
reply.AddThree(it->amount);
reply.AddChar(this->player->character->weight);
reply.AddChar(this->player->character->maxweight);
this->player->character->bank.erase(it);
UTIL_PTR_LIST_FOREACH(this->player->character->bank, Character_Item, item)
{
reply.AddShort(item->id);
reply.AddThree(item->amount);
}
CLIENT_SEND(reply);
break;
}
}
}
}
}
break;
case PACKET_OPEN: // Opening a bank locker
{
if (this->state < EOClient::Playing) return false;
unsigned char x = reader.GetChar();
unsigned char y = reader.GetChar();
if (util::path_length(this->player->character->x, this->player->character->y, x, y) <= 1)
{
if (this->player->character->map->GetSpec(x, y) == Map_Tile::BankVault || (this->player->character->x == x && this->player->character->y == y))
{
reply.SetID(PACKET_LOCKER, PACKET_OPEN);
reply.AddChar(x);
reply.AddChar(y);
UTIL_PTR_LIST_FOREACH(this->player->character->bank, Character_Item, item)
{
reply.AddShort(item->id);
reply.AddThree(item->amount);
}
CLIENT_SEND(reply);
}
}
}
break;
case PACKET_BUY: // Purchasing a locker space upgrade
{
if (this->state < EOClient::Playing) return false;
if (this->player->character->npc_type == ENF::Bank)
{
int cost = static_cast<int>(this->server->world->config["BankUpgradeBase"]) + this->player->character->bankmax * static_cast<int>(this->server->world->config["BankUpgradeStep"]);
if (this->player->character->bankmax >= static_cast<int>(this->server->world->config["MaxBankUpgrades"]))
{
return true;
}
if (this->player->character->HasItem(1) < cost)
{
return true;
}
++this->player->character->bankmax;
this->player->character->DelItem(1, cost);
reply.SetID(PACKET_LOCKER, PACKET_BUY);
reply.AddInt(this->player->character->HasItem(1));
reply.AddChar(this->player->character->bankmax);
CLIENT_SEND(reply);
}
}
break;
default:
return false;
}
return true;
}