Implemented mission rewards.

Might need to refactor item drops, especially after implementing
task-result quest item drops.
This commit is contained in:
dongresource 2020-09-09 21:09:01 +02:00
parent 3172724596
commit 5b49e71de7
5 changed files with 127 additions and 15 deletions

View File

@ -2,6 +2,9 @@
#include "CNStructs.hpp"
#include "MissionManager.hpp"
#include "PlayerManager.hpp"
#include "ItemManager.hpp"
std::map<int32_t, Reward*> MissionManager::Rewards;
void MissionManager::init() {
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TASK_START, acceptMission);
@ -27,9 +30,70 @@ void MissionManager::completeMission(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;
if (Rewards.find(missionData->iTaskNum) == Rewards.end()) {
// not a mission's final task
sock->sendPacket((void*)&response, P_FE2CL_REP_PC_TASK_END_SUCC, sizeof(sP_FE2CL_REP_PC_TASK_END_SUCC));
return;
}
Reward *reward = Rewards[missionData->iTaskNum];
int nrewards = 0;
for (int i = 0; i < 4; i++) {
if (reward->itemIds[i] != 0)
nrewards++;
}
int slots[4];
for (int i = 0; i < nrewards; i++) {
slots[i] = ItemManager::findFreeSlot(plr);
if (slots[i] == -1) {
std::cout << "Not enough room to complete task" << std::endl;
INITSTRUCT(sP_FE2CL_REP_PC_TASK_END_FAIL, fail);
fail.iTaskNum = missionData->iTaskNum;
fail.iErrorCode = 13; // inventory full
sock->sendPacket((void*)&fail, P_FE2CL_REP_PC_TASK_END_FAIL, sizeof(sP_FE2CL_REP_PC_TASK_END_FAIL));
return;
}
}
uint8_t respbuf[CN_PACKET_BUFFER_SIZE];
size_t resplen = sizeof(sP_FE2CL_REP_REWARD_ITEM) + nrewards * sizeof(sItemReward);
assert(resplen < CN_PACKET_BUFFER_SIZE);
sP_FE2CL_REP_REWARD_ITEM *resp = (sP_FE2CL_REP_REWARD_ITEM *)respbuf;
sItemReward *item = (sItemReward *)(respbuf + sizeof(sP_FE2CL_REP_REWARD_ITEM));
// don't forget to zero the buffer!
memset(respbuf, 0, resplen);
// update player
plr->money += reward->money;
plr->fusionmatter += reward->fusionmatter;
// simple rewards
resp->m_iCandy = plr->money;
resp->m_iFusionMatter = plr->fusionmatter;
resp->iFatigue = 100; // prevents warning message
resp->iFatigue_Level = 1;
resp->iItemCnt = nrewards;
for (int i = 0; i < nrewards; i++) {
item[i].sItem.iType = reward->itemTypes[i];
item[i].sItem.iID = reward->itemIds[i];
item[i].iSlotNum = slots[i];
item[i].eIL = 1;
// update player
plr->Inven[slots[i]] = item->sItem;
}
sock->sendPacket((void*)&response, P_FE2CL_REP_PC_TASK_END_SUCC, sizeof(sP_FE2CL_REP_PC_TASK_END_SUCC));
sock->sendPacket((void*)respbuf, P_FE2CL_REP_REWARD_ITEM, resplen);
}
void MissionManager::setMission(CNSocket* sock, CNPacketData* data) {
@ -52,4 +116,4 @@ void MissionManager::quitMission(CNSocket* sock, CNPacketData* data) {
response.iTaskNum = missionData->iTaskNum;
sock->sendPacket((void*)&response, P_FE2CL_REP_PC_TASK_STOP_SUCC, sizeof(sP_FE2CL_REP_PC_TASK_STOP_SUCC));
}
}

View File

@ -2,11 +2,30 @@
#include "CNShardServer.hpp"
#include "contrib/JSON.hpp"
struct Reward {
int32_t id;
int32_t itemTypes[4];
int32_t itemIds[4];
int32_t money;
int32_t fusionmatter;
Reward(int32_t id, nlohmann::json types, nlohmann::json ids, int32_t m, int32_t fm) :
id(id), money(m), fusionmatter(fm) {
for (int i = 0; i < 4; i++) {
itemTypes[i] = types[i];
itemIds[i] = ids[i];
}
};
};
namespace MissionManager {
extern std::map<int32_t, Reward*> Rewards;
void init();
void acceptMission(CNSocket* sock, CNPacketData* data);
void completeMission(CNSocket* sock, CNPacketData* data);
void setMission(CNSocket* sock, CNPacketData* data);
void quitMission(CNSocket* sock, CNPacketData* data);
}
}

View File

@ -1,11 +1,13 @@
#include "TableData.hpp"
#include "NPCManager.hpp"
#include "settings.hpp"
#include "MissionManager.hpp"
#include "contrib/JSON.hpp"
#include <fstream>
void TabledataManager::init() {
void TableData::init() {
int i = 0;
// load NPCs from NPC.json
@ -60,16 +62,15 @@ void TabledataManager::init() {
std::cerr << "[WARN] Malformed mobs.json file! Reason:" << err.what() << std::endl;
}
// load everything else from xdttable
std::ifstream infile(settings::XDTJSON);
nlohmann::json xdtData;
// read file into json
infile >> xdtData;
// load warps from m_pInstanceTable.m_pWarpData
try {
std::ifstream infile(settings::XDTJSON);
nlohmann::json xdtData;
// read file into json
infile >> xdtData;
// load warps from m_pInstanceTable.m_pWarpData
nlohmann::json warpData = xdtData["m_pInstanceTable"]["m_pWarpData"];
for (nlohmann::json::iterator warp = warpData.begin(); warp != warpData.end(); warp++) {
@ -79,9 +80,35 @@ void TabledataManager::init() {
}
std::cout << "[INFO] populated " << NPCManager::Warps.size() << " Warps" << std::endl;
// missions
nlohmann::json tasks = xdtData["m_pMissionTable"]["m_pMissionData"];
for (auto _task = tasks.begin(); _task != tasks.end(); _task++) {
auto task = _task.value();
// rewards
if (task["m_iSUReward"] != 0) {
auto tmp = xdtData["m_pMissionTable"]["m_pRewardData"][(int)task["m_iSUReward"]];
Reward *rew = new Reward(tmp["m_iMissionRewardID"], tmp["m_iMissionRewarItemType"],
tmp["m_iMissionRewardItemID"], tmp["m_iCash"], tmp["m_iFusionMatter"]);
MissionManager::Rewards[task["m_iHTaskID"]] = rew;
}
}
std::cout << "[INFO] Loaded mission-related data" << std::endl;
}
catch (const std::exception& err) {
std::cerr << "[WARN] Malformed xdt.json file! Reason:" << err.what() << std::endl;
}
}
}
void TableData::cleanup() {
/*
* This is just to shut the address sanitizer up. Dynamically allocated data
* doesn't need to be cleaned up if it's supposed to last the program's full runtime.
*/
for (auto& pair : MissionManager::Rewards)
delete pair.second;
}

View File

@ -1,6 +1,7 @@
#pragma once
#include <map>
namespace TabledataManager {
namespace TableData {
void init();
}
void cleanup();
}

View File

@ -34,6 +34,7 @@ void terminate(int arg) {
std::cout << "OpenFusion: terminating." << std::endl;
shardServer->kill();
shardThread->join();
TableData::cleanup();
exit(0);
}
@ -71,7 +72,7 @@ int main() {
settings::init();
std::cout << "[INFO] Protocol version: " << PROTOCOL_VERSION << std::endl;
std::cout << "[INFO] Intializing Packet Managers..." << std::endl;
TabledataManager::init();
TableData::init();
PlayerManager::init();
ChatManager::init();
CombatManager::init();