From b9ed4793ea0d228a23875325f698cef5cdd27783 Mon Sep 17 00:00:00 2001 From: cx384 Date: Tue, 11 Mar 2025 10:00:04 +0100 Subject: [PATCH] Move drawItemStack out of hud.h/cpp (#15868) --- src/client/hud.cpp | 295 +------------------------------ src/client/hud.h | 29 ---- src/gui/CMakeLists.txt | 1 + src/gui/drawItemStack.cpp | 307 +++++++++++++++++++++++++++++++++ src/gui/drawItemStack.h | 41 +++++ src/gui/guiButtonItemImage.cpp | 1 - src/gui/guiFormSpecMenu.cpp | 2 +- src/gui/guiHyperText.cpp | 2 +- src/gui/guiInventoryList.cpp | 2 +- src/gui/guiItemImage.cpp | 2 +- 10 files changed, 354 insertions(+), 328 deletions(-) create mode 100644 src/gui/drawItemStack.cpp create mode 100644 src/gui/drawItemStack.h diff --git a/src/client/hud.cpp b/src/client/hud.cpp index 4ef64fedc..47ef56039 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -17,17 +17,16 @@ #include "client/tile.h" #include "localplayer.h" #include "camera.h" -#include "porting.h" #include "fontengine.h" #include "guiscalingfilter.h" #include "mesh.h" -#include "wieldmesh.h" #include "client/renderingengine.h" #include "client/minimap.h" #include "client/texturesource.h" #include "gui/touchcontrols.h" #include "util/enriched_string.h" #include "irrlicht_changes/CGUITTFont.h" +#include "gui/drawItemStack.h" #define OBJECT_CROSSHAIR_LINE_SIZE 8 #define CROSSHAIR_LINE_SIZE 10 @@ -1039,295 +1038,3 @@ void Hud::resizeHotbar() { m_displaycenter = v2s32(m_screensize.X/2,m_screensize.Y/2); } } - -struct MeshTimeInfo { - u64 time; - scene::IMesh *mesh = nullptr; -}; - -void drawItemStack( - video::IVideoDriver *driver, - gui::IGUIFont *font, - const ItemStack &item, - const core::rect &rect, - const core::rect *clip, - Client *client, - ItemRotationKind rotation_kind, - const v3s16 &angle, - const v3s16 &rotation_speed) -{ - static MeshTimeInfo rotation_time_infos[IT_ROT_NONE]; - - if (item.empty()) { - if (rotation_kind < IT_ROT_NONE && rotation_kind != IT_ROT_OTHER) { - rotation_time_infos[rotation_kind].mesh = NULL; - } - return; - } - - const bool enable_animations = g_settings->getBool("inventory_items_animations"); - - auto *idef = client->idef(); - const ItemDefinition &def = item.getDefinition(idef); - - bool draw_overlay = false; - - const std::string inventory_image = item.getInventoryImage(idef); - const std::string inventory_overlay = item.getInventoryOverlay(idef); - - 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) || inventory_image.empty()) { - imesh = idef->getWieldMesh(item, client); - has_mesh = imesh && imesh->mesh; - } - if (has_mesh) { - scene::IMesh *mesh = imesh->mesh; - driver->clearBuffers(video::ECBF_DEPTH); - s32 delta = 0; - if (rotation_kind < IT_ROT_NONE) { - MeshTimeInfo &ti = rotation_time_infos[rotation_kind]; - if (mesh != ti.mesh && rotation_kind != IT_ROT_OTHER) { - ti.mesh = mesh; - ti.time = porting::getTimeMs(); - } else { - delta = porting::getDeltaMs(ti.time, porting::getTimeMs()) % 100000; - } - } - core::rect oldViewPort = driver->getViewPort(); - core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION); - core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW); - - core::matrix4 ProjMatrix; - ProjMatrix.buildProjectionMatrixOrthoLH(2.0f, 2.0f, -1.0f, 100.0f); - - core::matrix4 ViewMatrix; - ViewMatrix.buildProjectionMatrixOrthoLH( - 2.0f * viewrect.getWidth() / rect.getWidth(), - 2.0f * viewrect.getHeight() / rect.getHeight(), - -1.0f, - 100.0f); - ViewMatrix.setTranslation(core::vector3df( - 1.0f * (rect.LowerRightCorner.X + rect.UpperLeftCorner.X - - viewrect.LowerRightCorner.X - viewrect.UpperLeftCorner.X) / - viewrect.getWidth(), - 1.0f * (viewrect.LowerRightCorner.Y + viewrect.UpperLeftCorner.Y - - rect.LowerRightCorner.Y - rect.UpperLeftCorner.Y) / - viewrect.getHeight(), - 0.0f)); - - driver->setTransform(video::ETS_PROJECTION, ProjMatrix); - driver->setTransform(video::ETS_VIEW, ViewMatrix); - - core::matrix4 matrix; - matrix.makeIdentity(); - - if (enable_animations) { - float timer_f = (float) delta / 5000.f; - matrix.setRotationDegrees(v3f( - angle.X + rotation_speed.X * 3.60f * timer_f, - angle.Y + rotation_speed.Y * 3.60f * timer_f, - angle.Z + rotation_speed.Z * 3.60f * timer_f) - ); - } - - driver->setTransform(video::ETS_WORLD, matrix); - driver->setViewPort(viewrect); - - video::SColor basecolor = - client->idef()->getItemstackColor(item, client); - - const u32 mc = mesh->getMeshBufferCount(); - if (mc > imesh->buffer_colors.size()) - imesh->buffer_colors.resize(mc); - for (u32 j = 0; j < mc; ++j) { - scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); - video::SColor c = basecolor; - - auto &p = imesh->buffer_colors[j]; - p.applyOverride(c); - - // TODO: could be moved to a shader - if (p.needColorize(c)) { - buf->setDirty(scene::EBT_VERTEX); - if (imesh->needs_shading) - colorizeMeshBuffer(buf, &c); - else - setMeshBufferColor(buf, c); - } - - video::SMaterial &material = buf->getMaterial(); - material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; - driver->setMaterial(material); - driver->drawMeshBuffer(buf); - } - - driver->setTransform(video::ETS_VIEW, oldViewMat); - driver->setTransform(video::ETS_PROJECTION, oldProjMat); - driver->setViewPort(oldViewPort); - - draw_overlay = def.type == ITEM_NODE && inventory_image.empty(); - } else { // Otherwise just draw as 2D - video::ITexture *texture = client->idef()->getInventoryTexture(item, client); - video::SColor color; - if (texture) { - color = client->idef()->getItemstackColor(item, client); - } else { - color = video::SColor(255, 255, 255, 255); - ITextureSource *tsrc = client->getTextureSource(); - texture = tsrc->getTexture("no_texture.png"); - if (!texture) - return; - } - - const video::SColor colors[] = { color, color, color, color }; - - draw2DImageFilterScaled(driver, texture, rect, - core::rect({0, 0}, core::dimension2di(texture->getOriginalSize())), - clip, colors, true); - - draw_overlay = true; - } - - // draw the inventory_overlay - if (!inventory_overlay.empty() && draw_overlay) { - ITextureSource *tsrc = client->getTextureSource(); - video::ITexture *overlay_texture = tsrc->getTexture(inventory_overlay); - core::dimension2d dimens = overlay_texture->getOriginalSize(); - core::rect srcrect(0, 0, dimens.Width, dimens.Height); - draw2DImageFilterScaled(driver, overlay_texture, rect, srcrect, clip, 0, true); - } - - if (def.type == ITEM_TOOL && item.wear != 0) { - // Draw a progressbar - float barheight = static_cast(rect.getHeight()) / 16; - float barpad_x = static_cast(rect.getWidth()) / 16; - float barpad_y = static_cast(rect.getHeight()) / 16; - - core::rect progressrect( - rect.UpperLeftCorner.X + barpad_x, - rect.LowerRightCorner.Y - barpad_y - barheight, - rect.LowerRightCorner.X - barpad_x, - rect.LowerRightCorner.Y - barpad_y); - - // Shrink progressrect by amount of tool damage - float wear = item.wear / 65535.0f; - int progressmid = - wear * progressrect.UpperLeftCorner.X + - (1 - wear) * progressrect.LowerRightCorner.X; - - // Compute progressbar color - // default scheme: - // wear = 0.0: green - // wear = 0.5: yellow - // wear = 1.0: red - - video::SColor color; - auto barParams = item.getWearBarParams(client->idef()); - if (barParams.has_value()) { - f32 durabilityPercent = 1.0 - wear; - color = barParams->getWearBarColor(durabilityPercent); - } else { - color = video::SColor(255, 255, 255, 255); - int wear_i = MYMIN(std::floor(wear * 600), 511); - wear_i = MYMIN(wear_i + 10, 511); - - if (wear_i <= 255) - color.set(255, wear_i, 255, 0); - else - color.set(255, 255, 511 - wear_i, 0); - } - - core::rect progressrect2 = progressrect; - progressrect2.LowerRightCorner.X = progressmid; - driver->draw2DRectangle(color, progressrect2, clip); - - color = video::SColor(255, 0, 0, 0); - progressrect2 = progressrect; - progressrect2.UpperLeftCorner.X = progressmid; - driver->draw2DRectangle(color, progressrect2, clip); - } - - 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 = 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.LowerRightCorner - sdim, - rect.LowerRightCorner - ); - - // 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(utf8_to_wide(text).c_str(), rect2, color, false, false, &viewrect); - } -} - -void drawItemStack( - video::IVideoDriver *driver, - gui::IGUIFont *font, - const ItemStack &item, - const core::rect &rect, - const core::rect *clip, - Client *client, - ItemRotationKind rotation_kind) -{ - drawItemStack(driver, font, item, rect, clip, client, rotation_kind, - v3s16(0, 0, 0), v3s16(0, 100, 0)); -} diff --git a/src/client/hud.h b/src/client/hud.h index b42435f25..e2cf757de 100644 --- a/src/client/hud.h +++ b/src/client/hud.h @@ -153,32 +153,3 @@ private: HIGHLIGHT_NONE } m_mode; }; - -enum ItemRotationKind -{ - IT_ROT_SELECTED, - IT_ROT_HOVERED, - IT_ROT_DRAGGED, - IT_ROT_OTHER, - IT_ROT_NONE, // Must be last, also serves as number -}; - -void drawItemStack(video::IVideoDriver *driver, - gui::IGUIFont *font, - const ItemStack &item, - const core::rect &rect, - const core::rect *clip, - Client *client, - ItemRotationKind rotation_kind); - -void drawItemStack( - video::IVideoDriver *driver, - gui::IGUIFont *font, - const ItemStack &item, - const core::rect &rect, - const core::rect *clip, - Client *client, - ItemRotationKind rotation_kind, - const v3s16 &angle, - const v3s16 &rotation_speed); - diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 876acab74..26fd5bfcf 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -27,5 +27,6 @@ set(gui_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/touchcontrols.cpp ${CMAKE_CURRENT_SOURCE_DIR}/touchscreenlayout.cpp ${CMAKE_CURRENT_SOURCE_DIR}/touchscreeneditor.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drawItemStack.cpp PARENT_SCOPE ) diff --git a/src/gui/drawItemStack.cpp b/src/gui/drawItemStack.cpp new file mode 100644 index 000000000..728f5fd11 --- /dev/null +++ b/src/gui/drawItemStack.cpp @@ -0,0 +1,307 @@ +// Luanti +// SPDX-License-Identifier: LGPL-2.1-or-later +// Copyright (C) 2024 cx384 + +#include "drawItemStack.h" + +#include +#include "settings.h" +#include "client/client.h" +#include "porting.h" +#include "inventory.h" +#include "client/mesh.h" +#include "client/wieldmesh.h" +#include "client/texturesource.h" +#include "client/guiscalingfilter.h" + +struct MeshTimeInfo { + u64 time; + scene::IMesh *mesh = nullptr; +}; + +void drawItemStack( + video::IVideoDriver *driver, + gui::IGUIFont *font, + const ItemStack &item, + const core::rect &rect, + const core::rect *clip, + Client *client, + ItemRotationKind rotation_kind, + const v3s16 &angle, + const v3s16 &rotation_speed) +{ + static MeshTimeInfo rotation_time_infos[IT_ROT_NONE]; + + if (item.empty()) { + if (rotation_kind < IT_ROT_NONE && rotation_kind != IT_ROT_OTHER) { + rotation_time_infos[rotation_kind].mesh = NULL; + } + return; + } + + const bool enable_animations = g_settings->getBool("inventory_items_animations"); + + auto *idef = client->idef(); + const ItemDefinition &def = item.getDefinition(idef); + + bool draw_overlay = false; + + const std::string inventory_image = item.getInventoryImage(idef); + const std::string inventory_overlay = item.getInventoryOverlay(idef); + + 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) || inventory_image.empty()) { + imesh = idef->getWieldMesh(item, client); + has_mesh = imesh && imesh->mesh; + } + if (has_mesh) { + scene::IMesh *mesh = imesh->mesh; + driver->clearBuffers(video::ECBF_DEPTH); + s32 delta = 0; + if (rotation_kind < IT_ROT_NONE) { + MeshTimeInfo &ti = rotation_time_infos[rotation_kind]; + if (mesh != ti.mesh && rotation_kind != IT_ROT_OTHER) { + ti.mesh = mesh; + ti.time = porting::getTimeMs(); + } else { + delta = porting::getDeltaMs(ti.time, porting::getTimeMs()) % 100000; + } + } + core::rect oldViewPort = driver->getViewPort(); + core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION); + core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW); + + core::matrix4 ProjMatrix; + ProjMatrix.buildProjectionMatrixOrthoLH(2.0f, 2.0f, -1.0f, 100.0f); + + core::matrix4 ViewMatrix; + ViewMatrix.buildProjectionMatrixOrthoLH( + 2.0f * viewrect.getWidth() / rect.getWidth(), + 2.0f * viewrect.getHeight() / rect.getHeight(), + -1.0f, + 100.0f); + ViewMatrix.setTranslation(core::vector3df( + 1.0f * (rect.LowerRightCorner.X + rect.UpperLeftCorner.X - + viewrect.LowerRightCorner.X - viewrect.UpperLeftCorner.X) / + viewrect.getWidth(), + 1.0f * (viewrect.LowerRightCorner.Y + viewrect.UpperLeftCorner.Y - + rect.LowerRightCorner.Y - rect.UpperLeftCorner.Y) / + viewrect.getHeight(), + 0.0f)); + + driver->setTransform(video::ETS_PROJECTION, ProjMatrix); + driver->setTransform(video::ETS_VIEW, ViewMatrix); + + core::matrix4 matrix; + matrix.makeIdentity(); + + if (enable_animations) { + float timer_f = (float) delta / 5000.f; + matrix.setRotationDegrees(v3f( + angle.X + rotation_speed.X * 3.60f * timer_f, + angle.Y + rotation_speed.Y * 3.60f * timer_f, + angle.Z + rotation_speed.Z * 3.60f * timer_f) + ); + } + + driver->setTransform(video::ETS_WORLD, matrix); + driver->setViewPort(viewrect); + + video::SColor basecolor = + client->idef()->getItemstackColor(item, client); + + const u32 mc = mesh->getMeshBufferCount(); + if (mc > imesh->buffer_colors.size()) + imesh->buffer_colors.resize(mc); + for (u32 j = 0; j < mc; ++j) { + scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); + video::SColor c = basecolor; + + auto &p = imesh->buffer_colors[j]; + p.applyOverride(c); + + // TODO: could be moved to a shader + if (p.needColorize(c)) { + buf->setDirty(scene::EBT_VERTEX); + if (imesh->needs_shading) + colorizeMeshBuffer(buf, &c); + else + setMeshBufferColor(buf, c); + } + + video::SMaterial &material = buf->getMaterial(); + material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + driver->setMaterial(material); + driver->drawMeshBuffer(buf); + } + + driver->setTransform(video::ETS_VIEW, oldViewMat); + driver->setTransform(video::ETS_PROJECTION, oldProjMat); + driver->setViewPort(oldViewPort); + + draw_overlay = def.type == ITEM_NODE && inventory_image.empty(); + } else { // Otherwise just draw as 2D + video::ITexture *texture = client->idef()->getInventoryTexture(item, client); + video::SColor color; + if (texture) { + color = client->idef()->getItemstackColor(item, client); + } else { + color = video::SColor(255, 255, 255, 255); + ITextureSource *tsrc = client->getTextureSource(); + texture = tsrc->getTexture("no_texture.png"); + if (!texture) + return; + } + + const video::SColor colors[] = { color, color, color, color }; + + draw2DImageFilterScaled(driver, texture, rect, + core::rect({0, 0}, core::dimension2di(texture->getOriginalSize())), + clip, colors, true); + + draw_overlay = true; + } + + // draw the inventory_overlay + if (!inventory_overlay.empty() && draw_overlay) { + ITextureSource *tsrc = client->getTextureSource(); + video::ITexture *overlay_texture = tsrc->getTexture(inventory_overlay); + core::dimension2d dimens = overlay_texture->getOriginalSize(); + core::rect srcrect(0, 0, dimens.Width, dimens.Height); + draw2DImageFilterScaled(driver, overlay_texture, rect, srcrect, clip, 0, true); + } + + if (def.type == ITEM_TOOL && item.wear != 0) { + // Draw a progressbar + float barheight = static_cast(rect.getHeight()) / 16; + float barpad_x = static_cast(rect.getWidth()) / 16; + float barpad_y = static_cast(rect.getHeight()) / 16; + + core::rect progressrect( + rect.UpperLeftCorner.X + barpad_x, + rect.LowerRightCorner.Y - barpad_y - barheight, + rect.LowerRightCorner.X - barpad_x, + rect.LowerRightCorner.Y - barpad_y); + + // Shrink progressrect by amount of tool damage + float wear = item.wear / 65535.0f; + int progressmid = + wear * progressrect.UpperLeftCorner.X + + (1 - wear) * progressrect.LowerRightCorner.X; + + // Compute progressbar color + // default scheme: + // wear = 0.0: green + // wear = 0.5: yellow + // wear = 1.0: red + + video::SColor color; + auto barParams = item.getWearBarParams(client->idef()); + if (barParams.has_value()) { + f32 durabilityPercent = 1.0 - wear; + color = barParams->getWearBarColor(durabilityPercent); + } else { + color = video::SColor(255, 255, 255, 255); + int wear_i = MYMIN(std::floor(wear * 600), 511); + wear_i = MYMIN(wear_i + 10, 511); + + if (wear_i <= 255) + color.set(255, wear_i, 255, 0); + else + color.set(255, 255, 511 - wear_i, 0); + } + + core::rect progressrect2 = progressrect; + progressrect2.LowerRightCorner.X = progressmid; + driver->draw2DRectangle(color, progressrect2, clip); + + color = video::SColor(255, 0, 0, 0); + progressrect2 = progressrect; + progressrect2.UpperLeftCorner.X = progressmid; + driver->draw2DRectangle(color, progressrect2, clip); + } + + 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 = 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.LowerRightCorner - sdim, + rect.LowerRightCorner + ); + + // 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(utf8_to_wide(text).c_str(), rect2, color, false, false, &viewrect); + } +} + +void drawItemStack( + video::IVideoDriver *driver, + gui::IGUIFont *font, + const ItemStack &item, + const core::rect &rect, + const core::rect *clip, + Client *client, + ItemRotationKind rotation_kind) +{ + drawItemStack(driver, font, item, rect, clip, client, rotation_kind, + v3s16(0, 0, 0), v3s16(0, 100, 0)); +} diff --git a/src/gui/drawItemStack.h b/src/gui/drawItemStack.h new file mode 100644 index 000000000..52bccf089 --- /dev/null +++ b/src/gui/drawItemStack.h @@ -0,0 +1,41 @@ +// Luanti +// SPDX-License-Identifier: LGPL-2.1-or-later +// Copyright (C) 2024 cx384 + +#pragma once + +#include +#include +#include "irrlichttypes.h" +#include "irr_v3d.h" + +struct ItemStack; +class Client; + +enum ItemRotationKind +{ + IT_ROT_SELECTED, + IT_ROT_HOVERED, + IT_ROT_DRAGGED, + IT_ROT_OTHER, + IT_ROT_NONE, // Must be last, also serves as number +}; + +void drawItemStack(video::IVideoDriver *driver, + gui::IGUIFont *font, + const ItemStack &item, + const core::rect &rect, + const core::rect *clip, + Client *client, + ItemRotationKind rotation_kind); + +void drawItemStack( + video::IVideoDriver *driver, + gui::IGUIFont *font, + const ItemStack &item, + const core::rect &rect, + const core::rect *clip, + Client *client, + ItemRotationKind rotation_kind, + const v3s16 &angle, + const v3s16 &rotation_speed); diff --git a/src/gui/guiButtonItemImage.cpp b/src/gui/guiButtonItemImage.cpp index 9794b1889..bb7f55fff 100644 --- a/src/gui/guiButtonItemImage.cpp +++ b/src/gui/guiButtonItemImage.cpp @@ -5,7 +5,6 @@ #include "guiButtonItemImage.h" #include "client/client.h" -#include "client/hud.h" // drawItemStack #include "guiItemImage.h" #include "IGUIEnvironment.h" #include "itemdef.h" diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index 621eba1c2..29a8e1285 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -25,7 +25,7 @@ #include "client/renderingengine.h" #include "client/joystick_controller.h" #include "log.h" -#include "client/hud.h" // drawItemStack +#include "drawItemStack.h" #include "filesys.h" #include "gettime.h" #include "gettext.h" diff --git a/src/gui/guiHyperText.cpp b/src/gui/guiHyperText.cpp index 0f887ec4e..f3278a3ab 100644 --- a/src/gui/guiHyperText.cpp +++ b/src/gui/guiHyperText.cpp @@ -5,7 +5,7 @@ #include "guiHyperText.h" #include "guiScrollBar.h" #include "client/fontengine.h" -#include "client/hud.h" // drawItemStack +#include "drawItemStack.h" #include "IVideoDriver.h" #include "client/client.h" #include "client/renderingengine.h" diff --git a/src/gui/guiInventoryList.cpp b/src/gui/guiInventoryList.cpp index c19d45b71..b8ed324c3 100644 --- a/src/gui/guiInventoryList.cpp +++ b/src/gui/guiInventoryList.cpp @@ -4,7 +4,7 @@ #include "guiInventoryList.h" #include "guiFormSpecMenu.h" -#include "client/hud.h" +#include "drawItemStack.h" #include "client/client.h" #include "client/renderingengine.h" #include diff --git a/src/gui/guiItemImage.cpp b/src/gui/guiItemImage.cpp index 9e9205f52..1c3c17acb 100644 --- a/src/gui/guiItemImage.cpp +++ b/src/gui/guiItemImage.cpp @@ -4,7 +4,7 @@ #include "guiItemImage.h" #include "client/client.h" -#include "client/hud.h" // drawItemStack +#include "drawItemStack.h" #include "inventory.h" #include