diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index d64bbf53..af41327c 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -208,10 +208,16 @@ function _rules.listen(name, handler) end function _rules.create(name, value, handler) - _rules.set(name, value) + local handlerid if handler ~= nil then - return _rules.listen(name, handler) + handlerid = _rules.listen(name, handler) end + if _rules.get(name) == nil then + _rules.set(name, value) + else + handler(_rules.get(name)) + end + return handlerid end function _rules.unlisten(name, id) @@ -240,13 +246,36 @@ function __vc_create_hud_rules() input.set_enabled("player.attack", value) end) _rules.create("allow-cheat-movement", true, function(value) - input.set_enabled("player.cheat", value) + input.set_enabled("movement.cheat", value) end) _rules.create("allow-debug-cheats", true, function(value) hud._set_debug_cheats(value) end) end +local RULES_FILE = "world:rules.toml" +function __vc_on_world_open() + if not file.exists(RULES_FILE) then + return + end + local rule_values = toml.parse(file.read(RULES_FILE)) + for name, value in pairs(rule_values) do + _rules.set(name, value) + end +end + +function __vc_on_world_save() + local rule_values = {} + for name, rule in pairs(rules.rules) do + rule_values[name] = rule.value + end + file.write(RULES_FILE, toml.tostring(rule_values)) +end + +function __vc_on_world_quit() + _rules.clear() +end + -- --------- Deprecated functions ------ -- local function wrap_deprecated(func, name, alternatives) return function (...) diff --git a/src/engine.cpp b/src/engine.cpp index c5bae880..85a9e42b 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -360,7 +360,7 @@ void Engine::loadContent() { for (auto& pack : contentPacks) { ContentLoader(&pack, contentBuilder, *resPaths).load(); load_configs(pack.folder); - } + } content = contentBuilder.build(); @@ -421,8 +421,6 @@ double Engine::getDelta() const { } void Engine::setScreen(std::shared_ptr screen) { - // unblock all bindings - Events::enableBindings(); // reset audio channels (stop all sources) audio::reset_channel(audio::get_channel_index("regular")); audio::reset_channel(audio::get_channel_index("ambient")); diff --git a/src/frontend/screens/LevelScreen.cpp b/src/frontend/screens/LevelScreen.cpp index 2dda016c..c0e3e534 100644 --- a/src/frontend/screens/LevelScreen.cpp +++ b/src/frontend/screens/LevelScreen.cpp @@ -87,6 +87,8 @@ void LevelScreen::initializePack(ContentPackRuntime* pack) { LevelScreen::~LevelScreen() { saveWorldPreview(); scripting::on_frontend_close(); + // unblock all bindings + Events::enableBindings(); controller->onWorldQuit(); engine->getPaths()->setCurrentWorldFolder(fs::path()); } diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index c0d7dc97..72360ce1 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -150,7 +150,7 @@ void scripting::initialize(Engine* engine) { void scripting::process_post_runnables() { auto L = lua::get_main_state(); if (lua::getglobal(L, "__process_post_runnables")) { - lua::call_nothrow(L, 0); + lua::call_nothrow(L, 0, 0); } } @@ -160,9 +160,13 @@ void scripting::on_world_load(LevelController* controller) { scripting::indices = level->content->getIndices(); scripting::blocks = controller->getBlocksController(); scripting::controller = controller; - load_script("world.lua", false); auto L = lua::get_main_state(); + if (lua::getglobal(L, "__vc_on_world_open")) { + lua::call_nothrow(L, 0, 0); + } + load_script("world.lua", false); + for (auto& pack : scripting::engine->getContentPacks()) { lua::emit_event(L, pack.id + ":.worldopen"); } @@ -180,6 +184,9 @@ void scripting::on_world_save() { for (auto& pack : scripting::engine->getContentPacks()) { lua::emit_event(L, pack.id + ":.worldsave"); } + if (lua::getglobal(L, "__vc_on_world_save")) { + lua::call_nothrow(L, 0, 0); + } } void scripting::on_world_quit() { @@ -187,6 +194,9 @@ void scripting::on_world_quit() { for (auto& pack : scripting::engine->getContentPacks()) { lua::emit_event(L, pack.id + ":.worldquit"); } + if (lua::getglobal(L, "__vc_on_world_quit")) { + lua::call_nothrow(L, 0, 0); + } scripting::level = nullptr; scripting::content = nullptr; scripting::indices = nullptr; @@ -204,11 +214,6 @@ void scripting::cleanup() { } lua::pop(L); - lua::getglobal(L, "rules"); - lua::getfield(L, "clear"); - lua::call_nothrow(L, 0); - lua::pop(L); - if (lua::getglobal(L, "__scripts_cleanup")) { lua::call_nothrow(L, 0); }