contentpack removal feature + refactor
This commit is contained in:
parent
3f0c710a47
commit
daaba374a3
@ -65,29 +65,29 @@ void AssetsLoader::tryAddSound(std::string name) {
|
||||
if (name.empty()) {
|
||||
return;
|
||||
}
|
||||
fs::path file = SOUNDS_FOLDER"/"+name+".ogg";
|
||||
fs::path file = SOUNDS_FOLDER+"/"+name+".ogg";
|
||||
add(ASSET_SOUND, file, name);
|
||||
}
|
||||
|
||||
void AssetsLoader::addDefaults(AssetsLoader& loader, const Content* content) {
|
||||
loader.add(ASSET_FONT, FONTS_FOLDER"/font", "normal");
|
||||
loader.add(ASSET_SHADER, SHADERS_FOLDER"/ui", "ui");
|
||||
loader.add(ASSET_SHADER, SHADERS_FOLDER"/main", "main");
|
||||
loader.add(ASSET_SHADER, SHADERS_FOLDER"/lines", "lines");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/gui/menubg.png", "gui/menubg");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/gui/delete_icon.png", "gui/delete_icon");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/gui/no_icon.png", "gui/no_icon");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/gui/warning.png", "gui/warning");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/gui/error.png", "gui/error");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/gui/cross.png", "gui/cross");
|
||||
loader.add(ASSET_FONT, FONTS_FOLDER+"/font", "normal");
|
||||
loader.add(ASSET_SHADER, SHADERS_FOLDER+"/ui", "ui");
|
||||
loader.add(ASSET_SHADER, SHADERS_FOLDER+"/main", "main");
|
||||
loader.add(ASSET_SHADER, SHADERS_FOLDER+"/lines", "lines");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER+"/gui/menubg.png", "gui/menubg");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER+"/gui/delete_icon.png", "gui/delete_icon");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER+"/gui/no_icon.png", "gui/no_icon");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER+"/gui/warning.png", "gui/warning");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER+"/gui/error.png", "gui/error");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER+"/gui/cross.png", "gui/cross");
|
||||
if (content) {
|
||||
loader.add(ASSET_SHADER, SHADERS_FOLDER"/ui3d", "ui3d");
|
||||
loader.add(ASSET_SHADER, SHADERS_FOLDER"/screen", "screen");
|
||||
loader.add(ASSET_SHADER, SHADERS_FOLDER"/background", "background");
|
||||
loader.add(ASSET_SHADER, SHADERS_FOLDER"/skybox_gen", "skybox_gen");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/misc/moon.png", "misc/moon");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/misc/sun.png", "misc/sun");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/gui/crosshair.png", "gui/crosshair");
|
||||
loader.add(ASSET_SHADER, SHADERS_FOLDER+"/ui3d", "ui3d");
|
||||
loader.add(ASSET_SHADER, SHADERS_FOLDER+"/screen", "screen");
|
||||
loader.add(ASSET_SHADER, SHADERS_FOLDER+"/background", "background");
|
||||
loader.add(ASSET_SHADER, SHADERS_FOLDER+"/skybox_gen", "skybox_gen");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER+"/misc/moon.png", "misc/moon");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER+"/misc/sun.png", "misc/sun");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER+"/gui/crosshair.png", "gui/crosshair");
|
||||
|
||||
for (auto& entry : content->getBlockMaterials()) {
|
||||
auto& material = entry.second;
|
||||
@ -104,8 +104,8 @@ void AssetsLoader::addDefaults(AssetsLoader& loader, const Content* content) {
|
||||
addLayouts(pack->getEnvironment()->getId(), info.id, folder, loader);
|
||||
}
|
||||
}
|
||||
loader.add(ASSET_ATLAS, TEXTURES_FOLDER"/blocks", "blocks");
|
||||
loader.add(ASSET_ATLAS, TEXTURES_FOLDER"/items", "items");
|
||||
loader.add(ASSET_ATLAS, TEXTURES_FOLDER+"/blocks", "blocks");
|
||||
loader.add(ASSET_ATLAS, TEXTURES_FOLDER+"/items", "items");
|
||||
}
|
||||
|
||||
const ResPaths* AssetsLoader::getPaths() const {
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
inline constexpr int ENGINE_VERSION_MAJOR = 0;
|
||||
inline constexpr int ENGINE_VERSION_MINOR = 20;
|
||||
inline constexpr bool ENGINE_VERSION_INDEV = true;
|
||||
#define ENGINE_VERSION_STRING "0.20"
|
||||
inline const std::string ENGINE_VERSION_STRING = "0.20";
|
||||
|
||||
inline constexpr int BLOCK_AIR = 0;
|
||||
inline constexpr int ITEM_EMPTY = 0;
|
||||
@ -35,11 +35,10 @@ inline constexpr uint vox_index(uint x, uint y, uint z, uint w=CHUNK_W, uint d=C
|
||||
return (y * d + z) * w + x;
|
||||
}
|
||||
|
||||
//cannot replace defines with const while used for substitution
|
||||
#define SHADERS_FOLDER "shaders"
|
||||
#define TEXTURES_FOLDER "textures"
|
||||
#define FONTS_FOLDER "fonts"
|
||||
#define LAYOUTS_FOLDER "layouts"
|
||||
#define SOUNDS_FOLDER "sounds"
|
||||
inline const std::string SHADERS_FOLDER = "shaders";
|
||||
inline const std::string TEXTURES_FOLDER = "textures";
|
||||
inline const std::string FONTS_FOLDER = "fonts";
|
||||
inline const std::string LAYOUTS_FOLDER = "layouts";
|
||||
inline const std::string SOUNDS_FOLDER = "sounds";
|
||||
|
||||
#endif // SRC_CONSTANTS_H_
|
||||
|
||||
@ -67,6 +67,13 @@ bool List::flag(size_t index) const {
|
||||
}
|
||||
}
|
||||
|
||||
Value* List::getValueWriteable(size_t index) const {
|
||||
if (index > values.size()) {
|
||||
throw std::runtime_error("index error");
|
||||
}
|
||||
return values.at(index).get();
|
||||
}
|
||||
|
||||
List& List::put(std::string value) {
|
||||
valvalue val;
|
||||
val.str = new std::string(value);
|
||||
|
||||
@ -40,7 +40,7 @@ namespace dynamic {
|
||||
|
||||
std::string str(size_t index) const;
|
||||
double num(size_t index) const;
|
||||
int64_t integer(size_t num) const;
|
||||
int64_t integer(size_t index) const;
|
||||
Map* map(size_t index) const;
|
||||
List* list(size_t index) const;
|
||||
bool flag(size_t index) const;
|
||||
@ -64,6 +64,8 @@ namespace dynamic {
|
||||
List& put(List* value);
|
||||
List& put(bool value);
|
||||
|
||||
Value* getValueWriteable(size_t index) const;
|
||||
|
||||
List& putList();
|
||||
Map& putMap();
|
||||
|
||||
|
||||
@ -149,6 +149,9 @@ void Engine::mainloop() {
|
||||
|
||||
Engine::~Engine() {
|
||||
std::cout << "-- shutting down" << std::endl;
|
||||
if (screen) {
|
||||
screen->onEngineShutdown();
|
||||
}
|
||||
screen.reset();
|
||||
content.reset();
|
||||
assets.reset();
|
||||
|
||||
108
src/engine.h
108
src/engine.h
@ -22,100 +22,86 @@ class ResPaths;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace gui {
|
||||
class GUI;
|
||||
class GUI;
|
||||
}
|
||||
|
||||
class initialize_error : public std::runtime_error {
|
||||
public:
|
||||
initialize_error(const std::string& message) : std::runtime_error(message) {}
|
||||
initialize_error(const std::string& message) : std::runtime_error(message) {}
|
||||
};
|
||||
|
||||
class Engine {
|
||||
std::unique_ptr<Assets> assets = nullptr;
|
||||
std::shared_ptr<Screen> screen = nullptr;
|
||||
std::unique_ptr<Assets> assets = nullptr;
|
||||
std::shared_ptr<Screen> screen = nullptr;
|
||||
std::vector<ContentPack> contentPacks;
|
||||
EngineSettings& settings;
|
||||
std::unique_ptr<Content> content = nullptr;
|
||||
EnginePaths* paths;
|
||||
EngineSettings& settings;
|
||||
std::unique_ptr<Content> content = nullptr;
|
||||
EnginePaths* paths;
|
||||
std::unique_ptr<ResPaths> resPaths = nullptr;
|
||||
|
||||
uint64_t frame = 0;
|
||||
double lastTime = 0.0;
|
||||
double delta = 0.0;
|
||||
uint64_t frame = 0;
|
||||
double lastTime = 0.0;
|
||||
double delta = 0.0;
|
||||
|
||||
std::unique_ptr<gui::GUI> gui;
|
||||
std::unique_ptr<gui::GUI> gui;
|
||||
|
||||
void updateTimers();
|
||||
void updateHotkeys();
|
||||
void updateHotkeys();
|
||||
public:
|
||||
Engine(EngineSettings& settings, EnginePaths* paths);
|
||||
~Engine();
|
||||
Engine(EngineSettings& settings, EnginePaths* paths);
|
||||
~Engine();
|
||||
|
||||
/// @brief Start main engine input/update/render loop.
|
||||
/// Automatically sets MenuScreen
|
||||
void mainloop();
|
||||
|
||||
/**
|
||||
* Start main engine input/update/render loop
|
||||
* Automatically sets MenuScreen
|
||||
*/
|
||||
void mainloop();
|
||||
|
||||
/**
|
||||
* Set screen (scene).
|
||||
* nullptr may be used to delete previous screen before creating new one
|
||||
* example:
|
||||
*
|
||||
* engine->setScreen(nullptr);
|
||||
* engine->setScreen(std::make_shared<...>(...));
|
||||
*
|
||||
* not-null value must be set before next frame
|
||||
*/
|
||||
|
||||
/// @brief Set screen (scene).
|
||||
/// nullptr may be used to delete previous screen before creating new one,
|
||||
/// not-null value must be set before next frame
|
||||
/// @param screen nullable screen
|
||||
void setScreen(std::shared_ptr<Screen> screen);
|
||||
|
||||
/**
|
||||
* Change locale to specified
|
||||
* @param locale isolanguage_ISOCOUNTRY (example: en_US)
|
||||
*/
|
||||
void setLanguage(std::string locale);
|
||||
/// @brief Change locale to specified
|
||||
/// @param locale isolanguage_ISOCOUNTRY (example: en_US)
|
||||
void setLanguage(std::string locale);
|
||||
|
||||
/**
|
||||
* Load all selected content-packs and reload assets
|
||||
*/
|
||||
/// @brief Load all selected content-packs and reload assets
|
||||
void loadContent();
|
||||
/**
|
||||
* Collect world content-packs and load content
|
||||
* @see loadContent
|
||||
* @param folder world folder
|
||||
*/
|
||||
|
||||
/// @brief Collect world content-packs and load content
|
||||
/// @see loadContent
|
||||
/// @param folder world folder
|
||||
void loadWorldContent(const fs::path& folder);
|
||||
|
||||
/**
|
||||
* Collect all available content-packs from res/content
|
||||
*/
|
||||
void loadAllPacks();
|
||||
/// @brief Collect all available content-packs from res/content
|
||||
void loadAllPacks();
|
||||
|
||||
/** Get current frame delta-time */
|
||||
/// @brief Get current frame delta-time
|
||||
double getDelta() const;
|
||||
|
||||
/** Get active assets storage instance */
|
||||
Assets* getAssets();
|
||||
/// @brief Get active assets storage instance
|
||||
Assets* getAssets();
|
||||
|
||||
/** Get main UI controller */
|
||||
gui::GUI* getGUI();
|
||||
/// @brief Get main UI controller
|
||||
gui::GUI* getGUI();
|
||||
|
||||
/** Get writeable engine settings structure instance */
|
||||
EngineSettings& getSettings();
|
||||
/// @brief Get writeable engine settings structure instance
|
||||
EngineSettings& getSettings();
|
||||
|
||||
/** Get engine filesystem paths source */
|
||||
EnginePaths* getPaths();
|
||||
/// @brief Get engine filesystem paths source
|
||||
EnginePaths* getPaths();
|
||||
|
||||
/** Get engine resource paths controller */
|
||||
/// @brief Get engine resource paths controller
|
||||
ResPaths* getResPaths();
|
||||
|
||||
/** Get current Content instance */
|
||||
const Content* getContent() const;
|
||||
/// @brief Get current Content instance
|
||||
const Content* getContent() const;
|
||||
|
||||
/** Get selected content packs */
|
||||
/// @brief Get selected content packs
|
||||
std::vector<ContentPack>& getContentPacks();
|
||||
|
||||
/** Get current screen */
|
||||
/// @brief Get current screen
|
||||
std::shared_ptr<Screen> getScreen();
|
||||
};
|
||||
|
||||
|
||||
@ -13,10 +13,12 @@
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
WorldConverter::WorldConverter(fs::path folder,
|
||||
const Content* content,
|
||||
std::shared_ptr<ContentLUT> lut)
|
||||
: lut(lut), content(content) {
|
||||
WorldConverter::WorldConverter(
|
||||
fs::path folder,
|
||||
const Content* content,
|
||||
std::shared_ptr<ContentLUT> lut
|
||||
) : lut(lut), content(content)
|
||||
{
|
||||
DebugSettings settings;
|
||||
wfile = new WorldFiles(folder, settings);
|
||||
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
|
||||
#define REGION_FORMAT_MAGIC ".VOXREG"
|
||||
#define WORLD_FORMAT_MAGIC ".VOXWLD"
|
||||
|
||||
const size_t BUFFER_SIZE_UNKNOWN = -1;
|
||||
|
||||
regfile::regfile(fs::path filename) : file(filename) {
|
||||
@ -91,8 +94,6 @@ uint WorldRegion::getChunkDataSize(uint x, uint z) {
|
||||
return sizes[z * REGION_SIZE + x];
|
||||
}
|
||||
|
||||
const char* WorldFiles::WORLD_FILE = "world.json";
|
||||
|
||||
WorldFiles::WorldFiles(fs::path directory, const DebugSettings& settings)
|
||||
: directory(directory),
|
||||
generatorTestMode(settings.generatorTestMode),
|
||||
@ -161,11 +162,10 @@ int WorldFiles::getVoxelRegionsVersion() {
|
||||
return REGION_FORMAT_VERSION;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compress and store chunk voxels data in region
|
||||
* @param x chunk.x
|
||||
* @param z chunk.z
|
||||
*/
|
||||
|
||||
/// @brief Compress and store chunk voxels data in region
|
||||
/// @param x chunk.x
|
||||
/// @param z chunk.z
|
||||
void WorldFiles::put(int x, int z, const ubyte* voxelData) {
|
||||
int regionX = floordiv(x, REGION_SIZE);
|
||||
int regionZ = floordiv(z, REGION_SIZE);
|
||||
@ -181,9 +181,7 @@ void WorldFiles::put(int x, int z, const ubyte* voxelData) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Store chunk (voxels and lights) in region (existing or new)
|
||||
*/
|
||||
/// @brief Store chunk (voxels and lights) in region (existing or new)
|
||||
void WorldFiles::put(Chunk* chunk){
|
||||
assert(chunk != nullptr);
|
||||
|
||||
@ -201,7 +199,7 @@ void WorldFiles::put(Chunk* chunk){
|
||||
region->setUnsaved(true);
|
||||
region->put(localX, localZ, data, compressedSize);
|
||||
}
|
||||
/* Writing lights cache */
|
||||
// Writing lights cache
|
||||
if (doWriteLights && chunk->isLighted()) {
|
||||
size_t compressedSize;
|
||||
std::unique_ptr<ubyte[]> light_data (chunk->lightmap.encode());
|
||||
@ -211,7 +209,7 @@ void WorldFiles::put(Chunk* chunk){
|
||||
region->setUnsaved(true);
|
||||
region->put(localX, localZ, data, compressedSize);
|
||||
}
|
||||
/* Writing block inventories */
|
||||
// Writing block inventories
|
||||
if (!chunk->inventories.empty()){
|
||||
auto& inventories = chunk->inventories;
|
||||
ByteBuilder builder;
|
||||
@ -252,13 +250,11 @@ fs::path WorldFiles::getRegionFilename(int x, int z) const {
|
||||
return fs::path(std::to_string(x) + "_" + std::to_string(z) + ".bin");
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract X and Z from 'X_Z.bin' region file name.
|
||||
* @param name source region file name
|
||||
* @param x parsed X destination
|
||||
* @param z parsed Z destination
|
||||
* @return false if std::invalid_argument or std::out_of_range occurred
|
||||
*/
|
||||
/// @brief Extract X and Z from 'X_Z.bin' region file name.
|
||||
/// @param name source region file name
|
||||
/// @param x parsed X destination
|
||||
/// @param z parsed Z destination
|
||||
/// @return false if std::invalid_argument or std::out_of_range occurred
|
||||
bool WorldFiles::parseRegionFilename(const std::string& name, int& x, int& z) {
|
||||
size_t sep = name.find('_');
|
||||
if (sep == std::string::npos || sep == 0 || sep == name.length()-1)
|
||||
@ -294,8 +290,8 @@ ubyte* WorldFiles::getChunk(int x, int z){
|
||||
return getData(regions, getRegionsFolder(), x, z, REGION_LAYER_VOXELS, true);
|
||||
}
|
||||
|
||||
/* Get cached lights for chunk at x,z
|
||||
* @return lights data or nullptr */
|
||||
/// @brief Get cached lights for chunk at x,z
|
||||
/// @return lights data or nullptr
|
||||
light_t* WorldFiles::getLights(int x, int z) {
|
||||
std::unique_ptr<ubyte[]> data (getData(lights, getLightsFolder(), x, z, REGION_LAYER_LIGHTS, true));
|
||||
if (data == nullptr)
|
||||
@ -409,10 +405,9 @@ ubyte* WorldFiles::readChunkData(int x,
|
||||
return data;
|
||||
}
|
||||
|
||||
/* Read missing chunks data (null pointers) from region file
|
||||
* @param layer used as third part of openRegFiles map key
|
||||
* (see REGION_LAYER_* constants)
|
||||
*/
|
||||
/// @brief Read missing chunks data (null pointers) from region file
|
||||
/// @param layer used as third part of openRegFiles map key
|
||||
/// (see REGION_LAYER_* constants)
|
||||
void WorldFiles::fetchChunks(WorldRegion* region, int x, int z, fs::path folder, int layer) {
|
||||
ubyte** chunks = region->getChunks();
|
||||
uint32_t* sizes = region->getSizes();
|
||||
@ -426,12 +421,11 @@ void WorldFiles::fetchChunks(WorldRegion* region, int x, int z, fs::path folder,
|
||||
}
|
||||
}
|
||||
|
||||
/* Write or rewrite region file
|
||||
* @param x region X
|
||||
* @param z region Z
|
||||
* @param layer used as third part of openRegFiles map key
|
||||
* (see REGION_LAYER_* constants)
|
||||
*/
|
||||
/// @brief Write or rewrite region file
|
||||
/// @param x region X
|
||||
/// @param z region Z
|
||||
/// @param layer used as third part of openRegFiles map key
|
||||
/// (see REGION_LAYER_* constants)
|
||||
void WorldFiles::writeRegion(int x, int z, WorldRegion* entry, fs::path folder, int layer){
|
||||
fs::path filename = folder/getRegionFilename(x, z);
|
||||
|
||||
@ -501,7 +495,7 @@ void WorldFiles::write(const World* world, const Content* content) {
|
||||
if (generatorTestMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
writeIndices(content->getIndices());
|
||||
writeRegions(regions, regionsFolder, REGION_LAYER_VOXELS);
|
||||
writeRegions(lights, lightsFolder, REGION_LAYER_LIGHTS);
|
||||
@ -598,4 +592,26 @@ void WorldFiles::removePack(const World* world, const std::string& id) {
|
||||
ss << pack << "\n";
|
||||
}
|
||||
files::write_string(file, ss.str());
|
||||
|
||||
// erase invalid indices
|
||||
auto prefix = id+":";
|
||||
auto root = files::read_json(getIndicesFile());
|
||||
auto blocks = root->list("blocks");
|
||||
for (uint i = 0; i < blocks->size(); i++) {
|
||||
auto name = blocks->str(i);
|
||||
if (name.find(prefix) != 0)
|
||||
continue;
|
||||
auto value = blocks->getValueWriteable(i);
|
||||
*value->value.str = "core:air";
|
||||
}
|
||||
|
||||
auto items = root->list("items");
|
||||
for (uint i = 0; i < items->size(); i++) {
|
||||
auto name = items->str(i);
|
||||
if (name.find(prefix) != 0)
|
||||
continue;
|
||||
auto value = items->getValueWriteable(i);
|
||||
*value->value.str = "core:empty";
|
||||
}
|
||||
files::write_json(getIndicesFile(), root.get());
|
||||
}
|
||||
|
||||
@ -30,9 +30,6 @@ inline constexpr uint REGION_FORMAT_VERSION = 2;
|
||||
inline constexpr uint WORLD_FORMAT_VERSION = 1;
|
||||
inline constexpr uint MAX_OPEN_REGION_FILES = 16;
|
||||
|
||||
#define REGION_FORMAT_MAGIC ".VOXREG"
|
||||
#define WORLD_FORMAT_MAGIC ".VOXWLD"
|
||||
|
||||
class Player;
|
||||
class Content;
|
||||
class ContentIndices;
|
||||
@ -161,7 +158,7 @@ public:
|
||||
/// @param id pack id
|
||||
void removePack(const World* world, const std::string& id);
|
||||
|
||||
static const char* WORLD_FILE;
|
||||
static const inline std::string WORLD_FILE = "world.json";
|
||||
};
|
||||
|
||||
#endif /* FILES_WORLDFILES_H_ */
|
||||
|
||||
@ -13,14 +13,13 @@
|
||||
#include "../logic/LevelController.h"
|
||||
#include "../logic/PlayerController.h"
|
||||
|
||||
LevelFrontend::LevelFrontend(Level* level, Assets* assets)
|
||||
: level(level),
|
||||
LevelFrontend::LevelFrontend(LevelController* controller, Assets* assets)
|
||||
: level(controller->getLevel()),
|
||||
controller(controller),
|
||||
assets(assets),
|
||||
contentCache(std::make_unique<ContentGfxCache>(level->content, assets)),
|
||||
blocksAtlas(BlocksPreview::build(contentCache.get(), assets, level->content))
|
||||
{}
|
||||
|
||||
void LevelFrontend::observe(LevelController* controller) {
|
||||
{
|
||||
controller->getPlayerController()->listenBlockInteraction(
|
||||
[=](Player*, glm::ivec3 pos, const Block* def, BlockInteraction type) {
|
||||
auto material = level->content->findBlockMaterial(def->material);
|
||||
@ -85,3 +84,7 @@ ContentGfxCache* LevelFrontend::getContentGfxCache() const {
|
||||
Atlas* LevelFrontend::getBlocksAtlas() const {
|
||||
return blocksAtlas.get();
|
||||
}
|
||||
|
||||
LevelController* LevelFrontend::getController() const {
|
||||
return controller;
|
||||
}
|
||||
|
||||
@ -12,19 +12,20 @@ class LevelController;
|
||||
|
||||
class LevelFrontend {
|
||||
Level* level;
|
||||
LevelController* controller;
|
||||
Assets* assets;
|
||||
std::unique_ptr<ContentGfxCache> contentCache;
|
||||
std::unique_ptr<Atlas> blocksAtlas;
|
||||
public:
|
||||
LevelFrontend(Level* level, Assets* assets);
|
||||
LevelFrontend(LevelController* controller, Assets* assets);
|
||||
~LevelFrontend();
|
||||
|
||||
void observe(LevelController* controller);
|
||||
|
||||
Level* getLevel() const;
|
||||
Assets* getAssets() const;
|
||||
ContentGfxCache* getContentGfxCache() const;
|
||||
Atlas* getBlocksAtlas() const;
|
||||
|
||||
LevelController* getController() const;
|
||||
};
|
||||
|
||||
#endif // FRONTEND_LEVEL_FRONTEND_H_
|
||||
|
||||
@ -547,7 +547,7 @@ void Hud::setPause(bool pause) {
|
||||
|
||||
auto menu = gui->getMenu();
|
||||
if (pause) {
|
||||
menus::create_pause_panel(engine, frontend->getLevel());
|
||||
menus::create_pause_panel(engine, frontend->getController());
|
||||
menu->setPage("pause");
|
||||
} else {
|
||||
menu->reset();
|
||||
|
||||
@ -54,7 +54,7 @@ inline uint64_t randU64() {
|
||||
void menus::create_version_label(Engine* engine) {
|
||||
auto gui = engine->getGUI();
|
||||
auto vlabel = std::make_shared<gui::Label>(
|
||||
util::str2wstr_utf8(ENGINE_VERSION_STRING " development build ")
|
||||
util::str2wstr_utf8(ENGINE_VERSION_STRING+" development build ")
|
||||
);
|
||||
vlabel->setZIndex(1000);
|
||||
vlabel->setColor(glm::vec4(1, 1, 1, 0.5f));
|
||||
@ -210,9 +210,7 @@ void create_world_generators_panel(Engine* engine) {
|
||||
idlabel->setAlign(Align::right);
|
||||
|
||||
button->add(idlabel, glm::vec2(80, 4));
|
||||
|
||||
button->add(std::make_shared<Label>(fullName), glm::vec2(0, 8));
|
||||
|
||||
button->listenAction(
|
||||
[=](GUI*) {
|
||||
menus::generatorID = id;
|
||||
@ -224,21 +222,23 @@ void create_world_generators_panel(Engine* engine) {
|
||||
panel->add(guiutil::backButton(menu));
|
||||
}
|
||||
|
||||
void menus::open_world(std::string name, Engine* engine) {
|
||||
void menus::open_world(std::string name, Engine* engine, bool confirmConvert) {
|
||||
auto paths = engine->getPaths();
|
||||
auto folder = paths->getWorldsFolder()/fs::u8path(name);
|
||||
try {
|
||||
engine->loadWorldContent(folder);
|
||||
} catch (const contentpack_error& error) {
|
||||
// could not to find or read pack
|
||||
guiutil::alert(engine->getGUI(),
|
||||
langs::get(L"error.pack-not-found")+
|
||||
L": "+util::str2wstr_utf8(error.getPackId()));
|
||||
guiutil::alert(
|
||||
engine->getGUI(), langs::get(L"error.pack-not-found")+L": "+
|
||||
util::str2wstr_utf8(error.getPackId())
|
||||
);
|
||||
return;
|
||||
} catch (const std::runtime_error& error) {
|
||||
guiutil::alert(engine->getGUI(),
|
||||
langs::get(L"Content Error", L"menu")+
|
||||
L": "+util::str2wstr_utf8(error.what()));
|
||||
guiutil::alert(
|
||||
engine->getGUI(), langs::get(L"Content Error", L"menu")+L": "+
|
||||
util::str2wstr_utf8(error.what())
|
||||
);
|
||||
return;
|
||||
}
|
||||
paths->setWorldFolder(folder);
|
||||
@ -252,18 +252,25 @@ void menus::open_world(std::string name, Engine* engine) {
|
||||
if (lut->hasMissingContent()) {
|
||||
show_content_missing(engine, content, lut);
|
||||
} else {
|
||||
show_convert_request(engine, content, lut, folder, [=](){
|
||||
open_world(name, engine);
|
||||
});
|
||||
if (confirmConvert) {
|
||||
show_process_panel(engine, std::make_shared<WorldConverter>(folder, content, lut), [=](){
|
||||
open_world(name, engine, false);
|
||||
});
|
||||
} else {
|
||||
show_convert_request(engine, content, lut, folder, [=](){
|
||||
open_world(name, engine, false);
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
Level* level = World::load(folder, settings, content, packs);
|
||||
engine->setScreen(std::make_shared<LevelScreen>(engine, level));
|
||||
} catch (const world_load_error& error) {
|
||||
guiutil::alert(engine->getGUI(),
|
||||
langs::get(L"Error")+
|
||||
L": "+util::str2wstr_utf8(error.what()));
|
||||
guiutil::alert(
|
||||
engine->getGUI(), langs::get(L"Error")+L": "+
|
||||
util::str2wstr_utf8(error.what())
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -284,7 +291,7 @@ std::shared_ptr<Panel> create_worlds_panel(Engine* engine) {
|
||||
btn->setColor(glm::vec4(0.06f, 0.12f, 0.18f, 0.7f));
|
||||
btn->setHoverColor(glm::vec4(0.09f, 0.17f, 0.2f, 0.6f));
|
||||
btn->listenAction([=](GUI*) {
|
||||
menus::open_world(name, engine);
|
||||
menus::open_world(name, engine, false);
|
||||
});
|
||||
btn->add(std::make_shared<Label>(namews), glm::vec2(8, 8));
|
||||
|
||||
@ -296,8 +303,7 @@ std::shared_ptr<Panel> create_worlds_panel(Engine* engine) {
|
||||
delbtn->setHoverColor(glm::vec4(1.0f, 1.0f, 1.0f, 0.17f));
|
||||
delbtn->listenAction([=](GUI* gui) {
|
||||
guiutil::confirm(gui, langs::get(L"delete-confirm", L"world")+
|
||||
L" ("+util::str2wstr_utf8(folder.u8string())+L")", [=]()
|
||||
{
|
||||
L" ("+util::str2wstr_utf8(folder.u8string())+L")", [=]() {
|
||||
std::cout << "deleting " << folder.u8string() << std::endl;
|
||||
fs::remove_all(folder);
|
||||
menus::refresh_menus(engine);
|
||||
|
||||
@ -4,16 +4,22 @@
|
||||
#include <string>
|
||||
|
||||
class Engine;
|
||||
class Level;
|
||||
class LevelController;
|
||||
|
||||
namespace menus {
|
||||
// implemented in menu_settings.cpp
|
||||
extern void create_settings_panel(Engine* engine);
|
||||
|
||||
// implemented in menu_pause.cpp
|
||||
extern void create_pause_panel(Engine* engine, Level* level);
|
||||
extern void create_pause_panel(Engine* engine, LevelController* controller);
|
||||
|
||||
void open_world(std::string name, Engine* engine);
|
||||
/// @brief Load world, convert if required and set to LevelScreen.
|
||||
/// @param name world name
|
||||
/// @param engine engine instance
|
||||
/// @param confirmConvert automatically confirm convert if requested
|
||||
void open_world(std::string name, Engine* engine, bool confirmConvert);
|
||||
|
||||
/// @brief Create development version label at the top-right screen corner
|
||||
void create_version_label(Engine* engine);
|
||||
void create_menus(Engine* engine);
|
||||
void refresh_menus(Engine* engine);
|
||||
|
||||
@ -9,6 +9,8 @@
|
||||
#include "../../coders/png.h"
|
||||
#include "../../util/stringutil.h"
|
||||
#include "../../files/WorldFiles.h"
|
||||
#include "../../content/ContentLUT.h"
|
||||
#include "../../logic/LevelController.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
@ -96,14 +98,15 @@ std::shared_ptr<Panel> create_packs_panel(
|
||||
}
|
||||
|
||||
static void reopen_world(Engine* engine, World* world) {
|
||||
std::string wname = world->getName();
|
||||
std::string wname = world->wfile->directory.stem().u8string();
|
||||
engine->setScreen(nullptr);
|
||||
engine->setScreen(std::make_shared<MenuScreen>(engine));
|
||||
menus::open_world(wname, engine);
|
||||
menus::open_world(wname, engine, true);
|
||||
}
|
||||
|
||||
// TODO: refactor
|
||||
void create_content_panel(Engine* engine, Level* level) {
|
||||
void create_content_panel(Engine* engine, LevelController* controller) {
|
||||
auto level = controller->getLevel();
|
||||
auto menu = engine->getGUI()->getMenu();
|
||||
auto paths = engine->getPaths();
|
||||
auto mainPanel = menus::create_page(engine, "content", 550, 0.0f, 5);
|
||||
@ -122,16 +125,18 @@ void create_content_panel(Engine* engine, Level* level) {
|
||||
auto panel = create_packs_panel(
|
||||
engine->getContentPacks(), engine, false, nullptr,
|
||||
[=](const ContentPack& pack) {
|
||||
auto world = level->getWorld();
|
||||
auto runtime = engine->getContent()->getPackRuntime(pack.id);
|
||||
if (runtime->getStats().hasSavingContent()) {
|
||||
guiutil::confirm(engine->getGUI(), langs::get(L"remove-confirm", L"pack")+
|
||||
L" ("+util::str2wstr_utf8(pack.id)+L")", [=]() {
|
||||
// FIXME: work in progress
|
||||
controller->saveWorld();
|
||||
world->wfile->removePack(world, pack.id);
|
||||
reopen_world(engine, world);
|
||||
});
|
||||
} else {
|
||||
auto world = level->getWorld();
|
||||
controller->saveWorld();
|
||||
world->wfile->removePack(world, pack.id);
|
||||
|
||||
reopen_world(engine, world);
|
||||
}
|
||||
}
|
||||
@ -155,6 +160,7 @@ void create_content_panel(Engine* engine, Level* level) {
|
||||
}
|
||||
}
|
||||
world->wfile->addPack(world, pack.id);
|
||||
controller->saveWorld();
|
||||
reopen_world(engine, world);
|
||||
}, nullptr);
|
||||
menu->addPage("content-packs", panel);
|
||||
@ -163,7 +169,7 @@ void create_content_panel(Engine* engine, Level* level) {
|
||||
mainPanel->add(guiutil::backButton(menu));
|
||||
}
|
||||
|
||||
void menus::create_pause_panel(Engine* engine, Level* level) {
|
||||
void menus::create_pause_panel(Engine* engine, LevelController* controller) {
|
||||
auto menu = engine->getGUI()->getMenu();
|
||||
auto panel = create_page(engine, "pause", 400, 0.0f, 1);
|
||||
|
||||
@ -171,13 +177,15 @@ void menus::create_pause_panel(Engine* engine, Level* level) {
|
||||
menu->reset();
|
||||
}));
|
||||
panel->add(create_button(L"Content", glm::vec4(10.0f), glm::vec4(1), [=](GUI*) {
|
||||
create_content_panel(engine, level);
|
||||
create_content_panel(engine, controller);
|
||||
menu->setPage("content");
|
||||
}));
|
||||
panel->add(guiutil::gotoButton(L"Settings", "settings", menu));
|
||||
|
||||
panel->add(create_button(L"Save and Quit to Menu", glm::vec4(10.f), glm::vec4(1), [=](GUI*){
|
||||
// save world and destroy LevelScreen
|
||||
// save world
|
||||
controller->saveWorld();
|
||||
// destroy LevelScreen and run quit callbacks
|
||||
engine->setScreen(nullptr);
|
||||
// create and go to menu screen
|
||||
engine->setScreen(std::make_shared<MenuScreen>(engine));
|
||||
|
||||
@ -96,11 +96,11 @@ LevelScreen::LevelScreen(Engine* engine, Level* level) : Screen(engine) {
|
||||
menu->reset();
|
||||
|
||||
controller = std::make_unique<LevelController>(settings, level);
|
||||
frontend = std::make_unique<LevelFrontend>(level, assets);
|
||||
frontend = std::make_unique<LevelFrontend>(controller.get(), assets);
|
||||
|
||||
worldRenderer = std::make_unique<WorldRenderer>(engine, frontend.get(), controller->getPlayer());
|
||||
hud = std::make_unique<Hud>(engine, frontend.get(), controller->getPlayer());
|
||||
|
||||
frontend->observe(controller.get());
|
||||
|
||||
|
||||
backlight = settings.graphics.backlight;
|
||||
|
||||
@ -120,11 +120,7 @@ LevelScreen::LevelScreen(Engine* engine, Level* level) : Screen(engine) {
|
||||
}
|
||||
|
||||
LevelScreen::~LevelScreen() {
|
||||
std::cout << "-- writing world" << std::endl;
|
||||
scripting::on_frontend_close();
|
||||
controller->onWorldSave();
|
||||
auto world = controller->getLevel()->getWorld();
|
||||
world->write(controller->getLevel());
|
||||
controller->onWorldQuit();
|
||||
engine->getPaths()->setWorldFolder(fs::path());
|
||||
}
|
||||
@ -192,3 +188,11 @@ void LevelScreen::draw(float delta) {
|
||||
hud->draw(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void LevelScreen::onEngineShutdown() {
|
||||
controller->saveWorld();
|
||||
}
|
||||
|
||||
LevelController* LevelScreen::getLevelController() const {
|
||||
return controller.get();
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ class LevelFrontend;
|
||||
class LevelController;
|
||||
class TextureAnimator;
|
||||
|
||||
/* Screen is a mainloop state */
|
||||
/// @brief Screen is a mainloop state
|
||||
class Screen {
|
||||
protected:
|
||||
Engine* engine;
|
||||
@ -25,6 +25,7 @@ public:
|
||||
virtual ~Screen();
|
||||
virtual void update(float delta) = 0;
|
||||
virtual void draw(float delta) = 0;
|
||||
virtual void onEngineShutdown() {};
|
||||
};
|
||||
|
||||
class MenuScreen : public Screen {
|
||||
@ -52,6 +53,10 @@ public:
|
||||
|
||||
void update(float delta) override;
|
||||
void draw(float delta) override;
|
||||
|
||||
void onEngineShutdown() override;
|
||||
|
||||
LevelController* getLevelController() const;
|
||||
};
|
||||
|
||||
#endif // FRONTEND_SCREENS_H_
|
||||
|
||||
@ -10,7 +10,7 @@ class Chunks;
|
||||
class Lighting;
|
||||
class WorldGenerator;
|
||||
|
||||
/* ChunksController manages chunks dynamic loading/unloading */
|
||||
/// @brief ChunksController manages chunks dynamic loading/unloading
|
||||
class ChunksController {
|
||||
private:
|
||||
Level* level;
|
||||
@ -19,7 +19,7 @@ private:
|
||||
uint padding;
|
||||
std::unique_ptr<WorldGenerator> generator;
|
||||
|
||||
/* Process one chunk: load it or calculate lights for it */
|
||||
/// @brief Process one chunk: load it or calculate lights for it
|
||||
bool loadVisible();
|
||||
bool buildLights(std::shared_ptr<Chunk> chunk);
|
||||
void createChunk(int x, int y);
|
||||
@ -27,7 +27,7 @@ public:
|
||||
ChunksController(Level* level, uint padding);
|
||||
~ChunksController();
|
||||
|
||||
/* @param maxDuration milliseconds reserved for chunks loading */
|
||||
/// @param maxDuration milliseconds reserved for chunks loading
|
||||
void update(int64_t maxDuration);
|
||||
};
|
||||
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
#include "LevelController.h"
|
||||
#include "../world/Level.h"
|
||||
#include "../world/World.h"
|
||||
#include "../physics/Hitbox.h"
|
||||
|
||||
#include "scripting/scripting.h"
|
||||
#include "../interfaces/Object.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
LevelController::LevelController(EngineSettings& settings, Level* level)
|
||||
: settings(settings), level(level),
|
||||
blocks(std::make_unique<BlocksController>(level, settings.chunks.padding)),
|
||||
@ -42,8 +45,10 @@ void LevelController::update(float delta, bool input, bool pause) {
|
||||
}
|
||||
}
|
||||
|
||||
void LevelController::onWorldSave() {
|
||||
void LevelController::saveWorld() {
|
||||
std::cout << "-- writing world" << std::endl;
|
||||
scripting::on_world_save();
|
||||
level->getWorld()->write(level.get());
|
||||
}
|
||||
|
||||
void LevelController::onWorldQuit() {
|
||||
|
||||
@ -31,7 +31,8 @@ public:
|
||||
bool pause
|
||||
);
|
||||
|
||||
void onWorldSave();
|
||||
void saveWorld();
|
||||
|
||||
void onWorldQuit();
|
||||
|
||||
Level* getLevel();
|
||||
|
||||
@ -236,8 +236,20 @@ void Player::deserialize(dynamic::Map *src) {
|
||||
|
||||
|
||||
void Player::convert(dynamic::Map* data, const ContentLUT* lut) {
|
||||
auto inventory = data->map("inventory");
|
||||
if (inventory) {
|
||||
Inventory::convert(inventory, lut);
|
||||
auto players = data->list("players");
|
||||
if (players) {
|
||||
for (uint i = 0; i < players->size(); i++) {
|
||||
auto playerData = players->map(i);
|
||||
auto inventory = playerData->map("inventory");
|
||||
if (inventory) {
|
||||
Inventory::convert(inventory, lut);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
auto inventory = data->map("inventory");
|
||||
if (inventory) {
|
||||
Inventory::convert(inventory, lut);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,19 +13,20 @@
|
||||
#include "../items/Inventories.h"
|
||||
|
||||
Level::Level(World* world, const Content* content, EngineSettings& settings)
|
||||
: world(world),
|
||||
content(content),
|
||||
chunksStorage(std::make_unique<ChunksStorage>(this)),
|
||||
physics(std::make_unique<PhysicsSolver>(glm::vec3(0, -22.6f, 0))),
|
||||
events(std::make_unique<LevelEvents>()),
|
||||
settings(settings)
|
||||
: world(world),
|
||||
content(content),
|
||||
chunksStorage(std::make_unique<ChunksStorage>(this)),
|
||||
physics(std::make_unique<PhysicsSolver>(glm::vec3(0, -22.6f, 0))),
|
||||
events(std::make_unique<LevelEvents>()),
|
||||
settings(settings)
|
||||
{
|
||||
auto inv = std::make_shared<Inventory>(world->getNextInventoryId(), DEF_PLAYER_INVENTORY_SIZE);
|
||||
auto player = spawnObject<Player>(glm::vec3(0, DEF_PLAYER_Y, 0), DEF_PLAYER_SPEED, inv);
|
||||
|
||||
uint matrixSize = (settings.chunks.loadDistance + settings.chunks.padding) * 2;
|
||||
chunks = std::make_unique<Chunks>(matrixSize, matrixSize, 0, 0,
|
||||
world->wfile.get(), events.get(), content);
|
||||
chunks = std::make_unique<Chunks>(
|
||||
matrixSize, matrixSize, 0, 0, world->wfile.get(), events.get(), content
|
||||
);
|
||||
lighting = std::make_unique<Lighting>(content, chunks.get());
|
||||
|
||||
events->listen(EVT_CHUNK_HIDDEN, [this](lvl_event_type type, Chunk* chunk) {
|
||||
@ -53,4 +54,3 @@ void Level::loadMatrix(int32_t x, int32_t z, uint32_t radius) {
|
||||
World* Level::getWorld() {
|
||||
return world.get();
|
||||
}
|
||||
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
#ifndef WORLD_LEVEL_H_
|
||||
#define WORLD_LEVEL_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "../settings.h"
|
||||
#include "../interfaces/Object.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
const float DEF_PLAYER_Y = 100.0f;
|
||||
const float DEF_PLAYER_SPEED = 4.0f;
|
||||
const int DEF_PLAYER_INVENTORY_SIZE = 40;
|
||||
inline constexpr float DEF_PLAYER_Y = 100.0f;
|
||||
inline constexpr float DEF_PLAYER_SPEED = 4.0f;
|
||||
inline constexpr int DEF_PLAYER_INVENTORY_SIZE = 40;
|
||||
|
||||
class Content;
|
||||
class World;
|
||||
@ -22,36 +22,34 @@ class Lighting;
|
||||
class PhysicsSolver;
|
||||
class ChunksStorage;
|
||||
|
||||
/* A level, contains chunks and objects */
|
||||
/// @brief A level, contains chunks and objects
|
||||
class Level {
|
||||
public:
|
||||
std::unique_ptr<World> world;
|
||||
const Content* const content;
|
||||
std::vector<std::shared_ptr<Object>> objects;
|
||||
std::unique_ptr<World> world;
|
||||
const Content* const content;
|
||||
std::vector<std::shared_ptr<Object>> objects;
|
||||
std::unique_ptr<Chunks> chunks;
|
||||
std::unique_ptr<ChunksStorage> chunksStorage;
|
||||
std::unique_ptr<Inventories> inventories;
|
||||
std::unique_ptr<Inventories> inventories;
|
||||
|
||||
std::unique_ptr<PhysicsSolver> physics;
|
||||
std::unique_ptr<Lighting> lighting;
|
||||
std::unique_ptr<LevelEvents> events;
|
||||
|
||||
const EngineSettings& settings;
|
||||
const EngineSettings& settings;
|
||||
|
||||
Level(World* world,
|
||||
const Content* content,
|
||||
EngineSettings& settings);
|
||||
~Level();
|
||||
Level(World* world, const Content* content, EngineSettings& settings);
|
||||
~Level();
|
||||
|
||||
void loadMatrix(int32_t x, int32_t z, uint32_t radius);
|
||||
void loadMatrix(int32_t x, int32_t z, uint32_t radius);
|
||||
|
||||
World* getWorld();
|
||||
|
||||
// Spawns object of class T and returns pointer to it.
|
||||
// @param T class that derives the Object class
|
||||
// @param args pass arguments needed for T class constructor
|
||||
template<class T, typename... Args>
|
||||
std::shared_ptr<T> spawnObject(Args&&... args) {
|
||||
/// Spawns object of class T and returns pointer to it.
|
||||
/// @param T class that derives the Object class
|
||||
/// @param args pass arguments needed for T class constructor
|
||||
template<class T, typename... Args>
|
||||
std::shared_ptr<T> spawnObject(Args&&... args) {
|
||||
static_assert(std::is_base_of<Object, T>::value, "T must be a derived of Object class");
|
||||
std::shared_ptr<T> tObj = std::make_shared<T>(args...);
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ public:
|
||||
world_load_error(std::string message);
|
||||
};
|
||||
|
||||
/* World - holds all world data except the level (chunks and objects) */
|
||||
/// @brief holds all world data except the level (chunks and objects)
|
||||
class World : Serializable {
|
||||
std::string name;
|
||||
std::string generator;
|
||||
@ -40,116 +40,105 @@ class World : Serializable {
|
||||
public:
|
||||
std::unique_ptr<WorldFiles> wfile;
|
||||
|
||||
/**
|
||||
* Day/night loop timer in range 0..1
|
||||
* 0.0 - is midnight
|
||||
* 0.5 - is noon
|
||||
*/
|
||||
/// @brief Day/night loop timer in range 0..1 where
|
||||
/// 0.0 - is midnight and
|
||||
/// 0.5 - is noon
|
||||
float daytime = timeutil::time_value(10, 00, 00);
|
||||
|
||||
// looking bad
|
||||
float daytimeSpeed = 1.0f/60.0f/24.0f;
|
||||
|
||||
/// @brief total time passed in the world (not depending on daytimeSpeed)
|
||||
double totalTime = 0.0;
|
||||
|
||||
World(std::string name,
|
||||
std::string generator,
|
||||
fs::path directory,
|
||||
uint64_t seed,
|
||||
EngineSettings& settings,
|
||||
const Content* content,
|
||||
std::vector<ContentPack> packs);
|
||||
World(
|
||||
std::string name,
|
||||
std::string generator,
|
||||
fs::path directory,
|
||||
uint64_t seed,
|
||||
EngineSettings& settings,
|
||||
const Content* content,
|
||||
std::vector<ContentPack> packs
|
||||
);
|
||||
|
||||
~World();
|
||||
|
||||
/**
|
||||
* Update world day-time and total time
|
||||
* @param delta delta-time
|
||||
*/
|
||||
/// @brief Update world day-time and total time
|
||||
/// @param delta delta-time
|
||||
void updateTimers(float delta);
|
||||
|
||||
/**
|
||||
* Write all unsaved level data to the world directory
|
||||
*/
|
||||
/// @brief Write all unsaved level data to the world directory
|
||||
void write(Level* level);
|
||||
|
||||
/**
|
||||
* Check world indices and generate ContentLUT if convert required
|
||||
* @param directory world directory
|
||||
* @param content current Content instance
|
||||
* @return ContentLUT if world convert required else nullptr
|
||||
*/
|
||||
/// @brief Check world indices and generate ContentLUT if convert required
|
||||
/// @param directory world directory
|
||||
/// @param content current Content instance
|
||||
/// @return ContentLUT if world convert required else nullptr
|
||||
static ContentLUT* checkIndices(const fs::path& directory, const Content* content);
|
||||
|
||||
/**
|
||||
* Create new world
|
||||
* @param name internal world name
|
||||
* @param directory root world directory
|
||||
* @param type of the world
|
||||
* @param seed world generation seed
|
||||
* @param settings current engine settings
|
||||
* @param content current engine Content instance
|
||||
* with all world content-packs applied
|
||||
* @param packs vector of all world content-packs
|
||||
* @return Level instance containing World instance
|
||||
*/
|
||||
static Level* create(std::string name,
|
||||
std::string generator,
|
||||
fs::path directory,
|
||||
uint64_t seed,
|
||||
EngineSettings& settings,
|
||||
const Content* content,
|
||||
const std::vector<ContentPack>& packs);
|
||||
|
||||
/**
|
||||
* Load an existing world
|
||||
* @param directory root world directory
|
||||
* @param settings current engine settings
|
||||
* @param content current engine Content instance
|
||||
* with all world content-packs applied
|
||||
* @param packs vector of all world content-packs
|
||||
* @return Level instance containing World instance
|
||||
* @throws world_load_error on world.json load error
|
||||
*/
|
||||
static Level* load(fs::path directory,
|
||||
EngineSettings& settings,
|
||||
const Content* content,
|
||||
const std::vector<ContentPack>& packs);
|
||||
/// @brief Create new world
|
||||
/// @param name internal world name
|
||||
/// @param directory root world directory
|
||||
/// @param type of the world
|
||||
/// @param seed world generation seed
|
||||
/// @param settings current engine settings
|
||||
/// @param content current engine Content instance
|
||||
/// with all world content-packs applied
|
||||
/// @param packs vector of all world content-packs
|
||||
/// @return Level instance containing World instance
|
||||
static Level* create(
|
||||
std::string name,
|
||||
std::string generator,
|
||||
fs::path directory,
|
||||
uint64_t seed,
|
||||
EngineSettings& settings,
|
||||
const Content* content,
|
||||
const std::vector<ContentPack>& packs
|
||||
);
|
||||
|
||||
/// @brief Load an existing world
|
||||
/// @param directory root world directory
|
||||
/// @param settings current engine settings
|
||||
/// @param content current engine Content instance
|
||||
/// with all world content-packs applied
|
||||
/// @param packs vector of all world content-packs
|
||||
/// @return Level instance containing World instance
|
||||
/// @throws world_load_error on world.json load error
|
||||
static Level* load(
|
||||
fs::path directory,
|
||||
EngineSettings& settings,
|
||||
const Content* content,
|
||||
const std::vector<ContentPack>& packs
|
||||
);
|
||||
|
||||
void setName(const std::string& name);
|
||||
void setSeed(uint64_t seed);
|
||||
void setGenerator(const std::string& generator);
|
||||
|
||||
/**
|
||||
* Check if world has content-pack installed
|
||||
* @param id content-pack id
|
||||
*/
|
||||
/// @brief Check if world has content-pack installed
|
||||
/// @param id content-pack id
|
||||
bool hasPack(const std::string& id) const;
|
||||
|
||||
/**
|
||||
* Get internal world name (not the folder name)
|
||||
* @return name stored in world.json
|
||||
*/
|
||||
/// @brief Get internal world name (not the folder name)
|
||||
/// @return name stored in world.json
|
||||
std::string getName() const;
|
||||
|
||||
/** Get world generation seed */
|
||||
/// @brief Get world generation seed
|
||||
uint64_t getSeed() const;
|
||||
|
||||
/** Get world generator id */
|
||||
/// @brief Get world generator id
|
||||
std::string getGenerator() const;
|
||||
/**
|
||||
* Get vector of all content-packs installed in world
|
||||
*/
|
||||
|
||||
/// @brief Get vector of all content-packs installed in world
|
||||
const std::vector<ContentPack>& getPacks() const;
|
||||
|
||||
/**
|
||||
* Get next inventory id and increment it's counter
|
||||
* @return integer >= 1
|
||||
*/
|
||||
/// @brief Get next inventory id and increment it's counter
|
||||
/// @return integer >= 1
|
||||
int64_t getNextInventoryId() {
|
||||
return nextInventoryId++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current world Content instance
|
||||
*/
|
||||
/// @brief Get current world Content instance
|
||||
const Content* getContent() const {
|
||||
return content;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user