From 92c55c27cf520bd7b0e59639cc7cce7bcaf5d747 Mon Sep 17 00:00:00 2001 From: cx384 Date: Sun, 14 Jan 2024 17:46:29 +0100 Subject: [PATCH] Add function to get all HUD elements (#14042) --- doc/client_lua_api.md | 4 ++++ doc/lua_api.md | 4 ++++ games/devtest/mods/testhud/init.lua | 20 ++++++++++++++++++++ src/player.cpp | 6 ++++++ src/player.h | 2 ++ src/script/lua_api/l_localplayer.cpp | 21 +++++++++++++++++++++ src/script/lua_api/l_localplayer.h | 2 ++ src/script/lua_api/l_object.cpp | 23 +++++++++++++++++++++++ src/script/lua_api/l_object.h | 3 +++ 9 files changed, 85 insertions(+) diff --git a/doc/client_lua_api.md b/doc/client_lua_api.md index 8cf9238a0fde..a6feb5c302f6 100644 --- a/doc/client_lua_api.md +++ b/doc/client_lua_api.md @@ -779,6 +779,10 @@ Methods: * See [`HUD definition`](#hud-definition-hud_add-hud_get) * `hud_get(id)` * returns the [`definition`](#hud-definition-hud_add-hud_get) of the HUD with that ID number or `nil`, if non-existent. +* `hud_get_all()`: + * Returns a table in the form `{ [id] = HUD definition, [id] = ... }`. + * A mod should keep track of its introduced IDs and only use this to access foreign elements. + * It is discouraged to change foreign HUD elements. * `hud_remove(id)` * remove the HUD element of the specified id, returns `true` on success * `hud_change(id, stat, value)` diff --git a/doc/lua_api.md b/doc/lua_api.md index 8afe2b78d62e..2acc8e9ebbd2 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -7803,6 +7803,10 @@ child will follow movement and rotation of that bone. * `stat` supports the same keys as in the hud definition table except for `"type"` (or the deprecated `"hud_elem_type"`). * `hud_get(id)`: gets the HUD element definition structure of the specified ID +* `hud_get_all()`: + * Returns a table in the form `{ [id] = HUD definition, [id] = ... }`. + * A mod should keep track of its introduced IDs and only use this to access foreign elements. + * It is discouraged to change foreign HUD elements. * `hud_set_flags(flags)`: sets specified HUD flags of player. * `flags`: A table with the following fields set to boolean values * `hotbar` diff --git a/games/devtest/mods/testhud/init.lua b/games/devtest/mods/testhud/init.lua index 062976e14e03..5fdae3d3804d 100644 --- a/games/devtest/mods/testhud/init.lua +++ b/games/devtest/mods/testhud/init.lua @@ -210,3 +210,23 @@ minetest.register_on_leaveplayer(function(player) player_font_huds[player:get_player_name()] = nil player_waypoints[player:get_player_name()] = nil end) + +minetest.register_chatcommand("hudprint", { + description = "Writes all used Lua HUD elements into chat.", + func = function(name, params) + local player = minetest.get_player_by_name(name) + if not player then + return false, "No player." + end + + local s = "HUD elements:" + for k, elem in pairs(player:hud_get_all()) do + local ename = dump(elem.name) + local etype = dump(elem.type) + local epos = "{x="..elem.position.x..", y="..elem.position.y.."}" + s = s.."\n["..k.."] type = "..etype.." | name = "..ename.." | pos = ".. epos + end + + return true, s + end +}) diff --git a/src/player.cpp b/src/player.cpp index 8742454d2962..f0461c9e1e2d 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -139,6 +139,12 @@ HudElement* Player::getHud(u32 id) return NULL; } +void Player::hudApply(std::function&)> f) +{ + MutexAutoLock lock(m_mutex); + f(hud); +} + HudElement* Player::removeHud(u32 id) { MutexAutoLock lock(m_mutex); diff --git a/src/player.h b/src/player.h index af1d73f4a749..25109c3f9f97 100644 --- a/src/player.h +++ b/src/player.h @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/basic_macros.h" #include #include +#include #define PLAYERNAME_SIZE 20 @@ -225,6 +226,7 @@ class Player } HudElement* getHud(u32 id); + void hudApply(std::function&)> f); u32 addHud(HudElement* hud); HudElement* removeHud(u32 id); void clearHud(); diff --git a/src/script/lua_api/l_localplayer.cpp b/src/script/lua_api/l_localplayer.cpp index 42ca2e0c213f..dc88466f7ff1 100644 --- a/src/script/lua_api/l_localplayer.cpp +++ b/src/script/lua_api/l_localplayer.cpp @@ -422,6 +422,26 @@ int LuaLocalPlayer::l_hud_get(lua_State *L) return 1; } +// hud_get_all(self) +int LuaLocalPlayer::l_hud_get_all(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + if (player == nullptr) + return 0; + + lua_newtable(L); + player->hudApply([&](const std::vector& hud) { + for (std::size_t id = 0; id < hud.size(); ++id) { + HudElement *elem = hud[id]; + if (elem != nullptr) { + push_hud_element(L, elem); + lua_rawseti(L, -2, id); + } + } + }); + return 1; +} + LocalPlayer *LuaLocalPlayer::getobject(LuaLocalPlayer *ref) { return ref->m_localplayer; @@ -483,6 +503,7 @@ const luaL_Reg LuaLocalPlayer::methods[] = { luamethod(LuaLocalPlayer, hud_remove), luamethod(LuaLocalPlayer, hud_change), luamethod(LuaLocalPlayer, hud_get), + luamethod(LuaLocalPlayer, hud_get_all), luamethod(LuaLocalPlayer, get_move_resistance), diff --git a/src/script/lua_api/l_localplayer.h b/src/script/lua_api/l_localplayer.h index 0a416e58a095..d7865b08c943 100644 --- a/src/script/lua_api/l_localplayer.h +++ b/src/script/lua_api/l_localplayer.h @@ -93,6 +93,8 @@ class LuaLocalPlayer : public ModApiBase static int l_hud_change(lua_State *L); // hud_get(self, id) static int l_hud_get(lua_State *L); + // hud_get_all(self) + static int l_hud_get_all(lua_State *L); static int l_get_move_resistance(lua_State *L); diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 11ad7a7fe739..3d89bc279861 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1743,6 +1743,28 @@ int ObjectRef::l_hud_get(lua_State *L) return 1; } +// hud_get_all(self) +int ObjectRef::l_hud_get_all(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkObject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + lua_newtable(L); + player->hudApply([&](const std::vector& hud) { + for (std::size_t id = 0; id < hud.size(); ++id) { + HudElement *elem = hud[id]; + if (elem != nullptr) { + push_hud_element(L, elem); + lua_rawseti(L, -2, id); + } + } + }); + return 1; +} + // hud_set_flags(self, flags) int ObjectRef::l_hud_set_flags(lua_State *L) { @@ -2691,6 +2713,7 @@ luaL_Reg ObjectRef::methods[] = { luamethod(ObjectRef, hud_remove), luamethod(ObjectRef, hud_change), luamethod(ObjectRef, hud_get), + luamethod(ObjectRef, hud_get_all), luamethod(ObjectRef, hud_set_flags), luamethod(ObjectRef, hud_get_flags), luamethod(ObjectRef, hud_set_hotbar_itemcount), diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index d8cc8d6049e9..73264db105ec 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -300,6 +300,9 @@ class ObjectRef : public ModApiBase { // hud_get(self, id) static int l_hud_get(lua_State *L); + // hud_get_all(self) + static int l_hud_get_all(lua_State *L); + // hud_set_flags(self, flags) static int l_hud_set_flags(lua_State *L);