From f2ff4c7f4d7871838565f479c92fe2b675cdd47b Mon Sep 17 00:00:00 2001 From: kamilprzyb Date: Thu, 22 Oct 2020 10:23:12 +0200 Subject: [PATCH] added basic player buffs implementation --- src/ChatManager.cpp | 20 ++++++++++++++++++ src/NPCManager.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++ src/NPCManager.hpp | 6 +++++- src/NanoManager.cpp | 4 ++-- src/Player.hpp | 3 +++ 5 files changed, 79 insertions(+), 3 deletions(-) diff --git a/src/ChatManager.cpp b/src/ChatManager.cpp index de6f540..fe2b37e 100644 --- a/src/ChatManager.cpp +++ b/src/ChatManager.cpp @@ -436,6 +436,25 @@ void tasksCommand(std::string full, std::vector& args, CNSocket* so } } +void buffCommand(std::string full, std::vector& args, CNSocket* sock) { + if (args.size() < 3) { + ChatManager::sendServerMessage(sock, "/buff: no skill Id and duration time specified"); + return; + } + + char* tmp; + int skillId = std::strtol(args[1].c_str(), &tmp, 10); + if (*tmp) + return; + int duration = std::strtol(args[2].c_str(), &tmp, 10); + if (*tmp) + return; + + if (NPCManager::eggBuffPlayer(sock, skillId, duration)<0) + ChatManager::sendServerMessage(sock, "/buff: unknown skill Id"); + +} + void notifyCommand(std::string full, std::vector& args, CNSocket* sock) { Player *plr = PlayerManager::getPlayer(sock); @@ -478,6 +497,7 @@ void ChatManager::init() { registerCommand("population", 100, populationCommand, "check how many players are online"); registerCommand("refresh", 100, refreshCommand, "teleport yourself to your current location"); registerCommand("minfo", 30, minfoCommand, "show details of the current mission and task."); + registerCommand("buff", 50, buffCommand, "give yourself a buff effect"); registerCommand("tasks", 30, tasksCommand, "list all active missions and their respective task ids."); registerCommand("notify", 30, notifyCommand, "receive a message whenever a player joins the server"); registerCommand("players", 30, playersCommand, "print all players on the server"); diff --git a/src/NPCManager.cpp b/src/NPCManager.cpp index f1952ae..4eea30e 100644 --- a/src/NPCManager.cpp +++ b/src/NPCManager.cpp @@ -4,6 +4,7 @@ #include "MobManager.hpp" #include "MissionManager.hpp" #include "ChunkManager.hpp" +#include "NanoManager.hpp" #include #include @@ -18,6 +19,8 @@ std::map NPCManager::NPCs; std::map NPCManager::Warps; std::vector NPCManager::RespawnPoints; +/// Player Id, CBFlag -> remaining time +std::map, time_t> NPCManager::EggBuffs; nlohmann::json NPCManager::NPCData; /* @@ -648,3 +651,49 @@ BaseNPC* NPCManager::getNearestNPC(std::vector chunks, int X, int Y, int } return npc; } + + +int NPCManager::eggBuffPlayer(CNSocket* sock, int skillId, int duration) { + + Player* plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return -1; + + int32_t CBFlag = -1, iValue, CSTB; + + // find the right passive power data + for (auto& pwr : NanoManager::PassivePowers) + if (pwr.powers.count(skillId)) { + CBFlag = pwr.iCBFlag; + CSTB = pwr.eCharStatusTimeBuffID; + iValue = pwr.iValue; + } + + if (CBFlag < 0) + return -1; + + std::pair key = std::make_pair(plr->iID, CBFlag); + + // if player doesn't have this buff yet + if (EggBuffs.find(key) == EggBuffs.end()) + { + // save new cbflag serverside + plr->iEggConditionBitFlag |= CBFlag; + + // send buff update package + INITSTRUCT(sP_FE2CL_PC_BUFF_UPDATE, updatePacket); + updatePacket.eCSTB = CSTB; // eCharStatusTimeBuffID + updatePacket.eTBU = 1; // eTimeBuffUpdate 1 means Add + updatePacket.eTBT = 3; // eTimeBuffType 3 means egg + updatePacket.TimeBuff.iValue = iValue; + int32_t updatedFlag = plr->iConditionBitFlag | plr->iGroupConditionBitFlag | plr->iEggConditionBitFlag; + updatePacket.iConditionBitFlag = updatedFlag; + + sock->sendPacket((void*)&updatePacket, P_FE2CL_PC_BUFF_UPDATE, sizeof(sP_FE2CL_PC_BUFF_UPDATE)); + } + + // save the buff serverside; + EggBuffs[key] = duration; + + return 0; +} diff --git a/src/NPCManager.hpp b/src/NPCManager.hpp index 0c99941..24f5f44 100644 --- a/src/NPCManager.hpp +++ b/src/NPCManager.hpp @@ -19,7 +19,8 @@ struct WarpLocation { namespace NPCManager { extern std::map NPCs; extern std::map Warps; - extern std::vector RespawnPoints; + extern std::vector RespawnPoints; + extern std::map, time_t> EggBuffs; extern nlohmann::json NPCData; extern int32_t nextId; void init(); @@ -50,4 +51,7 @@ namespace NPCManager { void handleWarp(CNSocket* sock, int32_t warpId); BaseNPC* getNearestNPC(std::vector chunks, int X, int Y, int Z); + + /// returns -1 on fail + int eggBuffPlayer(CNSocket* sock, int skillId, int duration); } diff --git a/src/NanoManager.cpp b/src/NanoManager.cpp index 72d1a40..2a153cc 100644 --- a/src/NanoManager.cpp +++ b/src/NanoManager.cpp @@ -800,7 +800,7 @@ void NanoManager::nanoBuff(CNSocket* sock, int16_t nanoId, int skillId, int16_t pkt1.eCSTB = eCharStatusTimeBuffID; // eCharStatusTimeBuffID pkt1.eTBU = 1; // eTimeBuffUpdate pkt1.eTBT = 1; // eTimeBuffType 1 means nano - pkt1.iConditionBitFlag = bitFlag | varPlr->iConditionBitFlag; + pkt1.iConditionBitFlag = bitFlag | varPlr->iConditionBitFlag | varPlr->iEggConditionBitFlag; if (iValue > 0) pkt1.TimeBuff.iValue = iValue; @@ -852,7 +852,7 @@ void NanoManager::nanoUnbuff(CNSocket* sock, int32_t iCBFlag, int16_t eCharStatu resp1.eCSTB = eCharStatusTimeBuffID; // eCharStatusTimeBuffID resp1.eTBU = 2; // eTimeBuffUpdate resp1.eTBT = 1; // eTimeBuffType 1 means nano - resp1.iConditionBitFlag = bitFlag | varPlr->iConditionBitFlag; + resp1.iConditionBitFlag = bitFlag | varPlr->iConditionBitFlag | varPlr->iEggConditionBitFlag; if (iValue > 0) resp1.TimeBuff.iValue = iValue; diff --git a/src/Player.hpp b/src/Player.hpp index 0ecf1dd..9962f83 100644 --- a/src/Player.hpp +++ b/src/Player.hpp @@ -2,6 +2,7 @@ #include #include +#include #include "CNProtocol.hpp" #include "CNStructs.hpp" @@ -69,6 +70,8 @@ struct Player { int32_t groupIDs[4]; int32_t iGroupConditionBitFlag; + int32_t iEggConditionBitFlag; + bool notify; bool buddiesSynced;