Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- #include "../../libgame/include/grid.h"
- #include "constants.h"
- #include "utils.h"
- #include "config.h"
- #include "shop.h"
- #include "desc.h"
- #include "desc_manager.h"
- #include "char.h"
- #include "char_manager.h"
- #include "item.h"
- #include "item_manager.h"
- #include "buffer_manager.h"
- #include "packet.h"
- #include "log.h"
- #include "db.h"
- #include "questmanager.h"
- #include "monarch.h"
- #include "mob_manager.h"
- #include "locale_service.h"
- /* ------------------------------------------------------------------------------------ */
- CShop::CShop()
- : m_dwVnum(0), m_dwNPCVnum(0), m_pkPC(NULL)
- {
- m_pGrid = M2_NEW CGrid(10, 9);
- }
- CShop::~CShop()
- {
- TPacketGCShop pack;
- pack.header = HEADER_GC_SHOP;
- pack.subheader = SHOP_SUBHEADER_GC_END;
- pack.size = sizeof(TPacketGCShop);
- Broadcast(&pack, sizeof(pack));
- GuestMapType::iterator it;
- it = m_map_guest.begin();
- while (it != m_map_guest.end())
- {
- LPCHARACTER ch = it->first;
- ch->SetShop(NULL);
- ++it;
- }
- M2_DELETE(m_pGrid);
- }
- void CShop::SetPCShop(LPCHARACTER ch)
- {
- m_pkPC = ch;
- }
- bool CShop::Create(DWORD dwVnum, DWORD dwNPCVnum, TShopItemTable * pTable)
- {
- /*
- if (NULL == CMobManager::instance().Get(dwNPCVnum))
- {
- sys_err("No such a npc by vnum %d", dwNPCVnum);
- return false;
- }
- */
- sys_log(0, "SHOP #%d (Shopkeeper %d)", dwVnum, dwNPCVnum);
- m_dwVnum = dwVnum;
- m_dwNPCVnum = dwNPCVnum;
- BYTE bItemCount;
- for (bItemCount = 0; bItemCount < SHOP_HOST_ITEM_MAX_NUM; ++bItemCount)
- if (0 == (pTable + bItemCount)->vnum)
- break;
- SetShopItems(pTable, bItemCount);
- return true;
- }
- void CShop::SetShopItems(TShopItemTable * pTable, BYTE bItemCount)
- {
- if (bItemCount > SHOP_HOST_ITEM_MAX_NUM)
- return;
- m_pGrid->Clear();
- m_itemVector.resize(SHOP_HOST_ITEM_MAX_NUM);
- memset(&m_itemVector[0], 0, sizeof(SHOP_ITEM) * m_itemVector.size());
- for (int i = 0; i < bItemCount; ++i)
- {
- LPITEM pkItem = NULL;
- const TItemTable * item_table;
- if (m_pkPC)
- {
- pkItem = m_pkPC->GetItem(pTable->pos);
- if (!pkItem)
- {
- sys_err("cannot find item on pos (%d, %d) (name: %s)", pTable->pos.window_type, pTable->pos.cell, m_pkPC->GetName());
- continue;
- }
- item_table = pkItem->GetProto();
- }
- else
- {
- if (!pTable->vnum)
- continue;
- item_table = ITEM_MANAGER::instance().GetTable(pTable->vnum);
- }
- if (!item_table)
- {
- sys_err("Shop: no item table by item vnum #%d", pTable->vnum);
- continue;
- }
- int iPos;
- if (IsPCShop())
- {
- sys_log(0, "MyShop: use position %d", pTable->display_pos);
- iPos = pTable->display_pos;
- }
- else
- iPos = m_pGrid->FindBlank(1, item_table->bSize);
- if (iPos < 0)
- {
- sys_err("not enough shop window");
- continue;
- }
- if (!m_pGrid->IsEmpty(iPos, 1, item_table->bSize))
- {
- if (IsPCShop())
- {
- sys_err("not empty position for pc shop %s[%d]", m_pkPC->GetName(), m_pkPC->GetPlayerID());
- }
- else
- {
- sys_err("not empty position for npc shop");
- }
- continue;
- }
- m_pGrid->Put(iPos, 1, item_table->bSize);
- SHOP_ITEM & item = m_itemVector[iPos];
- item.pkItem = pkItem;
- item.itemid = 0;
- if (item.pkItem)
- {
- item.vnum = pkItem->GetVnum();
- item.count = pkItem->GetCount(); // PC ¼¥ÀÇ °æ¿ì ¾ÆÀÌÅÛ °³¼ö´Â ÁøÂ¥ ¾ÆÀÌÅÛÀÇ °³¼ö¿©¾ß ÇÑ´Ù.
- item.price = pTable->price; // °¡°Ýµµ »ç¿ëÀÚ°¡ Á¤ÇÑ´ë·Î..
- item.itemid = pkItem->GetID();
- }
- else
- {
- item.vnum = pTable->vnum;
- item.count = pTable->count;
- if (IS_SET(item_table->dwFlags, ITEM_FLAG_COUNT_PER_1GOLD))
- {
- if (item_table->dwGold == 0)
- item.price = item.count;
- else
- item.price = item.count / item_table->dwGold;
- }
- else
- item.price = item_table->dwGold * item.count;
- }
- char name[36];
- snprintf(name, sizeof(name), "%-20s(#%-5d) (x %d)", item_table->szName, (int) item.vnum, item.count);
- sys_log(0, "SHOP_ITEM: %-36s PRICE %-5d", name, item.price);
- ++pTable;
- }
- }
- long long CShop::Buy(LPCHARACTER ch, BYTE pos)
- {
- if (pos >= m_itemVector.size())
- {
- sys_log(0, "Shop::Buy : invalid position %d : %s", pos, ch->GetName());
- return SHOP_SUBHEADER_GC_INVALID_POS;
- }
- sys_log(0, "Shop::Buy : name %s pos %d", ch->GetName(), pos);
- GuestMapType::iterator it = m_map_guest.find(ch);
- if (it == m_map_guest.end())
- return SHOP_SUBHEADER_GC_END;
- SHOP_ITEM& r_item = m_itemVector[pos];
- if (r_item.price < 0)
- {
- LogManager::instance().HackLog("SHOP_BUY_GOLD_OVERFLOW", ch);
- return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY;
- }
- LPITEM pkSelectedItem = ITEM_MANAGER::instance().Find(r_item.itemid);
- if (IsPCShop())
- {
- if (!pkSelectedItem)
- {
- sys_log(0, "Shop::Buy : Critical: This user seems to be a hacker : invalid pcshop item : BuyerPID:%d SellerPID:%d",
- ch->GetPlayerID(),
- m_pkPC->GetPlayerID());
- return false;
- }
- if ((pkSelectedItem->GetOwner() != m_pkPC))
- {
- sys_log(0, "Shop::Buy : Critical: This user seems to be a hacker : invalid pcshop item : BuyerPID:%d SellerPID:%d",
- ch->GetPlayerID(),
- m_pkPC->GetPlayerID());
- return false;
- }
- }
- long long dwPrice = r_item.price;
- if (it->second) // if other empire, price is triple
- dwPrice *= 1;
- if (ch->GetGold() < (long long) dwPrice)
- {
- sys_log(1, "Shop::Buy : Not enough money : %s has %lld, price %lld", ch->GetName(), ch->GetGold(), dwPrice);
- return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY;
- }
- LPITEM item;
- if (m_pkPC) // ÇǾ¾°¡ ¿î¿µÇÏ´Â ¼¥Àº ÇǾ¾°¡ ½ÇÁ¦ ¾ÆÀÌÅÛÀ» °¡Áö°íÀÖ¾î¾ß ÇÑ´Ù.
- item = r_item.pkItem;
- else
- item = ITEM_MANAGER::instance().CreateItem(r_item.vnum, r_item.count);
- if (!item)
- return SHOP_SUBHEADER_GC_SOLD_OUT;
- int iEmptyPos;
- if (item->IsDragonSoul())
- {
- iEmptyPos = ch->GetEmptyDragonSoulInventory(item);
- }
- else
- {
- iEmptyPos = ch->GetEmptyInventory(item->GetSize());
- }
- if (iEmptyPos < 0)
- {
- if (m_pkPC)
- {
- sys_log(1, "Shop::Buy at PC Shop : Inventory full : %s size %d", ch->GetName(), item->GetSize());
- return SHOP_SUBHEADER_GC_INVENTORY_FULL;
- }
- else
- {
- sys_log(1, "Shop::Buy : Inventory full : %s size %d", ch->GetName(), item->GetSize());
- M2_DESTROY_ITEM(item);
- return SHOP_SUBHEADER_GC_INVENTORY_FULL;
- }
- }
- ch->PointChange(POINT_GOLD, -dwPrice, false);
- //¼¼±Ý °è»ê
- DWORD dwTax = 0;
- int iVal = 0;
- if (LC_IsYMIR() || LC_IsKorea())
- {
- if (0 < (iVal = quest::CQuestManager::instance().GetEventFlag("trade_tax")))
- {
- if (iVal > 100)
- iVal = 100;
- dwTax = dwPrice * iVal / 100;
- dwPrice = dwPrice - dwTax;
- }
- else
- {
- iVal = 0;
- dwTax = dwPrice * iVal / 100;
- dwPrice = dwPrice - dwTax;
- }
- }
- else
- {
- iVal = quest::CQuestManager::instance().GetEventFlag("personal_shop");
- if (0 < iVal)
- {
- if (iVal > 100)
- iVal = 100;
- dwTax = dwPrice * iVal / 100;
- dwPrice = dwPrice - dwTax;
- }
- else
- {
- iVal = 0;
- dwTax = 0;
- }
- }
- // »óÁ¡¿¡¼ »ì‹š ¼¼±Ý 5%
- if (!m_pkPC)
- {
- CMonarch::instance().SendtoDBAddMoney(dwTax, ch->GetEmpire(), ch);
- }
- // ±ºÁÖ ½Ã½ºÅÛ : ¼¼±Ý ¡¼ö
- if (m_pkPC)
- {
- m_pkPC->SyncQuickslot(QUICKSLOT_TYPE_ITEM, item->GetCell(), 255);
- if (item->GetVnum() == 90008 || item->GetVnum() == 90009) // VCARD
- {
- VCardUse(m_pkPC, ch, item);
- item = NULL;
- }
- else
- {
- char buf[512];
- if (item->GetVnum() >= 80003 && item->GetVnum() <= 80007)
- {
- snprintf(buf, sizeof(buf), "%s FROM: %u TO: %u PRICE: %u", item->GetName(), ch->GetPlayerID(), m_pkPC->GetPlayerID(), dwPrice);
- LogManager::instance().GoldBarLog(ch->GetPlayerID(), item->GetID(), SHOP_BUY, buf);
- LogManager::instance().GoldBarLog(m_pkPC->GetPlayerID(), item->GetID(), SHOP_SELL, buf);
- }
- item->RemoveFromCharacter();
- if (item->IsDragonSoul())
- item->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
- else
- item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
- ITEM_MANAGER::instance().FlushDelayedSave(item);
- snprintf(buf, sizeof(buf), "%s %u(%s) %u %u", item->GetName(), m_pkPC->GetPlayerID(), m_pkPC->GetName(), dwPrice, item->GetCount());
- LogManager::instance().ItemLog(ch, item, "SHOP_BUY", buf);
- snprintf(buf, sizeof(buf), "%s %u(%s) %u %u", item->GetName(), ch->GetPlayerID(), ch->GetName(), dwPrice, item->GetCount());
- LogManager::instance().ItemLog(m_pkPC, item, "SHOP_SELL", buf);
- }
- r_item.pkItem = NULL;
- BroadcastUpdateItem(pos);
- m_pkPC->PointChange(POINT_GOLD, dwPrice, false);
- if (iVal > 0)
- m_pkPC->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("ÆǸűݾ×ÀÇ %d %% °¡ ¼¼±ÝÀ¸·Î ³ª°¡°ÔµË´Ï´Ù"), iVal);
- CMonarch::instance().SendtoDBAddMoney(dwTax, m_pkPC->GetEmpire(), m_pkPC);
- }
- else
- {
- if (item->IsDragonSoul())
- item->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
- else
- item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
- ITEM_MANAGER::instance().FlushDelayedSave(item);
- LogManager::instance().ItemLog(ch, item, "BUY", item->GetName());
- if (item->GetVnum() >= 80003 && item->GetVnum() <= 80007)
- {
- LogManager::instance().GoldBarLog(ch->GetPlayerID(), item->GetID(), PERSONAL_SHOP_BUY, "");
- }
- DBManager::instance().SendMoneyLog(MONEY_LOG_SHOP, item->GetVnum(), -dwPrice);
- }
- if (item)
- sys_log(0, "SHOP: BUY: name %s %s(x %d):%u price %u", ch->GetName(), item->GetName(), item->GetCount(), item->GetID(), dwPrice);
- ch->Save();
- return (SHOP_SUBHEADER_GC_OK);
- }
- bool CShop::AddGuest(LPCHARACTER ch, DWORD owner_vid, bool bOtherEmpire)
- {
- if (!ch)
- return false;
- if (ch->GetExchange())
- return false;
- if (ch->GetShop())
- return false;
- ch->SetShop(this);
- m_map_guest.insert(GuestMapType::value_type(ch, bOtherEmpire));
- TPacketGCShop pack;
- pack.header = HEADER_GC_SHOP;
- pack.subheader = SHOP_SUBHEADER_GC_START;
- TPacketGCShopStart pack2;
- memset(&pack2, 0, sizeof(pack2));
- pack2.owner_vid = owner_vid;
- for (DWORD i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i)
- {
- const SHOP_ITEM & item = m_itemVector[i];
- if (m_pkPC && !item.pkItem)
- continue;
- pack2.items[i].vnum = item.vnum;
- if (bOtherEmpire) // no empire price penalty for pc shop
- pack2.items[i].price = item.price * 1;
- else
- pack2.items[i].price = item.price;
- pack2.items[i].count = item.count;
- if (item.pkItem)
- {
- thecore_memcpy(pack2.items[i].alSockets, item.pkItem->GetSockets(), sizeof(pack2.items[i].alSockets));
- thecore_memcpy(pack2.items[i].aAttr, item.pkItem->GetAttributes(), sizeof(pack2.items[i].aAttr));
- }
- }
- pack.size = sizeof(pack) + sizeof(pack2);
- ch->GetDesc()->BufferedPacket(&pack, sizeof(TPacketGCShop));
- ch->GetDesc()->Packet(&pack2, sizeof(TPacketGCShopStart));
- return true;
- }
- void CShop::RemoveGuest(LPCHARACTER ch)
- {
- if (ch->GetShop() != this)
- return;
- m_map_guest.erase(ch);
- ch->SetShop(NULL);
- TPacketGCShop pack;
- pack.header = HEADER_GC_SHOP;
- pack.subheader = SHOP_SUBHEADER_GC_END;
- pack.size = sizeof(TPacketGCShop);
- ch->GetDesc()->Packet(&pack, sizeof(pack));
- }
- void CShop::Broadcast(const void * data, int bytes)
- {
- sys_log(1, "Shop::Broadcast %p %d", data, bytes);
- GuestMapType::iterator it;
- it = m_map_guest.begin();
- while (it != m_map_guest.end())
- {
- LPCHARACTER ch = it->first;
- if (ch->GetDesc())
- ch->GetDesc()->Packet(data, bytes);
- ++it;
- }
- }
- void CShop::BroadcastUpdateItem(BYTE pos)
- {
- TPacketGCShop pack;
- TPacketGCShopUpdateItem pack2;
- TEMP_BUFFER buf;
- pack.header = HEADER_GC_SHOP;
- pack.subheader = SHOP_SUBHEADER_GC_UPDATE_ITEM;
- pack.size = sizeof(pack) + sizeof(pack2);
- pack2.pos = pos;
- if (m_pkPC && !m_itemVector[pos].pkItem)
- pack2.item.vnum = 0;
- else
- {
- pack2.item.vnum = m_itemVector[pos].vnum;
- if (m_itemVector[pos].pkItem)
- {
- thecore_memcpy(pack2.item.alSockets, m_itemVector[pos].pkItem->GetSockets(), sizeof(pack2.item.alSockets));
- thecore_memcpy(pack2.item.aAttr, m_itemVector[pos].pkItem->GetAttributes(), sizeof(pack2.item.aAttr));
- }
- else
- {
- memset(pack2.item.alSockets, 0, sizeof(pack2.item.alSockets));
- memset(pack2.item.aAttr, 0, sizeof(pack2.item.aAttr));
- }
- }
- pack2.item.price = m_itemVector[pos].price;
- pack2.item.count = m_itemVector[pos].count;
- buf.write(&pack, sizeof(pack));
- buf.write(&pack2, sizeof(pack2));
- Broadcast(buf.read_peek(), buf.size());
- }
- int CShop::GetNumberByVnum(DWORD dwVnum)
- {
- int itemNumber = 0;
- for (DWORD i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i)
- {
- const SHOP_ITEM & item = m_itemVector[i];
- if (item.vnum == dwVnum)
- {
- itemNumber += item.count;
- }
- }
- return itemNumber;
- }
- bool CShop::IsSellingItem(DWORD itemID)
- {
- bool isSelling = false;
- for (DWORD i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i)
- {
- if (m_itemVector[i].itemid == itemID)
- {
- isSelling = true;
- break;
- }
- }
- return isSelling;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement