Skip to content

Commit

Permalink
Add function to get all HUD elements (#14042)
Browse files Browse the repository at this point in the history
  • Loading branch information
cx384 committed Jan 14, 2024
1 parent ed7d403 commit 92c55c2
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 0 deletions.
4 changes: 4 additions & 0 deletions doc/client_lua_api.md
Expand Up @@ -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)`
Expand Down
4 changes: 4 additions & 0 deletions doc/lua_api.md
Expand Up @@ -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`
Expand Down
20 changes: 20 additions & 0 deletions games/devtest/mods/testhud/init.lua
Expand Up @@ -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
})
6 changes: 6 additions & 0 deletions src/player.cpp
Expand Up @@ -139,6 +139,12 @@ HudElement* Player::getHud(u32 id)
return NULL;
}

void Player::hudApply(std::function<void(const std::vector<HudElement*>&)> f)
{
MutexAutoLock lock(m_mutex);
f(hud);
}

HudElement* Player::removeHud(u32 id)
{
MutexAutoLock lock(m_mutex);
Expand Down
2 changes: 2 additions & 0 deletions src/player.h
Expand Up @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "util/basic_macros.h"
#include <list>
#include <mutex>
#include <functional>

#define PLAYERNAME_SIZE 20

Expand Down Expand Up @@ -225,6 +226,7 @@ class Player
}

HudElement* getHud(u32 id);
void hudApply(std::function<void(const std::vector<HudElement*>&)> f);
u32 addHud(HudElement* hud);
HudElement* removeHud(u32 id);
void clearHud();
Expand Down
21 changes: 21 additions & 0 deletions src/script/lua_api/l_localplayer.cpp
Expand Up @@ -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<HudElement*>& 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;
Expand Down Expand Up @@ -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),

Expand Down
2 changes: 2 additions & 0 deletions src/script/lua_api/l_localplayer.h
Expand Up @@ -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);

Expand Down
23 changes: 23 additions & 0 deletions src/script/lua_api/l_object.cpp
Expand Up @@ -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<ObjectRef>(L, 1);
RemotePlayer *player = getplayer(ref);
if (player == nullptr)
return 0;

lua_newtable(L);
player->hudApply([&](const std::vector<HudElement*>& 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)
{
Expand Down Expand Up @@ -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),
Expand Down
3 changes: 3 additions & 0 deletions src/script/lua_api/l_object.h
Expand Up @@ -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);

Expand Down

0 comments on commit 92c55c2

Please sign in to comment.