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
This commit is contained in:
dongresource 2020-09-25 23:05:36 +02:00
parent 1b35aab958
commit dccd92aff9
6 changed files with 62 additions and 41 deletions

View File

@ -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,10 +369,15 @@ 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
// 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)
@ -367,8 +390,6 @@ void MissionManager::updateFusionMatter(CNSocket* sock, int fusion) {
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));
return;
}
}
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);

View File

@ -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);
}

View File

@ -36,10 +36,10 @@ std::set<int> TreasureFinderPowers = {26, 40, 74};
* worker functions so we don't have to have unsightly function declarations.
*/
std::map<int32_t, NanoData> NanoManager::NanoTable;
}; // namespace
std::map<int32_t, NanoData> NanoManager::NanoTable;
void NanoManager::init() {
REGISTER_SHARD_PACKET(P_CL2FE_REQ_NANO_ACTIVE, nanoSummonHandler);
REGISTER_SHARD_PACKET(P_CL2FE_REQ_NANO_EQUIP, nanoEquipHandler);

View File

@ -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)

View File

@ -2,5 +2,4 @@ leak:TableData::init
leak:ChunkManager::addPlayer
leak:ChunkManager::addNPC
leak:NPCManager::npcSummonHandler
leak:BaseNPC::BaseNPC
leak:nlohmann::basic_json

2
tdata

@ -1 +1 @@
Subproject commit 2d16da519452c934b6fc2fa61adbcb25f855e95f
Subproject commit 9c595541b3803664359a19379a2cef9b1c2cdc65