diff --git a/src/BuiltinCommands.cpp b/src/BuiltinCommands.cpp index 5f24423..6f60430 100644 --- a/src/BuiltinCommands.cpp +++ b/src/BuiltinCommands.cpp @@ -283,35 +283,56 @@ static void itemGMGiveHandler(CNSocket* sock, CNPacketData* data) { Player* plr = PlayerManager::getPlayer(sock); if (plr->accountLevel > 50) { - // TODO: send fail packet + // TODO: send fail packet return; } - if (itemreq->eIL == 2) { - // Quest item, not a real item, handle this later, stubbed for now - } else if (itemreq->eIL == 1 && itemreq->Item.iType >= 0 && itemreq->Item.iType <= 10) { + INITSTRUCT(sP_FE2CL_REP_PC_GIVE_ITEM_SUCC, resp); - if (Items::ItemData.find(std::pair(itemreq->Item.iID, itemreq->Item.iType)) == Items::ItemData.end()) { + if (itemreq->eIL == 1) { + + if (Items::ItemData.find(std::pair(itemreq->Item.iID, itemreq->Item.iType)) == Items::ItemData.end() + || itemreq->Item.iType < 0 || itemreq->Item.iType > 10) { // invalid item std::cout << "[WARN] Item id " << itemreq->Item.iID << " with type " << itemreq->Item.iType << " is invalid (give item)" << std::endl; return; } - INITSTRUCT(sP_FE2CL_REP_PC_GIVE_ITEM_SUCC, resp); - - resp.eIL = itemreq->eIL; - resp.iSlotNum = itemreq->iSlotNum; if (itemreq->Item.iType == 10) { // item is vehicle, set expiration date // set time limit: current time + 7days itemreq->Item.iTimeLimit = getTimestamp() + 604800; } - resp.Item = itemreq->Item; plr->Inven[itemreq->iSlotNum] = itemreq->Item; + } else if (itemreq->eIL == 2) { + int id = itemreq->Item.iID; + int slot = Missions::findQSlot(plr, id); - sock->sendPacket(resp, P_FE2CL_REP_PC_GIVE_ITEM_SUCC); + if (slot == -1) { + std::cout << "[WARN] Player has no room for quest items" << std::endl; + return; + } + if (id != 0) + std::cout << "new qitem in slot " << slot << std::endl; + + // update player + if (id != 0) { + plr->QInven[slot].iType = 8; + plr->QInven[slot].iID = id; + plr->QInven[slot].iOpt += itemreq->Item.iOpt; + + // destroy the item if its 0 + if (plr->QInven[slot].iOpt == 0) + memset(&plr->QInven[slot], 0, sizeof(sItemBase)); + } + std::cout << "Item id " << id << " is in slot " << slot << " of count " << plr->QInven[slot].iOpt << std::endl; } + + resp.eIL = itemreq->eIL; + resp.iSlotNum = itemreq->iSlotNum; + resp.Item = itemreq->Item; + sock->sendPacket(resp, P_FE2CL_REP_PC_GIVE_ITEM_SUCC); } static void nanoGMGiveHandler(CNSocket* sock, CNPacketData* data) { diff --git a/src/Missions.cpp b/src/Missions.cpp index 4f62235..1988ef3 100644 --- a/src/Missions.cpp +++ b/src/Missions.cpp @@ -32,7 +32,7 @@ static bool isMissionCompleted(Player* player, int missionId) { return player->aQuestFlag[row] & (1ULL << column); } -static int findQSlot(Player *plr, int id) { +int Missions::findQSlot(Player *plr, int id) { int i; // two passes. we mustn't fail to find an existing stack. @@ -52,7 +52,7 @@ static int findQSlot(Player *plr, int id) { static bool isQuestItemFull(CNSocket* sock, int itemId, int itemCount) { Player* plr = PlayerManager::getPlayer(sock); - int slot = findQSlot(plr, itemId); + int slot = Missions::findQSlot(plr, itemId); if (slot == -1) { // this should never happen std::cout << "[WARN] Player has no room for quest item!?" << std::endl; @@ -78,7 +78,7 @@ static void dropQuestItem(CNSocket *sock, int task, int count, int id, int mobid memset(respbuf, 0, resplen); // find free quest item slot - int slot = findQSlot(plr, id); + int slot = Missions::findQSlot(plr, id); if (slot == -1) { // this should never happen std::cout << "[WARN] Player has no room for quest item!?" << std::endl; @@ -486,6 +486,12 @@ void Missions::quitTask(CNSocket* sock, int32_t taskNum, bool manual) { memset(&plr->QInven[j], 0, sizeof(sItemBase)); } } else { + for (i = 0; i < 3; i++) { + if (task["m_iFItemID"][i] == 0) + continue; + dropQuestItem(sock, taskNum, task["m_iFItemNumNeeded"][i], task["m_iFItemID"][i], 0); + } + INITSTRUCT(sP_FE2CL_REP_PC_TASK_END_FAIL, failResp); failResp.iErrorCode = 1; failResp.iTaskNum = taskNum; diff --git a/src/Missions.hpp b/src/Missions.hpp index 6dd95bd..acaf223 100644 --- a/src/Missions.hpp +++ b/src/Missions.hpp @@ -40,6 +40,7 @@ namespace Missions { extern std::map Tasks; extern nlohmann::json AvatarGrowth[37]; void init(); + int findQSlot(Player *plr, int id); bool startTask(Player* plr, int TaskID);