mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-22 13:30:06 +00:00
[refac] Compartmentalize TableData.cpp
This commit is contained in:
parent
14562f889e
commit
e761c700dc
@ -82,16 +82,198 @@ static void constructPathNPC(json::iterator _pathData, int32_t id=0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load paths from paths JSON.
|
* Load all relevant data from the XDT into memory
|
||||||
|
* This should be called first, before any of the other load functions
|
||||||
*/
|
*/
|
||||||
static void loadPaths(int* nextId) {
|
static void loadXDT(json& xdtData) {
|
||||||
|
// data we'll need for summoned mobs
|
||||||
|
NPCManager::NPCData = xdtData["m_pNpcTable"]["m_pNpcData"];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
std::ifstream inFile(settings::PATHJSON);
|
// load warps
|
||||||
json pathData;
|
json warpData = xdtData["m_pInstanceTable"]["m_pWarpData"];
|
||||||
|
|
||||||
// read file into json
|
for (json::iterator _warp = warpData.begin(); _warp != warpData.end(); _warp++) {
|
||||||
inFile >> pathData;
|
auto warp = _warp.value();
|
||||||
|
WarpLocation warpLoc = { warp["m_iToX"], warp["m_iToY"], warp["m_iToZ"], warp["m_iToMapNum"], warp["m_iIsInstance"], warp["m_iLimit_TaskID"], warp["m_iNpcNumber"] };
|
||||||
|
int warpID = warp["m_iWarpNumber"];
|
||||||
|
NPCManager::Warps[warpID] = warpLoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "[INFO] Loaded " << NPCManager::Warps.size() << " Warps" << std::endl;
|
||||||
|
|
||||||
|
// load transport routes and locations
|
||||||
|
json transRouteData = xdtData["m_pTransportationTable"]["m_pTransportationData"];
|
||||||
|
json transLocData = xdtData["m_pTransportationTable"]["m_pTransportationWarpLocation"];
|
||||||
|
|
||||||
|
for (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"] };
|
||||||
|
Transport::Locations[tLoc["m_iLocationID"]] = transLoc;
|
||||||
|
}
|
||||||
|
std::cout << "[INFO] Loaded " << Transport::Locations.size() << " S.C.A.M.P.E.R. locations" << std::endl;
|
||||||
|
|
||||||
|
for (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"] };
|
||||||
|
Transport::Routes[tRoute["m_iVehicleID"]] = transRoute;
|
||||||
|
}
|
||||||
|
std::cout << "[INFO] Loaded " << Transport::Routes.size() << " transportation routes" << std::endl;
|
||||||
|
|
||||||
|
// load mission-related data
|
||||||
|
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"]);
|
||||||
|
|
||||||
|
Missions::Rewards[task["m_iHTaskID"]] = rew;
|
||||||
|
}
|
||||||
|
|
||||||
|
// everything else lol. see TaskData comment.
|
||||||
|
Missions::Tasks[task["m_iHTaskID"]] = new TaskData(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "[INFO] Loaded mission-related data" << std::endl;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* load all equipment data. i'm sorry. it has to be done
|
||||||
|
* NOTE: please don't change the ordering. it determines the types, since type and equipLoc are used inconsistently
|
||||||
|
*/
|
||||||
|
const char* setNames[11] = { "m_pWeaponItemTable", "m_pShirtsItemTable", "m_pPantsItemTable", "m_pShoesItemTable",
|
||||||
|
"m_pHatItemTable", "m_pGlassItemTable", "m_pBackItemTable", "m_pGeneralItemTable", "",
|
||||||
|
"m_pChestItemTable", "m_pVehicleItemTable" };
|
||||||
|
json itemSet;
|
||||||
|
for (int i = 0; i < 11; i++) {
|
||||||
|
if (i == 8)
|
||||||
|
continue; // there is no type 8, of course
|
||||||
|
|
||||||
|
itemSet = xdtData[setNames[i]]["m_pItemData"];
|
||||||
|
for (json::iterator _item = itemSet.begin(); _item != itemSet.end(); _item++) {
|
||||||
|
auto item = _item.value();
|
||||||
|
int itemID = item["m_iItemNumber"];
|
||||||
|
INITSTRUCT(Items::Item, itemData);
|
||||||
|
itemData.tradeable = item["m_iTradeAble"] == 1;
|
||||||
|
itemData.sellable = item["m_iSellAble"] == 1;
|
||||||
|
itemData.buyPrice = item["m_iItemPrice"];
|
||||||
|
itemData.sellPrice = item["m_iItemSellPrice"];
|
||||||
|
itemData.stackSize = item["m_iStackNumber"];
|
||||||
|
if (i != 7 && i != 9) {
|
||||||
|
itemData.rarity = item["m_iRarity"];
|
||||||
|
itemData.level = item["m_iMinReqLev"];
|
||||||
|
itemData.pointDamage = item["m_iPointRat"];
|
||||||
|
itemData.groupDamage = item["m_iGroupRat"];
|
||||||
|
itemData.fireRate = item["m_iDelayTime"];
|
||||||
|
itemData.defense = item["m_iDefenseRat"];
|
||||||
|
itemData.gender = item["m_iReqSex"];
|
||||||
|
itemData.weaponType = item["m_iEquipType"];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
itemData.rarity = 1;
|
||||||
|
}
|
||||||
|
Items::ItemData[std::make_pair(itemID, i)] = itemData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "[INFO] Loaded " << Items::ItemData.size() << " items" << std::endl;
|
||||||
|
|
||||||
|
// load player limits from m_pAvatarTable.m_pAvatarGrowData
|
||||||
|
|
||||||
|
json growth = xdtData["m_pAvatarTable"]["m_pAvatarGrowData"];
|
||||||
|
|
||||||
|
for (int i = 0; i < 37; i++) {
|
||||||
|
Missions::AvatarGrowth[i] = growth[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// load vendor listings
|
||||||
|
json listings = xdtData["m_pVendorTable"]["m_pItemData"];
|
||||||
|
|
||||||
|
for (json::iterator _lst = listings.begin(); _lst != listings.end(); _lst++) {
|
||||||
|
auto lst = _lst.value();
|
||||||
|
VendorListing vListing = { lst["m_iSortNumber"], lst["m_iItemType"], lst["m_iitemID"] };
|
||||||
|
Vendors::VendorTables[lst["m_iNpcNumber"]].push_back(vListing);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "[INFO] Loaded " << Vendors::VendorTables.size() << " vendor tables" << std::endl;
|
||||||
|
|
||||||
|
// load crocpot entries
|
||||||
|
json crocs = xdtData["m_pCombiningTable"]["m_pCombiningData"];
|
||||||
|
|
||||||
|
for (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"] };
|
||||||
|
Items::CrocPotTable[croc.value()["m_iLevelGap"]] = crocEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "[INFO] Loaded " << Items::CrocPotTable.size() << " croc pot value sets" << std::endl;
|
||||||
|
|
||||||
|
// load nano info
|
||||||
|
json nanoInfo = xdtData["m_pNanoTable"]["m_pNanoData"];
|
||||||
|
for (json::iterator _nano = nanoInfo.begin(); _nano != nanoInfo.end(); _nano++) {
|
||||||
|
auto nano = _nano.value();
|
||||||
|
NanoData nanoData;
|
||||||
|
nanoData.style = nano["m_iStyle"];
|
||||||
|
Nanos::NanoTable[Nanos::NanoTable.size()] = nanoData;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "[INFO] Loaded " << Nanos::NanoTable.size() << " nanos" << std::endl;
|
||||||
|
|
||||||
|
json nanoTuneInfo = xdtData["m_pNanoTable"]["m_pNanoTuneData"];
|
||||||
|
for (json::iterator _nano = nanoTuneInfo.begin(); _nano != nanoTuneInfo.end(); _nano++) {
|
||||||
|
auto nano = _nano.value();
|
||||||
|
NanoTuning nanoData;
|
||||||
|
nanoData.reqItems = nano["m_iReqItemID"];
|
||||||
|
nanoData.reqItemCount = nano["m_iReqItemCount"];
|
||||||
|
Nanos::NanoTunings[nano["m_iSkillID"]] = nanoData;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "[INFO] Loaded " << Nanos::NanoTable.size() << " nano tunings" << std::endl;
|
||||||
|
|
||||||
|
// load nano powers
|
||||||
|
json skills = xdtData["m_pSkillTable"]["m_pSkillData"];
|
||||||
|
|
||||||
|
for (json::iterator _skills = skills.begin(); _skills != skills.end(); _skills++) {
|
||||||
|
auto skills = _skills.value();
|
||||||
|
SkillData skillData = { skills["m_iSkillType"], skills["m_iTargetType"], skills["m_iBatteryDrainType"], skills["m_iEffectArea"] };
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
skillData.batteryUse[i] = skills["m_iBatteryDrainUse"][i];
|
||||||
|
skillData.durationTime[i] = skills["m_iDurationTime"][i];
|
||||||
|
skillData.powerIntensity[i] = skills["m_iValueA"][i];
|
||||||
|
}
|
||||||
|
Nanos::SkillTable[skills["m_iSkillNumber"]] = skillData;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "[INFO] Loaded " << Nanos::SkillTable.size() << " nano skills" << std::endl;
|
||||||
|
|
||||||
|
// load EP data
|
||||||
|
json instances = xdtData["m_pInstanceTable"]["m_pInstanceData"];
|
||||||
|
|
||||||
|
for (json::iterator _instance = instances.begin(); _instance != instances.end(); _instance++) {
|
||||||
|
auto instance = _instance.value();
|
||||||
|
EPInfo epInfo = { instance["m_iZoneX"], instance["m_iZoneY"], instance["m_iIsEP"], (int)instance["m_ScoreMax"] };
|
||||||
|
Racing::EPData[instance["m_iInstanceNameID"]] = epInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "[INFO] Loaded " << Racing::EPData.size() << " instances" << std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (const std::exception& err) {
|
||||||
|
std::cerr << "[FATAL] Malformed xdt.json file! Reason:" << err.what() << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load paths from JSON
|
||||||
|
*/
|
||||||
|
static void loadPaths(json& pathData, int32_t* nextId) {
|
||||||
|
try {
|
||||||
// skyway paths
|
// skyway paths
|
||||||
json pathDataSkyway = pathData["skyway"];
|
json pathDataSkyway = pathData["skyway"];
|
||||||
for (json::iterator skywayPath = pathDataSkyway.begin(); skywayPath != pathDataSkyway.end(); skywayPath++) {
|
for (json::iterator skywayPath = pathDataSkyway.begin(); skywayPath != pathDataSkyway.end(); skywayPath++) {
|
||||||
@ -191,17 +373,11 @@ static void loadPaths(int* nextId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load drops data from JSON.
|
* Load drops data from JSON
|
||||||
* This has to be called after reading xdt because it reffers to ItemData!!!
|
* This has to be called after reading xdt because it reffers to ItemData!!!
|
||||||
*/
|
*/
|
||||||
static void loadDrops() {
|
static void loadDrops(json& dropData) {
|
||||||
try {
|
try {
|
||||||
std::ifstream inFile(settings::DROPSJSON);
|
|
||||||
json dropData;
|
|
||||||
|
|
||||||
// read file into json
|
|
||||||
inFile >> dropData;
|
|
||||||
|
|
||||||
// CrateDropChances
|
// CrateDropChances
|
||||||
json crateDropChances = dropData["CrateDropChances"];
|
json crateDropChances = dropData["CrateDropChances"];
|
||||||
for (json::iterator _crateDropChance = crateDropChances.begin(); _crateDropChance != crateDropChances.end(); _crateDropChance++) {
|
for (json::iterator _crateDropChance = crateDropChances.begin(); _crateDropChance != crateDropChances.end(); _crateDropChance++) {
|
||||||
@ -459,14 +635,11 @@ static void loadDrops() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loadEggs(int32_t* nextId) {
|
/*
|
||||||
|
* Load eggs from JSON
|
||||||
|
*/
|
||||||
|
static void loadEggs(json& eggData, int32_t* nextId) {
|
||||||
try {
|
try {
|
||||||
std::ifstream inFile(settings::EGGSJSON);
|
|
||||||
json eggData;
|
|
||||||
|
|
||||||
// read file into json
|
|
||||||
inFile >> eggData;
|
|
||||||
|
|
||||||
// EggTypes
|
// EggTypes
|
||||||
json eggTypes = eggData["EggTypes"];
|
json eggTypes = eggData["EggTypes"];
|
||||||
for (json::iterator _eggType = eggTypes.begin(); _eggType != eggTypes.end(); _eggType++) {
|
for (json::iterator _eggType = eggTypes.begin(); _eggType != eggTypes.end(); _eggType++) {
|
||||||
@ -502,18 +675,14 @@ static void loadEggs(int32_t* nextId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// load gruntwork output; if it exists
|
/*
|
||||||
static void loadGruntwork(int32_t *nextId) {
|
* Load gruntwork output; if it exists
|
||||||
|
*/
|
||||||
|
static void loadGruntwork(json& gruntwork, int32_t* nextId) {
|
||||||
|
|
||||||
|
if (gruntwork.is_null()) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
std::ifstream inFile(settings::GRUNTWORKJSON);
|
|
||||||
json gruntwork;
|
|
||||||
|
|
||||||
// skip if there's no gruntwork to load
|
|
||||||
if (inFile.fail())
|
|
||||||
return;
|
|
||||||
|
|
||||||
inFile >> gruntwork;
|
|
||||||
|
|
||||||
// skyway paths
|
// skyway paths
|
||||||
auto skyway = gruntwork["skyway"];
|
auto skyway = gruntwork["skyway"];
|
||||||
for (auto _route = skyway.begin(); _route != skyway.end(); _route++) {
|
for (auto _route = skyway.begin(); _route != skyway.end(); _route++) {
|
||||||
@ -647,16 +816,11 @@ static void loadGruntwork(int32_t *nextId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TableData::init() {
|
/*
|
||||||
int32_t nextId = INT32_MAX; // next dynamic ID to hand out
|
* Load NPCs from JSON
|
||||||
|
*/
|
||||||
// load NPCs from NPC.json
|
static void loadNPCs(json& npcData, int32_t* nextId) {
|
||||||
try {
|
try {
|
||||||
std::ifstream inFile(settings::NPCJSON);
|
|
||||||
json npcData;
|
|
||||||
|
|
||||||
// read file into json
|
|
||||||
inFile >> npcData;
|
|
||||||
npcData = npcData["NPCs"];
|
npcData = npcData["NPCs"];
|
||||||
for (json::iterator _npc = npcData.begin(); _npc != npcData.end(); _npc++) {
|
for (json::iterator _npc = npcData.begin(); _npc != npcData.end(); _npc++) {
|
||||||
auto npc = _npc.value();
|
auto npc = _npc.value();
|
||||||
@ -664,15 +828,15 @@ void TableData::init() {
|
|||||||
#ifdef ACADEMY
|
#ifdef ACADEMY
|
||||||
// do not spawn NPCs in the future
|
// do not spawn NPCs in the future
|
||||||
if (npc["iX"] > 512000 && npc["iY"] < 256000) {
|
if (npc["iX"] > 512000 && npc["iY"] < 256000) {
|
||||||
nextId--;
|
(*nextId)--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
BaseNPC *tmp = new BaseNPC(npc["iX"], npc["iY"], npc["iZ"], npc["iAngle"], instanceID, npc["iNPCType"], nextId);
|
BaseNPC* tmp = new BaseNPC(npc["iX"], npc["iY"], npc["iZ"], npc["iAngle"], instanceID, npc["iNPCType"], *nextId);
|
||||||
|
|
||||||
NPCManager::NPCs[nextId] = tmp;
|
NPCManager::NPCs[*nextId] = tmp;
|
||||||
NPCManager::updateNPCPosition(nextId, npc["iX"], npc["iY"], npc["iZ"], instanceID, npc["iAngle"]);
|
NPCManager::updateNPCPosition(*nextId, npc["iX"], npc["iY"], npc["iZ"], instanceID, npc["iAngle"]);
|
||||||
nextId--;
|
(*nextId)--;
|
||||||
|
|
||||||
if (npc["iNPCType"] == 641 || npc["iNPCType"] == 642)
|
if (npc["iNPCType"] == 641 || npc["iNPCType"] == 642)
|
||||||
NPCManager::RespawnPoints.push_back({ npc["iX"], npc["iY"], ((int)npc["iZ"]) + RESURRECT_HEIGHT, instanceID });
|
NPCManager::RespawnPoints.push_back({ npc["iX"], npc["iY"], ((int)npc["iZ"]) + RESURRECT_HEIGHT, instanceID });
|
||||||
@ -682,204 +846,14 @@ void TableData::init() {
|
|||||||
std::cerr << "[FATAL] Malformed NPCs.json file! Reason:" << err.what() << std::endl;
|
std::cerr << "[FATAL] Malformed NPCs.json file! Reason:" << err.what() << std::endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// load everything else from xdttable
|
/*
|
||||||
std::cout << "[INFO] Parsing xdt.json..." << std::endl;
|
* Load mobs from JSON
|
||||||
std::ifstream infile(settings::XDTJSON);
|
|
||||||
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
|
|
||||||
json warpData = xdtData["m_pInstanceTable"]["m_pWarpData"];
|
|
||||||
|
|
||||||
for (json::iterator _warp = warpData.begin(); _warp != warpData.end(); _warp++) {
|
|
||||||
auto warp = _warp.value();
|
|
||||||
WarpLocation warpLoc = { warp["m_iToX"], warp["m_iToY"], warp["m_iToZ"], warp["m_iToMapNum"], warp["m_iIsInstance"], warp["m_iLimit_TaskID"], warp["m_iNpcNumber"] };
|
|
||||||
int warpID = warp["m_iWarpNumber"];
|
|
||||||
NPCManager::Warps[warpID] = warpLoc;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "[INFO] Populated " << NPCManager::Warps.size() << " Warps" << std::endl;
|
|
||||||
|
|
||||||
// load transport routes and locations
|
|
||||||
json transRouteData = xdtData["m_pTransportationTable"]["m_pTransportationData"];
|
|
||||||
json transLocData = xdtData["m_pTransportationTable"]["m_pTransportationWarpLocation"];
|
|
||||||
|
|
||||||
for (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"] };
|
|
||||||
Transport::Locations[tLoc["m_iLocationID"]] = transLoc;
|
|
||||||
}
|
|
||||||
std::cout << "[INFO] Loaded " << Transport::Locations.size() << " S.C.A.M.P.E.R. locations" << std::endl;
|
|
||||||
|
|
||||||
for (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"] };
|
|
||||||
Transport::Routes[tRoute["m_iVehicleID"]] = transRoute;
|
|
||||||
}
|
|
||||||
std::cout << "[INFO] Loaded " << Transport::Routes.size() << " transportation routes" << std::endl;
|
|
||||||
|
|
||||||
// load mission-related data
|
|
||||||
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"]);
|
|
||||||
|
|
||||||
Missions::Rewards[task["m_iHTaskID"]] = rew;
|
|
||||||
}
|
|
||||||
|
|
||||||
// everything else lol. see TaskData comment.
|
|
||||||
Missions::Tasks[task["m_iHTaskID"]] = new TaskData(task);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "[INFO] Loaded mission-related data" << std::endl;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* load all equipment data. i'm sorry. it has to be done
|
|
||||||
* NOTE: please don't change the ordering. it determines the types, since type and equipLoc are used inconsistently
|
|
||||||
*/
|
*/
|
||||||
const char* setNames[11] = { "m_pWeaponItemTable", "m_pShirtsItemTable", "m_pPantsItemTable", "m_pShoesItemTable",
|
static void loadMobs(json& npcData, int32_t* nextId) {
|
||||||
"m_pHatItemTable", "m_pGlassItemTable", "m_pBackItemTable", "m_pGeneralItemTable", "",
|
|
||||||
"m_pChestItemTable", "m_pVehicleItemTable" };
|
|
||||||
json itemSet;
|
|
||||||
for (int i = 0; i < 11; i++) {
|
|
||||||
if (i == 8)
|
|
||||||
continue; // there is no type 8, of course
|
|
||||||
|
|
||||||
itemSet = xdtData[setNames[i]]["m_pItemData"];
|
|
||||||
for (json::iterator _item = itemSet.begin(); _item != itemSet.end(); _item++) {
|
|
||||||
auto item = _item.value();
|
|
||||||
int itemID = item["m_iItemNumber"];
|
|
||||||
INITSTRUCT(Items::Item, itemData);
|
|
||||||
itemData.tradeable = item["m_iTradeAble"] == 1;
|
|
||||||
itemData.sellable = item["m_iSellAble"] == 1;
|
|
||||||
itemData.buyPrice = item["m_iItemPrice"];
|
|
||||||
itemData.sellPrice = item["m_iItemSellPrice"];
|
|
||||||
itemData.stackSize = item["m_iStackNumber"];
|
|
||||||
if (i != 7 && i != 9) {
|
|
||||||
itemData.rarity = item["m_iRarity"];
|
|
||||||
itemData.level = item["m_iMinReqLev"];
|
|
||||||
itemData.pointDamage = item["m_iPointRat"];
|
|
||||||
itemData.groupDamage = item["m_iGroupRat"];
|
|
||||||
itemData.fireRate = item["m_iDelayTime"];
|
|
||||||
itemData.defense = item["m_iDefenseRat"];
|
|
||||||
itemData.gender = item["m_iReqSex"];
|
|
||||||
itemData.weaponType = item["m_iEquipType"];
|
|
||||||
} else {
|
|
||||||
itemData.rarity = 1;
|
|
||||||
}
|
|
||||||
Items::ItemData[std::make_pair(itemID, i)] = itemData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "[INFO] Loaded " << Items::ItemData.size() << " items" << std::endl;
|
|
||||||
|
|
||||||
// load player limits from m_pAvatarTable.m_pAvatarGrowData
|
|
||||||
|
|
||||||
json growth = xdtData["m_pAvatarTable"]["m_pAvatarGrowData"];
|
|
||||||
|
|
||||||
for (int i = 0; i < 37; i++) {
|
|
||||||
Missions::AvatarGrowth[i] = growth[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// load vendor listings
|
|
||||||
json listings = xdtData["m_pVendorTable"]["m_pItemData"];
|
|
||||||
|
|
||||||
for (json::iterator _lst = listings.begin(); _lst != listings.end(); _lst++) {
|
|
||||||
auto lst = _lst.value();
|
|
||||||
VendorListing vListing = { lst["m_iSortNumber"], lst["m_iItemType"], lst["m_iitemID"] };
|
|
||||||
Vendors::VendorTables[lst["m_iNpcNumber"]].push_back(vListing);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "[INFO] Loaded " << Vendors::VendorTables.size() << " vendor tables" << std::endl;
|
|
||||||
|
|
||||||
// load crocpot entries
|
|
||||||
json crocs = xdtData["m_pCombiningTable"]["m_pCombiningData"];
|
|
||||||
|
|
||||||
for (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"] };
|
|
||||||
Items::CrocPotTable[croc.value()["m_iLevelGap"]] = crocEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "[INFO] Loaded " << Items::CrocPotTable.size() << " croc pot value sets" << std::endl;
|
|
||||||
|
|
||||||
// load nano info
|
|
||||||
json nanoInfo = xdtData["m_pNanoTable"]["m_pNanoData"];
|
|
||||||
for (json::iterator _nano = nanoInfo.begin(); _nano != nanoInfo.end(); _nano++) {
|
|
||||||
auto nano = _nano.value();
|
|
||||||
NanoData nanoData;
|
|
||||||
nanoData.style = nano["m_iStyle"];
|
|
||||||
Nanos::NanoTable[Nanos::NanoTable.size()] = nanoData;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "[INFO] Loaded " << Nanos::NanoTable.size() << " nanos" << std::endl;
|
|
||||||
|
|
||||||
json nanoTuneInfo = xdtData["m_pNanoTable"]["m_pNanoTuneData"];
|
|
||||||
for (json::iterator _nano = nanoTuneInfo.begin(); _nano != nanoTuneInfo.end(); _nano++) {
|
|
||||||
auto nano = _nano.value();
|
|
||||||
NanoTuning nanoData;
|
|
||||||
nanoData.reqItems = nano["m_iReqItemID"];
|
|
||||||
nanoData.reqItemCount = nano["m_iReqItemCount"];
|
|
||||||
Nanos::NanoTunings[nano["m_iSkillID"]] = nanoData;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "[INFO] Loaded " << Nanos::NanoTable.size() << " nano tunings" << std::endl;
|
|
||||||
|
|
||||||
// load nano powers
|
|
||||||
json skills = xdtData["m_pSkillTable"]["m_pSkillData"];
|
|
||||||
|
|
||||||
for (json::iterator _skills = skills.begin(); _skills != skills.end(); _skills++) {
|
|
||||||
auto skills = _skills.value();
|
|
||||||
SkillData skillData = {skills["m_iSkillType"], skills["m_iTargetType"], skills["m_iBatteryDrainType"], skills["m_iEffectArea"]};
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
skillData.batteryUse[i] = skills["m_iBatteryDrainUse"][i];
|
|
||||||
skillData.durationTime[i] = skills["m_iDurationTime"][i];
|
|
||||||
skillData.powerIntensity[i] = skills["m_iValueA"][i];
|
|
||||||
}
|
|
||||||
Nanos::SkillTable[skills["m_iSkillNumber"]] = skillData;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "[INFO] Loaded " << Nanos::SkillTable.size() << " nano skills" << std::endl;
|
|
||||||
|
|
||||||
// load EP data
|
|
||||||
json instances = xdtData["m_pInstanceTable"]["m_pInstanceData"];
|
|
||||||
|
|
||||||
for (json::iterator _instance = instances.begin(); _instance != instances.end(); _instance++) {
|
|
||||||
auto instance = _instance.value();
|
|
||||||
EPInfo epInfo = {instance["m_iZoneX"], instance["m_iZoneY"], instance["m_iIsEP"], (int)instance["m_ScoreMax"]};
|
|
||||||
Racing::EPData[instance["m_iInstanceNameID"]] = epInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "[INFO] Loaded " << Racing::EPData.size() << " instances" << std::endl;
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (const std::exception& err) {
|
|
||||||
std::cerr << "[FATAL] Malformed xdt.json file! Reason:" << err.what() << std::endl;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// load mobs
|
|
||||||
try {
|
try {
|
||||||
std::ifstream inFile(settings::MOBJSON);
|
json groupData = npcData["groups"];
|
||||||
json npcData, groupData;
|
|
||||||
|
|
||||||
// read file into json
|
|
||||||
inFile >> npcData;
|
|
||||||
groupData = npcData["groups"];
|
|
||||||
npcData = npcData["mobs"];
|
npcData = npcData["mobs"];
|
||||||
|
|
||||||
// single mobs
|
// single mobs
|
||||||
@ -891,17 +865,17 @@ void TableData::init() {
|
|||||||
#ifdef ACADEMY
|
#ifdef ACADEMY
|
||||||
// do not spawn NPCs in the future
|
// do not spawn NPCs in the future
|
||||||
if (npc["iX"] > 512000 && npc["iY"] < 256000) {
|
if (npc["iX"] > 512000 && npc["iY"] < 256000) {
|
||||||
nextId--;
|
(*nextId)--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Mob *tmp = new Mob(npc["iX"], npc["iY"], npc["iZ"], npc["iAngle"], instanceID, npc["iNPCType"], td, nextId);
|
Mob* tmp = new Mob(npc["iX"], npc["iY"], npc["iZ"], npc["iAngle"], instanceID, npc["iNPCType"], td, *nextId);
|
||||||
|
|
||||||
NPCManager::NPCs[nextId] = tmp;
|
NPCManager::NPCs[*nextId] = tmp;
|
||||||
NPCManager::updateNPCPosition(nextId, npc["iX"], npc["iY"], npc["iZ"], instanceID, npc["iAngle"]);
|
NPCManager::updateNPCPosition(*nextId, npc["iX"], npc["iY"], npc["iZ"], instanceID, npc["iAngle"]);
|
||||||
|
|
||||||
nextId--;
|
(*nextId)--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// mob groups
|
// mob groups
|
||||||
@ -915,95 +889,121 @@ void TableData::init() {
|
|||||||
#ifdef ACADEMY
|
#ifdef ACADEMY
|
||||||
// do not spawn NPCs in the future
|
// do not spawn NPCs in the future
|
||||||
if (leader["iX"] > 512000 && leader["iY"] < 256000) {
|
if (leader["iX"] > 512000 && leader["iY"] < 256000) {
|
||||||
nextId--;
|
(*nextId)--;
|
||||||
nextId -= followers.size();
|
(*nextId) -= followers.size();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Mob* tmp = new Mob(leader["iX"], leader["iY"], leader["iZ"], leader["iAngle"], instanceID, leader["iNPCType"], td, nextId);
|
Mob* tmp = new Mob(leader["iX"], leader["iY"], leader["iZ"], leader["iAngle"], instanceID, leader["iNPCType"], td, *nextId);
|
||||||
|
|
||||||
NPCManager::NPCs[nextId] = tmp;
|
NPCManager::NPCs[*nextId] = tmp;
|
||||||
NPCManager::updateNPCPosition(nextId, leader["iX"], leader["iY"], leader["iZ"], instanceID, leader["iAngle"]);
|
NPCManager::updateNPCPosition(*nextId, leader["iX"], leader["iY"], leader["iZ"], instanceID, leader["iAngle"]);
|
||||||
|
|
||||||
tmp->groupLeader = nextId;
|
tmp->groupLeader = *nextId;
|
||||||
|
|
||||||
nextId--;
|
(*nextId)--;
|
||||||
|
|
||||||
if (followers.size() < 5) {
|
if (followers.size() < 5) {
|
||||||
int followerCount = 0;
|
int followerCount = 0;
|
||||||
for (json::iterator _fol = followers.begin(); _fol != followers.end(); _fol++) {
|
for (json::iterator _fol = followers.begin(); _fol != followers.end(); _fol++) {
|
||||||
auto follower = _fol.value();
|
auto follower = _fol.value();
|
||||||
auto tdFol = NPCManager::NPCData[(int)follower["iNPCType"]];
|
auto tdFol = NPCManager::NPCData[(int)follower["iNPCType"]];
|
||||||
Mob* tmpFol = new Mob((int)leader["iX"] + (int)follower["iOffsetX"], (int)leader["iY"] + (int)follower["iOffsetY"], leader["iZ"], leader["iAngle"], instanceID, follower["iNPCType"], tdFol, nextId);
|
Mob* tmpFol = new Mob((int)leader["iX"] + (int)follower["iOffsetX"], (int)leader["iY"] + (int)follower["iOffsetY"], leader["iZ"], leader["iAngle"], instanceID, follower["iNPCType"], tdFol, *nextId);
|
||||||
|
|
||||||
NPCManager::NPCs[nextId] = tmpFol;
|
NPCManager::NPCs[*nextId] = tmpFol;
|
||||||
NPCManager::updateNPCPosition(nextId, (int)leader["iX"] + (int)follower["iOffsetX"], (int)leader["iY"] + (int)follower["iOffsetY"], leader["iZ"], instanceID, leader["iAngle"]);
|
NPCManager::updateNPCPosition(*nextId, (int)leader["iX"] + (int)follower["iOffsetX"], (int)leader["iY"] + (int)follower["iOffsetY"], leader["iZ"], instanceID, leader["iAngle"]);
|
||||||
|
|
||||||
tmpFol->offsetX = follower.find("iOffsetX") == follower.end() ? 0 : (int)follower["iOffsetX"];
|
tmpFol->offsetX = follower.find("iOffsetX") == follower.end() ? 0 : (int)follower["iOffsetX"];
|
||||||
tmpFol->offsetY = follower.find("iOffsetY") == follower.end() ? 0 : (int)follower["iOffsetY"];
|
tmpFol->offsetY = follower.find("iOffsetY") == follower.end() ? 0 : (int)follower["iOffsetY"];
|
||||||
tmpFol->groupLeader = tmp->appearanceData.iNPC_ID;
|
tmpFol->groupLeader = tmp->appearanceData.iNPC_ID;
|
||||||
tmp->groupMember[followerCount++] = nextId;
|
tmp->groupMember[followerCount++] = *nextId;
|
||||||
|
|
||||||
nextId--;
|
(*nextId)--;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
std::cout << "[WARN] Mob group leader with ID " << nextId << " has too many followers (" << followers.size() << ")\n";
|
else {
|
||||||
|
std::cout << "[WARN] Mob group leader with ID " << *nextId << " has too many followers (" << followers.size() << ")\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "[INFO] Populated " << NPCManager::NPCs.size() << " NPCs" << std::endl;
|
std::cout << "[INFO] Loaded " << NPCManager::NPCs.size() << " NPCs" << std::endl;
|
||||||
}
|
}
|
||||||
catch (const std::exception& err) {
|
catch (const std::exception& err) {
|
||||||
std::cerr << "[FATAL] Malformed mobs.json file! Reason:" << err.what() << std::endl;
|
std::cerr << "[FATAL] Malformed mobs.json file! Reason:" << err.what() << std::endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ACADEMY
|
static void loadingError(const char* which) {
|
||||||
// load Academy NPCs from academy.json
|
std::cerr << "[FATAL] Critical tdata file missing: " << which << std::endl;
|
||||||
try {
|
|
||||||
std::ifstream inFile(settings::ACADEMYJSON);
|
|
||||||
json npcData;
|
|
||||||
|
|
||||||
// read file into json
|
|
||||||
inFile >> npcData;
|
|
||||||
npcData = npcData["NPCs"];
|
|
||||||
for (json::iterator _npc = npcData.begin(); _npc != npcData.end(); _npc++) {
|
|
||||||
auto npc = _npc.value();
|
|
||||||
int instanceID = npc.find("iMapNum") == npc.end() ? INSTANCE_OVERWORLD : (int)npc["iMapNum"];
|
|
||||||
|
|
||||||
int team = NPCManager::NPCData[(int)npc["iNPCType"]]["m_iTeam"];
|
|
||||||
|
|
||||||
if (team == 2)
|
|
||||||
NPCManager::NPCs[nextId] = new Mob(npc["iX"], npc["iY"], npc["iZ"], npc["iAngle"], instanceID, npc["iNPCType"], NPCManager::NPCData[(int)npc["iNPCType"]], nextId);
|
|
||||||
else
|
|
||||||
NPCManager::NPCs[nextId] = new BaseNPC(npc["iX"], npc["iY"], npc["iZ"], npc["iAngle"], instanceID, npc["iNPCType"], nextId);
|
|
||||||
|
|
||||||
NPCManager::updateNPCPosition(nextId, npc["iX"], npc["iY"], npc["iZ"], instanceID, npc["iAngle"]);
|
|
||||||
nextId--;
|
|
||||||
|
|
||||||
if (npc["iNPCType"] == 641 || npc["iNPCType"] == 642)
|
|
||||||
NPCManager::RespawnPoints.push_back({ npc["iX"], npc["iY"], ((int)npc["iZ"]) + RESURRECT_HEIGHT, instanceID });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (const std::exception& err) {
|
|
||||||
std::cerr << "[FATAL] Malformed academy.json file! Reason:" << err.what() << std::endl;
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
loadDrops();
|
void TableData::init() {
|
||||||
|
int32_t nextId = INT32_MAX; // next dynamic ID to hand out
|
||||||
|
|
||||||
loadEggs(&nextId);
|
// base JSON tables
|
||||||
|
json xdt;
|
||||||
|
json paths;
|
||||||
|
json drops;
|
||||||
|
json eggs;
|
||||||
|
json npcs;
|
||||||
|
json mobs;
|
||||||
|
json gruntwork;
|
||||||
|
|
||||||
loadPaths(&nextId); // load paths
|
// open file streams
|
||||||
|
std::ifstream fXDT(settings::XDTJSON);
|
||||||
|
std::ifstream fPaths(settings::PATHJSON);
|
||||||
|
std::ifstream fDrops(settings::DROPSJSON);
|
||||||
|
std::ifstream fEggs(settings::EGGSJSON);
|
||||||
|
std::ifstream fNPCs(settings::NPCJSON);
|
||||||
|
std::ifstream fMobs(settings::MOBJSON);
|
||||||
|
std::ifstream fGruntwork(settings::GRUNTWORKJSON);
|
||||||
|
|
||||||
loadGruntwork(&nextId);
|
if (fXDT.fail()) loadingError("XDT.json");
|
||||||
|
if (fPaths.fail()) loadingError("paths.json");
|
||||||
|
if (fDrops.fail()) loadingError("drops.json");
|
||||||
|
if (fEggs.fail()) loadingError("eggs.json");
|
||||||
|
if (fNPCs.fail()) loadingError("NPCs.json");
|
||||||
|
if (fMobs.fail()) loadingError("mobs.json");
|
||||||
|
|
||||||
|
// read contents into json tables
|
||||||
|
fXDT >> xdt;
|
||||||
|
fPaths >> paths;
|
||||||
|
fDrops >> drops;
|
||||||
|
fEggs >> eggs;
|
||||||
|
fNPCs >> npcs;
|
||||||
|
fMobs >> mobs;
|
||||||
|
if (!fGruntwork.fail()) fGruntwork >> gruntwork;
|
||||||
|
|
||||||
|
// close file streams
|
||||||
|
fXDT.close();
|
||||||
|
fPaths.close();
|
||||||
|
fDrops.close();
|
||||||
|
fEggs.close();
|
||||||
|
fNPCs.close();
|
||||||
|
fMobs.close();
|
||||||
|
fGruntwork.close();
|
||||||
|
|
||||||
|
// TODO patching system
|
||||||
|
|
||||||
|
// fetch data from patched tables and load them appropriately
|
||||||
|
// note: the order of these is important
|
||||||
|
loadXDT(xdt);
|
||||||
|
loadNPCs(npcs, &nextId);
|
||||||
|
loadMobs(mobs, &nextId);
|
||||||
|
loadDrops(drops);
|
||||||
|
loadEggs(eggs, &nextId);
|
||||||
|
loadPaths(paths, &nextId);
|
||||||
|
loadGruntwork(gruntwork, &nextId);
|
||||||
|
|
||||||
NPCManager::nextId = nextId;
|
NPCManager::nextId = nextId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// write gruntwork output to file
|
/*
|
||||||
|
* Write gruntwork output to file
|
||||||
|
*/
|
||||||
void TableData::flush() {
|
void TableData::flush() {
|
||||||
std::ofstream file(settings::GRUNTWORKJSON);
|
std::ofstream file(settings::GRUNTWORKJSON);
|
||||||
json gruntwork;
|
json gruntwork;
|
||||||
|
Loading…
Reference in New Issue
Block a user