From 1423709e822746e77af6e7d9851d1d88ef2b38ab Mon Sep 17 00:00:00 2001 From: Webster Sheets Date: Fri, 15 Sep 2023 01:27:14 -0400 Subject: [PATCH] CustomSystem: support loading Json partial systems - Migration path for old 02_local_stars.lua - CustomSystem definitions use nicer storage values for sector position - Loads full system definitions from systems/custom - Loads partial system definitions from systems/partial - Add example Json-based partial system def --- data/systems/02_local_stars.lua | 2 +- data/systems/partial/02_local_stars.json | 3 + src/galaxy/CustomSystem.cpp | 96 +++++++++++++++++------- src/galaxy/CustomSystem.h | 2 +- src/galaxy/Factions.cpp | 6 +- src/galaxy/StarSystem.cpp | 6 +- 6 files changed, 80 insertions(+), 35 deletions(-) create mode 100644 data/systems/partial/02_local_stars.json diff --git a/data/systems/02_local_stars.lua b/data/systems/02_local_stars.lua index 35a1ea336f9..a983534ba95 100644 --- a/data/systems/02_local_stars.lua +++ b/data/systems/02_local_stars.lua @@ -1,7 +1,7 @@ -- Copyright © 2008-2023 Pioneer Developers. See AUTHORS.txt for details -- Licensed under the terms of the GPL v3. See licenses/GPL-3.txt -CustomSystem:new('GJ 1075',{'STAR_K'}):add_to_sector(2,-1,-4,v(0.451,0.409,0.034)) +-- CustomSystem:new('GJ 1075',{'STAR_K'}):add_to_sector(2,-1,-4,v(0.451,0.409,0.034)) CustomSystem:new('NN 3707',{'STAR_M'}):add_to_sector(-1,3,-1,v(0.845,0.512,0.054)) CustomSystem:new('NN 3253',{'STAR_M'}):add_to_sector(3,-2,1,v(0.185,0.023,0.148)) CustomSystem:new('Gliese 766',{'STAR_M','STAR_M'}):add_to_sector(-4,-2,1,v(0.511,0.265,0.998)) diff --git a/data/systems/partial/02_local_stars.json b/data/systems/partial/02_local_stars.json new file mode 100644 index 00000000000..42876ea24bd --- /dev/null +++ b/data/systems/partial/02_local_stars.json @@ -0,0 +1,3 @@ +[ + {"name":"GJ 1075","stars":["STAR_K"],"sector":[2,-1,-4],"pos":[3.608,3.272,0.272]} +] diff --git a/src/galaxy/CustomSystem.cpp b/src/galaxy/CustomSystem.cpp index ab6a6e6cbad..939f0ae8f0b 100644 --- a/src/galaxy/CustomSystem.cpp +++ b/src/galaxy/CustomSystem.cpp @@ -642,16 +642,21 @@ void CustomSystem::LoadFromJson(const Json &systemdef) primaryType[starIdx++] = SystemBody::BodyType(EnumStrings::GetValue("BodyType", type.get().c_str())); } - sectorX = systemdef["sectorX"]; - sectorY = systemdef["sectorY"]; - sectorZ = systemdef["sectorZ"]; + const Json §or = systemdef["sector"]; + sectorX = sector[0].get(); + sectorZ = sector[1].get(); + sectorY = sector[2].get(); - pos = systemdef["pos"]; - seed = systemdef["seed"]; + const Json &position = systemdef["pos"]; + pos.x = sector[0].get(); + pos.y = sector[1].get(); + pos.z = sector[2].get(); + + seed = systemdef.value("seed", 0); explored = systemdef.value("explored", true); lawlessness = systemdef.value("lawlessness", 0); - want_rand_seed = false; + want_rand_seed = !systemdef.count("seed"); want_rand_explored = !systemdef.count("explored"); want_rand_lawlessness = !systemdef.count("lawlessness"); @@ -678,11 +683,8 @@ void CustomSystem::SaveToJson(Json &obj) obj["numStars"] = numStars; - obj["sectorX"] = sectorX; - obj["sectorY"] = sectorY; - obj["sectorZ"] = sectorZ; - - obj["pos"] = pos; + obj["sector"] = Json::array({ sectorX, sectorY, sectorZ }); + obj["pos"] = Json::array({ pos.x, pos.y, pos.z }); obj["seed"] = seed; if (!want_rand_explored) @@ -760,18 +762,37 @@ void CustomSystemsDatabase::Load() LoadAllLuaSystems(); - auto enumerator = FileSystem::FileEnumerator(FileSystem::gameDataFiles, m_customSysDirectory, FileSystem::FileEnumerator::Recurse); - for (auto &file : enumerator) { + // Load Json array files containing random-fill system definitions + std::string partialPath = FileSystem::JoinPathBelow(m_customSysDirectory, "partial"); + for (auto &file : FileSystem::gameDataFiles.Recurse(partialPath)) { if (!ends_with_ci(file.GetPath(), ".json")) continue; - PROFILE_SCOPED_DESC("Load Custom System File") - + PROFILE_SCOPED_DESC("Load Partial System List") const Json fileData = JsonUtils::LoadJsonDataFile(file.GetPath()); - CustomSystem *sys = LoadSystemFromJSON(file.GetPath(), fileData); + for (const Json &sysdef : fileData) { + if (!sysdef.is_object()) + continue; - SystemPath path(sys->sectorX, sys->sectorY, sys->sectorZ); - AddCustomSystem(path, sys); + LoadSystemFromJSON(file.GetPath(), sysdef); + } + } + + // Load top-level custom system defines + for (auto &file : FileSystem::gameDataFiles.Enumerate(m_customSysDirectory, 0)) { + if (!ends_with_ci(file.GetPath(), ".json")) + continue; + + LoadSystemFromJSON(file.GetPath(), JsonUtils::LoadJsonDataFile(file.GetPath())); + } + + // Load all complete custom system definitions + std::string customPath = FileSystem::JoinPathBelow(m_customSysDirectory, "custom"); + for (auto &file : FileSystem::gameDataFiles.Recurse(customPath)) { + if (!ends_with_ci(file.GetPath(), ".json")) + continue; + + LoadSystemFromJSON(file.GetPath(), JsonUtils::LoadJsonDataFile(file.GetPath())); } } @@ -813,7 +834,7 @@ const CustomSystem *CustomSystemsDatabase::LoadSystem(std::string_view filepath) return m_sectorMap[m_lastAddedSystem.first][m_lastAddedSystem.second]; } -CustomSystem *CustomSystemsDatabase::LoadSystemFromJSON(std::string_view filename, const Json &systemdef) +CustomSystem *CustomSystemsDatabase::LoadSystemFromJSON(std::string_view filename, const Json &systemdef, bool mergeWithGalaxy) { PROFILE_SCOPED() @@ -826,8 +847,8 @@ CustomSystem *CustomSystemsDatabase::LoadSystemFromJSON(std::string_view filenam // Validate number of stars constexpr int MAX_STARS = COUNTOF(sys->primaryType); if (sys->numStars > MAX_STARS) { - Log::Warning("Custom system {} defines {} stars of {} max! Extra stars will not be used in Sector generation.", - filename, sys->numStars, MAX_STARS); + Log::Warning("Custom system {} ({}) defines {} stars of {} max! Extra stars will not be used in Sector generation.", + sys->name, filename, sys->numStars, MAX_STARS); sys->numStars = MAX_STARS; } @@ -839,12 +860,30 @@ CustomSystem *CustomSystemsDatabase::LoadSystemFromJSON(std::string_view filenam } else { sys->faction = GetGalaxy()->GetFactions()->GetFaction(factionName); if (sys->faction->idx == Faction::BAD_FACTION_IDX) { - Log::Warning("Unknown faction {} for custom system {}.", factionName, filename); + Log::Warning("Unknown faction {} for custom system {} ({}).", factionName, sys->name, filename); sys->faction = nullptr; } } } + if (sys->want_rand_seed) { + Random rand = { + hash_32_fnv1a(sys->name.data(), sys->name.size()), + uint32_t(sys->sectorX), uint32_t(sys->sectorY), uint32_t(sys->sectorZ), UNIVERSE_SEED + }; + + sys->seed = rand.Int32(); + sys->want_rand_seed = false; + } + + // Partially-defined system, return as-is + if (!systemdef.count("bodies")) { + if (mergeWithGalaxy) + AddCustomSystem(SystemPath(sys->sectorX, sys->sectorY, sys->sectorZ), sys); + + return sys; + } + size_t numBodies = systemdef["bodies"].size(); sys->bodies.reserve(numBodies); @@ -860,8 +899,8 @@ CustomSystem *CustomSystemsDatabase::LoadSystemFromJSON(std::string_view filenam for (const Json &childIndex : bodynode["children"]) { if (childIndex >= numBodies) { - Log::Warning("Body {} in system {} has out-of-range child index {}", - body->bodyData.m_name, filename, childIndex.get()); + Log::Warning("Body {} in system {} ({}) has out-of-range child index {}", + body->bodyData.m_name, sys->name, filename, childIndex.get()); continue; } @@ -883,6 +922,9 @@ CustomSystem *CustomSystemsDatabase::LoadSystemFromJSON(std::string_view filenam } + if (mergeWithGalaxy) + AddCustomSystem(SystemPath(sys->sectorX, sys->sectorY, sys->sectorZ), sys); + return sys; } catch (Json::out_of_range &e) { @@ -923,14 +965,14 @@ void CustomSystemsDatabase::AddCustomSystem(const SystemPath &path, CustomSystem if (system->name != csys->name) continue; - // Partially-defined systems are ignored if there is a fully-defined - // system with the same name + // Partially-defined systems are ignored if there is an existing + // system already loaded with that name in that sector if (csys->IsRandom()) { delete csys; return; } - // Fully-defined custom systems override partially-defined systems + // Fully-defined custom systems override existing systems csys->systemIndex = system->systemIndex; m_lastAddedSystem = SystemIndex(path, csys->systemIndex); diff --git a/src/galaxy/CustomSystem.h b/src/galaxy/CustomSystem.h index da393b8df82..ef9a7fa9d5e 100644 --- a/src/galaxy/CustomSystem.h +++ b/src/galaxy/CustomSystem.h @@ -101,7 +101,7 @@ class CustomSystemsDatabase { void LoadAllLuaSystems(); const CustomSystem *LoadSystem(std::string_view filepath); - CustomSystem *LoadSystemFromJSON(std::string_view filename, const Json &systemdef); + CustomSystem *LoadSystemFromJSON(std::string_view filename, const Json &systemdef, bool mergeWithGalaxy = true); typedef std::vector SystemList; // XXX this is not as const-safe as it should be diff --git a/src/galaxy/Factions.cpp b/src/galaxy/Factions.cpp index 21a977462e5..03314ed3525 100644 --- a/src/galaxy/Factions.cpp +++ b/src/galaxy/Factions.cpp @@ -451,6 +451,8 @@ static void RegisterFactionsAPI(lua_State *L) void FactionsDatabase::Init() { + PROFILE_SCOPED() + assert(!s_activeFactionsDatabase); s_activeFactionsDatabase = this; @@ -491,6 +493,8 @@ void FactionsDatabase::Init() void FactionsDatabase::PostInit() { + PROFILE_SCOPED() + assert(m_initialized); assert(m_galaxy->IsInitialized()); SetHomeSectors(); @@ -792,7 +796,6 @@ Faction::Faction(Galaxy *galaxy) : void FactionsDatabase::Octsapling::Add(const Faction *faction) { - PROFILE_SCOPED() /* The general principle here is to put the faction in every octbox cell that a system that is a member of that faction could be in. This should let us cut the number of factions that have to be checked by GetNearestFaction, by eliminating right off @@ -874,7 +877,6 @@ void FactionsDatabase::Octsapling::PruneDuplicates(const int bx, const int by, c const std::vector &FactionsDatabase::Octsapling::CandidateFactions(const Sector::System *sys) const { - PROFILE_SCOPED() /* answer the factions that we've put in the same octobox cell as the one the system would go in. This part happens every time we do GetNearest faction so *is* performance criticale.e diff --git a/src/galaxy/StarSystem.cpp b/src/galaxy/StarSystem.cpp index 0852838774f..8d53b466fb6 100644 --- a/src/galaxy/StarSystem.cpp +++ b/src/galaxy/StarSystem.cpp @@ -573,10 +573,8 @@ void StarSystem::DumpToJson(Json &obj) for (size_t idx = 0; idx < m_numStars; idx++) out_types.push_back(EnumStrings::GetString("BodyType", m_stars[idx]->GetType())); - obj["sectorX"] = m_path.sectorX; - obj["sectorY"] = m_path.sectorY; - obj["sectorZ"] = m_path.sectorZ; - obj["pos"] = m_pos; + obj["sector"] = Json::array({ m_path.sectorX, m_path.sectorY, m_path.sectorZ }); + obj["pos"] = Json::array({ m_pos.x, m_pos.y, m_pos.z }); obj["seed"] = m_seed; obj["explored"] = m_explored == ExplorationState::eEXPLORED_AT_START;