3d_armor/wieldview/get_texture.lua
2022-11-26 21:38:10 +01:00

216 lines
5.0 KiB
Lua

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 ("[combine:%ix%i^[noalpha^[colorize:#FFF:255^[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)