/*
* The ManaPlus Client
* Copyright (C) 2011-2020 The ManaPlus Developers
* Copyright (C) 2020-2023 The ManaVerse Developers
*
* This file is part of The ManaPlus Client.
*
* This program 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 2 of the License, or
* 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 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 .
*/
#include "net/eathena/buyingstorerecv.h"
#include "actormanager.h"
#include "notifymanager.h"
#include "being/localplayer.h"
#include "being/playerinfo.h"
#include "const/net/inventory.h"
#include "enums/resources/notifytypes.h"
#include "gui/windows/buyingstoreselldialog.h"
#include "gui/widgets/createwidget.h"
#include "listeners/arrowslistener.h"
#include "listeners/buyingstoremodelistener.h"
#include "listeners/buyingstoreslotslistener.h"
#include "net/messagein.h"
#include "resources/inventory/inventory.h"
#include "resources/item/item.h"
#include "debug.h"
extern int itemIdLen;
namespace EAthena
{
void BuyingStoreRecv::processBuyingStoreOpen(Net::MessageIn &msg)
{
BuyingStoreSlotsListener::distributeEvent(msg.readUInt8("slots"));
}
void BuyingStoreRecv::processBuyingStoreCreateFailed(Net::MessageIn &msg)
{
const int16_t result = msg.readInt16("result");
const int weight = msg.readInt32("weight");
switch (result)
{
case 1:
default:
NotifyManager::notify(NotifyTypes::BUYING_STORE_CREATE_FAILED);
break;
case 2:
NotifyManager::notify(
NotifyTypes::BUYING_STORE_CREATE_FAILED_WEIGHT,
weight);
break;
case 8:
NotifyManager::notify(NotifyTypes::BUYING_STORE_CREATE_EMPTY);
break;
}
}
void BuyingStoreRecv::processBuyingStoreOwnItems(Net::MessageIn &msg)
{
const int count = (msg.readInt16("len") - 12) / (7 + itemIdLen);
msg.readBeingId("account id");
msg.readInt32("money limit");
for (int f = 0; f < count; f ++)
{
msg.readInt32("price");
msg.readInt16("amount");
msg.readUInt8("item type");
msg.readItemId("item id");
}
PlayerInfo::enableVending(true);
BuyingStoreModeListener::distributeEvent(true);
}
void BuyingStoreRecv::processBuyingStoreShowBoard(Net::MessageIn &msg)
{
if (actorManager == nullptr)
return;
const BeingId id = msg.readBeingId("owner id");
Being *const dstBeing = actorManager->findBeing(id);
if (dstBeing != nullptr)
{
dstBeing->setBuyBoard(msg.readString(80, "shop name"));
}
else
{
msg.readString(80, "shop name");
}
}
void BuyingStoreRecv::processBuyingStoreHideBoard(Net::MessageIn &msg)
{
if (actorManager == nullptr)
return;
const BeingId id = msg.readBeingId("owner id");
Being *const dstBeing = actorManager->findBeing(id);
if (dstBeing != nullptr)
dstBeing->setBuyBoard(std::string());
if (dstBeing == localPlayer)
{
PlayerInfo::enableVending(false);
BuyingStoreModeListener::distributeEvent(false);
}
}
void BuyingStoreRecv::processBuyingStoreItemsList(Net::MessageIn &msg)
{
if (actorManager == nullptr)
return;
const int count = (msg.readInt16("len") - 16) / (7 + itemIdLen);
const BeingId id = msg.readBeingId("account id");
const int storeId = msg.readInt32("store id");
// +++ in future need use it too
msg.readInt32("money limit");
const Being *const dstBeing = actorManager->findBeing(id);
if (dstBeing == nullptr)
return;
SellDialog *const dialog = CREATEWIDGETR(BuyingStoreSellDialog,
dstBeing->getId(),
storeId);
dialog->setMoney(PlayerInfo::getAttribute(Attributes::MONEY));
const Inventory *const inv = PlayerInfo::getInventory();
for (int f = 0; f < count; f ++)
{
const int price = msg.readInt32("price");
const int amount = msg.readInt16("amount");
const ItemTypeT itemType = static_cast(
msg.readUInt8("item type"));
const int itemId = msg.readItemId("item id");
if (inv == nullptr)
continue;
const Item *const item = inv->findItem(itemId, ItemColor_one);
if (item == nullptr)
continue;
// +++ need add colors support
dialog->addItem(itemId, itemType, ItemColor_one, amount, price);
}
}
void BuyingStoreRecv::processBuyingStoreSellFailed(Net::MessageIn &msg)
{
const int16_t result = msg.readInt16("result");
switch (result)
{
case 3:
NotifyManager::notify(
NotifyTypes::BUYING_STORE_SELL_FAILED_MONEY_LIMIT);
break;
case 4:
NotifyManager::notify(NotifyTypes::BUYING_STORE_SELL_FAILED_EMPTY);
break;
default:
NotifyManager::notify(NotifyTypes::BUYING_STORE_SELL_FAILED);
break;
}
}
void BuyingStoreRecv::processBuyingStoreSellerSellFailed(Net::MessageIn &msg)
{
const int16_t result = msg.readInt16("result");
msg.readItemId("item id");
switch (result)
{
case 5:
NotifyManager::notify(
NotifyTypes::BUYING_STORE_SELLER_SELL_FAILED_DEAL);
break;
case 6:
NotifyManager::notify(
NotifyTypes::BUYING_STORE_SELLER_SELL_FAILED_AMOUNT);
break;
case 7:
NotifyManager::notify(
NotifyTypes::BUYING_STORE_SELLER_SELL_FAILED_BALANCE);
break;
default:
NotifyManager::notify(
NotifyTypes::BUYING_STORE_SELLER_SELL_FAILED);
break;
}
}
void BuyingStoreRecv::processBuyingStoreReport(Net::MessageIn &msg)
{
UNIMPLEMENTEDPACKET;
msg.readItemId("item id");
msg.readInt16("amount");
if (msg.getVersion() >= 20141016)
{
msg.readInt32("money");
msg.readInt32("money limit");
msg.readInt32("char id");
msg.readInt32("date");
}
else
{
msg.readInt32("money limit");
}
}
void BuyingStoreRecv::processBuyingStoreDeleteItem(Net::MessageIn &msg)
{
Inventory *const inventory = localPlayer != nullptr
? PlayerInfo::getInventory() : nullptr;
const int index = msg.readInt16("index") - INVENTORY_OFFSET;
const int amount = msg.readInt16("amount");
msg.readInt32("price");
if (inventory != nullptr)
{
if (Item *const item = inventory->getItem(index))
{
item->increaseQuantity(-amount);
if (item->getQuantity() == 0)
inventory->removeItemAt(index);
ArrowsListener::distributeEvent();
}
}
}
} // namespace EAthena