]> git.lizzy.rs Git - dragonfireclient.git/commitdiff
Add on_object_hp_change callback and nametag images
authorElias Fleckenstein <eliasfleckenstein@web.de>
Mon, 10 May 2021 18:45:05 +0000 (20:45 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Mon, 10 May 2021 18:45:05 +0000 (20:45 +0200)
builtin/client/register.lua
doc/client_lua_api.txt
src/client/camera.cpp
src/client/camera.h
src/client/content_cao.cpp
src/client/content_cao.h
src/client/hud.cpp
src/script/cpp_api/s_client.cpp
src/script/cpp_api/s_client.h
src/script/lua_api/l_clientobject.cpp
src/script/lua_api/l_clientobject.h

index 5bf6346994c8f0b784083835330522a84807eec7..835ec5002c1d6c41fbe9bc3b3004937680597d0e 100644 (file)
@@ -106,6 +106,7 @@ core.registered_on_recieve_physics_override, core.register_on_recieve_physics_ov
 core.registered_on_play_sound, core.register_on_play_sound = make_registration()
 core.registered_on_spawn_particle, core.register_on_spawn_particle = make_registration()
 core.registered_on_object_properties_change, core.register_on_object_properties_change = make_registration()
+core.registered_on_object_hp_change, core.register_on_object_hp_change = make_registration()
 
 core.registered_nodes = {}
 core.registered_items = {}
index 2728ed632fc5f3d2497d31ac9d02cdb65abcd9e8..2e347ec47fcc4903ebea65f9097c13c6e592a365 100644 (file)
@@ -766,6 +766,8 @@ Call these functions only at load time!
 * `minetest.register_on_object_properties_change(function(obj))`
     * Called every time the properties of an object are changed server-side
     * May modify the object's properties without the fear of infinite recursion
+* `minetest.register_on_object_hp_change(function(obj))`
+    * Called every time the hp of an object are changes server-side
 
 ### Setting-related
 * `minetest.settings`: Settings object containing all of the settings from the
@@ -1422,6 +1424,7 @@ This is basically a reference to a C++ `GenericCAO`.
 * `punch()`: punches the object
 * `rightclick()`: rightclicks the object
 * `remove()`: removes the object permanently
+* `set_nametag_images(images)`: Provides a list of images to be drawn below the nametag
 
 ### `Raycast`
 
index 3afd45c55613d6bbec82eb9560e59385be63ff6f..854d9eae8865901cfd9ec7ebc5b27e8e9ea58c37 100644 (file)
@@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "util/numeric.h"
 #include "constants.h"
 #include "fontengine.h"
+#include "guiscalingfilter.h"
 #include "script/scripting_client.h"
 
 #define CAMERA_OFFSET_STEP 200
@@ -715,7 +716,7 @@ void Camera::drawNametags()
                        screen_pos.Y = screensize.Y *
                                (0.5 - transformed_pos[1] * zDiv * 0.5) - textsize.Height / 2;
                        core::rect<s32> size(0, 0, textsize.Width, textsize.Height);
-                       core::rect<s32> bg_size(-2, 0, textsize.Width+2, textsize.Height);
+                       core::rect<s32> bg_size(-2, 0, std::max(textsize.Width+2, (u32) nametag->images_dim.Width), textsize.Height + nametag->images_dim.Height);
 
                        auto bgcolor = nametag->getBgColor(m_show_nametag_backgrounds);
                        if (bgcolor.getAlpha() != 0)
@@ -724,15 +725,29 @@ void Camera::drawNametags()
                        font->draw(
                                translate_string(utf8_to_wide(nametag->text)).c_str(),
                                size + screen_pos, nametag->textcolor);
+
+                       v2s32 image_pos(screen_pos);
+                       image_pos.Y += textsize.Height;
+
+                       const video::SColor color(255, 255, 255, 255);
+                       const video::SColor colors[] = {color, color, color, color};
+
+                       for (video::ITexture *texture : nametag->images) {
+                               core::dimension2di imgsize(texture->getOriginalSize());
+                               core::rect<s32> rect(core::position2d<s32>(0, 0), imgsize);
+                               draw2DImageFilterScaled(driver, texture, rect + image_pos, rect, NULL, colors, true);
+                               image_pos += core::dimension2di(imgsize.Width, 0);
+                       }
+
                }
        }
 }
-
 Nametag *Camera::addNametag(scene::ISceneNode *parent_node,
                const std::string &text, video::SColor textcolor,
-               Optional<video::SColor> bgcolor, const v3f &pos)
+               Optional<video::SColor> bgcolor, const v3f &pos,
+               const std::vector<std::string> &images)
 {
-       Nametag *nametag = new Nametag(parent_node, text, textcolor, bgcolor, pos);
+       Nametag *nametag = new Nametag(parent_node, text, textcolor, bgcolor, pos, m_client->tsrc(), images);
        m_nametags.push_back(nametag);
        return nametag;
 }
index 6fd8d9aa7666a00c35089c30948556260e6fad1e..c162df5152d6333fb602e9d9618d1db59c6fd3ec 100644 (file)
@@ -39,18 +39,44 @@ struct Nametag
        video::SColor textcolor;
        Optional<video::SColor> bgcolor;
        v3f pos;
+       ITextureSource *texture_source;
+       std::vector<video::ITexture *> images;
+       core::dimension2di images_dim;
 
        Nametag(scene::ISceneNode *a_parent_node,
                        const std::string &text,
                        const video::SColor &textcolor,
                        const Optional<video::SColor> &bgcolor,
-                       const v3f &pos):
+                       const v3f &pos,
+                       ITextureSource *tsrc,
+                       const std::vector<std::string> &image_names):
                parent_node(a_parent_node),
                text(text),
                textcolor(textcolor),
                bgcolor(bgcolor),
-               pos(pos)
+               pos(pos),
+               texture_source(tsrc),
+               images(),
+               images_dim(0, 0)
        {
+               setImages(image_names);
+       }
+
+       void setImages(const std::vector<std::string> &image_names)
+       {
+               images.clear();
+               images_dim = core::dimension2di(0, 0);
+
+               for (const std::string &image_name : image_names) {
+                       video::ITexture *texture = texture_source->getTexture(image_name);
+                       core::dimension2di imgsize(texture->getOriginalSize());
+
+                       images_dim.Width += imgsize.Width;
+                       if (images_dim.Height < imgsize.Height)
+                               images_dim.Height = imgsize.Height;
+
+                       images.push_back(texture);
+               }
        }
 
        video::SColor getBgColor(bool use_fallback) const
@@ -185,7 +211,8 @@ class Camera
 
        Nametag *addNametag(scene::ISceneNode *parent_node,
                const std::string &text, video::SColor textcolor,
-               Optional<video::SColor> bgcolor, const v3f &pos);
+               Optional<video::SColor> bgcolor, const v3f &pos,
+               const std::vector<std::string> &image_names);
 
        void removeNametag(Nametag *nametag);
 
index ea034f629d013192322c120110502d060c058108..84d200a7397f14801da1b899bc39528aac0f3832 100644 (file)
@@ -962,13 +962,14 @@ void GenericCAO::updateNametag()
                // Add nametag
                m_nametag = m_client->getCamera()->addNametag(node,
                        m_prop.nametag, m_prop.nametag_color,
-                       m_prop.nametag_bgcolor, pos);
+                       m_prop.nametag_bgcolor, pos, nametag_images);
        } else {
                // Update nametag
                m_nametag->text = m_prop.nametag;
                m_nametag->textcolor = m_prop.nametag_color;
                m_nametag->bgcolor = m_prop.nametag_bgcolor;
                m_nametag->pos = pos;
+               m_nametag->setImages(nametag_images);
        }
 }
 
@@ -1863,6 +1864,9 @@ void GenericCAO::processMessage(const std::string &data)
                        // Same as 'ObjectRef::l_remove'
                        if (!m_is_player)
                                clearChildAttachments();
+               } else {
+                       if (m_client->modsLoaded())
+                               m_client->getScript()->on_object_hp_change(m_id);
                }
        } else if (cmd == AO_CMD_UPDATE_ARMOR_GROUPS) {
                m_armor_groups.clear();
index 360c30995137de1e54316c970c42dbd7c72c2830..450023d1986d01303bc2f8489a6ed8bd8695ac9e 100644 (file)
@@ -318,4 +318,6 @@ class GenericCAO : public ClientActiveObject
        void setProperties(ObjectProperties newprops);
 
        void updateMeshCulling();
+
+       std::vector<std::string> nametag_images = {};
 };
index 74c1828e34cfcf499936fee289e975e79a420c41..5971948fd8251b56b67f7ed1d50488552eb58aa7 100644 (file)
@@ -149,7 +149,7 @@ void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect,
                bool selected)
 {
        if (selected) {
-               /* draw hihlighting around selected item */
+               /* draw highlighting around selected item */
                if (use_hotbar_selected_image) {
                        core::rect<s32> imgrect2 = rect;
                        imgrect2.UpperLeftCorner.X  -= (m_padding*2);
index b8decf2cdb70552a49d3438008e083448925f6df..2231cf5730a965ee2fd582283b6b4d920ea80247 100644 (file)
@@ -308,6 +308,21 @@ void ScriptApiClient::on_object_properties_change(s16 id)
        runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
 }
 
+void ScriptApiClient::on_object_hp_change(s16 id)
+{
+       SCRIPTAPI_PRECHECKHEADER
+
+       // Get core.on_object_hp_change
+       lua_getglobal(L, "core");
+       lua_getfield(L, -1, "registered_on_object_hp_change");
+
+       // Push data
+       ClientObjectRef::create(L, id);
+
+       // Call functions
+       runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
+}
+
 bool ScriptApiClient::on_inventory_open(Inventory *inventory)
 {
        SCRIPTAPI_PRECHECKHEADER
index 62921b528b572bdb74cbd110fed1a1b67a905bed..a2babfac8b10b100d58f824eaf74c3d4dd59678e 100644 (file)
@@ -64,6 +64,7 @@ class ScriptApiClient : virtual public ScriptApiBase
        bool on_play_sound(SimpleSoundSpec spec);
        bool on_spawn_particle(struct ParticleParameters param);
        void on_object_properties_change(s16 id);
+       void on_object_hp_change(s16 id);
 
        bool on_inventory_open(Inventory *inventory);
        void open_enderchest();
index 0147fd48b1636aba6adf1ef9ba8c796c191535f6..8a4647d456265b9fbdd1b6e31eeaa4c324e57565 100644 (file)
@@ -205,6 +205,23 @@ int ClientObjectRef::l_remove(lua_State *L)
        return 0;
 }
 
+int ClientObjectRef::l_set_nametag_images(lua_State *L)
+{
+       ClientObjectRef *ref = checkobject(L, 1);
+       GenericCAO *gcao = get_generic_cao(ref, L);
+       gcao->nametag_images.clear();
+       if(lua_istable(L, 2)){
+               lua_pushnil(L);
+               while(lua_next(L, 2) != 0){
+                       gcao->nametag_images.push_back(lua_tostring(L, -1));
+                       lua_pop(L, 1);
+               }
+       }
+       gcao->updateNametag();
+
+       return 0;
+}
+
 ClientObjectRef::ClientObjectRef(ClientActiveObject *object) : m_object(object)
 {
 }
@@ -271,5 +288,7 @@ luaL_Reg ClientObjectRef::methods[] = {luamethod(ClientObjectRef, get_pos),
                luamethod(ClientObjectRef, get_properties),
                luamethod(ClientObjectRef, set_properties),
                luamethod(ClientObjectRef, get_hp),
-               luamethod(ClientObjectRef, get_max_hp), luamethod(ClientObjectRef, punch),
-               luamethod(ClientObjectRef, rightclick), {0, 0}};
+               luamethod(ClientObjectRef, get_max_hp),
+               luamethod(ClientObjectRef, punch),
+               luamethod(ClientObjectRef, rightclick),
+               luamethod(ClientObjectRef, set_nametag_images), {0, 0}};
index 22d2f4a1cb00623365831c40982eb9a9a1aba922..60d10dcf6d0453dd0c4e40d7e84363fea937df54 100644 (file)
@@ -98,4 +98,7 @@ class ClientObjectRef : public ModApiBase
 
        // remove(self)
        static int l_remove(lua_State *L);
+
+       // set_nametag_images(self, images)
+       static int l_set_nametag_images(lua_State *L);
 };