Make nano skill change consume FM & power items

This commit is contained in:
Titan 2020-10-24 22:28:35 +02:00 committed by Gent
parent 4ab686bc46
commit 6d97aaa1d0
3 changed files with 76 additions and 14 deletions

View File

@ -46,6 +46,7 @@ std::set<int> TreasureFinderPowers = {26, 40, 74};
}; // namespace
std::map<int32_t, NanoData> NanoManager::NanoTable;
std::map<int32_t, NanoTuning> NanoManager::NanoTunings;
void NanoManager::init() {
REGISTER_SHARD_PACKET(P_CL2FE_REQ_NANO_ACTIVE, nanoSummonHandler);
@ -187,7 +188,7 @@ void NanoManager::nanoSkillSetHandler(CNSocket* sock, CNPacketData* data) {
return; // malformed packet
sP_CL2FE_REQ_NANO_TUNE* skill = (sP_CL2FE_REQ_NANO_TUNE*)data->buf;
setNanoSkill(sock, skill->iNanoID, skill->iTuneID);
setNanoSkill(sock, skill);
}
void NanoManager::nanoSkillSetGMHandler(CNSocket* sock, CNPacketData* data) {
@ -195,7 +196,7 @@ void NanoManager::nanoSkillSetGMHandler(CNSocket* sock, CNPacketData* data) {
return; // malformed packet
sP_CL2FE_REQ_NANO_TUNE* skillGM = (sP_CL2FE_REQ_NANO_TUNE*)data->buf;
setNanoSkill(sock, skillGM->iNanoID, skillGM->iTuneID);
setNanoSkill(sock, skillGM);
}
void NanoManager::nanoRecallHandler(CNSocket* sock, CNPacketData* data) {
@ -347,8 +348,8 @@ void NanoManager::summonNano(CNSocket *sock, int slot) {
plr->activeNano = nanoId;
}
void NanoManager::setNanoSkill(CNSocket* sock, int16_t nanoId, int16_t skillId) {
if (nanoId > 36)
void NanoManager::setNanoSkill(CNSocket* sock, sP_CL2FE_REQ_NANO_TUNE* skill) {
if (skill->iNanoID > 36)
return;
Player *plr = PlayerManager::getPlayer(sock);
@ -356,25 +357,68 @@ void NanoManager::setNanoSkill(CNSocket* sock, int16_t nanoId, int16_t skillId)
if (plr == nullptr)
return;
if (plr->activeNano > 0 && plr->activeNano == nanoId)
if (plr->activeNano > 0 && plr->activeNano == skill->iNanoID)
summonNano(sock, -1); // just unsummon the nano to prevent infinite buffs
sNano nano = plr->Nanos[nanoId];
nano.iSkillID = skillId;
plr->Nanos[nanoId] = nano;
sNano nano = plr->Nanos[skill->iNanoID];
nano.iSkillID = skill->iTuneID;
plr->Nanos[skill->iNanoID] = nano;
// Send to client
INITSTRUCT(sP_FE2CL_REP_NANO_TUNE_SUCC, resp);
resp.iNanoID = nanoId;
resp.iSkillID = skillId;
resp.iNanoID = skill->iNanoID;
resp.iSkillID = skill->iTuneID;
resp.iPC_FusionMatter = plr->fusionmatter;
resp.aItem[9] = plr->Inven[0]; // temp fix for a bug TODO: Use this for nano power changing later
resp.aItem[9] = plr->Inven[0]; // quick fix to make sure item in slot 0 doesn't get yeeted by default
// check if there's any garbage in the item slot array (this'll happen when a nano station isn't used)
for (int i = 0; i < 10; i++) {
if (skill->aiNeedItemSlotNum[i] < 0 || skill->aiNeedItemSlotNum[i] >= AINVEN_COUNT) {
sock->sendPacket((void*)&resp, P_FE2CL_REP_NANO_TUNE_SUCC, sizeof(sP_FE2CL_REP_NANO_TUNE_SUCC));
return; // stop execution, don't run consumption logic
}
}
if (plr->fusionmatter < (int)MissionManager::AvatarGrowth[plr->level]["m_iReqBlob_NanoTune"]) // sanity check
return;
plr->fusionmatter -= (int)MissionManager::AvatarGrowth[plr->level]["m_iReqBlob_NanoTune"];
int reqItemCount = NanoTunings[skill->iTuneID].reqItemCount;
int reqItemID = NanoTunings[skill->iTuneID].reqItems;
int i = 0;
while (reqItemCount > 0 && i < 10) {
sItemBase& item = plr->Inven[skill->aiNeedItemSlotNum[i]];
if (item.iType == 7 && item.iID == reqItemID) {
if (item.iOpt > reqItemCount) {
item.iOpt -= reqItemCount;
reqItemCount = 0;
}
else {
reqItemCount -= item.iOpt;
item.iID = 0;
item.iType = 0;
item.iOpt = 0;
}
}
i++; // next slot
}
resp.iPC_FusionMatter = plr->fusionmatter; // update fusion matter in packet
// update items clientside
for (int i = 0; i < 10; i++) {
if (skill->aiNeedItemSlotNum[i]) { // non-zero check
resp.aItem[i] = plr->Inven[skill->aiNeedItemSlotNum[i]];
resp.aiItemSlotNum[i] = skill->aiNeedItemSlotNum[i];
}
}
sock->sendPacket((void*)&resp, P_FE2CL_REP_NANO_TUNE_SUCC, sizeof(sP_FE2CL_REP_NANO_TUNE_SUCC));
DEBUGLOG(
std::cout << U16toU8(plr->PCStyle.szFirstName) << U16toU8(plr->PCStyle.szLastName) << " set skill id " << skillId << " for nano: " << nanoId << std::endl;
std::cout << U16toU8(plr->PCStyle.szFirstName) << U16toU8(plr->PCStyle.szLastName) << " set skill id " << skill->iTuneID << " for nano: " << skill->iNanoID << std::endl;
)
}

View File

@ -39,10 +39,16 @@ struct NanoData {
int style;
};
struct NanoTuning {
int reqItemCount;
int reqItems;
};
namespace NanoManager {
extern std::vector<ActivePower> ActivePowers;
extern std::vector<PassivePower> PassivePowers;
extern std::map<int32_t, NanoData> NanoTable;
extern std::map<int32_t, NanoTuning> NanoTunings;
void init();
void nanoSummonHandler(CNSocket* sock, CNPacketData* data);
@ -58,7 +64,7 @@ namespace NanoManager {
// Helper methods
void addNano(CNSocket* sock, int16_t nanoId, int16_t slot, bool spendfm=false);
void summonNano(CNSocket* sock, int slot);
void setNanoSkill(CNSocket* sock, int16_t nanoId, int16_t skillId);
void setNanoSkill(CNSocket* sock, sP_CL2FE_REQ_NANO_TUNE* skill);
void resetNanoSkill(CNSocket* sock, int16_t nanoId);
void nanoBuff(CNSocket* sock, int16_t nanoId, int skillId, int16_t eSkillType, int32_t iCBFlag, int16_t eCharStatusTimeBuffID, int16_t iValue = 0, bool groupPower = false);

View File

@ -175,6 +175,18 @@ void TableData::init() {
}
std::cout << "[INFO] Loaded " << NanoManager::NanoTable.size() << " nanos" << std::endl;
nlohmann::json nanoTuneInfo = xdtData["m_pNanoTable"]["m_pNanoTuneData"];
for (nlohmann::json::iterator _nano = nanoTuneInfo.begin(); _nano != nanoTuneInfo.end(); _nano++) {
auto nano = _nano.value();
NanoTuning nanoData;
nanoData.reqItems = nano["m_iReqItemID"];
nanoData.reqItemCount = nano["m_iReqItemCount"];
NanoManager::NanoTunings[nano["m_iSkillID"]] = nanoData;
}
std::cout << "[INFO] Loaded " << NanoManager::NanoTable.size() << " nano tunings" << std::endl;
}
catch (const std::exception& err) {
std::cerr << "[FATAL] Malformed xdt.json file! Reason:" << err.what() << std::endl;