replace biomes.json with biomes.toml & make it combined object
This commit is contained in:
parent
e7d7753d47
commit
7c56d8fd7f
@ -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}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
67
res/content/base/generators/demo.files/biomes.toml
Normal file
67
res/content/base/generators/demo.files/biomes.toml
Normal 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}
|
||||||
|
]
|
||||||
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"flat": {
|
|
||||||
"parameters": [],
|
|
||||||
"layers": [
|
|
||||||
{"height": -1, "block": "core:obstacle"}
|
|
||||||
],
|
|
||||||
"sea_layers": [
|
|
||||||
{"height": -1, "block": "core:obstacle"}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
8
res/generators/default.files/biomes.toml
Normal file
8
res/generators/default.files/biomes.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[flat]
|
||||||
|
parameters = []
|
||||||
|
layers = [
|
||||||
|
{height=-1, block="core:obstacle"}
|
||||||
|
]
|
||||||
|
sea_layers = [
|
||||||
|
{height=-1, block="core:obstacle"}
|
||||||
|
]
|
||||||
@ -242,7 +242,7 @@ dv::value Parser::parseValue() {
|
|||||||
} else if (literal == "nan") {
|
} else if (literal == "nan") {
|
||||||
return NAN;
|
return NAN;
|
||||||
}
|
}
|
||||||
throw error("invalid literal ");
|
throw error("invalid keyword " + literal);
|
||||||
}
|
}
|
||||||
if (next == '{') {
|
if (next == '{') {
|
||||||
return parseObject();
|
return parseObject();
|
||||||
|
|||||||
@ -28,8 +28,10 @@ using namespace data;
|
|||||||
|
|
||||||
static debug::Logger logger("content-loader");
|
static debug::Logger logger("content-loader");
|
||||||
|
|
||||||
ContentLoader::ContentLoader(ContentPack* pack, ContentBuilder& builder)
|
ContentLoader::ContentLoader(
|
||||||
: pack(pack), builder(builder) {
|
ContentPack* pack, ContentBuilder& builder, const ResPaths& paths
|
||||||
|
)
|
||||||
|
: pack(pack), builder(builder), paths(paths) {
|
||||||
auto runtime = std::make_unique<ContentPackRuntime>(
|
auto runtime = std::make_unique<ContentPackRuntime>(
|
||||||
*pack, scripting::create_pack_environment(*pack)
|
*pack, scripting::create_pack_environment(*pack)
|
||||||
);
|
);
|
||||||
|
|||||||
@ -16,6 +16,7 @@ struct EntityDef;
|
|||||||
struct ContentPack;
|
struct ContentPack;
|
||||||
struct GeneratorDef;
|
struct GeneratorDef;
|
||||||
|
|
||||||
|
class ResPaths;
|
||||||
class ContentBuilder;
|
class ContentBuilder;
|
||||||
class ContentPackRuntime;
|
class ContentPackRuntime;
|
||||||
struct ContentPackStats;
|
struct ContentPackStats;
|
||||||
@ -26,6 +27,7 @@ class ContentLoader {
|
|||||||
scriptenv env;
|
scriptenv env;
|
||||||
ContentBuilder& builder;
|
ContentBuilder& builder;
|
||||||
ContentPackStats* stats;
|
ContentPackStats* stats;
|
||||||
|
const ResPaths& paths;
|
||||||
|
|
||||||
void loadBlock(
|
void loadBlock(
|
||||||
Block& def, const std::string& full, const std::string& name
|
Block& def, const std::string& full, const std::string& name
|
||||||
@ -55,7 +57,11 @@ class ContentLoader {
|
|||||||
|
|
||||||
void loadContent(const dv::value& map);
|
void loadContent(const dv::value& map);
|
||||||
public:
|
public:
|
||||||
ContentLoader(ContentPack* pack, ContentBuilder& builder);
|
ContentLoader(
|
||||||
|
ContentPack* pack,
|
||||||
|
ContentBuilder& builder,
|
||||||
|
const ResPaths& paths
|
||||||
|
);
|
||||||
|
|
||||||
// Refresh pack content.json
|
// Refresh pack content.json
|
||||||
static bool fixPackIndices(
|
static bool fixPackIndices(
|
||||||
|
|||||||
@ -3,10 +3,12 @@
|
|||||||
#include "../ContentPack.hpp"
|
#include "../ContentPack.hpp"
|
||||||
|
|
||||||
#include "files/files.hpp"
|
#include "files/files.hpp"
|
||||||
|
#include "files/engine_paths.hpp"
|
||||||
#include "logic/scripting/scripting.hpp"
|
#include "logic/scripting/scripting.hpp"
|
||||||
#include "world/generator/GeneratorDef.hpp"
|
#include "world/generator/GeneratorDef.hpp"
|
||||||
#include "world/generator/VoxelFragment.hpp"
|
#include "world/generator/VoxelFragment.hpp"
|
||||||
#include "debug/Logger.hpp"
|
#include "debug/Logger.hpp"
|
||||||
|
#include "util/stringutil.hpp"
|
||||||
|
|
||||||
static BlocksLayer load_layer(
|
static BlocksLayer load_layer(
|
||||||
const dv::value& map, uint& lastLayersHeight, bool& hasResizeableLayer
|
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 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 inline const auto GENERATORS_DIR = fs::u8path("generators");
|
||||||
|
|
||||||
static void load_biomes(GeneratorDef& def, const fs::path& file) {
|
static void load_biomes(GeneratorDef& def, const dv::value& root) {
|
||||||
auto root = files::read_json(file);
|
|
||||||
for (const auto& [biomeName, biomeMap] : root.asObject()) {
|
for (const auto& [biomeName, biomeMap] : root.asObject()) {
|
||||||
try {
|
try {
|
||||||
def.biomes.push_back(
|
def.biomes.push_back(
|
||||||
@ -205,14 +206,16 @@ void ContentLoader::loadGenerator(
|
|||||||
if (fs::exists(structuresFile)) {
|
if (fs::exists(structuresFile)) {
|
||||||
load_structures(def, 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(
|
throw std::runtime_error(
|
||||||
BIOMES_FILE.u8string() +
|
"generator " + util::quote(def.name) +
|
||||||
": file not found (at least one biome required)"
|
": at least one biome required"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
load_biomes(def, biomesFiles);
|
load_biomes(def, biomesMap);
|
||||||
def.script = scripting::load_generator(
|
def.script = scripting::load_generator(
|
||||||
def, scriptFile, pack->id+":generators/"+name+".files");
|
def, scriptFile, pack->id+":generators/"+name+".files");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -322,11 +322,11 @@ void Engine::loadContent() {
|
|||||||
|
|
||||||
// Load content
|
// Load content
|
||||||
{
|
{
|
||||||
ContentLoader(&corePack, contentBuilder).load();
|
ContentLoader(&corePack, contentBuilder, *resPaths).load();
|
||||||
load_configs(corePack.folder);
|
load_configs(corePack.folder);
|
||||||
}
|
}
|
||||||
for (auto& pack : contentPacks) {
|
for (auto& pack : contentPacks) {
|
||||||
ContentLoader(&pack, contentBuilder).load();
|
ContentLoader(&pack, contentBuilder, *resPaths).load();
|
||||||
load_configs(pack.folder);
|
load_configs(pack.folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -255,7 +255,7 @@ std::vector<std::filesystem::path> ResPaths::listdir(
|
|||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
dv::value ResPaths::readCombinedList(const std::string& filename) {
|
dv::value ResPaths::readCombinedList(const std::string& filename) const {
|
||||||
dv::value list = dv::list();
|
dv::value list = dv::list();
|
||||||
for (const auto& root : roots) {
|
for (const auto& root : roots) {
|
||||||
auto path = root.path / fs::u8path(filename);
|
auto path = root.path / fs::u8path(filename);
|
||||||
@ -280,6 +280,31 @@ dv::value ResPaths::readCombinedList(const std::string& filename) {
|
|||||||
return list;
|
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 {
|
const std::filesystem::path& ResPaths::getMainRoot() const {
|
||||||
return mainRoot;
|
return mainRoot;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -68,7 +68,9 @@ public:
|
|||||||
/// @brief Read all found list versions from all packs and combine into a
|
/// @brief Read all found list versions from all packs and combine into a
|
||||||
/// single list. Invalid versions will be skipped with logging a warning
|
/// single list. Invalid versions will be skipped with logging a warning
|
||||||
/// @param file *.json file path relative to entry point
|
/// @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;
|
const std::filesystem::path& getMainRoot() const;
|
||||||
|
|
||||||
|
|||||||
@ -251,6 +251,7 @@ void WorldGenerator::generateStructures(
|
|||||||
util::PseudoRandom structsRand;
|
util::PseudoRandom structsRand;
|
||||||
structsRand.setSeed(chunkX, chunkZ);
|
structsRand.setSeed(chunkX, chunkZ);
|
||||||
|
|
||||||
|
// Place structures defined in biome
|
||||||
auto heights = heightmap->getValues();
|
auto heights = heightmap->getValues();
|
||||||
for (uint z = 0; z < CHUNK_D; z++) {
|
for (uint z = 0; z < CHUNK_D; z++) {
|
||||||
for (uint x = 0; x < CHUNK_W; x++) {
|
for (uint x = 0; x < CHUNK_W; x++) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user