From f55cc8f36df0202cf395e7442bf355a2ac354f3e Mon Sep 17 00:00:00 2001 From: Gent Date: Sun, 13 Sep 2020 18:54:47 -0400 Subject: [PATCH] Load vendor tables --- src/ItemManager.cpp | 2 ++ src/ItemManager.hpp | 9 +++++- src/NPCManager.cpp | 67 +++++++++++++++------------------------------ src/TableData.cpp | 11 ++++++++ 4 files changed, 43 insertions(+), 46 deletions(-) diff --git a/src/ItemManager.cpp b/src/ItemManager.cpp index fff60df..05e6696 100644 --- a/src/ItemManager.cpp +++ b/src/ItemManager.cpp @@ -7,6 +7,8 @@ #include // for memset() and memcmp() #include +std::map> ItemManager::VendorTables; + void ItemManager::init() { REGISTER_SHARD_PACKET(P_CL2FE_REQ_ITEM_MOVE, itemMoveHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_ITEM_DELETE, itemDeleteHandler); diff --git a/src/ItemManager.hpp b/src/ItemManager.hpp index cd7a302..66c9545 100644 --- a/src/ItemManager.hpp +++ b/src/ItemManager.hpp @@ -3,13 +3,20 @@ #include "CNShardServer.hpp" #include "Player.hpp" +struct VendorListing { + int sort, type, iID, price; +}; + namespace ItemManager { enum class SlotType { EQUIP = 0, INVENTORY = 1, BANK = 3 }; - void init(); + // hopefully this is fine since it's never modified after load + extern std::map> VendorTables; + + void init(); void itemMoveHandler(CNSocket* sock, CNPacketData* data); void itemDeleteHandler(CNSocket* sock, CNPacketData* data); diff --git a/src/NPCManager.cpp b/src/NPCManager.cpp index d1e7f76..d1876ab 100644 --- a/src/NPCManager.cpp +++ b/src/NPCManager.cpp @@ -102,56 +102,33 @@ void NPCManager::npcVendorTable(CNSocket* sock, CNPacketData* data) { if (data->size != sizeof(sP_CL2FE_REQ_PC_VENDOR_TABLE_UPDATE)) return; // malformed packet - //sP_CL2FE_REQ_PC_VENDOR_TABLE_UPDATE* req = (sP_CL2FE_REQ_PC_VENDOR_TABLE_UPDATE*)data->buf; + sP_CL2FE_REQ_PC_VENDOR_TABLE_UPDATE* req = (sP_CL2FE_REQ_PC_VENDOR_TABLE_UPDATE*)data->buf; + + if (req->iVendorID != req->iNPC_ID || ItemManager::VendorTables.find(req->iNPC_ID) == ItemManager::VendorTables.end()) + return; + + std::vector listings = ItemManager::VendorTables[req->iNPC_ID]; // maybe use iVendorID instead...? + INITSTRUCT(sP_FE2CL_REP_PC_VENDOR_TABLE_UPDATE_SUCC, resp); - // TODO: data needs to be read from shopkeeper tabledata - // check req->iVendorID and req->iNPC_ID - // Exaple Items - // shirt - sItemBase base1; - base1.iID = 60; - base1.iOpt = 0; - // expire date - base1.iTimeLimit = 0; - base1.iType = 1; + for (int i = 0; i < 20; i++) { // 20 is the max - sItemVendor item1; - item1.item = base1; - item1.iSortNum = 0; - item1.iVendorID = 1; - // cost amount in float? (doesn't work rn, need to figure out) - item1.fBuyCost = 100.0; + if (i < listings.size()) { // check to make sure listing exists first + sItemBase base; + base.iID = listings[i].iID; + base.iOpt = 0; + base.iTimeLimit = 0; + base.iType = listings[i].type; - // pants - sItemBase base2; - base2.iID = 61; - base2.iOpt = 0; - base2.iTimeLimit = 0; - base2.iType = 2; + sItemVendor vItem; + vItem.item = base; + vItem.iSortNum = listings[i].sort; + vItem.iVendorID = req->iVendorID; + vItem.fBuyCost = listings[i].price; - sItemVendor item2; - item2.item = base2; - item2.iSortNum = 1; - item2.iVendorID = 1; - item2.fBuyCost = 250.0; - - // shoes - sItemBase base3; - base3.iID = 51; - base3.iOpt = 0; - base3.iTimeLimit = 0; - base3.iType = 3; - - sItemVendor item3; - item3.item = base3; - item3.iSortNum = 2; - item3.iVendorID = 1; - item3.fBuyCost = 350.0; - - resp.item[0] = item1; - resp.item[1] = item2; - resp.item[2] = item3; + resp.item[i] = vItem; + } + } sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_VENDOR_TABLE_UPDATE_SUCC, sizeof(sP_FE2CL_REP_PC_VENDOR_TABLE_UPDATE_SUCC)); } diff --git a/src/TableData.cpp b/src/TableData.cpp index df367b1..711a4fa 100644 --- a/src/TableData.cpp +++ b/src/TableData.cpp @@ -1,6 +1,7 @@ #include "TableData.hpp" #include "NPCManager.hpp" #include "TransportManager.hpp" +#include "ItemManager.hpp" #include "settings.hpp" #include "MissionManager.hpp" @@ -119,6 +120,16 @@ void TableData::init() { } std::cout << "[INFO] Loaded mission-related data" << std::endl; + + // load vendor listings + nlohmann::json listings = xdtData["m_pVendorTable"]["m_pItemData"]; + + for (nlohmann::json::iterator listing = listings.begin(); listing != listings.end(); listing++) { + VendorListing vListing = {listing.value()["m_iSortNumber"], listing.value()["m_iItemType"], listing.value()["m_iitemID"], listing.value()["m_iSellCost"]}; + ItemManager::VendorTables[listing.value()["m_iNpcNumber"]].push_back(vListing); + } + + std::cout << "[INFO] Loaded " << ItemManager::VendorTables.size() << " vendor tables" << std::endl; } catch (const std::exception& err) { std::cerr << "[WARN] Malformed xdt.json file! Reason:" << err.what() << std::endl;