mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-12 06:21:50 +00:00
feat: environment is primary
This commit is contained in:
parent
4aaa5b2d7e
commit
3476bddc6b
10 changed files with 60 additions and 29 deletions
|
|
@ -25,7 +25,7 @@ const uint MIN_SURROUNDING = 9;
|
||||||
ChunksController::ChunksController(Level& level)
|
ChunksController::ChunksController(Level& level)
|
||||||
: level(level),
|
: level(level),
|
||||||
generator(std::make_unique<WorldGenerator>(
|
generator(std::make_unique<WorldGenerator>(
|
||||||
level.content.generators.require(level.getWorld()->getGenerator()),
|
level.content.generators.require(level.environment.generator),
|
||||||
level.content,
|
level.content,
|
||||||
level.getWorld()->getSeed()
|
level.getWorld()->getSeed()
|
||||||
)) {}
|
)) {}
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ void EngineController::onMissingContent(
|
||||||
if (engine.isHeadless()) {
|
if (engine.isHeadless()) {
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"missing content: " +
|
"missing content: " +
|
||||||
json::stringify(create_missing_content_report(report), true, " ")
|
util::quote(json::stringify(create_missing_content_report(report), true, " "))
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
engine.setScreen(std::make_shared<MenuScreen>(engine));
|
engine.setScreen(std::make_shared<MenuScreen>(engine));
|
||||||
|
|
@ -268,7 +268,7 @@ inline uint64_t str2seed(const std::string& seedstr) {
|
||||||
void EngineController::createWorld(
|
void EngineController::createWorld(
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
const std::string& seedstr,
|
const std::string& seedstr,
|
||||||
const std::string& generatorID
|
const std::string& environment
|
||||||
) {
|
) {
|
||||||
uint64_t seed = str2seed(seedstr);
|
uint64_t seed = str2seed(seedstr);
|
||||||
|
|
||||||
|
|
@ -279,17 +279,31 @@ void EngineController::createWorld(
|
||||||
paths.setCurrentWorldFolder(folder);
|
paths.setCurrentWorldFolder(folder);
|
||||||
engine.getContentControl().loadContent();
|
engine.getContentControl().loadContent();
|
||||||
});
|
});
|
||||||
|
const auto& generators = engine.getContentControl().get()->generators;
|
||||||
|
|
||||||
|
// generator-based environments must die in 1.0
|
||||||
|
bool genBasedEnv = false;
|
||||||
|
if (auto genDef = generators.find(environment)) {
|
||||||
|
genBasedEnv = true;
|
||||||
|
}
|
||||||
|
|
||||||
auto& contentControl = engine.getContentControl();
|
auto& contentControl = engine.getContentControl();
|
||||||
auto level = World::create(
|
auto level = World::create(
|
||||||
name,
|
name,
|
||||||
generatorID,
|
genBasedEnv ? "" : environment,
|
||||||
|
genBasedEnv ? environment : "",
|
||||||
folder,
|
folder,
|
||||||
seed,
|
seed,
|
||||||
engine.getSettings(),
|
engine.getSettings(),
|
||||||
*contentControl.get(),
|
*contentControl.get(),
|
||||||
contentControl.getContentPacks()
|
contentControl.getContentPacks()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// generator-based environment initialization
|
||||||
|
if (genBasedEnv) {
|
||||||
|
level->environment.generator = environment;
|
||||||
|
}
|
||||||
|
|
||||||
if (!engine.isHeadless()) {
|
if (!engine.isHeadless()) {
|
||||||
level->players->create(localPlayer);
|
level->players->create(localPlayer);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ void LevelController::saveWorld() {
|
||||||
world->wfile->createDirectories();
|
world->wfile->createDirectories();
|
||||||
scripting::on_world_save();
|
scripting::on_world_save();
|
||||||
level->onSave();
|
level->onSave();
|
||||||
level->getWorld()->write(level.get());
|
level->getWorld()->write(*level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LevelController::onWorldQuit() {
|
void LevelController::onWorldQuit() {
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ static int l_is_night(lua::State* L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_get_generator(lua::State* L) {
|
static int l_get_generator(lua::State* L) {
|
||||||
return lua::pushstring(L, require_world_info().generator);
|
return lua::pushstring(L, require_level().environment.generator);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_get_chunk_data(lua::State* L) {
|
static int l_get_chunk_data(lua::State* L) {
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ void Player::teleport(glm::vec3 position) {
|
||||||
void Player::attemptToChooseSpawnpoint() {
|
void Player::attemptToChooseSpawnpoint() {
|
||||||
// looks bad to be here tbh
|
// looks bad to be here tbh
|
||||||
const auto& generatorDef =
|
const auto& generatorDef =
|
||||||
level.content.generators.require(level.getWorld()->getGenerator());
|
level.content.generators.require(level.environment.generator);
|
||||||
|
|
||||||
int minHeight = generatorDef.playerMinSpawnHeight;
|
int minHeight = generatorDef.playerMinSpawnHeight;
|
||||||
int maxHeight = generatorDef.playerMaxSpawnHeight;
|
int maxHeight = generatorDef.playerMaxSpawnHeight;
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ dv::value Environment::serialize() const {
|
||||||
{"clouds", sky.clouds},
|
{"clouds", sky.clouds},
|
||||||
{"sprites", std::move(skySpritesList)},
|
{"sprites", std::move(skySpritesList)},
|
||||||
})},
|
})},
|
||||||
|
{"generator", generator}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -44,4 +45,5 @@ void Environment::deserialize(const dv::value& src) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
src.at("generator").get(generator);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,8 @@ public:
|
||||||
};
|
};
|
||||||
} sky;
|
} sky;
|
||||||
|
|
||||||
|
std::string generator;
|
||||||
|
|
||||||
Environment() = default;
|
Environment() = default;
|
||||||
|
|
||||||
dv::value serialize() const override;
|
dv::value serialize() const override;
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ Level::Level(
|
||||||
entities(std::make_unique<Entities>(*this)),
|
entities(std::make_unique<Entities>(*this)),
|
||||||
players(std::make_unique<Players>(*this)),
|
players(std::make_unique<Players>(*this)),
|
||||||
pathfinding(std::make_unique<voxels::Pathfinding>(*this)) {
|
pathfinding(std::make_unique<voxels::Pathfinding>(*this)) {
|
||||||
|
|
||||||
const auto& worldInfo = world->getInfo();
|
const auto& worldInfo = world->getInfo();
|
||||||
auto& cameraIndices = content.getIndices(ResourceType::CAMERA);
|
auto& cameraIndices = content.getIndices(ResourceType::CAMERA);
|
||||||
for (size_t i = 0; i < cameraIndices.size(); i++) {
|
for (size_t i = 0; i < cameraIndices.size(); i++) {
|
||||||
|
|
|
||||||
|
|
@ -65,12 +65,12 @@ void World::writeResources(const Content& content) {
|
||||||
io::write_json(wfile->getResourcesFile(), root);
|
io::write_json(wfile->getResourcesFile(), root);
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::write(Level* level) {
|
void World::write(Level& level) {
|
||||||
level->chunks->saveAll();
|
level.chunks->saveAll();
|
||||||
info.nextEntityId = level->entities->peekNextID();
|
info.nextEntityId = level.entities->peekNextID();
|
||||||
wfile->write(this, &content);
|
wfile->write(this, &content);
|
||||||
|
|
||||||
auto playerFile = level->players->serialize();
|
auto playerFile = level.players->serialize();
|
||||||
io::write_json(wfile->getPlayerFile(), playerFile);
|
io::write_json(wfile->getPlayerFile(), playerFile);
|
||||||
|
|
||||||
writeResources(content);
|
writeResources(content);
|
||||||
|
|
@ -78,7 +78,8 @@ void World::write(Level* level) {
|
||||||
|
|
||||||
std::unique_ptr<Level> World::create(
|
std::unique_ptr<Level> World::create(
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
const std::string& generator,
|
const std::string& environment,
|
||||||
|
const std::string& generatorOverride,
|
||||||
const io::path& directory,
|
const io::path& directory,
|
||||||
uint64_t seed,
|
uint64_t seed,
|
||||||
EngineSettings& settings,
|
EngineSettings& settings,
|
||||||
|
|
@ -87,7 +88,8 @@ std::unique_ptr<Level> World::create(
|
||||||
) {
|
) {
|
||||||
WorldInfo info {};
|
WorldInfo info {};
|
||||||
info.name = name;
|
info.name = name;
|
||||||
info.generator = generator;
|
info.environment = environment;
|
||||||
|
info.explicitGenerator = generatorOverride;
|
||||||
info.seed = seed;
|
info.seed = seed;
|
||||||
auto world = std::make_unique<World>(
|
auto world = std::make_unique<World>(
|
||||||
info,
|
info,
|
||||||
|
|
@ -101,7 +103,7 @@ std::unique_ptr<Level> World::create(
|
||||||
logger.info() << "created world '" << name << "' ("
|
logger.info() << "created world '" << name << "' ("
|
||||||
<< directory.string() << ")";
|
<< directory.string() << ")";
|
||||||
}
|
}
|
||||||
logger.info() << "world seed: " << seed << " generator: " << generator;
|
logger.info() << "world seed: " << seed << " environment: " << environment;
|
||||||
return std::make_unique<Level>(std::move(world), content, settings);
|
return std::make_unique<Level>(std::move(world), content, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,16 +124,19 @@ std::unique_ptr<Level> World::load(
|
||||||
<< worldFilesPtr->getFolder().string() << ")";
|
<< worldFilesPtr->getFolder().string() << ")";
|
||||||
logger.info() << "world version: " << info->major << "." << info->minor
|
logger.info() << "world version: " << info->major << "." << info->minor
|
||||||
<< " seed: " << info->seed
|
<< " seed: " << info->seed
|
||||||
<< " generator: " << info->generator;
|
<< " environment: " << info->environment;
|
||||||
|
|
||||||
auto world = std::make_unique<World>(
|
auto worldPtr = std::make_unique<World>(
|
||||||
info.value(), std::move(worldFilesPtr), content, packs
|
info.value(), std::move(worldFilesPtr), content, packs
|
||||||
);
|
);
|
||||||
|
auto world = worldPtr.get();
|
||||||
auto& wfile = world->wfile;
|
auto& wfile = world->wfile;
|
||||||
wfile->readResourcesData(content);
|
wfile->readResourcesData(content);
|
||||||
|
|
||||||
auto level = std::make_unique<Level>(std::move(world), content, settings);
|
auto level = std::make_unique<Level>(std::move(worldPtr), content, settings);
|
||||||
|
if (world->getEnvironment().empty()) {
|
||||||
|
level->environment.generator = world->getInfo().explicitGenerator;
|
||||||
|
}
|
||||||
io::path file = wfile->getPlayerFile();
|
io::path file = wfile->getPlayerFile();
|
||||||
if (!io::is_regular_file(file)) {
|
if (!io::is_regular_file(file)) {
|
||||||
logger.warning() << "player.json does not exists";
|
logger.warning() << "player.json does not exists";
|
||||||
|
|
@ -163,8 +168,8 @@ void World::setName(const std::string& name) {
|
||||||
this->info.name = name;
|
this->info.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::setGenerator(const std::string& generator) {
|
void World::setEnvironment(const std::string& environment) {
|
||||||
this->info.generator = generator;
|
this->info.environment = environment;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::hasPack(const std::string& id) const {
|
bool World::hasPack(const std::string& id) const {
|
||||||
|
|
@ -186,8 +191,8 @@ uint64_t World::getSeed() const {
|
||||||
return info.seed;
|
return info.seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string World::getGenerator() const {
|
std::string World::getEnvironment() const {
|
||||||
return info.generator;
|
return info.environment;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<ContentPack>& World::getPacks() const {
|
const std::vector<ContentPack>& World::getPacks() const {
|
||||||
|
|
@ -196,7 +201,8 @@ const std::vector<ContentPack>& World::getPacks() const {
|
||||||
|
|
||||||
void WorldInfo::deserialize(const dv::value& root) {
|
void WorldInfo::deserialize(const dv::value& root) {
|
||||||
name = root["name"].asString();
|
name = root["name"].asString();
|
||||||
generator = root["generator"].asString(generator);
|
root.at("environment").get(environment);
|
||||||
|
root.at("generator").get(explicitGenerator);
|
||||||
seed = root["seed"].asInteger(seed);
|
seed = root["seed"].asInteger(seed);
|
||||||
|
|
||||||
if (root.has("version")) {
|
if (root.has("version")) {
|
||||||
|
|
@ -226,7 +232,11 @@ dv::value WorldInfo::serialize() const {
|
||||||
versionobj["minor"] = ENGINE_VERSION_MINOR;
|
versionobj["minor"] = ENGINE_VERSION_MINOR;
|
||||||
|
|
||||||
root["name"] = name;
|
root["name"] = name;
|
||||||
root["generator"] = generator;
|
if (environment.empty()) {
|
||||||
|
root["generator"] = explicitGenerator;
|
||||||
|
} else {
|
||||||
|
root["environment"] = environment;
|
||||||
|
}
|
||||||
root["seed"] = seed;
|
root["seed"] = seed;
|
||||||
|
|
||||||
auto& timeobj = root.object("time");
|
auto& timeobj = root.object("time");
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,8 @@ public:
|
||||||
|
|
||||||
struct WorldInfo : public Serializable {
|
struct WorldInfo : public Serializable {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string generator;
|
std::string environment;
|
||||||
|
std::string explicitGenerator;
|
||||||
uint64_t seed;
|
uint64_t seed;
|
||||||
int64_t nextInventoryId = 1;
|
int64_t nextInventoryId = 1;
|
||||||
int64_t nextPlayerId = 0;
|
int64_t nextPlayerId = 0;
|
||||||
|
|
@ -76,7 +77,7 @@ public:
|
||||||
void updateTimers(float delta);
|
void updateTimers(float delta);
|
||||||
|
|
||||||
/// @brief Write all unsaved level data to the world directory
|
/// @brief Write all unsaved level data to the world directory
|
||||||
void write(Level* level);
|
void write(Level& level);
|
||||||
|
|
||||||
/// @brief Check world indices and generate ContentReport if convert required
|
/// @brief Check world indices and generate ContentReport if convert required
|
||||||
/// @param directory world directory
|
/// @param directory world directory
|
||||||
|
|
@ -98,7 +99,8 @@ public:
|
||||||
/// @return Level instance containing World instance
|
/// @return Level instance containing World instance
|
||||||
static std::unique_ptr<Level> create(
|
static std::unique_ptr<Level> create(
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
const std::string& generator,
|
const std::string& environment,
|
||||||
|
const std::string& generatorOverride,
|
||||||
const io::path& directory,
|
const io::path& directory,
|
||||||
uint64_t seed,
|
uint64_t seed,
|
||||||
EngineSettings& settings,
|
EngineSettings& settings,
|
||||||
|
|
@ -123,7 +125,7 @@ public:
|
||||||
|
|
||||||
void setName(const std::string& name);
|
void setName(const std::string& name);
|
||||||
void setSeed(uint64_t seed);
|
void setSeed(uint64_t seed);
|
||||||
void setGenerator(const std::string& generator);
|
void setEnvironment(const std::string& environment);
|
||||||
|
|
||||||
/// @brief Check if world has content-pack installed
|
/// @brief Check if world has content-pack installed
|
||||||
/// @param id content-pack id
|
/// @param id content-pack id
|
||||||
|
|
@ -137,7 +139,7 @@ public:
|
||||||
uint64_t getSeed() const;
|
uint64_t getSeed() const;
|
||||||
|
|
||||||
/// @brief Get world generator id
|
/// @brief Get world generator id
|
||||||
std::string getGenerator() const;
|
std::string getEnvironment() const;
|
||||||
|
|
||||||
bool isNameless() const {
|
bool isNameless() const {
|
||||||
return info.name.empty();
|
return info.name.empty();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue