From 86c1cbd0f228002870eeedc031404bcc435269f9 Mon Sep 17 00:00:00 2001 From: kamilprzyb Date: Fri, 25 Sep 2020 02:14:11 +0200 Subject: [PATCH] added gumballs functionality --- src/ItemManager.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++ src/ItemManager.hpp | 1 + src/NanoManager.cpp | 9 +++++++ src/NanoManager.hpp | 7 ++++++ src/TableData.cpp | 12 ++++++++++ 5 files changed, 86 insertions(+) diff --git a/src/ItemManager.cpp b/src/ItemManager.cpp index 45a5376..11feb73 100644 --- a/src/ItemManager.cpp +++ b/src/ItemManager.cpp @@ -2,6 +2,7 @@ #include "CNStructs.hpp" #include "ItemManager.hpp" #include "PlayerManager.hpp" +#include "NanoManager.hpp" #include "Player.hpp" #include // for memset() and memcmp() @@ -15,6 +16,8 @@ void ItemManager::init() { REGISTER_SHARD_PACKET(P_CL2FE_REQ_ITEM_MOVE, itemMoveHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_ITEM_DELETE, itemDeleteHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_GIVE_ITEM, itemGMGiveHandler); + //this one is for gumballs + REGISTER_SHARD_PACKET(P_CL2FE_REQ_ITEM_USE, itemUseHandler); // Bank REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_BANK_OPEN, itemBankOpenHandler); // Trade handlers @@ -186,6 +189,60 @@ void ItemManager::itemGMGiveHandler(CNSocket* sock, CNPacketData* data) { } } +void ItemManager::itemUseHandler(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_REQ_ITEM_USE)) + return; // ignore the malformed packet + sP_CL2FE_REQ_ITEM_USE* request = (sP_CL2FE_REQ_ITEM_USE*)data->buf; + Player* player = PlayerManager::getPlayer(sock); + + //gumball can only be used from inventory, so we ignore eIL + sItemBase gumball = player->Inven[request->iSlotNum]; + sNano nano = player->Nanos[player->equippedNanos[request->iNanoSlot]]; + + //sanity check, check if gumball exists + if (!(gumball.iOpt > 0 && gumball.iType == 7 && gumball.iID>=119 && gumball.iID<=121)) { + std::cout << "[WARN] Gumball not found" << std::endl; + INITSTRUCT(sP_FE2CL_REP_PC_ITEM_USE_FAIL, response); + sock->sendPacket((void*)&response, P_FE2CL_REP_PC_ITEM_USE_FAIL, sizeof(sP_FE2CL_REP_PC_ITEM_USE_FAIL)); + return; + } + + //sanity check, check if gumball type matches nano style + int nanoStyle = NanoManager::nanoStyle(nano.iID); + if (!((gumball.iID == 119 && nanoStyle == 0) || + ( gumball.iID == 120 && nanoStyle == 1) || + ( gumball.iID == 121 && nanoStyle == 2))) { + std::cout << "[WARN] Gumball type doesn't match nano type" << std::endl; + INITSTRUCT(sP_FE2CL_REP_PC_ITEM_USE_FAIL, response); + sock->sendPacket((void*)&response, P_FE2CL_REP_PC_ITEM_USE_FAIL, sizeof(sP_FE2CL_REP_PC_ITEM_USE_FAIL)); + return; + } + + gumball.iOpt -= 1; + if (gumball.iOpt == 0) + gumball = {}; + + INITSTRUCT(sP_FE2CL_REP_PC_ITEM_USE_SUCC, response); + response.iPC_ID = player->iID; + response.eIL = 1; + response.iSlotNum = request->iSlotNum; + response.RemainItem = gumball; + // response.iTargetCnt = ? + // response.eST = ? + // response.iSkillID = ? + + sock->sendPacket((void*)&response, P_FE2CL_REP_PC_ITEM_USE_SUCC, sizeof(sP_FE2CL_REP_PC_ITEM_USE_SUCC)); + //update inventory serverside + player->Inven[response.iSlotNum] = response.RemainItem; + + //this is a temporary way of calling buff efect + //TODO: send buff data via response packet + int value1 = CSB_BIT_STIMPAKSLOT1 << request->iNanoSlot; + int value2 = ECSB_STIMPAKSLOT1 + request->iNanoSlot; + + NanoManager::nanoBuff(sock, nano.iID, 144, EST_NANOSTIMPAK, value1, value2, 0); +} + void ItemManager::itemBankOpenHandler(CNSocket* sock, CNPacketData* data) { if (data->size != sizeof(sP_CL2FE_REQ_PC_BANK_OPEN)) return; // ignore the malformed packet diff --git a/src/ItemManager.hpp b/src/ItemManager.hpp index 7972734..b7221c3 100644 --- a/src/ItemManager.hpp +++ b/src/ItemManager.hpp @@ -31,6 +31,7 @@ namespace ItemManager { void itemMoveHandler(CNSocket* sock, CNPacketData* data); void itemDeleteHandler(CNSocket* sock, CNPacketData* data); void itemGMGiveHandler(CNSocket* sock, CNPacketData* data); + void itemUseHandler(CNSocket* sock, CNPacketData* data); // Bank void itemBankOpenHandler(CNSocket* sock, CNPacketData* data); void itemTradeOfferHandler(CNSocket* sock, CNPacketData* data); diff --git a/src/NanoManager.cpp b/src/NanoManager.cpp index a132b54..fbe6217 100644 --- a/src/NanoManager.cpp +++ b/src/NanoManager.cpp @@ -36,6 +36,8 @@ std::set TreasureFinderPowers = {26, 40, 74}; * worker functions so we don't have to have unsightly function declarations. */ +std::map NanoManager::NanoTable; + }; // namespace void NanoManager::init() { @@ -593,6 +595,13 @@ void NanoManager::nanoUnbuff(CNSocket* sock, int32_t iCBFlag, int16_t eCharStatu sock->sendPacket((void*)&resp1, P_FE2CL_PC_BUFF_UPDATE, sizeof(sP_FE2CL_PC_BUFF_UPDATE)); } +// 0=A 1=B 2=C -1=Not found +int NanoManager::nanoStyle(int nanoId) { + if (nanoId < 0 || nanoId >= NanoTable.size()) + return -1; + return NanoTable[nanoId].style; +} + namespace NanoManager { std::vector PassivePowers = { diff --git a/src/NanoManager.hpp b/src/NanoManager.hpp index 8a6f3fd..246474d 100644 --- a/src/NanoManager.hpp +++ b/src/NanoManager.hpp @@ -34,9 +34,14 @@ struct PassivePower { PassivePower(std::set p, int16_t t, int32_t f, int16_t b, int16_t a) : powers(p), eSkillType(t), iCBFlag(f), eCharStatusTimeBuffID(b), iValue(a) {} }; +struct NanoData { + int style; +}; + namespace NanoManager { extern std::vector ActivePowers; extern std::vector PassivePowers; + extern std::map NanoTable; void init(); void nanoSummonHandler(CNSocket* sock, CNPacketData* data); @@ -56,4 +61,6 @@ namespace NanoManager { void nanoBuff(CNSocket* sock, int16_t nanoId, int skillId, int16_t eSkillType, int32_t iCBFlag, int16_t eCharStatusTimeBuffID, int16_t iValue = 0); void nanoUnbuff(CNSocket* sock, int32_t iCBFlag, int16_t eCharStatusTimeBuffID, int16_t iValue = 0); + + int nanoStyle(int nanoId); } diff --git a/src/TableData.cpp b/src/TableData.cpp index f1a5312..a4d1c43 100644 --- a/src/TableData.cpp +++ b/src/TableData.cpp @@ -6,6 +6,7 @@ #include "MissionManager.hpp" #include "MobManager.hpp" #include "ChunkManager.hpp" +#include "NanoManager.hpp" #include "contrib/JSON.hpp" @@ -152,6 +153,17 @@ void TableData::init() { } std::cout << "[INFO] Loaded " << ItemManager::CrocPotTable.size() << " croc pot value sets" << std::endl; + + //load nano info + nlohmann::json nanoInfo = xdtData["m_pNanoTable"]["m_pNanoData"]; + for (nlohmann::json::iterator _nano = nanoInfo.begin(); _nano != nanoInfo.end(); _nano++) { + auto nano = _nano.value(); + NanoData nanoData; + nanoData.style = nano["m_iStyle"]; + NanoManager::NanoTable[nano["m_iNanoNumber"]] = nanoData; + } + + std::cout << "[INFO] Loaded " << NanoManager::NanoTable.size() << " nanos" << std::endl; } catch (const std::exception& err) { std::cerr << "[WARN] Malformed xdt.json file! Reason:" << err.what() << std::endl;