From fcdea2e723f34b11cdb5b8f5ac05c188c022cf97 Mon Sep 17 00:00:00 2001 From: dongresource Date: Sun, 13 Dec 2020 01:32:19 +0100 Subject: [PATCH] Implement multiple-choice mission rewards --- src/MissionManager.cpp | 22 ++++++++++++++++------ src/MissionManager.hpp | 4 ++-- src/PlayerManager.cpp | 16 +--------------- src/structs/1013.hpp | 5 +++++ 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/MissionManager.cpp b/src/MissionManager.cpp index 60ffc09..7141642 100644 --- a/src/MissionManager.cpp +++ b/src/MissionManager.cpp @@ -147,14 +147,14 @@ void MissionManager::taskEnd(CNSocket* sock, CNPacketData* data) { response.iTaskNum = missionData->iTaskNum; - if (!endTask(sock, missionData->iTaskNum)) { + if (!endTask(sock, missionData->iTaskNum, missionData->iBox1Choice)) { 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) { +bool MissionManager::endTask(CNSocket *sock, int32_t taskNum, int choice) { Player *plr = PlayerManager::getPlayer(sock); if (Tasks.find(taskNum) == Tasks.end()) @@ -165,7 +165,7 @@ bool MissionManager::endTask(CNSocket *sock, int32_t taskNum) { // mission rewards if (Rewards.find(taskNum) != Rewards.end()) { - if (giveMissionReward(sock, taskNum) == -1) + if (giveMissionReward(sock, taskNum, choice) == -1) return false; // we don't want to send anything } // don't take away quest items if we haven't finished the quest @@ -360,7 +360,7 @@ void MissionManager::dropQuestItem(CNSocket *sock, int task, int count, int id, sock->sendPacket((void*)respbuf, P_FE2CL_REP_REWARD_ITEM, resplen); } -int MissionManager::giveMissionReward(CNSocket *sock, int task) { +int MissionManager::giveMissionReward(CNSocket *sock, int task, int choice) { Reward *reward = Rewards[task]; Player *plr = PlayerManager::getPlayer(sock); @@ -370,6 +370,10 @@ int MissionManager::giveMissionReward(CNSocket *sock, int task) { nrewards++; } + // this handles multiple choice rewards in the Academy's Mt. Neverest missions + if (choice != 0) + nrewards = 1; + int slots[4]; for (int i = 0; i < nrewards; i++) { slots[i] = ItemManager::findFreeSlot(plr); @@ -427,9 +431,15 @@ int MissionManager::giveMissionReward(CNSocket *sock, int task) { resp->m_iBatteryN = plr->batteryN; resp->m_iBatteryW = plr->batteryW; + int offset = 0; + + // choice is actually a bitfield + if (choice != 0) + offset = (int)log2((int)choice); + for (int i = 0; i < nrewards; i++) { - item[i].sItem.iType = reward->itemTypes[i]; - item[i].sItem.iID = reward->itemIds[i]; + item[i].sItem.iType = reward->itemTypes[offset+i]; + item[i].sItem.iID = reward->itemIds[offset+i]; item[i].iSlotNum = slots[i]; item[i].eIL = 1; diff --git a/src/MissionManager.hpp b/src/MissionManager.hpp index 8d6a52e..769d9c4 100644 --- a/src/MissionManager.hpp +++ b/src/MissionManager.hpp @@ -51,12 +51,12 @@ namespace MissionManager { void dropQuestItem(CNSocket *sock, int task, int count, int id, int mobid); // checks if player doesn't have n/n quest items bool isQuestItemFull(CNSocket* sock, int itemId, int itemCount); - int giveMissionReward(CNSocket *sock, int task); + int giveMissionReward(CNSocket *sock, int task, int choice=0); void updateFusionMatter(CNSocket* sock, int fusion); void mobKilled(CNSocket *sock, int mobid); - bool endTask(CNSocket *sock, int32_t taskNum); + bool endTask(CNSocket *sock, int32_t taskNum, int choice=0); void saveMission(Player* player, int missionId); void quitTask(CNSocket* sock, int32_t taskNum, bool manual); diff --git a/src/PlayerManager.cpp b/src/PlayerManager.cpp index bb7a999..b84cf74 100644 --- a/src/PlayerManager.cpp +++ b/src/PlayerManager.cpp @@ -325,11 +325,8 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) { */ void PlayerManager::sendNanoBookSubset(CNSocket *sock) { #ifdef ACADEMY -//#if 0 Player *plr = getPlayer(sock); -#define P_FE2CL_REP_NANO_BOOK_SUBSET 822083892 - int16_t id = 0; INITSTRUCT(sP_FE2CL_REP_NANO_BOOK_SUBSET, pkt); @@ -339,22 +336,11 @@ void PlayerManager::sendNanoBookSubset(CNSocket *sock) { while (id < NANO_COUNT) { pkt.elementOffset = id; - for (int i = id - pkt.elementOffset; id < NANO_COUNT && i < 10; id++, i = id - pkt.elementOffset) { - // change between these two lines to either get all nanos or none - //pkt.element[i] = plr->Nanos[id] = {id, 36, 150}; - //pkt.element[i] = plr->Nanos[id] = {0}; - - // this one should be kept + for (int i = id - pkt.elementOffset; id < NANO_COUNT && i < 10; id++, i = id - pkt.elementOffset) pkt.element[i] = plr->Nanos[id]; - std::cout << "adding " << (int) id << std::endl; - } - - std::cout << "sending subset" << std::endl; sock->sendPacket((void*)&pkt, P_FE2CL_REP_NANO_BOOK_SUBSET, sizeof(sP_FE2CL_REP_NANO_BOOK_SUBSET)); } - - // TODO: possibly send a player refresh packet from here #endif } diff --git a/src/structs/1013.hpp b/src/structs/1013.hpp index f6f2d70..9cbd09a 100644 --- a/src/structs/1013.hpp +++ b/src/structs/1013.hpp @@ -10,6 +10,11 @@ // 56 real nanos, zeroeth entry, Van Kleiss #define NANO_COUNT 58 +// Academy-specific packets +#define P_FE2CL_REP_NANO_BOOK_SUBSET 822083892 +// There are more, but we don't currently implement them +// and they might all be unused anyway. + #pragma pack(push) #pragma pack(4)