nametags = { nametag_cache = {}, item_texture_cache = {}, armor_cache = {}, } function nametags.get_wield_entity(player) for _, child in pairs(minetest.get_objects_inside_radius(player:get_pos(), 1)) do if child:get_attach() == player then local child_prop = child:get_properties() if child_prop.visual == "wielditem" then return child end end end end function nametags.resize_image(image) return image .. "^[resize:32x32" end function nametags.colorize_tiledef(tile, node_color) if tile.name == "" then return end local color = tile.color or node_color if color then return "(" .. tile.name .. ")^[multiply:" .. minetest.rgba(color.r, color.g, color.b, color.a) else return tile.name end end function nametags.render_tile(nodedef, n) local img = nametags.colorize_tiledef(nodedef.tiles[n], nodedef.color) local overlay = nametags.colorize_tiledef(nodedef.overlay_tiles[n], nodedef.color) if overlay then img = img .. "^(" .. overlay .. ")" end return img end function nametags.create_item_texture(itemname) local itemdef = minetest.get_item_def(itemname) local nodedef = minetest.get_node_def(itemname) if itemdef then if itemdef.inventory_image ~= "" then return itemdef.inventory_image elseif nodedef then if nodedef.drawtype == "mesh" or nodedef.drawtype == "nodebox" then return nodedef.tiles[1].name else return minetest.inventorycube( nametags.render_tile(nodedef, 1), nametags.render_tile(nodedef, 6), nametags.render_tile(nodedef, 5) ) end end end end function nametags.get_item_texture(itemname) local cached_texture = nametags.item_texture_cache[itemname] if cached_texture then return cached_texture end local texture = nametags.create_item_texture(itemname) nametags.item_texture_cache[itemname] = texture return texture end function nametags.parse_armor_texture(armor_texture) if armor_texture == "blank.png" then return {} end local armor_pieces = {} local armor_textures = armor_texture:sub(2, #armor_texture - 1):split(")^(") for _, texture in ipairs(armor_textures) do local itemname = nametags.armor_cache[texture] if not itemname then local piece_textures = texture:split("^") local enchanted = false if #piece_textures > 1 and piece_textures[2] == "[colorize:purple:50" then enchanted = true end local components = (piece_textures[1] or ""):split("_") local modname = table.remove(components, 1) or "" if modname then if modname == "mcl" then modname = modname .. "_" .. (table.remove(components, 1) or "") end local subname = table.concat(components, "_"):split(".")[1] itemname = modname .. ":" .. subname if enchanted then itemname = itemname .. "_enchanted" end end nametags.armor_cache[texture] = itemname end table.insert(armor_pieces, 1, itemname) end return armor_pieces end function nametags.wield_entity_get_itemname(obj) local prop = obj and obj:get_properties() return prop and prop.textures[1] or "" end local blank_resized = nametags.resize_image("blank.png") function nametags.update_nametag(player) if player:is_player() and not player:is_local_player() then local props = player:get_properties() local nametag = props.nametag local hp = player:get_hp() local idx = nametag:find("♥") if idx then nametag = nametag:sub(1, idx + 2) .. hp else nametag = nametag .. minetest.get_color_escape_sequence("#FF0000") .. " ♥" .. hp end player:set_properties({ nametag = nametag, nametag_bgcolor = {a = 128, r = 0, g = 0, b = 0} }) local cache = nametags.nametag_cache[player] if not cache then cache = { armor_texture = "blank.png", armor_textures = {}, wield_texture = "blank.png", wield_texture_resized = blank_resized, wield_entity_itemname = "", wield_entity = nametags.get_wield_entity(player), nametag_images = {blank_resized}, } nametags.nametag_cache[player] = cache end local wield_texture = props.textures[3] local wield_texture_blank = wield_texture == "blank.png" local wield_entity_itemname = "" local wield_cached = cache.wield_texture == wield_texture if wield_texture_blank then wield_entity_itemname = nametags.wield_entity_get_itemname(cache.wield_entity) wield_cached = wield_cached and cache.wield_entity_itemname == wield_entity_itemname end local armor_texture = props.textures[2] local armor_cached = cache.armor_texture == armor_texture local nametag_images if wield_cached and armor_cached then nametag_images = cache.nametag_images else local wield_texture_resized if wield_cached then wield_texture_resized = cache.wield_texture_resized else if wield_texture_blank then if wield_entity_itemname ~= "" then wield_texture = nametags.get_item_texture(wield_entity_itemname) or "blank.png" end end wield_texture_resized = nametags.resize_image(wield_texture) cache.wield_texture = wield_texture cache.wield_texture_resized = wield_texture_resized end local armor_textures if armor_cached then armor_textures = cache.armor_textures else armor_textures = {} for _, piece in ipairs(nametags.parse_armor_texture(armor_texture)) do local texture = nametags.get_item_texture(piece) if texture then table.insert(armor_textures, nametags.resize_image(texture)) end end cache.armor_texture = armor_texture cache.armor_textures = armor_textures end nametag_images = {wield_texture_resized} for _, texture in ipairs(armor_textures) do table.insert(nametag_images, texture) end cache.nametag_images = nametag_images end player:set_nametag_images(nametag_images) end end minetest.register_on_object_properties_change(nametags.update_nametag) minetest.register_on_object_hp_change(nametags.update_nametag) minetest.register_on_object_add(function(obj) local attach = obj:get_attach() if attach and attach:is_player() and not attach:is_local_player() then local cache = nametags.nametag_cache[attach] if cache then cache.wield_entity = obj end end end)