From f2c26aed193b12b45d0a967b476d0e85ef2a2e89 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 19 Mar 2024 13:22:35 +0300 Subject: [PATCH 1/5] double event handlers calls fix --- res/scripts/stdlib.lua | 12 ++++++++++++ src/logic/scripting/scripting.cpp | 9 +++++++++ 2 files changed, 21 insertions(+) diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index c547f7d3..d8397f57 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -135,6 +135,18 @@ function events.on(event, func) table.insert(events.handlers[event], func) end +function events.remove_by_prefix(prefix) + for name, handlers in pairs(events.handlers) do + if name:sub(1, #prefix) == prefix then + events.handlers[name] = nil + end + end +end + +function pack.unload(prefix) + events.remove_by_prefix(prefix) +end + function events.emit(event, ...) result = nil if events.handlers[event] then diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index f74dc943..8624a394 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -125,6 +125,15 @@ void scripting::on_world_quit() { for (auto& pack : scripting::engine->getContentPacks()) { emit_event(pack.id + ".worldquit"); } + + state->getglobal("pack"); + for (auto& pack : scripting::engine->getContentPacks()) { + state->getfield("unload"); + state->pushstring(pack.id); + state->callNoThrow(1); + } + state->pop(); + if (state->getglobal("__scripts_cleanup")) { state->callNoThrow(0); } From d5c39a05fbce42de797ca03314c12634a315ecea Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 19 Mar 2024 13:42:38 +0300 Subject: [PATCH 2/5] audio stats functions --- doc/en/7.Audio.md | 10 ++++++++++ doc/ru/7.Аудио.md | 9 +++++++++ src/logic/scripting/lua/libaudio.cpp | 14 ++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/doc/en/7.Audio.md b/doc/en/7.Audio.md index 5b810a34..9322583f 100644 --- a/doc/en/7.Audio.md +++ b/doc/en/7.Audio.md @@ -193,3 +193,13 @@ audio.set_velocity(speakerid: integer, x: number, y: number, z: number) -- also returns 0, if duration is unknown (example: radio) audio.get_duration(speakerid: integer) -> number ``` + +### Other functions + +```lua +-- get current number of alive speakers +audio.count_speakers() -> integer + +-- get current number of playing streams +audio.count_streams() -> integer +``` \ No newline at end of file diff --git a/doc/ru/7.Аудио.md b/doc/ru/7.Аудио.md index 66dfb311..b560b739 100644 --- a/doc/ru/7.Аудио.md +++ b/doc/ru/7.Аудио.md @@ -194,3 +194,12 @@ audio.set_velocity(speakerid: integer, x: number, y: number, z: number) audio.get_duration(speakerid: integer) -> number ``` +### Другие функции + +```lua +-- получить текущее число живых спикеров +audio.count_speakers() -> integer + +-- получить текущее число проигрываемых аудио-потоков +audio.count_streams() -> integer +``` diff --git a/src/logic/scripting/lua/libaudio.cpp b/src/logic/scripting/lua/libaudio.cpp index 1a786692..04401ea5 100644 --- a/src/logic/scripting/lua/libaudio.cpp +++ b/src/logic/scripting/lua/libaudio.cpp @@ -391,6 +391,18 @@ static int l_audio_get_velocity(lua_State* L) { return 0; } +// @brief audio.count_speakers() -> integer +static int l_audio_count_speakers(lua_State* L) { + lua_pushinteger(L, audio::count_speakers()); + return 1; +} + +// @brief audio.count_streams() -> integer +static int l_audio_count_streams(lua_State* L) { + lua_pushinteger(L, audio::count_streams()); + return 1; +} + const luaL_Reg audiolib [] = { {"play_sound", lua_wrap_errors}, {"play_sound_2d", lua_wrap_errors}, @@ -414,5 +426,7 @@ const luaL_Reg audiolib [] = { {"get_duration", lua_wrap_errors}, {"get_position", lua_wrap_errors}, {"get_velocity", lua_wrap_errors}, + {"count_speakers", lua_wrap_errors}, + {"count_streams", lua_wrap_errors}, {NULL, NULL} }; From f89c252ddfe5657dc6a65cd059e1deb16f6bea37 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 19 Mar 2024 14:04:06 +0300 Subject: [PATCH 3/5] lua suppliers update + label supplier XML attribute --- src/frontend/gui/gui_xml.cpp | 8 ++++++++ src/logic/scripting/lua/LuaState.cpp | 8 ++++++++ src/logic/scripting/lua/LuaState.h | 2 ++ src/logic/scripting/scripting_functional.cpp | 16 ++++++++++++---- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/frontend/gui/gui_xml.cpp b/src/frontend/gui/gui_xml.cpp index 8ddb4494..228abac2 100644 --- a/src/frontend/gui/gui_xml.cpp +++ b/src/frontend/gui/gui_xml.cpp @@ -170,6 +170,14 @@ static std::shared_ptr readLabel(UiXmlReader& reader, xml::xmlelement el align_from_string(element->attr("valign").getText(), label->getVerticalAlign()) ); } + if (element->has("supplier")) { + auto supplier = scripting::create_wstring_supplier( + reader.getEnvironment().getId(), + element->attr("supplier").getText(), + reader.getFilename() + ); + label->textSupplier(supplier); + } return label; } diff --git a/src/logic/scripting/lua/LuaState.cpp b/src/logic/scripting/lua/LuaState.cpp index e472831d..1dab0c38 100644 --- a/src/logic/scripting/lua/LuaState.cpp +++ b/src/logic/scripting/lua/LuaState.cpp @@ -247,6 +247,14 @@ const char* lua::LuaState::tostring(int idx) { return lua_tostring(L, idx); } +bool lua::LuaState::isstring(int idx) { + return lua_isstring(L, idx); +} + +bool lua::LuaState::isfunction(int idx) { + return lua_isfunction(L, idx); +} + void lua::LuaState::openlib(const std::string& name, const luaL_Reg* libfuncs, int nup) { lua_newtable(L); luaL_setfuncs(L, libfuncs, nup); diff --git a/src/logic/scripting/lua/LuaState.h b/src/logic/scripting/lua/LuaState.h index a49d1660..5e753bb1 100644 --- a/src/logic/scripting/lua/LuaState.h +++ b/src/logic/scripting/lua/LuaState.h @@ -45,6 +45,8 @@ namespace lua { luaint tointeger(int idx); luanumber tonumber(int idx); const char* tostring(int idx); + bool isstring(int idx); + bool isfunction(int idx); int call(int argc); int callNoThrow(int argc); int execute(int env, const std::string& src, const std::string& file=""); diff --git a/src/logic/scripting/scripting_functional.cpp b/src/logic/scripting/scripting_functional.cpp index d45bbfda..2a9bb81c 100644 --- a/src/logic/scripting/scripting_functional.cpp +++ b/src/logic/scripting/scripting_functional.cpp @@ -58,7 +58,9 @@ wstringsupplier scripting::create_wstring_supplier( ) { return [=](){ if (processCallback(env, src, file)) { - state->callNoThrow(0); + if (state->isfunction(-1)) { + state->callNoThrow(0); + } auto str = state->tostring(-1); state->pop(); return util::str2wstr_utf8(str); } @@ -101,7 +103,9 @@ boolsupplier scripting::create_bool_supplier( ) { return [=](){ if (processCallback(env, src, file)) { - state->callNoThrow(0); + if (state->isfunction(-1)) { + state->callNoThrow(0); + } bool x = state->toboolean(-1); state->pop(); return x; } @@ -129,7 +133,9 @@ doublesupplier scripting::create_number_supplier( ) { return [=](){ if (processCallback(env, src, file)) { - state->callNoThrow(0); + if (state->isfunction(-1)) { + state->callNoThrow(0); + } lua::luanumber x = state->tonumber(-1); state->pop(); return x; } @@ -159,7 +165,9 @@ vec2supplier scripting::create_vec2_supplier( ) { return [=](){ if (processCallback(env, src, file)) { - state->callNoThrow(0); + if (state->isfunction(-1)) { + state->callNoThrow(0); + } lua::luanumber y = state->tonumber(-1); state->pop(); lua::luanumber x = state->tonumber(-1); state->pop(); return glm::vec2(x, y); From 69f4e165a40aa67e55915916dd910bcce1fed71c Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 19 Mar 2024 14:20:39 +0300 Subject: [PATCH 4/5] core:empty as default picking-item for hidden blocks --- src/content/ContentLoader.cpp | 5 ++++ src/core_defs.h | 43 +++++++++++++++++++---------------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index 35ce691e..3da09e47 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -13,6 +13,7 @@ #include "../files/files.h" #include "../coders/json.h" #include "../typedefs.h" +#include "../core_defs.h" #include "../data/dynamic.h" #include "ContentPack.h" @@ -207,6 +208,10 @@ void ContentLoader::loadBlock(Block& def, std::string name, fs::path file) { root->str("script-name", def.scriptName); root->str("ui-layout", def.uiLayout); root->num("inventory-size", def.inventorySize); + + if (def.hidden && def.pickingItem == def.name+BLOCK_ITEM_SUFFIX) { + def.pickingItem = CORE_EMPTY; + } } void ContentLoader::loadCustomBlockModel(Block& def, dynamic::Map* primitives) { diff --git a/src/core_defs.h b/src/core_defs.h index a813c133..f9ff9d9a 100644 --- a/src/core_defs.h +++ b/src/core_defs.h @@ -1,27 +1,30 @@ -#ifndef SRC_CORE_DEFS_H_ -#define SRC_CORE_DEFS_H_ +#ifndef CORE_DEFS_H_ +#define CORE_DEFS_H_ #include -const std::string TEXTURE_NOTFOUND = "notfound"; +inline const std::string CORE_EMPTY = "core:empty"; +inline const std::string CORE_AIR = "core:air"; + +inline const std::string TEXTURE_NOTFOUND = "notfound"; /* bindings used in engine code */ -const std::string BIND_MOVE_FORWARD = "movement.forward"; -const std::string BIND_MOVE_BACK = "movement.back"; -const std::string BIND_MOVE_LEFT = "movement.left"; -const std::string BIND_MOVE_RIGHT = "movement.right"; -const std::string BIND_MOVE_JUMP = "movement.jump"; -const std::string BIND_MOVE_SPRINT = "movement.sprint"; -const std::string BIND_MOVE_CROUCH = "movement.crouch"; -const std::string BIND_MOVE_CHEAT = "movement.cheat"; -const std::string BIND_CAM_ZOOM = "camera.zoom"; -const std::string BIND_CAM_MODE = "camera.mode"; -const std::string BIND_PLAYER_NOCLIP = "player.noclip"; -const std::string BIND_PLAYER_FLIGHT = "player.flight"; -const std::string BIND_PLAYER_ATTACK = "player.attack"; -const std::string BIND_PLAYER_BUILD = "player.build"; -const std::string BIND_PLAYER_PICK = "player.pick"; -const std::string BIND_HUD_INVENTORY = "hud.inventory"; +inline const std::string BIND_MOVE_FORWARD = "movement.forward"; +inline const std::string BIND_MOVE_BACK = "movement.back"; +inline const std::string BIND_MOVE_LEFT = "movement.left"; +inline const std::string BIND_MOVE_RIGHT = "movement.right"; +inline const std::string BIND_MOVE_JUMP = "movement.jump"; +inline const std::string BIND_MOVE_SPRINT = "movement.sprint"; +inline const std::string BIND_MOVE_CROUCH = "movement.crouch"; +inline const std::string BIND_MOVE_CHEAT = "movement.cheat"; +inline const std::string BIND_CAM_ZOOM = "camera.zoom"; +inline const std::string BIND_CAM_MODE = "camera.mode"; +inline const std::string BIND_PLAYER_NOCLIP = "player.noclip"; +inline const std::string BIND_PLAYER_FLIGHT = "player.flight"; +inline const std::string BIND_PLAYER_ATTACK = "player.attack"; +inline const std::string BIND_PLAYER_BUILD = "player.build"; +inline const std::string BIND_PLAYER_PICK = "player.pick"; +inline const std::string BIND_HUD_INVENTORY = "hud.inventory"; class ContentBuilder; @@ -30,4 +33,4 @@ namespace corecontent { extern void setup(ContentBuilder* builder); } -#endif // SRC_CORE_DEFS_H_ \ No newline at end of file +#endif // CORE_DEFS_H_ From 23682cfd5aa4e13320a6b1404e02c11fc921e6c3 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 20 Mar 2024 10:18:08 +0300 Subject: [PATCH 5/5] docs: block.get_rotation, block.set_rotation --- doc/en/8.Scripting.md | 13 +++++++++++++ doc/ru/8.Скриптинг.md | 12 ++++++++++++ 2 files changed, 25 insertions(+) diff --git a/doc/en/8.Scripting.md b/doc/en/8.Scripting.md index 68b1e04b..ace3c80e 100644 --- a/doc/en/8.Scripting.md +++ b/doc/en/8.Scripting.md @@ -213,6 +213,19 @@ block.get_Z(x: int, y: int, z: int) -> int, int, int Returns Z: integer direction vector of the block at specified coordinates. Example: no rotation: 0, 0, 1 + +```python +block.get_rotation(x: int, y: int, z: int) -> int +``` + +Returns block rotation index based on used profile. + +```python +block.set_rotation(x: int, y: int, z: int, rotation: int) +``` + +Set block rotation by index. + ### User bits Part of a voxel data used for scripting. Size: 8 bit. diff --git a/doc/ru/8.Скриптинг.md b/doc/ru/8.Скриптинг.md index 7d174252..40b0a5a3 100644 --- a/doc/ru/8.Скриптинг.md +++ b/doc/ru/8.Скриптинг.md @@ -208,6 +208,18 @@ block.get_Z(x: int, y: int, z: int) -> int, int, int Возвращает целочисленный единичный вектор Z блока на указанных координатах с учётом его вращения (три целых числа). Если поворот отсутствует, возвращает 0, 0, 1 +```python +block.get_rotation(x: int, y: int, z: int) -> int +``` + +Возвращает индекс поворота блока в его профиле вращения. + +```python +block.set_rotation(x: int, y: int, z: int, rotation: int) +``` + +Устанавливает вращение блока по индексу в его профиле вращения. + ### Пользовательские биты Выделенная под использования в скриптах часть поля `voxel.states` хранящего доп-информацию о вокселе, такую как вращение блока. На данный момент выделенная часть составляет 8 бит.