diff --git a/config.ini b/config.ini index b37d439..86c280d 100644 --- a/config.ini +++ b/config.ini @@ -37,6 +37,8 @@ xdtdata=tdata/xdt.json mobdata=tdata/mobs.json # path json pathdata=tdata/paths.json +# gruntwork output (this is what you submit) +gruntwork=tdata/gruntwork.json # account permission level that will be set upon character creation # 1 = default, will allow *all* commands diff --git a/src/CNShardServer.cpp b/src/CNShardServer.cpp index 029e214..0a5dae7 100644 --- a/src/CNShardServer.cpp +++ b/src/CNShardServer.cpp @@ -6,6 +6,7 @@ #include "CNShared.hpp" #include "settings.hpp" #include "Database.hpp" +#include "TableData.hpp" // for flush() #include #include @@ -56,6 +57,7 @@ void CNShardServer::periodicSaveTimer(CNServer* serv, time_t currTime) { Database::updatePlayer(pair.second.plr); } + TableData::flush(); std::cout << "[INFO] Done." << std::endl; } diff --git a/src/ChatManager.cpp b/src/ChatManager.cpp index a5314b1..59dae23 100644 --- a/src/ChatManager.cpp +++ b/src/ChatManager.cpp @@ -99,7 +99,7 @@ void mssCommand(std::string full, std::vector& args, CNSocket* sock if (args.size() < 3) { ChatManager::sendServerMessage(sock, "[MSS] Too few arguments"); - ChatManager::sendServerMessage(sock, "[MSS] Usage: /mss <>"); + ChatManager::sendServerMessage(sock, "[MSS] Usage: /mss <>"); return; } @@ -167,26 +167,16 @@ void mssCommand(std::string full, std::vector& args, CNSocket* sock return; } - // IMPROMPTU LERP - int speed = 1500; // TODO: make this adjustable - std::queue path; - WarpLocation last = route->front(); // start pos - PlayerManager::sendPlayerTo(sock, last.x, last.y, last.z); // send the player to the start of the path - for (int i = 1; i < route->size(); i++) { - WarpLocation coords = route->at(i); - TransportManager::lerp(&path, last, coords, speed); - path.push(coords); // add keyframe to the queue - last = coords; // update start pos - } - - TransportManager::SkywayQueues[sock] = path; + WarpLocation pulled = route->front(); + PlayerManager::sendPlayerTo(sock, pulled.x, pulled.y, pulled.z); + TransportManager::testMssRoute(sock, route); return; } - // mss export + // for compatibility: mss export if (args[2] == "export") { ChatManager::sendServerMessage(sock, "[MSS] export on " + std::to_string(routeNum)); - // TODO: dump route to tdata + TableData::flush(); return; } @@ -195,6 +185,11 @@ void mssCommand(std::string full, std::vector& args, CNSocket* sock } +void flushCommand(std::string full, std::vector& args, CNSocket* sock) { + ChatManager::sendServerMessage(sock, "Wrote gruntwork to " + settings::GRUNTWORKJSON); + TableData::flush(); +} + void ChatManager::init() { REGISTER_SHARD_PACKET(P_CL2FE_REQ_SEND_FREECHAT_MESSAGE, chatHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_AVATAR_EMOTES_CHAT, emoteHandler); @@ -204,6 +199,7 @@ void ChatManager::init() { registerCommand("access", 100, accessCommand); // TODO: add help command registerCommand("mss", 30, mssCommand); + registerCommand("flush", 30, flushCommand); registerCommand("level", 50, levelCommand); registerCommand("population", 100, populationCommand); } diff --git a/src/TableData.cpp b/src/TableData.cpp index e9d09e6..0a8b1d3 100644 --- a/src/TableData.cpp +++ b/src/TableData.cpp @@ -196,6 +196,8 @@ void TableData::init() { std::cerr << "[WARN] Malformed mobs.json file! Reason:" << err.what() << std::endl; } + loadGruntwork(); + NPCManager::nextId = nextId; } @@ -290,7 +292,6 @@ void TableData::constructPathSkyway(nlohmann::json::iterator _pathData) { } void TableData::constructPathSlider(nlohmann::json points, int rotations, int sliderID) { - std::queue route; std::rotate(points.begin(), points.begin() + rotations, points.end()); // rotate points nlohmann::json::iterator _point = points.begin(); // iterator @@ -336,3 +337,64 @@ void TableData::constructPathNPC(nlohmann::json::iterator _pathData) { } TransportManager::NPCQueues[pathData["iNPCID"]] = points; } + +// load gruntwork output; if it exists +void TableData::loadGruntwork() { + try { + std::ifstream inFile(settings::GRUNTWORKJSON); + nlohmann::json gruntwork; + + // skip if there's no gruntwork to load + if (inFile.fail()) + return; + + inFile >> gruntwork; + + // skyway paths + auto skyway = gruntwork["skyway"]; + for (auto _route = skyway.begin(); _route != skyway.end(); _route++) { + auto route = _route.value(); + std::vector points; + + for (auto _point = route["points"].begin(); _point != route["points"].end(); _point++) { + auto point = _point.value(); + points.push_back(WarpLocation{point["x"], point["y"], point["z"]}); + } + + RunningSkywayRoutes[(int)route["iRouteID"]] = points; + } + + std::cout << "[INFO] Loaded gruntwork.json" << std::endl; + } + catch (const std::exception& err) { + std::cerr << "[WARN] Malformed gruntwork.json file! Reason:" << err.what() << std::endl; + } +} + +// write gruntwork output to file +void TableData::flush() { + std::ofstream file(settings::GRUNTWORKJSON); + nlohmann::json gruntwork; + + for (auto& pair : RunningSkywayRoutes) { + nlohmann::json route; + + route["iRouteID"] = (int)pair.first; + route["iMonkeySpeed"] = 1500; // TODO + + std::cout << "serializing mss route " << (int)pair.first << std::endl; + for (WarpLocation& point : pair.second) { + nlohmann::json tmp; + + tmp["x"] = point.x; + tmp["y"] = point.y; + tmp["z"] = point.z; + + route["points"].push_back(tmp); + } + + gruntwork["skyway"].push_back(route); + } + + file << gruntwork << std::endl; +} diff --git a/src/TableData.hpp b/src/TableData.hpp index adba0ae..2913f87 100644 --- a/src/TableData.hpp +++ b/src/TableData.hpp @@ -9,6 +9,8 @@ namespace TableData { void init(); void cleanup(); + void loadGruntwork(); + void flush(); int getItemType(int); void loadPaths(int*); diff --git a/src/TransportManager.cpp b/src/TransportManager.cpp index 84a9f89..45c4e15 100644 --- a/src/TransportManager.cpp +++ b/src/TransportManager.cpp @@ -3,6 +3,7 @@ #include "PlayerManager.hpp" #include "NanoManager.hpp" #include "TransportManager.hpp" +#include "TableData.hpp" #include #include @@ -157,6 +158,12 @@ void TransportManager::transportWarpHandler(CNSocket* sock, CNPacketData* data) NanoManager::summonNano(sock, -1); // make sure that no nano is active during the ride SkywayQueues[sock] = SkywayPaths[route.mssRouteNum]; // set socket point queue to route break; + } else if (TableData::RunningSkywayRoutes.find(route.mssRouteNum) != TableData::RunningSkywayRoutes.end()) { + std::vector* _route = &TableData::RunningSkywayRoutes[route.mssRouteNum]; + + NanoManager::summonNano(sock, -1); + testMssRoute(sock, _route); + break; } // refund and send alert packet @@ -184,6 +191,21 @@ void TransportManager::transportWarpHandler(CNSocket* sock, CNPacketData* data) sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_WARP_USE_TRANSPORTATION_SUCC, sizeof(sP_FE2CL_REP_PC_WARP_USE_TRANSPORTATION_SUCC)); } +void TransportManager::testMssRoute(CNSocket *sock, std::vector* route) { + int speed = 1500; // TODO: make this adjustable + std::queue path; + WarpLocation last = route->front(); // start pos + + for (int i = 1; i < route->size(); i++) { + WarpLocation coords = route->at(i); + TransportManager::lerp(&path, last, coords, speed); + path.push(coords); // add keyframe to the queue + last = coords; // update start pos + } + + SkywayQueues[sock] = path; +} + void TransportManager::tickTransportationSystem(CNServer* serv, time_t currTime) { stepNPCPathing(); stepSkywaySystem(); diff --git a/src/TransportManager.hpp b/src/TransportManager.hpp index 7df3825..2967b2d 100644 --- a/src/TransportManager.hpp +++ b/src/TransportManager.hpp @@ -30,6 +30,8 @@ namespace TransportManager { void transportRegisterLocationHandler(CNSocket*, CNPacketData*); void transportWarpHandler(CNSocket*, CNPacketData*); + void testMssRoute(CNSocket *sock, std::vector* route); + void tickTransportationSystem(CNServer*, time_t); void stepNPCPathing(); void stepSkywaySystem(); diff --git a/src/settings.cpp b/src/settings.cpp index 5f50807..dad9ef3 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -24,6 +24,7 @@ std::string settings::NPCJSON = "tdata/NPCs.json"; std::string settings::XDTJSON = "tdata/xdt.json"; std::string settings::MOBJSON = "tdata/mobs.json"; std::string settings::PATHJSON = "tdata/paths.json"; +std::string settings::GRUNTWORKJSON = "tdata/gruntwork.json"; std::string settings::MOTDSTRING = "Welcome to OpenFusion!"; int settings::ACCLEVEL = 1; @@ -56,6 +57,7 @@ void settings::init() { XDTJSON = reader.Get("shard", "xdtdata", XDTJSON); MOBJSON = reader.Get("shard", "mobdata", MOBJSON); PATHJSON = reader.Get("shard", "pathdata", PATHJSON); + GRUNTWORKJSON = reader.Get("shard", "gruntwork", GRUNTWORKJSON); MOTDSTRING = reader.Get("shard", "motd", MOTDSTRING); ACCLEVEL = reader.GetInteger("shard", "accountlevel", ACCLEVEL); } diff --git a/src/settings.hpp b/src/settings.hpp index 19006f3..915eefd 100644 --- a/src/settings.hpp +++ b/src/settings.hpp @@ -20,6 +20,7 @@ namespace settings { extern std::string XDTJSON; extern std::string MOBJSON; extern std::string PATHJSON; + extern std::string GRUNTWORKJSON; void init(); }