diff --git a/wieldview/get_texture.lua b/wieldview/get_texture.lua new file mode 100644 index 0000000..31173c1 --- /dev/null +++ b/wieldview/get_texture.lua @@ -0,0 +1,215 @@ +local f = string.format + +local node_tiles = minetest.settings:get_bool("wieldview_node_tiles") +if not node_tiles then + node_tiles = false + minetest.settings:set("wieldview_node_tiles", "false") +end + +-- https://github.com/minetest/minetest/blob/9fc018ded10225589d2559d24a5db739e891fb31/doc/lua_api.txt#L453-L462 +local function escape_texture(texturestring) + -- store in a variable so we don't return both rvs of gsub + local v = texturestring:gsub("%^", "\\^"):gsub(":", "\\:") + return v +end + +local function memoize(func) + local memo = {} + return function(arg) + if arg == nil then + return func(arg) + end + local rv = memo[arg] + + if not rv then + rv = func(arg) + memo[arg] = rv + end + + return rv + end +end + +local function is_vertical_frames(animation) + return ( + animation.type == "vertical_frames" and + animation.aspect_w and + animation.aspect_h + ) +end + +local function get_single_frame(animation, image_name) + return ("smartshop_animation_mask.png^[resize:%ix%i^[mask:%s"):format( + animation.aspect_w, + animation.aspect_h, + image_name + ) +end + +local function is_sheet_2d(animation) + return ( + animation.type == "sheet_2d" and + animation.frames_w and + animation.frames_h + ) +end + +local function get_sheet_2d(animation, image_name) + return ("%s^[sheet:%ix%i:0,0"):format( + image_name, + animation.frames_w, + animation.frames_h + ) +end + +local get_image_from_tile = memoize(function(tile) + if type(tile) == "string" then + return tile + + elseif type(tile) == "table" then + local image_name + + if type(tile.image) == "string" then + image_name = tile.image + + elseif type(tile.name) == "string" then + image_name = tile.name + + end + + if image_name then + local animation = tile.animation + if animation then + if is_vertical_frames(animation) then + return get_single_frame(animation, image_name) + + elseif is_sheet_2d(animation) then + return get_sheet_2d(animation, image_name) + end + end + + return image_name + end + end + + return "3d_armor_trans.png" +end) + +local function get_image_cube(tiles) + if #tiles >= 6 then + return minetest.inventorycube( + get_image_from_tile(tiles[1] or "no_texture.png"), + get_image_from_tile(tiles[6] or "no_texture.png"), + get_image_from_tile(tiles[3] or "no_texture.png") + ) + + elseif #tiles == 5 then + return minetest.inventorycube( + get_image_from_tile(tiles[1] or "no_texture.png"), + get_image_from_tile(tiles[5] or "no_texture.png"), + get_image_from_tile(tiles[3] or "no_texture.png") + ) + + elseif #tiles == 4 then + return minetest.inventorycube( + get_image_from_tile(tiles[1] or "no_texture.png"), + get_image_from_tile(tiles[4] or "no_texture.png"), + get_image_from_tile(tiles[3] or "no_texture.png") + ) + + elseif #tiles == 3 then + return minetest.inventorycube( + get_image_from_tile(tiles[1] or "no_texture.png"), + get_image_from_tile(tiles[3] or "no_texture.png"), + get_image_from_tile(tiles[3] or "no_texture.png") + ) + + elseif #tiles == 2 then + return minetest.inventorycube( + get_image_from_tile(tiles[1] or "no_texture.png"), + get_image_from_tile(tiles[2] or "no_texture.png"), + get_image_from_tile(tiles[2] or "no_texture.png") + ) + + elseif #tiles == 1 then + return minetest.inventorycube( + get_image_from_tile(tiles[1] or "no_texture.png"), + get_image_from_tile(tiles[1] or "no_texture.png"), + get_image_from_tile(tiles[1] or "no_texture.png") + ) + end + + return "3d_armor_trans.png" +end + +local function is_normal_node(drawtype) + return ( + drawtype == "normal" or + drawtype == "allfaces" or + drawtype == "allfaces_optional" or + drawtype == "glasslike" or + drawtype == "glasslike_framed" or + drawtype == "glasslike_framed_optional" or + drawtype == "liquid" + ) +end + +armor.get_wield_image = memoize(function(item) + item = ItemStack(item) + + if item:is_empty() then + return "3d_armor_trans.png" + end + + local def = item:get_definition() + if not def then + return "unknown_item.png" + end + + local meta = item:get_meta() + local color = meta:get("color") or def.color + + local image = "3d_armor_trans.png" + + if def.wield_image and def.wield_image ~= "" then + local parts = {def.wield_image} + if color then + parts[#parts + 1] = f("[colorize:%s:alpha", escape_texture(color)) + end + if def.wield_overlay then + parts[#parts + 1] = def.wield_overlay + end + image = table.concat(parts, "^") + + elseif def.inventory_image and def.inventory_image ~= "" then + local parts = {def.inventory_image} + if color then + parts[#parts + 1] = f("[colorize:%s:alpha", escape_texture(color)) + end + if def.inventory_overlay then + parts[#parts + 1] = def.inventory_overlay + end + image = table.concat(parts, "^") + + elseif def.type == "node" then + if def.drawtype == "nodebox" or def.drawtype == "mesh" then + image = "3d_armor_trans.png" + + else + local tiles = def.tiles + if type(tiles) == "string" then + image = get_image_from_tile(tiles) + + elseif type(tiles) == "table" then + if is_normal_node(def.drawtype) and node_tiles then + image = get_image_cube(tiles) + + else + image = get_image_from_tile(tiles[1]) + end + end + end + end + + return image +end) diff --git a/wieldview/init.lua b/wieldview/init.lua index 6397d04..ecdece9 100644 --- a/wieldview/init.lua +++ b/wieldview/init.lua @@ -4,31 +4,20 @@ if not update_time then update_time = 2 minetest.settings:set("wieldview_update_time", tostring(update_time)) end -local node_tiles = minetest.settings:get_bool("wieldview_node_tiles") -if not node_tiles then - node_tiles = false - minetest.settings:set("wieldview_node_tiles", "false") -end wieldview = { wielded_item = {}, transform = {}, } +dofile(minetest.get_modpath(minetest.get_current_modname()).."/get_texture.lua") dofile(minetest.get_modpath(minetest.get_current_modname()).."/transform.lua") wieldview.get_item_texture = function(self, item) local texture = "3d_armor_trans.png" if item ~= "" then - if minetest.registered_items[item] then - if minetest.registered_items[item].inventory_image ~= "" then - texture = minetest.registered_items[item].inventory_image - elseif node_tiles == true and minetest.registered_items[item].tiles - and type(minetest.registered_items[item].tiles[1]) == "string" - and minetest.registered_items[item].tiles[1] ~= "" then - texture = minetest.inventorycube(minetest.registered_items[item].tiles[1]) - end - end + texture = armor.get_wield_image(item) + -- Get item image transformation, first from group, then from transform.lua local transform = minetest.get_item_group(item, "wieldview_transform") if transform == 0 then