diff --git a/src/ChatManager.cpp b/src/ChatManager.cpp index e6b7537..71aaf54 100644 --- a/src/ChatManager.cpp +++ b/src/ChatManager.cpp @@ -8,6 +8,7 @@ #include "MobManager.hpp" #include "MissionManager.hpp" #include "ChunkManager.hpp" +#include "ItemManager.hpp" #include #include @@ -716,6 +717,49 @@ void unhideCommand(std::string full, std::vector& args, CNSocket* s ChatManager::sendServerMessage(sock, "[HIDE] Successfully un-hidden from the map."); } +void redeemCommand(std::string full, std::vector& args, CNSocket* sock) { + if (args.size() < 2) { + ChatManager::sendServerMessage(sock, "/redeem: no code specified"); + return; + } + + std::string code = args[1]; + if (ItemManager::CodeItems.find(code) == ItemManager::CodeItems.end()) { + ChatManager::sendServerMessage(sock, "/redeem: Unknown code"); + return; + } + + Player* plr = PlayerManager::getPlayer(sock); + int slotNum = ItemManager::findFreeSlot(plr); + + // no space + if (slotNum == -1) { + ChatManager::sendServerMessage(sock, "/redeem: Inventory full"); + return; + } + + std::pair item = ItemManager::CodeItems[code]; + INITSTRUCT(sP_FE2CL_REP_PC_GIVE_ITEM_SUCC, resp); + + resp.eIL = 1; + resp.iSlotNum = slotNum; + // just in case it's a vehicle + if (item.second == 10) { + // set time limit: current time + 7days + resp.Item.iTimeLimit = getTimestamp() + 604800; + } + resp.Item.iID = item.first; + resp.Item.iType = item.second; + // I think it is safe? :eyes + resp.Item.iOpt = 1; + + // save serverside + plr->Inven[resp.iSlotNum] = resp.Item; + + sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_GIVE_ITEM_SUCC, sizeof(sP_FE2CL_REP_PC_GIVE_ITEM_SUCC)); + ChatManager::sendServerMessage(sock, "You have redeemed a code item"); +} + void ChatManager::init() { REGISTER_SHARD_PACKET(P_CL2FE_REQ_SEND_FREECHAT_MESSAGE, chatHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_AVATAR_EMOTES_CHAT, emoteHandler); @@ -748,6 +792,7 @@ void ChatManager::init() { registerCommand("lair", 50, lairUnlockCommand, "get the required mission for the nearest fusion lair"); registerCommand("hide", 100, hideCommand, "hide yourself from the global player map"); registerCommand("unhide", 100, unhideCommand, "un-hide yourself from the global player map"); + registerCommand("redeem", 100, redeemCommand, "redeem a code item"); } void ChatManager::registerCommand(std::string cmd, int requiredLevel, CommandHandler handlr, std::string help) { diff --git a/src/ItemManager.cpp b/src/ItemManager.cpp index 6f9fce4..7c89dfc 100644 --- a/src/ItemManager.cpp +++ b/src/ItemManager.cpp @@ -16,6 +16,7 @@ std::map> ItemManager::RarityRatios; std::map ItemManager::Crates; // pair Itemset, Rarity -> vector of pointers (map iterators) to records in ItemData std::map, std::vector, ItemManager::Item>::iterator>> ItemManager::CrateItems; +std::map> ItemManager::CodeItems; #ifdef ACADEMY std::map ItemManager::NanoCapsules; // crate id -> nano id diff --git a/src/ItemManager.hpp b/src/ItemManager.hpp index 725da4a..90a2dff 100644 --- a/src/ItemManager.hpp +++ b/src/ItemManager.hpp @@ -34,6 +34,7 @@ namespace ItemManager { // pair -> vector of pointers (map iterators) to records in ItemData (it looks a lot scarier than it is) extern std::map, std::vector, Item>::iterator>> CrateItems; + extern std::map> CodeItems; // code -> void init(); diff --git a/src/TableData.cpp b/src/TableData.cpp index fb4ea46..e227bbc 100644 --- a/src/TableData.cpp +++ b/src/TableData.cpp @@ -578,6 +578,12 @@ void TableData::loadDrops() { ItemManager::NanoCapsules[(int)capsule["Crate"]] = (int)capsule["Nano"]; } #endif + nlohmann::json codes = dropData["Codes"]; + for (nlohmann::json::iterator _code = codes.begin(); _code != codes.end(); _code++) { + auto code = _code.value(); + std::pair item = std::make_pair((int)code["Id"], (int)code["Type"]); + ItemManager::CodeItems[code["Code"]] = item; + } std::cout << "[INFO] Loaded " << ItemManager::Crates.size() << " Crates containing " << itemCount << " items" << std::endl;