move weather back to gfx & add world:client/environment.json file

This commit is contained in:
MihailRis 2025-03-09 22:50:45 +03:00
parent 7a86cbdd60
commit db620010a3
11 changed files with 68 additions and 37 deletions

View File

@ -273,7 +273,7 @@ console.add_command(
return "weather preset not found"
end
local preset = json.parse(file.read(filename))
weather.change(preset, args[2], args[1])
gfx.weather.change(preset, args[2], args[1])
return "weather set to "..filename.." preset ("..tostring(args[2]).." s)"
end
)
@ -282,9 +282,9 @@ console.add_command(
"weather",
"Display current weather preset name",
function (args, kwargs)
local name = weather.get_current()
local name = gfx.weather.get_current()
if name == "" then
return "unnamed " .. json.tostring(weather.get_current_data(), true)
return "unnamed " .. json.tostring(gfx.weather.get_current_data(), true)
else
return name
end

View File

@ -36,10 +36,14 @@
static debug::Logger logger("level-screen");
inline const io::path CLIENT_FILE = "world:client/environment.json";
LevelScreen::LevelScreen(
Engine& engine, std::unique_ptr<Level> levelPtr, int64_t localPlayer
)
: Screen(engine), postProcessing(std::make_unique<PostProcessing>()) {
: Screen(engine),
world(*levelPtr->getWorld()),
postProcessing(std::make_unique<PostProcessing>()) {
Level* level = levelPtr.get();
auto& settings = engine.getSettings();
@ -92,9 +96,22 @@ LevelScreen::LevelScreen(
animator = std::make_unique<TextureAnimator>();
animator->addAnimations(assets.getAnimations());
loadDecorations();
initializeContent();
}
LevelScreen::~LevelScreen() {
if (!controller->getLevel()->getWorld()->isNameless()) {
saveDecorations();
saveWorldPreview();
}
scripting::on_frontend_close();
// unblock all bindings
Events::enableBindings();
controller->onWorldQuit();
engine.getPaths().setCurrentWorldFolder("");
}
void LevelScreen::initializeContent() {
auto& content = controller->getLevel()->content;
for (auto& entry : content.getPacks()) {
@ -116,15 +133,22 @@ void LevelScreen::initializePack(ContentPackRuntime* pack) {
}
}
LevelScreen::~LevelScreen() {
if (!controller->getLevel()->getWorld()->isNameless()) {
saveWorldPreview();
void LevelScreen::loadDecorations() {
if (!io::exists(CLIENT_FILE)) {
return;
}
scripting::on_frontend_close();
// unblock all bindings
Events::enableBindings();
controller->onWorldQuit();
engine.getPaths().setCurrentWorldFolder("");
auto data = io::read_object(CLIENT_FILE);
if (data.has("weather")) {
worldRenderer->getWeather().deserialize(data["weather"]);
}
}
void LevelScreen::saveDecorations() {
io::create_directory("world:client");
auto data = dv::object();
data["weather"] = worldRenderer->getWeather().serialize();
io::write_json(CLIENT_FILE, data, true);
}
void LevelScreen::saveWorldPreview() {
@ -144,7 +168,7 @@ void LevelScreen::saveWorldPreview() {
Viewport viewport(previewSize * 1.5, previewSize);
DrawContext ctx(&pctx, viewport, batch.get());
worldRenderer->draw(ctx, camera, false, true, 0.0f, postProcessing.get());
worldRenderer->draw(ctx, camera, false, true, 0.0f, *postProcessing);
auto image = postProcessing->toImage();
image->flipY();
imageio::write("world:preview.png", image.get());
@ -210,7 +234,7 @@ void LevelScreen::update(float delta) {
hud->update(hudVisible);
const auto& weather = level->getWorld()->getInfo().weather;
const auto& weather = worldRenderer->getWeather();
decorator->update(
hud->isPause() ? 0.0f : delta, *camera, weather.a, weather.b
);
@ -226,7 +250,7 @@ void LevelScreen::draw(float delta) {
scripting::on_entities_render(engine.getTime().getDelta());
}
worldRenderer->draw(
ctx, *camera, hudVisible, hud->isPause(), delta, postProcessing.get()
ctx, *camera, hudVisible, hud->isPause(), delta, *postProcessing
);
if (hudVisible) {

View File

@ -15,8 +15,10 @@ class PostProcessing;
class ContentPackRuntime;
class Decorator;
class Level;
class World;
class LevelScreen : public Screen {
World& world;
std::unique_ptr<LevelFrontend> frontend;
std::unique_ptr<LevelController> controller;
std::unique_ptr<PlayerController> playerController;
@ -33,6 +35,9 @@ class LevelScreen : public Screen {
void updateHotkeys();
void initializeContent();
void initializePack(ContentPackRuntime* pack);
void loadDecorations();
void saveDecorations();
public:
LevelScreen(
Engine& engine, std::unique_ptr<Level> level, int64_t localPlayer

View File

@ -111,7 +111,6 @@ void WorldRenderer::setupWorldShader(
const EngineSettings& settings,
float fogFactor
) {
const auto& weather = level.getWorld()->getInfo().weather;
shader.use();
shader.uniformMatrix("u_model", glm::mat4(1.0f));
shader.uniformMatrix("u_proj", camera.getProjection());
@ -153,8 +152,6 @@ void WorldRenderer::renderLevel(
bool pause,
bool hudVisible
) {
const auto& weather = level.getWorld()->getInfo().weather;
texts->render(ctx, camera, settings, hudVisible, false);
bool culling = engine.getSettings().graphics.frustumCulling.get();
@ -332,12 +329,15 @@ void WorldRenderer::draw(
Camera& camera,
bool hudVisible,
bool pause,
float delta,
PostProcessing* postProcessing
float uiDelta,
PostProcessing& postProcessing
) {
timer += delta * !pause;
float delta = uiDelta * !pause;
timer += delta;
weather.update(delta);
auto world = level.getWorld();
const auto& weather = world->getInfo().weather;
const Viewport& vp = pctx.getViewport();
camera.aspect = vp.getWidth() / static_cast<float>(vp.getHeight());
@ -357,7 +357,7 @@ void WorldRenderer::draw(
/* World render scope with diegetic HUD included */ {
DrawContext wctx = pctx.sub();
postProcessing->use(wctx);
postProcessing.use(wctx);
Window::clearDepth();
@ -368,7 +368,7 @@ void WorldRenderer::draw(
DrawContext ctx = wctx.sub();
ctx.setDepthTest(true);
ctx.setCullFace(true);
renderLevel(ctx, camera, settings, delta, pause, hudVisible);
renderLevel(ctx, camera, settings, uiDelta, pause, hudVisible);
// Debug lines
if (hudVisible) {
if (debug) {
@ -377,7 +377,7 @@ void WorldRenderer::draw(
);
}
if (player.currentCamera == player.fpCamera) {
renderHands(camera, delta * !pause);
renderHands(camera, delta);
}
}
}
@ -393,7 +393,7 @@ void WorldRenderer::draw(
screenShader->use();
screenShader->uniform1f("u_timer", timer);
screenShader->uniform1f("u_dayTime", worldInfo.daytime);
postProcessing->render(pctx, screenShader);
postProcessing.render(pctx, screenShader);
}
void WorldRenderer::renderBlockOverlay(const DrawContext& wctx) {
@ -447,3 +447,7 @@ void WorldRenderer::clear() {
void WorldRenderer::setDebug(bool flag) {
debug = flag;
}
Weather& WorldRenderer::getWeather() {
return weather;
}

View File

@ -47,6 +47,7 @@ class WorldRenderer {
std::unique_ptr<GuidesRenderer> guides;
std::unique_ptr<Skybox> skybox;
std::unique_ptr<ModelBatch> modelBatch;
Weather weather {};
float timer = 0.0f;
bool debug = false;
@ -89,7 +90,7 @@ public:
bool hudVisible,
bool pause,
float delta,
PostProcessing* postProcessing
PostProcessing& postProcessing
);
/// @brief Render level without diegetic interface
@ -108,4 +109,6 @@ public:
void clear();
void setDebug(bool flag);
Weather& getWeather();
};

View File

@ -69,8 +69,6 @@ LevelController::LevelController(
}
void LevelController::update(float delta, bool pause) {
level->getWorld()->getInfo().weather.update(delta);
for (const auto& [_, player] : *level->players) {
if (player->isSuspended()) {
continue;

View File

@ -1,4 +1,5 @@
#include "api_lua.hpp"
#include "libhud.hpp"
#include "world/Level.hpp"
#include "world/World.hpp"
@ -8,7 +9,7 @@ static Weather& require_weather() {
if (level == nullptr) {
throw std::runtime_error("world is not open");
}
return level->getWorld()->getInfo().weather;
return renderer->getWeather();
}
static int l_change(lua::State* L) {

View File

@ -73,7 +73,6 @@ static void create_libs(State* L, StateType stateType) {
openlib(L, "player", playerlib);
openlib(L, "time", timelib);
openlib(L, "world", worldlib);
openlib(L, "weather", weatherlib);
openlib(L, "entities", entitylib);
openlib(L, "cameras", cameralib);

View File

@ -35,6 +35,7 @@ void scripting::on_frontend_init(Hud* hud, WorldRenderer* renderer) {
lua::openlib(L, "hud", hudlib);
lua::openlib(L, "gfx", "blockwraps", blockwrapslib);
lua::openlib(L, "gfx", "particles", particleslib);
lua::openlib(L, "gfx", "weather", weatherlib);
lua::openlib(L, "gfx", "text3d", text3dlib);
load_script("hud_classes.lua");

View File

@ -208,7 +208,6 @@ void WorldInfo::deserialize(const dv::value& root) {
totalTime = timeobj["total-time"].asNumber();
}
if (root.has("weather")) {
weather.deserialize(root["weather"]);
fog = root["weather"]["fog"].asNumber();
}
nextInventoryId = root["next-inventory-id"].asInteger(2);
@ -232,7 +231,7 @@ dv::value WorldInfo::serialize() const {
timeobj["day-time-speed"] = daytimeSpeed;
timeobj["total-time"] = totalTime;
root["weather"] = weather.serialize();
root["weather"] = dv::object();
root["weather"]["fog"] = fog;
root["next-inventory-id"] = nextInventoryId;

View File

@ -7,7 +7,6 @@
#include "content/ContentPack.hpp"
#include "interfaces/Serializable.hpp"
#include "io/fwd.hpp"
#include "Weather.hpp"
#include "typedefs.hpp"
#include "util/timeutil.hpp"
@ -46,8 +45,6 @@ struct WorldInfo : public Serializable {
int major = 0, minor = -1;
Weather weather {};
dv::value serialize() const override;
void deserialize(const dv::value& src) override;
};