From a8707158a5be8c604fdb028a9c5f68ce5804016e Mon Sep 17 00:00:00 2001 From: DS Date: Thu, 10 Feb 2022 12:17:52 +0100 Subject: [PATCH] Allow to set the displayed item count and its alignment via meta (#8448) * Allow to set the displayed item count and its offset via meta * fix rect constr call * devtest: add dump_item chatcommand * fix rect2 constr call (sdim is a position (typedef for v2s32), not a dimension) and remove background because it would work now * add missing utf8 to wide conversion * rename to count_meta --- doc/lua_api.txt | 7 +++ games/devtest/mods/util_commands/init.lua | 47 +++++++++++++++ src/client/hud.cpp | 69 +++++++++++++++++++---- 3 files changed, 111 insertions(+), 12 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 7061a5b8a..1dc5f305d 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -2174,6 +2174,13 @@ Some of the values in the key-value store are handled specially: * `color`: A `ColorString`, which sets the stack's color. * `palette_index`: If the item has a palette, this is used to get the current color from the palette. +* `count_meta`: Replace the displayed count with any string. +* `count_alignment`: Set the alignment of the displayed count value. This is an + int value. The lowest 2 bits specify the alignment in x-direction, the 3rd and + 4th bit specify the alignment in y-direction: + 0 = default, 1 = left / up, 2 = middle, 3 = right / down + The default currently is the same as right/down. + Example: 6 = 2 + 1*4 = middle,up Example: diff --git a/games/devtest/mods/util_commands/init.lua b/games/devtest/mods/util_commands/init.lua index 79acaa0d0..9be989e67 100644 --- a/games/devtest/mods/util_commands/init.lua +++ b/games/devtest/mods/util_commands/init.lua @@ -246,3 +246,50 @@ function minetest.handle_node_drops(pos, drops, digger) end end end + +minetest.register_chatcommand("set_displayed_itemcount", { + params = "(-s \"\" [-c ]) | -a ", + description = "Set the displayed itemcount of the wielded item", + func = function(name, param) + local player = minetest.get_player_by_name(name) + local item = player:get_wielded_item() + local meta = item:get_meta() + local flag1 = param:sub(1, 2) + if flag1 == "-s" then + if param:sub(3, 4) ~= " \"" then + return false, "Error: Space and string with \"s expected after -s." + end + local se = param:find("\"", 5, true) + if not se then + return false, "Error: String with two \"s expected after -s." + end + local s = param:sub(5, se - 1) + if param:sub(se + 1, se + 4) == " -c " then + s = minetest.colorize(param:sub(se + 5), s) + end + meta:set_string("count_meta", s) + elseif flag1 == "-a" then + local num = tonumber(param:sub(4)) + if not num then + return false, "Error: Invalid number: "..param:sub(4) + end + meta:set_int("count_alignment", num) + else + return false + end + player:set_wielded_item(item) + return true, "Displayed itemcount set." + end, +}) + +minetest.register_chatcommand("dump_item", { + params = "", + description = "Prints a dump of the wielded item in table form", + func = function(name, param) + local player = minetest.get_player_by_name(name) + local item = player:get_wielded_item() + local str = dump(item:to_table()) + print(str) + return true, str + end, +}) diff --git a/src/client/hud.cpp b/src/client/hud.cpp index 259a18ab9..01f4d6ff3 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -1013,6 +1013,10 @@ void drawItemStack( bool has_mesh = false; ItemMesh *imesh; + core::rect viewrect = rect; + if (clip != nullptr) + viewrect.clipAgainst(*clip); + // Render as mesh if animated or no inventory image if ((enable_animations && rotation_kind < IT_ROT_NONE) || def.inventory_image.empty()) { imesh = client->idef()->getWieldMesh(def.name, client); @@ -1034,9 +1038,6 @@ void drawItemStack( core::rect oldViewPort = driver->getViewPort(); core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION); core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW); - core::rect viewrect = rect; - if (clip) - viewrect.clipAgainst(*clip); core::matrix4 ProjMatrix; ProjMatrix.buildProjectionMatrixOrthoLH(2.0f, 2.0f, -1.0f, 100.0f); @@ -1180,24 +1181,68 @@ void drawItemStack( driver->draw2DRectangle(color, progressrect2, clip); } - if (font != NULL && item.count >= 2) { + const std::string &count_text = item.metadata.getString("count_meta"); + if (font != nullptr && (item.count >= 2 || !count_text.empty())) { // Get the item count as a string - std::string text = itos(item.count); - v2u32 dim = font->getDimension(utf8_to_wide(text).c_str()); + std::string text = count_text.empty() ? itos(item.count) : count_text; + v2u32 dim = font->getDimension(utf8_to_wide(unescape_enriched(text)).c_str()); v2s32 sdim(dim.X, dim.Y); core::rect rect2( - /*rect.UpperLeftCorner, - core::dimension2d(rect.getWidth(), 15)*/ rect.LowerRightCorner - sdim, - sdim + rect.LowerRightCorner ); - video::SColor bgcolor(128, 0, 0, 0); - driver->draw2DRectangle(bgcolor, rect2, clip); + // get the count alignment + s32 count_alignment = stoi(item.metadata.getString("count_alignment")); + if (count_alignment != 0) { + s32 a_x = count_alignment & 3; + s32 a_y = (count_alignment >> 2) & 3; + + s32 x1, x2, y1, y2; + switch (a_x) { + case 1: // left + x1 = rect.UpperLeftCorner.X; + x2 = x1 + sdim.X; + break; + case 2: // middle + x1 = (rect.UpperLeftCorner.X + rect.LowerRightCorner.X - sdim.X) / 2; + x2 = x1 + sdim.X; + break; + case 3: // right + x2 = rect.LowerRightCorner.X; + x1 = x2 - sdim.X; + break; + default: // 0 = default + x1 = rect2.UpperLeftCorner.X; + x2 = rect2.LowerRightCorner.X; + break; + } + + switch (a_y) { + case 1: // up + y1 = rect.UpperLeftCorner.Y; + y2 = y1 + sdim.Y; + break; + case 2: // middle + y1 = (rect.UpperLeftCorner.Y + rect.LowerRightCorner.Y - sdim.Y) / 2; + y2 = y1 + sdim.Y; + break; + case 3: // down + y2 = rect.LowerRightCorner.Y; + y1 = y2 - sdim.Y; + break; + default: // 0 = default + y1 = rect2.UpperLeftCorner.Y; + y2 = rect2.LowerRightCorner.Y; + break; + } + + rect2 = core::rect(x1, y1, x2, y2); + } video::SColor color(255, 255, 255, 255); - font->draw(text.c_str(), rect2, color, false, false, clip); + font->draw(utf8_to_wide(text).c_str(), rect2, color, false, false, &viewrect); } }