#include "NPCManager.hpp" #include "settings.hpp" #include #include #include #include #include "contrib/JSON.hpp" std::map NPCManager::NPCs; void NPCManager::init() { // load NPCs from NPCs.json into our NPC manager try { std::ifstream inFile("NPCs.json"); nlohmann::json jsonData; // read file into jsonData inFile >> jsonData; for (auto& npc : jsonData) { BaseNPC tmp(npc["x"], npc["y"], npc["z"], npc["id"]); NPCManager::NPCs[tmp.appearanceData.iNPC_ID] = tmp; } std::cout << "populated " << NPCs.size() << " NPCs" << std::endl; } catch (const std::exception& err) { std::cerr << "[WARN] Malformed NPC.json file! Reason:" << std::endl << err.what() << std::endl; } } #undef CHECKNPC void NPCManager::updatePlayerNPCS(CNSocket* sock, PlayerView& view) { std::list yesView; std::list noView; for (auto& pair : NPCs) { int diffX = abs(view.plr.x - pair.second.appearanceData.iX); int diffY = abs(view.plr.y - pair.second.appearanceData.iY); if (diffX < settings::VIEWDISTANCE && diffY < settings::VIEWDISTANCE) { yesView.push_back(pair.first); } else { noView.push_back(pair.first); } } INITSTRUCT(sP_FE2CL_NPC_EXIT, exitData); std::list::iterator i = view.viewableNPCs.begin(); while (i != view.viewableNPCs.end()) { int32_t id = *i; if (std::find(noView.begin(), noView.end(), id) != noView.end()) { // it shouldn't be visible, send NPC_EXIT exitData.iNPC_ID = id; sock->sendPacket((void*)&exitData, P_FE2CL_NPC_EXIT, sizeof(sP_FE2CL_NPC_EXIT)); // remove from view view.viewableNPCs.erase(i++); } ++i; } INITSTRUCT(sP_FE2CL_NPC_ENTER, enterData); for (int32_t id : yesView) { if (std::find(view.viewableNPCs.begin(), view.viewableNPCs.end(), id) == view.viewableNPCs.end()) { // needs to be added to viewableNPCs! send NPC_ENTER enterData.NPCAppearanceData = NPCs[id].appearanceData; sock->sendPacket((void*)&enterData, P_FE2CL_NPC_ENTER, sizeof(sP_FE2CL_NPC_ENTER)); // add to viewable view.viewableNPCs.push_back(id); } } PlayerManager::players[sock].viewableNPCs = view.viewableNPCs; }