From dccd92aff91d48245c0466284d756dec9b8350d8 Mon Sep 17 00:00:00 2001 From: dongresource Date: Fri, 25 Sep 2020 23:05:36 +0200 Subject: [PATCH] The Future is now playable. * Sync'd tdata so it has all the lair NPCs * Bypassed Eduardo escort task * Fixed the level 36 updateFusionMatter() memory error * Fixed qitems being deleted even if the player fails to complete the mission due to not having any inventory space, thus softlocking the mission --- src/MissionManager.cpp | 91 ++++++++++++++++++++++++++---------------- src/MissionManager.hpp | 1 + src/NanoManager.cpp | 4 +- src/TableData.cpp | 4 +- suppr.txt | 1 - tdata | 2 +- 6 files changed, 62 insertions(+), 41 deletions(-) diff --git a/src/MissionManager.cpp b/src/MissionManager.cpp index 91c6fba..2595e97 100644 --- a/src/MissionManager.cpp +++ b/src/MissionManager.cpp @@ -76,6 +76,18 @@ void MissionManager::taskStart(CNSocket* sock, CNPacketData* data) { response.iTaskNum = missionData->iTaskNum; sock->sendPacket((void*)&response, P_FE2CL_REP_PC_TASK_START_SUCC, sizeof(sP_FE2CL_REP_PC_TASK_START_SUCC)); + + // HACK: auto-succeed Eduardo escort task + // TODO: maybe check for iTaskType == 6 and skip all escort missions? + if (missionData->iTaskNum == 576) { + std::cout << "Sending Eduardo success packet" << std::endl; + INITSTRUCT(sP_FE2CL_REP_PC_TASK_END_SUCC, response); + + endTask(sock, 576); + response.iTaskNum = 576; + + sock->sendPacket((void*)&response, P_FE2CL_REP_PC_TASK_END_SUCC, sizeof(sP_FE2CL_REP_PC_TASK_END_SUCC)); + } } void MissionManager::taskEnd(CNSocket* sock, CNPacketData* data) { @@ -84,20 +96,31 @@ void MissionManager::taskEnd(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_PC_TASK_END* missionData = (sP_CL2FE_REQ_PC_TASK_END*)data->buf; INITSTRUCT(sP_FE2CL_REP_PC_TASK_END_SUCC, response); - Player *plr = PlayerManager::getPlayer(sock); response.iTaskNum = missionData->iTaskNum; - //std::cout << missionData->iTaskNum << std::endl; - if (Tasks.find(missionData->iTaskNum) == Tasks.end()) { - std::cout << "[WARN] Player submitted unknown task!?" << std::endl; - // TODO: TASK_FAIL? - sock->sendPacket((void*)&response, P_FE2CL_REP_PC_TASK_END_SUCC, sizeof(sP_FE2CL_REP_PC_TASK_END_SUCC)); + if (!endTask(sock, missionData->iTaskNum)) { return; } + sock->sendPacket((void*)&response, P_FE2CL_REP_PC_TASK_END_SUCC, sizeof(sP_FE2CL_REP_PC_TASK_END_SUCC)); +} + +bool MissionManager::endTask(CNSocket *sock, int32_t taskNum) { + Player *plr = PlayerManager::getPlayer(sock); + + if (Tasks.find(taskNum) == Tasks.end()) + return false; + // ugly pointer/reference juggling for the sake of operator overloading... - TaskData& task = *Tasks[missionData->iTaskNum]; + TaskData& task = *Tasks[taskNum]; + + // mission rewards + if (Rewards.find(taskNum) != Rewards.end()) { + if (giveMissionReward(sock, taskNum) == -1) + return false; // we don't want to send anything + } + // don't take away quest items if we haven't finished the quest /* * Give (or take away) quest items @@ -114,18 +137,12 @@ void MissionManager::taskEnd(CNSocket* sock, CNPacketData* data) { for (int i = 0; i < 3; i++) if (task["m_iSUItem"][i] != 0) - dropQuestItem(sock, missionData->iTaskNum, task["m_iSUInstancename"][i], task["m_iSUItem"][i], 0); - - // mission rewards - if (Rewards.find(missionData->iTaskNum) != Rewards.end()) { - if (giveMissionReward(sock, missionData->iTaskNum) == -1) - return; - } + dropQuestItem(sock, taskNum, task["m_iSUInstancename"][i], task["m_iSUItem"][i], 0); // update player int i; for (i = 0; i < ACTIVE_MISSION_COUNT; i++) { - if (plr->tasks[i] == missionData->iTaskNum) + if (plr->tasks[i] == taskNum) { plr->tasks[i] = 0; for (int j = 0; j < 3; j++) { @@ -146,13 +163,15 @@ void MissionManager::taskEnd(CNSocket* sock, CNPacketData* data) { // if it's a nano mission, reward the nano. if (task["m_iSTNanoID"] != 0) { NanoManager::addNano(sock, task["m_iSTNanoID"], 0); + // check if the player already has enough fm for the next mission + updateFusionMatter(sock, 0); } // remove current mission plr->CurrentMissionID = 0; } - sock->sendPacket((void*)&response, P_FE2CL_REP_PC_TASK_END_SUCC, sizeof(sP_FE2CL_REP_PC_TASK_END_SUCC)); + return true; } void MissionManager::setMission(CNSocket* sock, CNPacketData* data) { @@ -217,7 +236,6 @@ void MissionManager::quitTask(CNSocket* sock, int32_t taskNum) { sock->sendPacket((void*)&response, P_FE2CL_REP_PC_TASK_STOP_SUCC, sizeof(sP_FE2CL_REP_PC_TASK_STOP_SUCC)); } -// TODO: coalesce into ItemManager::findFreeSlot()? int MissionManager::findQSlot(Player *plr, int id) { int i; @@ -322,7 +340,7 @@ int MissionManager::giveMissionReward(CNSocket *sock, int task) { // update player plr->money += reward->money; - MissionManager::updateFusionMatter(sock, reward->fusionmatter); + updateFusionMatter(sock, reward->fusionmatter); // simple rewards resp->m_iCandy = plr->money; @@ -351,24 +369,27 @@ void MissionManager::updateFusionMatter(CNSocket* sock, int fusion) { plr->fusionmatter += fusion; - // check if it is over the limit - if (plr->fusionmatter > AvatarGrowth[plr->level]["m_iReqBlob_NanoCreate"]) { - // check if the nano task is already started - - for (int i = 0; i < ACTIVE_MISSION_COUNT; i++) { - TaskData& task = *Tasks[plr->tasks[i]]; - if (task["m_iSTNanoID"] != 0) - return; // nano mission was already started! - } - - // start the nano mission - startTask(plr, AvatarGrowth[plr->level]["m_iNanoQuestTaskID"], true); - - INITSTRUCT(sP_FE2CL_REP_PC_TASK_START_SUCC, response); - response.iTaskNum = AvatarGrowth[plr->level]["m_iNanoQuestTaskID"]; - sock->sendPacket((void*)&response, P_FE2CL_REP_PC_TASK_START_SUCC, sizeof(sP_FE2CL_REP_PC_TASK_START_SUCC)); + // sanity check + if (plr->level >= 36) return; + + // check if it is over the limit + if (plr->fusionmatter <= AvatarGrowth[plr->level]["m_iReqBlob_NanoCreate"]) + return; + + // check if the nano task is already started + for (int i = 0; i < ACTIVE_MISSION_COUNT; i++) { + TaskData& task = *Tasks[plr->tasks[i]]; + if (task["m_iSTNanoID"] != 0) + return; // nano mission was already started! } + + // start the nano mission + startTask(plr, AvatarGrowth[plr->level]["m_iNanoQuestTaskID"], true); + + INITSTRUCT(sP_FE2CL_REP_PC_TASK_START_SUCC, response); + response.iTaskNum = AvatarGrowth[plr->level]["m_iNanoQuestTaskID"]; + sock->sendPacket((void*)&response, P_FE2CL_REP_PC_TASK_START_SUCC, sizeof(sP_FE2CL_REP_PC_TASK_START_SUCC)); } void MissionManager::mobKilled(CNSocket *sock, int mobid) { @@ -430,7 +451,7 @@ void MissionManager::saveMission(Player* player, int missionId) { return; } - // Missions are stored in int_64t array + // Missions are stored in int64_t array int row = missionId / 64; int column = missionId % 64; player->aQuestFlag[row] |= (1ULL << column); diff --git a/src/MissionManager.hpp b/src/MissionManager.hpp index a6a27af..abfafec 100644 --- a/src/MissionManager.hpp +++ b/src/MissionManager.hpp @@ -55,6 +55,7 @@ namespace MissionManager { void mobKilled(CNSocket *sock, int mobid); + bool endTask(CNSocket *sock, int32_t taskNum); void saveMission(Player* player, int missionId); void quitTask(CNSocket* sock, int32_t taskNum); } diff --git a/src/NanoManager.cpp b/src/NanoManager.cpp index 45248e9..a15d383 100644 --- a/src/NanoManager.cpp +++ b/src/NanoManager.cpp @@ -36,10 +36,10 @@ std::set TreasureFinderPowers = {26, 40, 74}; * worker functions so we don't have to have unsightly function declarations. */ -std::map NanoManager::NanoTable; - }; // namespace +std::map NanoManager::NanoTable; + void NanoManager::init() { REGISTER_SHARD_PACKET(P_CL2FE_REQ_NANO_ACTIVE, nanoSummonHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_NANO_EQUIP, nanoEquipHandler); diff --git a/src/TableData.cpp b/src/TableData.cpp index 49e8082..d55db2a 100644 --- a/src/TableData.cpp +++ b/src/TableData.cpp @@ -199,8 +199,8 @@ void TableData::init() { } /* -* Some item categories either don't possess iEquipLoc or use a different value for item type. -*/ + * Some item categories either don't possess iEquipLoc or use a different value for item type. + */ int TableData::getItemType(int itemSet) { int overriden; switch (itemSet) diff --git a/suppr.txt b/suppr.txt index 767e5a4..781647b 100644 --- a/suppr.txt +++ b/suppr.txt @@ -2,5 +2,4 @@ leak:TableData::init leak:ChunkManager::addPlayer leak:ChunkManager::addNPC leak:NPCManager::npcSummonHandler -leak:BaseNPC::BaseNPC leak:nlohmann::basic_json diff --git a/tdata b/tdata index 2d16da5..9c59554 160000 --- a/tdata +++ b/tdata @@ -1 +1 @@ -Subproject commit 2d16da519452c934b6fc2fa61adbcb25f855e95f +Subproject commit 9c595541b3803664359a19379a2cef9b1c2cdc65