Fix failed task QItem handling, implement /itemQ command

This commit is contained in:
Jade 2021-05-14 14:24:08 -05:00 committed by CakeLancelot
parent 19fd4ecb83
commit 81cc19f985
3 changed files with 42 additions and 14 deletions

View File

@ -283,35 +283,56 @@ static void itemGMGiveHandler(CNSocket* sock, CNPacketData* data) {
Player* plr = PlayerManager::getPlayer(sock); Player* plr = PlayerManager::getPlayer(sock);
if (plr->accountLevel > 50) { if (plr->accountLevel > 50) {
// TODO: send fail packet // TODO: send fail packet
return; return;
} }
if (itemreq->eIL == 2) { INITSTRUCT(sP_FE2CL_REP_PC_GIVE_ITEM_SUCC, resp);
// 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) {
if (Items::ItemData.find(std::pair<int32_t, int32_t>(itemreq->Item.iID, itemreq->Item.iType)) == Items::ItemData.end()) { if (itemreq->eIL == 1) {
if (Items::ItemData.find(std::pair<int32_t, int32_t>(itemreq->Item.iID, itemreq->Item.iType)) == Items::ItemData.end()
|| itemreq->Item.iType < 0 || itemreq->Item.iType > 10) {
// invalid item // invalid item
std::cout << "[WARN] Item id " << itemreq->Item.iID << " with type " << itemreq->Item.iType << " is invalid (give item)" << std::endl; std::cout << "[WARN] Item id " << itemreq->Item.iID << " with type " << itemreq->Item.iType << " is invalid (give item)" << std::endl;
return; return;
} }
INITSTRUCT(sP_FE2CL_REP_PC_GIVE_ITEM_SUCC, resp);
resp.eIL = itemreq->eIL;
resp.iSlotNum = itemreq->iSlotNum;
if (itemreq->Item.iType == 10) { if (itemreq->Item.iType == 10) {
// item is vehicle, set expiration date // item is vehicle, set expiration date
// set time limit: current time + 7days // set time limit: current time + 7days
itemreq->Item.iTimeLimit = getTimestamp() + 604800; itemreq->Item.iTimeLimit = getTimestamp() + 604800;
} }
resp.Item = itemreq->Item;
plr->Inven[itemreq->iSlotNum] = 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) { static void nanoGMGiveHandler(CNSocket* sock, CNPacketData* data) {

View File

@ -32,7 +32,7 @@ static bool isMissionCompleted(Player* player, int missionId) {
return player->aQuestFlag[row] & (1ULL << column); return player->aQuestFlag[row] & (1ULL << column);
} }
static int findQSlot(Player *plr, int id) { int Missions::findQSlot(Player *plr, int id) {
int i; int i;
// two passes. we mustn't fail to find an existing stack. // 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) { static bool isQuestItemFull(CNSocket* sock, int itemId, int itemCount) {
Player* plr = PlayerManager::getPlayer(sock); Player* plr = PlayerManager::getPlayer(sock);
int slot = findQSlot(plr, itemId); int slot = Missions::findQSlot(plr, itemId);
if (slot == -1) { if (slot == -1) {
// this should never happen // this should never happen
std::cout << "[WARN] Player has no room for quest item!?" << std::endl; 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); memset(respbuf, 0, resplen);
// find free quest item slot // find free quest item slot
int slot = findQSlot(plr, id); int slot = Missions::findQSlot(plr, id);
if (slot == -1) { if (slot == -1) {
// this should never happen // this should never happen
std::cout << "[WARN] Player has no room for quest item!?" << std::endl; 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)); memset(&plr->QInven[j], 0, sizeof(sItemBase));
} }
} else { } 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); INITSTRUCT(sP_FE2CL_REP_PC_TASK_END_FAIL, failResp);
failResp.iErrorCode = 1; failResp.iErrorCode = 1;
failResp.iTaskNum = taskNum; failResp.iTaskNum = taskNum;

View File

@ -40,6 +40,7 @@ namespace Missions {
extern std::map<int32_t, TaskData*> Tasks; extern std::map<int32_t, TaskData*> Tasks;
extern nlohmann::json AvatarGrowth[37]; extern nlohmann::json AvatarGrowth[37];
void init(); void init();
int findQSlot(Player *plr, int id);
bool startTask(Player* plr, int TaskID); bool startTask(Player* plr, int TaskID);