mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-05 06:50:04 +00:00
dongresource
72d625fd8d
Unfortunetly, this necessitated keeping around yet more JSON objects for the duration of the server's runtime. It also involved unifying the way NPC IDs are handled, such that they may be allocated and deallocated out of order. If any NPCID-related bugs occour, this commit should be regarded as the prime suspect.
256 lines
10 KiB
C++
256 lines
10 KiB
C++
#include "TableData.hpp"
|
|
#include "NPCManager.hpp"
|
|
#include "TransportManager.hpp"
|
|
#include "ItemManager.hpp"
|
|
#include "settings.hpp"
|
|
#include "MissionManager.hpp"
|
|
#include "MobManager.hpp"
|
|
#include "ChunkManager.hpp"
|
|
|
|
#include "contrib/JSON.hpp"
|
|
|
|
#include <fstream>
|
|
|
|
void TableData::init() {
|
|
int32_t nextId = 0;
|
|
|
|
// load NPCs from NPC.json
|
|
try {
|
|
std::ifstream inFile(settings::NPCJSON);
|
|
nlohmann::json npcData;
|
|
|
|
// read file into json
|
|
inFile >> npcData;
|
|
|
|
for (nlohmann::json::iterator _npc = npcData.begin(); _npc != npcData.end(); _npc++) {
|
|
auto npc = _npc.value();
|
|
BaseNPC *tmp = new BaseNPC(npc["x"], npc["y"], npc["z"], npc["id"], nextId);
|
|
|
|
NPCManager::NPCs[nextId] = tmp;
|
|
ChunkManager::addNPC(npc["x"], npc["y"], nextId);
|
|
nextId++;
|
|
|
|
if (npc["id"] == 641 || npc["id"] == 642)
|
|
NPCManager::RespawnPoints.push_back({ npc["x"], npc["y"], ((int)npc["z"]) + RESURRECT_HEIGHT });
|
|
}
|
|
|
|
}
|
|
catch (const std::exception& err) {
|
|
std::cerr << "[WARN] Malformed NPCs.json file! Reason:" << err.what() << std::endl;
|
|
}
|
|
|
|
loadPaths(); // load paths
|
|
|
|
// load everything else from xdttable
|
|
std::cout << "[INFO] Parsing xdt.json..." << std::endl;
|
|
std::ifstream infile(settings::XDTJSON);
|
|
nlohmann::json xdtData;
|
|
|
|
// read file into json
|
|
infile >> xdtData;
|
|
|
|
// data we'll need for summoned mobs
|
|
NPCManager::NPCData = xdtData["m_pNpcTable"]["m_pNpcData"];
|
|
|
|
try {
|
|
// load warps
|
|
nlohmann::json warpData = xdtData["m_pInstanceTable"]["m_pWarpData"];
|
|
|
|
for (nlohmann::json::iterator _warp = warpData.begin(); _warp != warpData.end(); _warp++) {
|
|
auto warp = _warp.value();
|
|
WarpLocation warpLoc = { warp["m_iToX"], warp["m_iToY"], warp["m_iToZ"] };
|
|
int warpID = warp["m_iWarpNumber"];
|
|
NPCManager::Warps[warpID] = warpLoc;
|
|
}
|
|
|
|
std::cout << "[INFO] Populated " << NPCManager::Warps.size() << " Warps" << std::endl;
|
|
|
|
// load transport routes and locations
|
|
nlohmann::json transRouteData = xdtData["m_pTransportationTable"]["m_pTransportationData"];
|
|
nlohmann::json transLocData = xdtData["m_pTransportationTable"]["m_pTransportationWarpLocation"];
|
|
|
|
for (nlohmann::json::iterator _tLoc = transLocData.begin(); _tLoc != transLocData.end(); _tLoc++) {
|
|
auto tLoc = _tLoc.value();
|
|
TransportLocation transLoc = { tLoc["m_iNPCID"], tLoc["m_iXpos"], tLoc["m_iYpos"], tLoc["m_iZpos"] };
|
|
TransportManager::Locations[tLoc["m_iLocationID"]] = transLoc;
|
|
}
|
|
std::cout << "[INFO] Loaded " << TransportManager::Locations.size() << " S.C.A.M.P.E.R. locations" << std::endl;
|
|
|
|
for (nlohmann::json::iterator _tRoute = transRouteData.begin(); _tRoute != transRouteData.end(); _tRoute++) {
|
|
auto tRoute = _tRoute.value();
|
|
TransportRoute transRoute = { tRoute["m_iMoveType"], tRoute["m_iStartLocation"], tRoute["m_iEndLocation"],
|
|
tRoute["m_iCost"] , tRoute["m_iSpeed"], tRoute["m_iRouteNum"] };
|
|
TransportManager::Routes[tRoute["m_iVehicleID"]] = transRoute;
|
|
}
|
|
std::cout << "[INFO] Loaded " << TransportManager::Routes.size() << " transportation routes" << std::endl;
|
|
|
|
// load mission-related data
|
|
nlohmann::json tasks = xdtData["m_pMissionTable"]["m_pMissionData"];
|
|
|
|
for (auto _task = tasks.begin(); _task != tasks.end(); _task++) {
|
|
auto task = _task.value();
|
|
|
|
// rewards
|
|
if (task["m_iSUReward"] != 0) {
|
|
auto _rew = xdtData["m_pMissionTable"]["m_pRewardData"][(int)task["m_iSUReward"]];
|
|
Reward *rew = new Reward(_rew["m_iMissionRewardID"], _rew["m_iMissionRewarItemType"],
|
|
_rew["m_iMissionRewardItemID"], _rew["m_iCash"], _rew["m_iFusionMatter"]);
|
|
|
|
MissionManager::Rewards[task["m_iHTaskID"]] = rew;
|
|
}
|
|
|
|
// everything else lol. see TaskData comment.
|
|
MissionManager::Tasks[task["m_iHTaskID"]] = new TaskData(task);
|
|
}
|
|
|
|
std::cout << "[INFO] Loaded mission-related data" << std::endl;
|
|
|
|
// load all item data. i'm sorry. it has to be done
|
|
const char* setNames[12] = { "m_pBackItemTable", "m_pFaceItemTable", "m_pGlassItemTable", "m_pHatItemTable",
|
|
"m_pHeadItemTable", "m_pPantsItemTable", "m_pShirtsItemTable", "m_pShoesItemTable", "m_pWeaponItemTable",
|
|
"m_pVehicleItemTable", "m_pGeneralItemTable", "m_pChestItemTable" };
|
|
nlohmann::json itemSet;
|
|
for (int i = 0; i < 12; i++) {
|
|
itemSet = xdtData[setNames[i]]["m_pItemData"];
|
|
for (nlohmann::json::iterator _item = itemSet.begin(); _item != itemSet.end(); _item++) {
|
|
auto item = _item.value();
|
|
int typeOverride = getItemType(i); // used for special cases where iEquipLoc doesn't indicate item type
|
|
ItemManager::ItemData[std::pair<int32_t, int32_t>(item["m_iItemNumber"], typeOverride != -1 ? typeOverride : (int)item["m_iEquipLoc"])]
|
|
= { item["m_iTradeAble"] == 1, item["m_iSellAble"] == 1, item["m_iItemPrice"], item["m_iItemSellPrice"], item["m_iStackNumber"], i > 9 ? 0 : (int)item["m_iMinReqLev"],
|
|
i > 9 ? 1 : (int)item["m_iRarity"] };
|
|
}
|
|
}
|
|
|
|
std::cout << "[INFO] Loaded " << ItemManager::ItemData.size() << " items" << std::endl;
|
|
|
|
// load player limits from m_pAvatarTable.m_pAvatarGrowData
|
|
|
|
nlohmann::json growth = xdtData["m_pAvatarTable"]["m_pAvatarGrowData"];
|
|
|
|
for (int i = 0; i < 36; i++) {
|
|
MissionManager::AvatarGrowth[i] = growth[i];
|
|
}
|
|
|
|
// load vendor listings
|
|
nlohmann::json listings = xdtData["m_pVendorTable"]["m_pItemData"];
|
|
|
|
for (nlohmann::json::iterator _lst = listings.begin(); _lst != listings.end(); _lst++) {
|
|
auto lst = _lst.value();
|
|
VendorListing vListing = { lst["m_iSortNumber"], lst["m_iItemType"], lst["m_iitemID"] };
|
|
ItemManager::VendorTables[lst["m_iNpcNumber"]].push_back(vListing);
|
|
}
|
|
|
|
std::cout << "[INFO] Loaded " << ItemManager::VendorTables.size() << " vendor tables" << std::endl;
|
|
|
|
// load crocpot entries
|
|
nlohmann::json crocs = xdtData["m_pCombiningTable"]["m_pCombiningData"];
|
|
|
|
for (nlohmann::json::iterator croc = crocs.begin(); croc != crocs.end(); croc++) {
|
|
CrocPotEntry crocEntry = { croc.value()["m_iStatConstant"], croc.value()["m_iLookConstant"], croc.value()["m_fLevelGapStandard"],
|
|
croc.value()["m_fSameGrade"], croc.value()["m_fOneGrade"], croc.value()["m_fTwoGrade"], croc.value()["m_fThreeGrade"] };
|
|
ItemManager::CrocPotTable[croc.value()["m_iLevelGap"]] = crocEntry;
|
|
}
|
|
|
|
std::cout << "[INFO] Loaded " << ItemManager::CrocPotTable.size() << " croc pot value sets" << std::endl;
|
|
}
|
|
catch (const std::exception& err) {
|
|
std::cerr << "[WARN] Malformed xdt.json file! Reason:" << err.what() << std::endl;
|
|
}
|
|
|
|
// load temporary mob dump
|
|
try {
|
|
std::ifstream inFile(settings::MOBJSON);
|
|
nlohmann::json npcData;
|
|
|
|
// read file into json
|
|
inFile >> npcData;
|
|
|
|
for (nlohmann::json::iterator _npc = npcData.begin(); _npc != npcData.end(); _npc++) {
|
|
auto npc = _npc.value();
|
|
auto td = NPCManager::NPCData[(int)npc["iNPCType"]];
|
|
Mob *tmp = new Mob(npc["iX"], npc["iY"], npc["iZ"], npc["iNPCType"], npc["iHP"], npc["iAngle"], td, nextId);
|
|
|
|
NPCManager::NPCs[nextId] = tmp;
|
|
MobManager::Mobs[nextId] = (Mob*)NPCManager::NPCs[nextId];
|
|
ChunkManager::addNPC(npc["iX"], npc["iY"], nextId);
|
|
|
|
nextId++;
|
|
}
|
|
|
|
std::cout << "[INFO] Populated " << NPCManager::NPCs.size() << " NPCs" << std::endl;
|
|
}
|
|
catch (const std::exception& err) {
|
|
std::cerr << "[WARN] Malformed mobs.json file! Reason:" << err.what() << std::endl;
|
|
}
|
|
|
|
NPCManager::nextId = nextId;
|
|
}
|
|
|
|
/*
|
|
* Some item categories either don't possess iEquipLoc or use a different value for item type.
|
|
*/
|
|
int TableData::getItemType(int itemSet) {
|
|
int overriden;
|
|
switch (itemSet)
|
|
{
|
|
case 11: // Chest items don't have iEquipLoc and are type 9.
|
|
overriden = 9;
|
|
break;
|
|
case 10: // General items don't have iEquipLoc and are type 7.
|
|
overriden = 7;
|
|
break;
|
|
case 9: // Vehicles have iEquipLoc 8, but type 10.
|
|
overriden = 10;
|
|
break;
|
|
default:
|
|
overriden = -1;
|
|
}
|
|
return overriden;
|
|
}
|
|
|
|
/*
|
|
* Load paths from paths JSON.
|
|
*/
|
|
void TableData::loadPaths() {
|
|
try {
|
|
std::ifstream inFile(settings::PATHJSON);
|
|
nlohmann::json pathData;
|
|
|
|
// read file into json
|
|
inFile >> pathData;
|
|
|
|
// skyway paths
|
|
nlohmann::json pathDataSkyway = pathData["skyway"];
|
|
for (nlohmann::json::iterator skywayPath = pathDataSkyway.begin(); skywayPath != pathDataSkyway.end(); skywayPath++) {
|
|
constructPath(skywayPath);
|
|
}
|
|
|
|
std::cout << "[INFO] Loaded " << TransportManager::SkywayPaths.size() << " skyway paths" << std::endl;
|
|
}
|
|
catch (const std::exception& err) {
|
|
std::cerr << "[WARN] Malformed paths.json file! Reason:" << err.what() << std::endl;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Create a full and properly-paced Skyway System path by interpolating between keyframes.
|
|
*/
|
|
void TableData::constructPath(nlohmann::json::iterator _pathData) {
|
|
auto pathData = _pathData.value();
|
|
// Interpolate
|
|
nlohmann::json pathPoints = pathData["points"];
|
|
std::queue<WarpLocation> points;
|
|
nlohmann::json::iterator _point = pathPoints.begin();
|
|
auto point = _point.value();
|
|
WarpLocation last = { point["iX"] , point["iY"] , point["iZ"] }; // start pos
|
|
// use some for loop trickery; start position should not be a point
|
|
for (_point++; _point != pathPoints.end(); _point++) {
|
|
point = _point.value();
|
|
WarpLocation coords = { point["iX"] , point["iY"] , point["iZ"] };
|
|
TransportManager::lerp(&points, last, coords, pathData["iMonkeySpeed"]);
|
|
points.push(coords); // add keyframe to the queue
|
|
last = coords; // update start pos
|
|
}
|
|
TransportManager::SkywayPaths[pathData["iRouteID"]] = points;
|
|
}
|