replace biomes.json with biomes.toml & make it combined object

This commit is contained in:
MihailRis 2024-10-13 21:50:39 +03:00
parent e7d7753d47
commit 7c56d8fd7f
12 changed files with 130 additions and 95 deletions

View File

@ -1,68 +0,0 @@
{
"forest": {
"parameters": [
{"weight": 1, "value": 1},
{"weight": 0.5, "value": 0.2}
],
"layers": [
{"below_sea_level": false, "height": 1, "block": "base:grass_block"},
{"below_sea_level": false, "height": 7, "block": "base:dirt"},
{"height": -1, "block": "base:stone"},
{"height": 1, "block": "base:bazalt"}
],
"sea_layers": [
{"height": -1, "block": "base:water"}
],
"plant_chance": 0.4,
"plants": [
{"weight": 1, "block": "base:grass"},
{"weight": 0.03, "block": "base:flower"}
],
"structure_chance": 0.032,
"structures": [
{"name": "tree0", "weight": 1},
{"name": "tree1", "weight": 1},
{"name": "tree2", "weight": 1},
{"name": "tower", "weight": 0.002}
]
},
"desert": {
"parameters": [
{"weight": 0.3, "value": 0},
{"weight": 0.1, "value": 0}
],
"layers": [
{"height": 6, "block": "base:sand"},
{"height": -1, "block": "base:stone"},
{"height": 1, "block": "base:bazalt"}
],
"sea_layers": [
{"height": -1, "block": "base:water"}
]
},
"plains": {
"parameters": [
{"weight": 0.6, "value": 0.5},
{"weight": 0.6, "value": 0.5}
],
"layers": [
{"below_sea_level": false, "height": 1, "block": "base:grass_block"},
{"below_sea_level": false, "height": 5, "block": "base:dirt"},
{"height": -1, "block": "base:stone"},
{"height": 1, "block": "base:bazalt"}
],
"sea_layers": [
{"height": -1, "block": "base:water"}
],
"plant_chance": 0.3,
"plants": [
{"weight": 1, "block": "base:grass"},
{"weight": 0.03, "block": "base:flower"}
],
"structure_chance": 0.0001,
"structures": [
{"name": "tree0", "weight": 1},
{"name": "tree1", "weight": 1}
]
}
}

View File

@ -0,0 +1,67 @@
[forest]
parameters = [
{weight=1, value=1},
{weight=0.5, value=0.2}
]
layers = [
{below_sea_level=false, height=1, block="base:grass_block"},
{below_sea_level=false, height=7, block="base:dirt"},
{height=-1, block="base:stone"},
{height=1, block="base:bazalt"}
]
sea_layers = [
{height=-1, block="base:water"}
]
plant_chance = 0.4
plants = [
{weight=1, block="base:grass"},
{weight=0.03, block="base:flower"}
]
structure_chance = 0.032
structures = [
{name="tree0", weight=1},
{name="tree1", weight=1},
{name="tree2", weight=1},
{name="tower", weight=0.002}
]
[desert]
parameters = [
{weight=0.3, value=0},
{weight=0.1, value=0}
]
layers = [
{height=6, block="base:sand"},
{height=-1, block="base:stone"},
{height=1, block="base:bazalt"}
]
sea_layers = [
{height=-1, block="base:water"}
]
[plains]
parameters = [
{weight=0.6, value=0.5},
{weight=0.6, value=0.5}
]
layers = [
{below_sea_level=false, height=1, block="base:grass_block"},
{below_sea_level=false, height=5, block="base:dirt"},
{height=-1, block="base:stone"},
{height=1, block="base:bazalt"}
]
sea_layers = [
{height=-1, block="base:water"}
]
plant_chance = 0.3
plants = [
{weight=1, block="base:grass"},
{weight=0.03, block="base:flower"}
]
structure_chance=0.0001
structures = [
{name="tree0", weight=1},
{name="tree1", weight=1}
]

View File

@ -1,11 +0,0 @@
{
"flat": {
"parameters": [],
"layers": [
{"height": -1, "block": "core:obstacle"}
],
"sea_layers": [
{"height": -1, "block": "core:obstacle"}
]
}
}

View File

@ -0,0 +1,8 @@
[flat]
parameters = []
layers = [
{height=-1, block="core:obstacle"}
]
sea_layers = [
{height=-1, block="core:obstacle"}
]

View File

@ -242,7 +242,7 @@ dv::value Parser::parseValue() {
} else if (literal == "nan") {
return NAN;
}
throw error("invalid literal ");
throw error("invalid keyword " + literal);
}
if (next == '{') {
return parseObject();

View File

@ -28,8 +28,10 @@ using namespace data;
static debug::Logger logger("content-loader");
ContentLoader::ContentLoader(ContentPack* pack, ContentBuilder& builder)
: pack(pack), builder(builder) {
ContentLoader::ContentLoader(
ContentPack* pack, ContentBuilder& builder, const ResPaths& paths
)
: pack(pack), builder(builder), paths(paths) {
auto runtime = std::make_unique<ContentPackRuntime>(
*pack, scripting::create_pack_environment(*pack)
);

View File

@ -16,6 +16,7 @@ struct EntityDef;
struct ContentPack;
struct GeneratorDef;
class ResPaths;
class ContentBuilder;
class ContentPackRuntime;
struct ContentPackStats;
@ -26,6 +27,7 @@ class ContentLoader {
scriptenv env;
ContentBuilder& builder;
ContentPackStats* stats;
const ResPaths& paths;
void loadBlock(
Block& def, const std::string& full, const std::string& name
@ -55,7 +57,11 @@ class ContentLoader {
void loadContent(const dv::value& map);
public:
ContentLoader(ContentPack* pack, ContentBuilder& builder);
ContentLoader(
ContentPack* pack,
ContentBuilder& builder,
const ResPaths& paths
);
// Refresh pack content.json
static bool fixPackIndices(

View File

@ -3,10 +3,12 @@
#include "../ContentPack.hpp"
#include "files/files.hpp"
#include "files/engine_paths.hpp"
#include "logic/scripting/scripting.hpp"
#include "world/generator/GeneratorDef.hpp"
#include "world/generator/VoxelFragment.hpp"
#include "debug/Logger.hpp"
#include "util/stringutil.hpp"
static BlocksLayer load_layer(
const dv::value& map, uint& lastLayersHeight, bool& hasResizeableLayer
@ -167,11 +169,10 @@ static void load_structures(GeneratorDef& def, const fs::path& structuresFile) {
}
static inline const auto STRUCTURES_FILE = fs::u8path("structures.json");
static inline const auto BIOMES_FILE = fs::u8path("biomes.json");
static inline const auto BIOMES_FILE = fs::u8path("biomes.toml");
static inline const auto GENERATORS_DIR = fs::u8path("generators");
static void load_biomes(GeneratorDef& def, const fs::path& file) {
auto root = files::read_json(file);
static void load_biomes(GeneratorDef& def, const dv::value& root) {
for (const auto& [biomeName, biomeMap] : root.asObject()) {
try {
def.biomes.push_back(
@ -205,14 +206,16 @@ void ContentLoader::loadGenerator(
if (fs::exists(structuresFile)) {
load_structures(def, structuresFile);
}
auto biomesFiles = folder / BIOMES_FILE;
if (!fs::exists(biomesFiles)) {
auto biomesFile = GENERATORS_DIR / fs::u8path(name + ".files") / BIOMES_FILE;
auto biomesMap = paths.readCombinedObject(biomesFile.u8string());
if (biomesMap.empty()) {
throw std::runtime_error(
BIOMES_FILE.u8string() +
": file not found (at least one biome required)"
"generator " + util::quote(def.name) +
": at least one biome required"
);
}
load_biomes(def, biomesFiles);
load_biomes(def, biomesMap);
def.script = scripting::load_generator(
def, scriptFile, pack->id+":generators/"+name+".files");
}

View File

@ -322,11 +322,11 @@ void Engine::loadContent() {
// Load content
{
ContentLoader(&corePack, contentBuilder).load();
ContentLoader(&corePack, contentBuilder, *resPaths).load();
load_configs(corePack.folder);
}
for (auto& pack : contentPacks) {
ContentLoader(&pack, contentBuilder).load();
ContentLoader(&pack, contentBuilder, *resPaths).load();
load_configs(pack.folder);
}

View File

@ -255,7 +255,7 @@ std::vector<std::filesystem::path> ResPaths::listdir(
return entries;
}
dv::value ResPaths::readCombinedList(const std::string& filename) {
dv::value ResPaths::readCombinedList(const std::string& filename) const {
dv::value list = dv::list();
for (const auto& root : roots) {
auto path = root.path / fs::u8path(filename);
@ -280,6 +280,31 @@ dv::value ResPaths::readCombinedList(const std::string& filename) {
return list;
}
dv::value ResPaths::readCombinedObject(const std::string& filename) const {
dv::value object = dv::object();
for (const auto& root : roots) {
auto path = root.path / fs::u8path(filename);
if (!fs::exists(path)) {
continue;
}
try {
auto value = files::read_object(path);
if (!value.isObject()) {
logger.warning()
<< "reading combined object " << root.name << ": "
<< filename << " is not an object (skipped)";
}
for (const auto& [key, element] : value.asObject()) {
object[key] = element;
}
} catch (const std::runtime_error& err) {
logger.warning() << "reading combined object " << root.name << ":"
<< filename << ": " << err.what();
}
}
return object;
}
const std::filesystem::path& ResPaths::getMainRoot() const {
return mainRoot;
}

View File

@ -68,7 +68,9 @@ public:
/// @brief Read all found list versions from all packs and combine into a
/// single list. Invalid versions will be skipped with logging a warning
/// @param file *.json file path relative to entry point
dv::value readCombinedList(const std::string& file);
dv::value readCombinedList(const std::string& file) const;
dv::value readCombinedObject(const std::string& file) const;
const std::filesystem::path& getMainRoot() const;

View File

@ -251,6 +251,7 @@ void WorldGenerator::generateStructures(
util::PseudoRandom structsRand;
structsRand.setSeed(chunkX, chunkZ);
// Place structures defined in biome
auto heights = heightmap->getValues();
for (uint z = 0; z < CHUNK_D; z++) {
for (uint x = 0; x < CHUNK_W; x++) {