From e28af89de2ff4b79cbfc84515005fc3ae3074004 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 8 Apr 2026 20:28:51 +0300 Subject: [PATCH 1/8] fix teleports loop on low obstacles --- src/physics/PhysicsSolver.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/physics/PhysicsSolver.cpp b/src/physics/PhysicsSolver.cpp index 117136ea0..5fb959670 100644 --- a/src/physics/PhysicsSolver.cpp +++ b/src/physics/PhysicsSolver.cpp @@ -151,10 +151,7 @@ bool PhysicsSolver::calcCollisionNegY( continue; } auto aabb = AABB(pos - half, pos + half); - glm::vec3 scale(1.0f); - scale.x = 1.0f - E * 4.0f; - scale.z = 1.0f - E * 4.0f; - aabb.scale(scale); + aabb.scale(glm::vec3(1.0f - E * 4.0f, 1.0f - E * 2, 1.0f - E * 4.0f)); auto boxhalf = box->getHalfSize(); if (box->position.y < pos.y && box->getAABB().intersects(aabb)) { @@ -279,7 +276,7 @@ void PhysicsSolver::calcCollisions( // step on if (stepHeight > 0.0 && vel.y <= 0.0f) { AABB boxAABB = AABB(pos - half, pos + half); - boxAABB.scale(glm::vec3(1.0f - E * 2, 1.0f - E * 2, 1.0f - E * 2)); + boxAABB.scale(glm::vec3(1.0f - E * 4.0f, 1.0f - E * 2, 1.0f - E * 4.0f)); for (int ix = 0; ix <= glm::ceil((half.x - E) * 2); ix++) { float x = (pos.x - half.x) + ix; for (int iz = 0; iz <= glm::ceil((half.z - E) * 2); iz++) { From 736cdb0980f68f64e5b3c0135cf5962169c05349 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 9 Apr 2026 19:42:21 +0300 Subject: [PATCH 2/8] fix 3d text scaling in projected display mode --- src/graphics/render/TextsRenderer.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/graphics/render/TextsRenderer.cpp b/src/graphics/render/TextsRenderer.cpp index 0f9d32285..ed822fc9f 100644 --- a/src/graphics/render/TextsRenderer.cpp +++ b/src/graphics/render/TextsRenderer.cpp @@ -71,10 +71,9 @@ void TextsRenderer::renderNote( if (preset.displayMode == NoteDisplayMode::PROJECTED) { float scale = 1.0f; if (glm::abs(preset.perspective) > 0.0001f) { - float scale2 = scale / - (glm::distance(camera.position, pos) * - util::sqr(camera.zoom) * - glm::sqrt(glm::tan(camera.getFov() * 0.5f))); + float scale2 = + scale / (glm::distance(camera.position, pos) * camera.zoom * + glm::sqrt(glm::tan(camera.getFov() * 0.5f))); scale = scale2 * preset.perspective + scale * (1.0f - preset.perspective); } From 6daaa4895bee30e4a92b3e769116ec8e473f2728 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 10 Apr 2026 12:21:11 +0300 Subject: [PATCH 3/8] fix audio.play type checks --- src/logic/scripting/lua/libs/libaudio.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/logic/scripting/lua/libs/libaudio.cpp b/src/logic/scripting/lua/libs/libaudio.cpp index ba8595af1..31be7553f 100644 --- a/src/logic/scripting/lua/libs/libaudio.cpp +++ b/src/logic/scripting/lua/libs/libaudio.cpp @@ -8,7 +8,7 @@ inline const char* DEFAULT_CHANNEL = "regular"; inline int extract_channel_index(lua::State* L, int idx) { const char* channel = DEFAULT_CHANNEL; - if (!lua::isnoneornil(L, idx)) { + if (lua::isstring(L, idx)) { channel = lua::tostring(L, idx); } int index = audio::get_channel_index(channel); @@ -121,7 +121,7 @@ static int l_audio_play_stream(lua::State* L) { return lua::pushinteger( L, static_cast(play_stream( - lua::tostring(L, 1), + lua::require_string(L, 1), false, lua::tonumber(L, 2), lua::tonumber(L, 3), @@ -144,7 +144,7 @@ static int l_audio_play_stream_2d(lua::State* L) { return lua::pushinteger( L, static_cast(play_stream( - lua::tostring(L, 1), + lua::require_string(L, 1), true, 0.0, 0.0, @@ -170,7 +170,7 @@ static int l_audio_play_sound(lua::State* L) { return lua::pushinteger( L, static_cast(play_sound( - lua::tostring(L, 1), + lua::require_string(L, 1), false, lua::tonumber(L, 2), lua::tonumber(L, 3), @@ -193,7 +193,7 @@ static int l_audio_play_sound_2d(lua::State* L) { return lua::pushinteger( L, static_cast(play_sound( - lua::tostring(L, 1), + lua::require_string(L, 1), true, 0.0, 0.0, From 497780c650c2660fbf26950d0845d0c23c0e214a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 10 Apr 2026 20:15:36 +0300 Subject: [PATCH 4/8] fix doc/*/world-generator.md --- doc/en/world-generator.md | 2 +- doc/ru/world-generator.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/en/world-generator.md b/doc/en/world-generator.md index cce303a44..cd868b404 100644 --- a/doc/en/world-generator.md +++ b/doc/en/world-generator.md @@ -416,7 +416,7 @@ Structure: Where: - structure_name - a string containing the name of the structure, registered in structures.toml. -- structure_position - a vec3 (an array of three numbers) relative to the position of the chunk. +- structure_position - a vec3 (an array of three numbers). - rotation - a number from 0 to 3 indicating the rotation of the structure along the Y axis. - priority - a number determining the order in which structures are placed. Structures with lower priority are overlapped by structures with higher priority. diff --git a/doc/ru/world-generator.md b/doc/ru/world-generator.md index e22920a1e..30e4b1098 100644 --- a/doc/ru/world-generator.md +++ b/doc/ru/world-generator.md @@ -419,7 +419,7 @@ end Где: - имя_структуры - строка содержащая имя структуры, зарегистрированная в structures.toml. -- позиция_структуры - vec3 (массив из трех чисел) относительно позиции чанка. +- позиция_структуры - vec3 (массив из трех чисел). - поворот - число от 0 до 3 обозначающая поворот структуры по оси Y. - приоритет - число определяющее порядок установки структур. Структуры с меньшем приоритетом перекрываются структурами с большим. From 73837082c2f629614dd28e04880d9ca6f59908b1 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 11 Apr 2026 12:14:36 +0300 Subject: [PATCH 5/8] fix app.reconfig_packs --- src/logic/EngineController.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/logic/EngineController.cpp b/src/logic/EngineController.cpp index 2e9bfa58e..9231ffe67 100644 --- a/src/logic/EngineController.cpp +++ b/src/logic/EngineController.cpp @@ -321,7 +321,10 @@ static void reconfig_packs_outside( } for (const auto& id : packsToRemove) { manager.exclude(id); - names.erase(std::find(names.begin(), names.end(), id)); + auto it = std::find(names.begin(), names.end(), id); + if (it != names.end()) { + names.erase(it); + } } names = manager.assemble(names); contentControl.setContentPacksRaw(manager.getAll(names)); From ea64560b5d95b446bcddeaa011b5cf7b60c44f5d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 11 Apr 2026 12:31:01 +0300 Subject: [PATCH 6/8] add missing error handling to gui_util::* functions --- src/graphics/ui/gui_util.cpp | 42 ++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/src/graphics/ui/gui_util.cpp b/src/graphics/ui/gui_util.cpp index 6c240e601..13364b0ed 100644 --- a/src/graphics/ui/gui_util.cpp +++ b/src/graphics/ui/gui_util.cpp @@ -12,6 +12,9 @@ #include "gui_xml.hpp" #include "logic/scripting/scripting.hpp" #include "util/stringutil.hpp" +#include "debug/Logger.hpp" + +debug::Logger logger("gui-util"); using namespace gui; @@ -25,6 +28,20 @@ std::shared_ptr guiutil::create( return reader.readXML("[string]", source); } +static bool notify_callback(const runnable& callback, std::string_view name) { + if (callback == nullptr) { + return false; + } + try { + callback(); + return true; + } catch (std::exception& err) { + logger.error() + << "exception thrown in " << name << ": " << err.what(); + } + return false; +} + void guiutil::alert( Engine& engine, const std::wstring& text, const runnable& on_hidden ) { @@ -47,9 +64,7 @@ void guiutil::alert( auto& menu = *menuPtr; runnable on_hidden_final = [on_hidden, &menu]() { menu.removePage(""); - if (on_hidden) { - on_hidden(); - } else if (!menu.back()) { + if (!notify_callback(on_hidden, "on_hidden") && !menu.back()) { menu.reset(); } }; @@ -119,18 +134,16 @@ void guiutil::confirm( runnable on_confirm_final = [on_confirm, menu]() { menu->removePage(""); - if (on_confirm) { - on_confirm(); - } else if (!menu->back()) { + + if (!notify_callback(on_confirm, "on_confirm") && !menu->back()) { menu->reset(); } }; runnable on_deny_final = [on_deny, menu]() { menu->removePage(""); - if (on_deny) { - on_deny(); - } else if (!menu->back()) { + + if (!notify_callback(on_deny, "on_deny") && !menu->back()) { menu->reset(); } }; @@ -189,9 +202,16 @@ void guiutil::confirm_with_memo( auto subpanel = std::make_shared(gui, glm::vec2(600, 53)); subpanel->setColor(glm::vec4(0)); + runnable on_confirm_final = [on_confirm, menu]() { + menu->removePage(""); + + if (!notify_callback(on_confirm, "on_confirm") && !menu->back()) { + menu->reset(); + } + }; + subpanel->add(std::make_shared