From cf7fda00831372d981415f9a830513b2b28fdf25 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Mon, 4 Nov 2019 09:30:02 +0100 Subject: [PATCH] Add z-index management to HUD --- doc/lua_api.txt | 8 ++++++++ src/client/clientevent.h | 1 + src/client/game.cpp | 5 +++++ src/client/hud.cpp | 14 ++++++++++++++ src/hud.cpp | 2 ++ src/hud.h | 4 +++- src/network/clientpackethandler.cpp | 7 +++++++ src/network/networkprotocol.h | 1 + src/script/common/c_content.cpp | 19 ++++++++++++++----- src/server.cpp | 3 ++- 10 files changed, 57 insertions(+), 7 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 9ca44747f..697efcdbc 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1260,6 +1260,11 @@ precisely positioned items in the HUD. **Note**: `offset` _will_ adapt to screen DPI as well as user defined scaling factor! +The `z_index` field specifies the order of HUD elements from back to front. +Lower z-index elements are displayed behind higher z-index elements. Elements +with same z-index are displayed in an arbitrary order. Default 0. +Supports negative values. + Below are the specific uses for fields in each type; fields not listed for that type are ignored. @@ -7322,6 +7327,9 @@ Used by `Player:hud_add`. Returned by `Player:hud_get`. size = { x=100, y=100 }, -- Size of element in pixels + + z_index = 0, + -- Z index : lower z-index HUDs are displayed behind higher z-index HUDs } Particle definition diff --git a/src/client/clientevent.h b/src/client/clientevent.h index 2a44717ce..69e8838b4 100644 --- a/src/client/clientevent.h +++ b/src/client/clientevent.h @@ -131,6 +131,7 @@ struct ClientEvent v2f *offset; v3f *world_pos; v2s32 *size; + s16 z_index; } hudadd; struct { diff --git a/src/client/game.cpp b/src/client/game.cpp index 59654e892..e3e0e1150 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -2650,6 +2650,7 @@ void Game::handleClientEvent_HudAdd(ClientEvent *event, CameraOrientation *cam) e->offset = *event->hudadd.offset; e->world_pos = *event->hudadd.world_pos; e->size = *event->hudadd.size; + e->z_index = event->hudadd.z_index; hud_server_to_client[server_id] = player->addHud(e); delete event->hudadd.pos; @@ -2728,6 +2729,10 @@ void Game::handleClientEvent_HudChange(ClientEvent *event, CameraOrientation *ca case HUD_STAT_SIZE: e->size = *event->hudchange.v2s32data; break; + + case HUD_STAT_Z_INDEX: + e->z_index = event->hudchange.data; + break; } delete event->hudchange.v3fdata; diff --git a/src/client/hud.cpp b/src/client/hud.cpp index 304a3ab16..e78130dd4 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -283,11 +283,25 @@ void Hud::drawLuaElements(const v3s16 &camera_offset) { u32 text_height = g_fontengine->getTextHeight(); irr::gui::IGUIFont* font = g_fontengine->getFont(); + + // Reorder elements by z_index + std::vector ids; + for (size_t i = 0; i != player->maxHudId(); i++) { HudElement *e = player->getHud(i); if (!e) continue; + auto it = ids.begin(); + while (it != ids.end() && player->getHud(*it)->z_index <= e->z_index) + ++it; + + ids.insert(it, i); + } + + for (size_t i : ids) { + HudElement *e = player->getHud(i); + v2s32 pos(floor(e->pos.X * (float) m_screensize.X + 0.5), floor(e->pos.Y * (float) m_screensize.Y + 0.5)); switch (e->type) { diff --git a/src/hud.cpp b/src/hud.cpp index 8ada65274..7711e3a4a 100644 --- a/src/hud.cpp +++ b/src/hud.cpp @@ -43,6 +43,8 @@ const struct EnumString es_HudElementStat[] = {HUD_STAT_ALIGN, "alignment"}, {HUD_STAT_OFFSET, "offset"}, {HUD_STAT_WORLD_POS, "world_pos"}, + {HUD_STAT_SIZE, "size"}, + {HUD_STAT_Z_INDEX, "z_index"}, {0, NULL}, }; diff --git a/src/hud.h b/src/hud.h index bfb644303..23f189dff 100644 --- a/src/hud.h +++ b/src/hud.h @@ -74,7 +74,8 @@ enum HudElementStat { HUD_STAT_ALIGN, HUD_STAT_OFFSET, HUD_STAT_WORLD_POS, - HUD_STAT_SIZE + HUD_STAT_SIZE, + HUD_STAT_Z_INDEX, }; struct HudElement { @@ -90,6 +91,7 @@ struct HudElement { v2f offset; v3f world_pos; v2s32 size; + s16 z_index = 0; }; extern const EnumString es_HudElementType[]; diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index b6e9defb0..79f2b95ba 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -1081,6 +1081,7 @@ void Client::handleCommand_HudAdd(NetworkPacket* pkt) v2f offset; v3f world_pos; v2s32 size; + s16 z_index = 0; *pkt >> server_id >> type >> pos >> name >> scale >> text >> number >> item >> dir >> align >> offset; @@ -1093,6 +1094,11 @@ void Client::handleCommand_HudAdd(NetworkPacket* pkt) *pkt >> size; } catch(SerializationError &e) {}; + try { + *pkt >> z_index; + } + catch(PacketError &e) {} + ClientEvent *event = new ClientEvent(); event->type = CE_HUDADD; event->hudadd.server_id = server_id; @@ -1108,6 +1114,7 @@ void Client::handleCommand_HudAdd(NetworkPacket* pkt) event->hudadd.offset = new v2f(offset); event->hudadd.world_pos = new v3f(world_pos); event->hudadd.size = new v2s32(size); + event->hudadd.z_index = z_index; m_client_event_queue.push(event); } diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index 236c7892e..f74027828 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -563,6 +563,7 @@ enum ToClientCommand v2f1000 offset v3f1000 world_pos v2s32 size + s16 z_index */ TOCLIENT_HUDRM = 0x4a, diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 72142798e..fc1d82bcc 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -1851,11 +1851,13 @@ void read_hud_element(lua_State *L, HudElement *elem) elem->size = lua_istable(L, -1) ? read_v2s32(L, -1) : v2s32(); lua_pop(L, 1); - elem->name = getstringfield_default(L, 2, "name", ""); - elem->text = getstringfield_default(L, 2, "text", ""); - elem->number = getintfield_default(L, 2, "number", 0); - elem->item = getintfield_default(L, 2, "item", 0); - elem->dir = getintfield_default(L, 2, "direction", 0); + elem->name = getstringfield_default(L, 2, "name", ""); + elem->text = getstringfield_default(L, 2, "text", ""); + elem->number = getintfield_default(L, 2, "number", 0); + elem->item = getintfield_default(L, 2, "item", 0); + elem->dir = getintfield_default(L, 2, "direction", 0); + elem->z_index = MYMAX(S16_MIN, MYMIN(S16_MAX, + getintfield_default(L, 2, "z_index", 0))); // Deprecated, only for compatibility's sake if (elem->dir == 0) @@ -1921,6 +1923,9 @@ void push_hud_element(lua_State *L, HudElement *elem) push_v3f(L, elem->world_pos); lua_setfield(L, -2, "world_pos"); + + lua_pushnumber(L, elem->z_index); + lua_setfield(L, -2, "z_index"); } HudElementStat read_hud_change(lua_State *L, HudElement *elem, void **value) @@ -1978,6 +1983,10 @@ HudElementStat read_hud_change(lua_State *L, HudElement *elem, void **value) elem->size = read_v2s32(L, 4); *value = &elem->size; break; + case HUD_STAT_Z_INDEX: + elem->z_index = MYMAX(S16_MIN, MYMIN(S16_MAX, luaL_checknumber(L, 4))); + *value = &elem->z_index; + break; } return stat; } diff --git a/src/server.cpp b/src/server.cpp index d914beead..4090dd773 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1654,7 +1654,8 @@ void Server::SendHUDAdd(session_t peer_id, u32 id, HudElement *form) pkt << id << (u8) form->type << form->pos << form->name << form->scale << form->text << form->number << form->item << form->dir - << form->align << form->offset << form->world_pos << form->size; + << form->align << form->offset << form->world_pos << form->size + << form->z_index; Send(&pkt); }