saving active missions works

This commit is contained in:
kamilprzyb 2020-09-15 23:17:37 +02:00
parent 76fa7b154b
commit f467617c2f
5 changed files with 119 additions and 14 deletions

View File

@ -54,8 +54,7 @@ auto db = make_storage("database.db",
make_column("Quests", &Database::DbPlayer::QuestFlag),
make_column("BatteryW", &Database::DbPlayer::BatteryW),
make_column("BatteryN", &Database::DbPlayer::BatteryN),
make_column("Mentor", &Database::DbPlayer::Mentor),
make_column("ActiveTasks", &Database::DbPlayer::ActiveTasks)
make_column("Mentor", &Database::DbPlayer::Mentor)
),
make_table("Inventory",
make_column("PlayerId", &Database::Inventory::playerId),
@ -70,6 +69,16 @@ auto db = make_storage("database.db",
make_column("Id", &Database::Nano::iID),
make_column("Skill", &Database::Nano::iSkillID),
make_column("Stamina", &Database::Nano::iStamina)
),
make_table("RunningQuests",
make_column("PlayerId", &Database::DbQuest::PlayerId),
make_column("TaskId", &Database::DbQuest::TaskId),
make_column("KillNPCCount1", &Database::DbQuest::KillNPCCount1),
make_column("KillNPCCount2", &Database::DbQuest::KillNPCCount2),
make_column("KillNPCCount3", &Database::DbQuest::KillNPCCount3),
make_column("NeededItemCount1", &Database::DbQuest::NeededItemCount1),
make_column("NeededItemCount2", &Database::DbQuest::NeededItemCount2),
make_column("NeededItemCount3", &Database::DbQuest::NeededItemCount3)
)
);
@ -381,6 +390,7 @@ Player Database::DbToPlayer(DbPlayer player) {
Database::getInventory(&result);
Database::getNanos(&result);
Database::getQuests(&result);
std::vector<char>::iterator it = player.QuestFlag.begin();
for (int i = 0; i < 16; i++)
@ -415,6 +425,7 @@ void Database::updatePlayer(Player *player) {
db.update(toUpdate);
updateInventory(player);
updateNanos(player);
updateQuests(player);
}
void Database::updateInventory(Player *player){
@ -504,6 +515,33 @@ void Database::updateNanos(Player *player) {
}
db.commit();
}
void Database::updateQuests(Player* player) {
// start transaction
db.begin_transaction();
// remove all
db.remove_all<DbQuest>(
where(c(&DbQuest::PlayerId) == player->iID)
);
// insert
for (int i = 0; i < ACTIVE_MISSION_COUNT; i++)
{
if (player->tasks[i] == 0)
continue;
DbQuest toAdd = {};
toAdd.PlayerId = player->iID;
toAdd.TaskId = player->tasks[i];
toAdd.KillNPCCount1 = player->killNPCCount[i][0];
toAdd.KillNPCCount2 = player->killNPCCount[i][1];
toAdd.KillNPCCount3 = player->killNPCCount[i][2];
toAdd.NeededItemCount1 = player->NeededItemCount[i][0];
toAdd.NeededItemCount2 = player->NeededItemCount[i][1];
toAdd.NeededItemCount3 = player->NeededItemCount[i][2];
db.insert(toAdd);
}
db.commit();
}
void Database::getInventory(Player* player) {
// get items from DB
auto items = db.get_all<Inventory>(
@ -517,11 +555,11 @@ void Database::getInventory(Player* player) {
toSet.iOpt = current.Opt;
toSet.iTimeLimit = current.TimeLimit;
// assign to proper arrays
if (current.slot <= AEQUIP_COUNT)
if (current.slot < AEQUIP_COUNT)
player->Equip[current.slot] = toSet;
else if (current.slot <= (AEQUIP_COUNT + AINVEN_COUNT))
else if (current.slot < (AEQUIP_COUNT + AINVEN_COUNT))
player->Inven[current.slot - AEQUIP_COUNT] = toSet;
else if (current.slot <= (AEQUIP_COUNT + AINVEN_COUNT + ABANK_COUNT))
else if (current.slot < (AEQUIP_COUNT + AINVEN_COUNT + ABANK_COUNT))
player->Bank[current.slot - AEQUIP_COUNT - AINVEN_COUNT] = toSet;
else
player->QInven[current.slot - AEQUIP_COUNT - AINVEN_COUNT - ABANK_COUNT] = toSet;
@ -541,6 +579,26 @@ void Database::getNanos(Player* player) {
toSet->iStamina = current.iStamina;
}
}
void Database::getQuests(Player* player) {
// get from DB
auto quests = db.get_all<DbQuest>(
where(c(&DbQuest::PlayerId) == player->iID)
);
// set
int i = 0;
for (const DbQuest& current : quests) {
player->tasks[i] = current.TaskId;
player->killNPCCount[i][0] = current.KillNPCCount1;
player->killNPCCount[i][1] = current.KillNPCCount2;
player->killNPCCount[i][2] = current.KillNPCCount3;
player->NeededItemCount[i][0] = current.NeededItemCount1;
player->NeededItemCount[i][1] = current.NeededItemCount2;
player->NeededItemCount[i][2] = current.NeededItemCount3;
i++;
}
}
#pragma endregion ShardServer
#pragma region parsingBlobs

View File

@ -66,9 +66,17 @@ namespace Database {
int BatteryN;
int16_t Mentor;
std::vector<char> QuestFlag;
std::vector<char> ActiveTasks;
};
struct DbQuest {
int PlayerId;
int32_t TaskId;
int KillNPCCount1;
int KillNPCCount2;
int KillNPCCount3;
int NeededItemCount1;
int NeededItemCount2;
int NeededItemCount3;
};
#pragma endregion DatabaseStructs
@ -108,9 +116,11 @@ namespace Database {
void updatePlayer(Player *player);
void updateInventory(Player *player);
void updateNanos(Player *player);
void updateQuests(Player* player);
void getInventory(Player* player);
void getNanos(Player* player);
void getQuests(Player* player);
//parsing blobs
void appendBlob(std::vector<char>*blob, int64_t input);

View File

@ -31,7 +31,7 @@ void MissionManager::taskStart(CNSocket* sock, CNPacketData* data) {
sock->sendPacket((void*)&response, P_FE2CL_REP_PC_TASK_START_SUCC, sizeof(sP_FE2CL_REP_PC_TASK_START_SUCC));
return;
}
int i;
for (i = 0; i < ACTIVE_MISSION_COUNT; i++) {
if (plr->tasks[i] == 0) {
@ -80,10 +80,18 @@ void MissionManager::taskEnd(CNSocket* sock, CNPacketData* data) {
* iSUInstancename is the number of items to give. It is usually negative at the end of
* a mission, so as to clean up it's quest items.
*/
int playerTaskNum = 0;
for (int i = 0; i < ACTIVE_MISSION_COUNT; i++) {
if (plr->tasks[i] == missionData->iTaskNum) {
playerTaskNum = i;
break;
}
}
for (int i = 0; i < 3; i++)
if (task["m_iSUItem"][i] != 0)
if (task["m_iSUItem"][i] != 0) {
dropQuestItem(sock, missionData->iTaskNum, task["m_iSUInstancename"][i], task["m_iSUItem"][i], 0);
plr->NeededItemCount[playerTaskNum][i]++;
}
// mission rewards
if (Rewards.find(missionData->iTaskNum) != Rewards.end()) {
if (giveMissionReward(sock, missionData->iTaskNum) == -1)
@ -94,7 +102,13 @@ void MissionManager::taskEnd(CNSocket* sock, CNPacketData* data) {
int i;
for (i = 0; i < ACTIVE_MISSION_COUNT; i++) {
if (plr->tasks[i] == missionData->iTaskNum)
{
plr->tasks[i] = 0;
for (int j = 0; j < 3; j++) {
plr->killNPCCount[i][j] = 0;
plr->NeededItemCount[i][j] = 0;
}
}
}
if (i == ACTIVE_MISSION_COUNT - 1 && plr->tasks[i] != 0) {
std::cout << "[WARN] Player completed non-active mission!?" << std::endl;
@ -304,14 +318,17 @@ void MissionManager::mobKilled(CNSocket *sock, int mobid) {
// acknowledge killing of mission mob...
if (task["m_iCSUNumToKill"][j] != 0)
{
missionmob = true;
plr->killNPCCount[i][j]++;
}
// drop quest item
if (task["m_iCSUItemNumNeeded"][j] != 0) {
bool drop = rand() % 100 < task["m_iSTItemDropRate"][j];
if (drop) {
// XXX: are CSUItemID and CSTItemID the same?
dropQuestItem(sock, plr->tasks[i], 1, task["m_iCSUItemID"][j], mobid);
plr->NeededItemCount[i][j]++;
} else {
// fail to drop (itemID == 0)
dropQuestItem(sock, plr->tasks[i], 1, 0, mobid);

View File

@ -5,6 +5,7 @@
#include "CNProtocol.hpp"
#include "CNStructs.hpp"
#include "Database.hpp"
#define ACTIVE_MISSION_COUNT 6
@ -41,7 +42,9 @@ struct Player {
bool isTradeConfirm;
bool IsGM;
int64_t aQuestFlag[16];
int64_t aQuestFlag[16];
int tasks[ACTIVE_MISSION_COUNT];
int killNPCCount[ACTIVE_MISSION_COUNT][3];
int NeededItemCount[ACTIVE_MISSION_COUNT][3];
sItemBase QInven[AQINVEN_COUNT];
};

View File

@ -3,6 +3,7 @@
#include "NPCManager.hpp"
#include "CNShardServer.hpp"
#include "CNShared.hpp"
#include "MissionManager.hpp"
#include "settings.hpp"
@ -225,9 +226,11 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) {
// inventory
for (int i = 0; i < AEQUIP_COUNT; i++)
response.PCLoadData2CL.aEquip[i] = plr.Equip[i];
for (int i = 0; i < AINVEN_COUNT; i++)
response.PCLoadData2CL.aInven[i] = plr.Inven[i];
// quest inventory
for (int i = 0; i < AQINVEN_COUNT; i++)
response.PCLoadData2CL.aQInven[i] = plr.QInven[i];
// nanos
for (int i = 1; i < SIZEOF_NANO_BANK_SLOT; i++) {
response.PCLoadData2CL.aNanoBank[i] = plr.Nanos[i];
@ -235,8 +238,22 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) {
for (int i = 0; i < 3; i++) {
response.PCLoadData2CL.aNanoSlots[i] = plr.equippedNanos[i];
}
//missions in progress
for (int i = 0; i < ACTIVE_MISSION_COUNT; i++) {
if (plr.tasks[i] == 0)
break;
response.PCLoadData2CL.aRunningQuest[i].m_aCurrTaskID = plr.tasks[i];
TaskData &task = *MissionManager::Tasks[plr.tasks[i]];
for (int j = 0; j < 3; j++) {
response.PCLoadData2CL.aRunningQuest[i].m_aKillNPCID[j] = (int)task["m_iCSUEnemyID"][j];
response.PCLoadData2CL.aRunningQuest[i].m_aNeededItemID[j] = (int)task["m_iCSUItemID"][j];
response.PCLoadData2CL.aRunningQuest[i].m_aKillNPCCount[j] = plr.killNPCCount[i][j];
//response.PCLoadData2CL.aRunningQuest[i].m_aNeededItemCount[j] = plr.NeededItemCount[i][j];
//why is client not using that smh
}
}
// missions
// completed missions
// the packet requires 32 items, but the client only checks the first 16 (shrug)
for (int i = 0; i < 16; i++) {
response.PCLoadData2CL.aQuestFlag[i] = plr.aQuestFlag[i];