From 3ff9ed4419a06611fd2fac21f7782b98c7db131c Mon Sep 17 00:00:00 2001 From: iliekprogrammar Date: Sun, 7 Aug 2022 17:45:39 +0800 Subject: [PATCH 1/4] [heads] refactor and trivial renames --- mods/ITEMS/mcl_heads/init.lua | 353 +++++++++++++++++++++------------- 1 file changed, 214 insertions(+), 139 deletions(-) diff --git a/mods/ITEMS/mcl_heads/init.lua b/mods/ITEMS/mcl_heads/init.lua index c14079393..14f79bfa9 100644 --- a/mods/ITEMS/mcl_heads/init.lua +++ b/mods/ITEMS/mcl_heads/init.lua @@ -1,5 +1,6 @@ local S = minetest.get_translator(minetest.get_current_modname()) +local minetest = minetest local mod_doc = minetest.get_modpath("doc") local mod_screwdriver = minetest.get_modpath("screwdriver") @@ -8,159 +9,233 @@ if minetest.get_modpath("mcl_armor") then equip_armor = mcl_armor.equip_on_use end --- Heads system +mcl_heads = {} -local function addhead(name, texture, desc, longdesc, rangemob, rangefactor) - local on_rotate_floor, on_rotate_wall - if mod_screwdriver then - on_rotate_floor = function(pos, node, user, mode, new_param2) - if mode == screwdriver.ROTATE_AXIS then - node.name = node.name .. "_wall" - node.param2 = minetest.dir_to_wallmounted(minetest.facedir_to_dir(node.param2)) - minetest.set_node(pos, node) - return true - end - end - on_rotate_wall = function(pos, node, user, mode, new_param2) - if mode == screwdriver.ROTATE_AXIS then - node.name = string.sub(node.name, 1, string.len(node.name)-5) - node.param2 = minetest.dir_to_facedir(minetest.wallmounted_to_dir(node.param2)) - minetest.set_node(pos, node) - return true - end +-- box of head nodes +mcl_heads.FLOOR_BOX = { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, } + +-- floor head node nodedef template ------------------------------------------------------------------------------------ + +--- node definition template for floor mod heads +mcl_heads.deftemplate_floor = { + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = mcl_heads.FLOOR_BOX, + }, + groups = { + handy = 1, + armor = 1, + armor_head = 1, + non_combat_armor = 1, + non_combat_armor_head = 1, + head = 1, + deco_block = 1, + dig_by_piston = 1, + }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + paramtype = "light", + paramtype2 = "facedir", + stack_max = 64, + sunlight_propagates = true, + sounds = mcl_sounds.node_sound_defaults{ + footstep = {name="default_hard_footstep", gain=0.3}, + }, + is_ground_content = false, + + _mcl_armor_element = "head", + _mcl_blast_resistance = 1, + _mcl_hardness = 1, + + on_secondary_use = equip_armor, +} + +function mcl_heads.deftemplate_floor.on_rotate(pos, node, user, mode, new_param2) + if mode == screwdriver.ROTATE_AXIS then + node.name = node.name .. "_wall" + node.param2 = minetest.dir_to_wallmounted(minetest.facedir_to_dir(node.param2)) + minetest.set_node(pos, node) + return true + end +end + +function mcl_heads.deftemplate_floor.on_place(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + + local under = pointed_thing.under + local node = minetest.get_node(under) + local def = minetest.registered_nodes[node.name] + if not def then return itemstack end + + -- Allow pointed node's on_rightclick callback to override place. + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then + return minetest.registered_nodes[node.name].on_rightclick(under, node, placer, itemstack) or itemstack end end - minetest.register_node("mcl_heads:"..name, { - description = desc, - _doc_items_longdesc = longdesc, - drawtype = "nodebox", - is_ground_content = false, - node_box = { - type = "fixed", - fixed = { - { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, }, - }, - }, - groups = {handy = 1, armor = 1, armor_head = 1, non_combat_armor = 1, non_combat_armor_head = 1, head = 1, deco_block = 1, dig_by_piston = 1}, + local above = pointed_thing.above + local dir = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z} + local wdir = minetest.dir_to_wallmounted(dir) + + -- place floor mob head + if wdir == 0 or wdir == 1 then + return minetest.item_place(itemstack, placer, pointed_thing) + end + + -- place wall mob head + local itemstring = itemstack:get_name() + local placestack = ItemStack(itemstack) + placestack:set_name(itemstring .."_wall") + itemstack = minetest.item_place(placestack, placer, pointed_thing, wdir) + itemstack:set_name(itemstring) + return itemstack +end + +-- wall head node nodedef template ------------------------------------------------------------------------------------- + +--- node definition template for wall mod heads +mcl_heads.deftemplate_wall = { + drawtype = "nodebox", + node_box = { + type = "wallmounted", + wall_bottom = { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, }, + wall_top = { -0.25, 0.0, -0.25, 0.25, 0.5, 0.25, }, + wall_side = { -0.5, -0.25, -0.25, 0.0, 0.25, 0.25, }, + }, + groups = { + handy = 1, + head = 1, + deco_block = 1, + dig_by_piston = 1, + not_in_creative_inventory = 1, + }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + paramtype = "light", + paramtype2 = "wallmounted", + stack_max = 64, + sunlight_propagates = true, + sounds = mcl_sounds.node_sound_defaults{ + footstep = {name="default_hard_footstep", gain=0.3}, + }, + is_ground_content = false, + + _doc_items_create_entry = false, + _mcl_blast_resistance = 1, + _mcl_hardness = 1, +} + +function mcl_heads.deftemplate_wall.on_rotate(pos, node, user, mode, new_param2) + if mode == screwdriver.ROTATE_AXIS then + node.name = string.sub(node.name, 1, string.len(node.name)-5) + node.param2 = minetest.dir_to_facedir(minetest.wallmounted_to_dir(node.param2)) + minetest.set_node(pos, node) + return true + end +end + +-- API functions ------------------------------------------------------------------------------------------------------- + +--- @class HeadDef +--- @field name string identifier for node +--- @field texture string texture filename for node +--- @field description string translated description +--- @field longdesc string translated doc description +--- @field armor_texture string texture filename for armor +--- @field range_mob string name of mob affected by range reduction +--- @field range_factor number factor of range reduction + +--- registers a head +--- @param head_def HeadDef head node definition +function mcl_heads.register_head(head_def) + local name = "mcl_heads:" ..head_def.name + + -- register the floor head node + minetest.register_node(name, table.update(table.copy(mcl_heads.deftemplate_floor), { + description = head_def.description, + _doc_items_longdesc = head_def.longdesc, + -- The head textures are based off the textures of an actual mob. tiles = { -- Note: bottom texture is overlaid over top texture to get rid of possible transparency. -- This is required for skeleton skull and wither skeleton skull. - "[combine:16x16:-4,4="..texture, -- top - "([combine:16x16:-4,4="..texture..")^([combine:16x16:-12,4="..texture..")", -- bottom - "[combine:16x16:-12,0="..texture, -- left - "[combine:16x16:4,0="..texture, -- right - "[combine:16x16:-20,0="..texture, -- back - "[combine:16x16:-4,0="..texture, -- front + "[combine:16x16:-4,4=" ..head_def.texture, -- top + "([combine:16x16:-4,4=" ..head_def.texture..")^([combine:16x16:-12,4="..head_def.texture..")", -- bottom + "[combine:16x16:-12,0=" ..head_def.texture, -- left + "[combine:16x16:4,0=" ..head_def.texture, -- right + "[combine:16x16:-20,0=" ..head_def.texture, -- back + "[combine:16x16:-4,0=" ..head_def.texture, -- front }, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, - paramtype = "light", - stack_max = 64, - paramtype2 = "facedir", - sunlight_propagates = true, - walkable = true, - selection_box = { - type = "fixed", - fixed = { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, }, - }, - sounds = mcl_sounds.node_sound_defaults({ - footstep = {name="default_hard_footstep", gain=0.3} - }), - on_place = function(itemstack, placer, pointed_thing) - if pointed_thing.type ~= "node" then - -- no interaction possible with entities, for now. - return itemstack - end - local under = pointed_thing.under - local node = minetest.get_node(under) - local def = minetest.registered_nodes[node.name] - if not def then return itemstack end + _mcl_armor_mob_range_mob = head_def.range_mob, + _mcl_armor_mob_range_factor = head_def.range_factor, + _mcl_armor_texture = head_def.armor_texture + })) - -- Call on_rightclick if the pointed node defines it - if placer and not placer:get_player_control().sneak then - if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then - return minetest.registered_nodes[node.name].on_rightclick(under, node, placer, itemstack) or itemstack - end - end - - local above = pointed_thing.above - local diff = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z} - local wdir = minetest.dir_to_wallmounted(diff) - - local itemstring = itemstack:get_name() - local fakestack = ItemStack(itemstack) - --local idef = fakestack:get_definition() - local retval - if wdir == 0 or wdir == 1 then - return minetest.item_place(itemstack, placer, pointed_thing) - else - retval = fakestack:set_name("mcl_heads:"..name.."_wall") - end - if not retval then - return itemstack - end - itemstack = minetest.item_place(fakestack, placer, pointed_thing, wdir) - itemstack:set_name(itemstring) - return itemstack - end, - on_secondary_use = equip_armor, - - on_rotate = on_rotate_floor, - - _mcl_armor_mob_range_mob = rangemob, - _mcl_armor_mob_range_factor = rangefactor, - _mcl_armor_element = "head", - _mcl_armor_texture = "mcl_heads_" .. name .. ".png", - _mcl_blast_resistance = 1, - _mcl_hardness = 1, - }) - - minetest.register_node("mcl_heads:"..name.."_wall", { - _doc_items_create_entry = false, - drawtype = "nodebox", - is_ground_content = false, - node_box = { - type = "wallmounted", - wall_bottom = { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, }, - wall_top = { -0.25, 0.0, -0.25, 0.25, 0.5, 0.25, }, - wall_side = { -0.5, -0.25, -0.25, 0.0, 0.25, 0.25, }, - }, - groups = {handy=1, head=1, deco_block=1, dig_by_piston=1, not_in_creative_inventory=1}, + -- register the wall head node + minetest.register_node(name .."_wall", table.update(table.copy(mcl_heads.deftemplate_wall), { -- The head textures are based off the textures of an actual mob. tiles = { - { name = "[combine:16x16:-4,-4="..texture, align_style = "world" }, -- front - { name = "[combine:16x16:-20,-4="..texture, align_style = "world" }, -- back - { name = "[combine:16x16:-8,-4="..texture, align_style = "world" }, -- left - { name = "[combine:16x16:0,-4="..texture, align_style = "world" }, -- right - { name = "([combine:16x16:-4,0="..texture..")^[transformR180", align_style = "node" }, -- top - { name = "([combine:16x16:-4,8="..texture..")^([combine:16x16:-12,8="..texture..")", align_style = "node" }, -- bottom + { name = "[combine:16x16:-4,-4=" ..head_def.texture, align_style = "world" }, -- front + { name = "[combine:16x16:-20,-4="..head_def.texture, align_style = "world" }, -- back + { name = "[combine:16x16:-8,-4=" ..head_def.texture, align_style = "world" }, -- left + { name = "[combine:16x16:0,-4=" ..head_def.texture, align_style = "world" }, -- right + { name = "([combine:16x16:-4,0=" ..head_def.texture ..")^[transformR180", align_style = "node" }, -- top + -- Note: bottom texture is overlaid over top texture to get rid of possible transparency. + -- This is required for skeleton skull and wither skeleton skull. + { name = "([combine:16x16:-4,8=" ..head_def.texture ..")^([combine:16x16:-12,8=" ..head_def.texture..")", align_style = "node" }, -- bottom }, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, - paramtype = "light", - stack_max = 64, - paramtype2 = "wallmounted", - sunlight_propagates = true, - walkable = true, - sounds = mcl_sounds.node_sound_defaults({ - footstep = {name="default_hard_footstep", gain=0.3} - }), - drop = "mcl_heads:"..name, - on_rotate = on_rotate_wall, - _mcl_blast_resistance = 1, - _mcl_hardness = 1, - }) - - if mod_doc then - doc.add_entry_alias("nodes", "mcl_heads:" .. name, "nodes", "mcl_heads:" .. name .. "_wall") - end + drop = name, + })) end --- Add heads -addhead("zombie", "mcl_heads_zombie_node.png", S("Zombie Head"), S("A zombie head is a small decorative block which resembles the head of a zombie. It can also be worn as a helmet, which reduces the detection range of zombies by 50%."), "mobs_mc:zombie", 0.5) -addhead("creeper", "mcl_heads_creeper_node.png", S("Creeper Head"), S("A creeper head is a small decorative block which resembles the head of a creeper. It can also be worn as a helmet, which reduces the detection range of creepers by 50%."), "mobs_mc:creeper", 0.5) +-- initial heads ------------------------------------------------------------------------------------------------------- + +mcl_heads.register_head{ + name = "zombie", + texture = "mcl_heads_zombie_node.png", + description = S("Zombie Head"), + longdesc = S("A zombie head is a small decorative block which resembles the head of a zombie. It can also be worn as a helmet, which reduces the detection range of zombies by 50%."), + armor_texture = "mcl_heads_zombie.png", + range_mob = "mobs_mc:zombie", + range_factor = 0.5, +} + +mcl_heads.register_head{ + name = "creeper", + texture = "mcl_heads_creeper_node.png", + description = S("Creeper Head"), + longdesc = S("A creeper head is a small decorative block which resembles the head of a creeper. It can also be worn as a helmet, which reduces the detection range of creepers by 50%."), + armor_texture = "mcl_heads_creeper.png", + range_mob = "mobs_mc:creeper", + range_factor = 0.5, +} + -- Original Minecraft name: “Head” -addhead("steve", "mcl_heads_steve_node.png", S("Human Head"), S("A human head is a small decorative block which resembles the head of a human (i.e. a player character). It can also be worn as a helmet for fun, but does not offer any protection.")) -addhead("skeleton", "mcl_heads_skeleton_node.png", S("Skeleton Skull"), S("A skeleton skull is a small decorative block which resembles the skull of a skeleton. It can also be worn as a helmet, which reduces the detection range of skeletons by 50%."), "mobs_mc:skeleton", 0.5) -addhead("wither_skeleton", "mcl_heads_wither_skeleton_node.png", S("Wither Skeleton Skull"), S("A wither skeleton skull is a small decorative block which resembles the skull of a wither skeleton. It can also be worn as a helmet for fun, but does not offer any protection.")) +mcl_heads.register_head{ + name = "steve", + texture = "mcl_heads_steve_node.png", + description = S("Human Head"), + longdesc = S("A human head is a small decorative block which resembles the head of a human (i.e. a player character). It can also be worn as a helmet for fun, but does not offer any protection."), + armor_texture = "mcl_heads_steve.png", +} + +mcl_heads.register_head{ + name = "skeleton", + texture = "mcl_heads_skeleton_node.png", + description = S("Skeleton Skull"), + longdesc = S("A skeleton skull is a small decorative block which resembles the skull of a skeleton. It can also be worn as a helmet, which reduces the detection range of skeletons by 50%."), + armor_texture = "mcl_heads_skeleton.png", + range_mob = "mobs_mc:skeleton", + range_factor = 0.5, +} + +mcl_heads.register_head{ + name = "wither_skeleton", + texture = "mcl_heads_wither_skeleton_node.png", + description = S("Wither Skeleton Skull"), + longdesc = S("A wither skeleton skull is a small decorative block which resembles the skull of a wither skeleton. It can also be worn as a helmet for fun, but does not offer any protection."), + armor_texture = "mcl_heads_wither_skeleton.png", +} From 44d234dd2c6c211649fae753d999990359753a8f Mon Sep 17 00:00:00 2001 From: iliekprogrammar Date: Thu, 11 Aug 2022 17:12:18 +0800 Subject: [PATCH 2/4] [heads] implement 16 directional head node --- mods/ITEMS/mcl_heads/init.lua | 74 +++++++++++++++++-- .../mcl_heads/models/mcl_heads_floor22_5.obj | 42 +++++++++++ .../mcl_heads/models/mcl_heads_floor45.obj | 42 +++++++++++ .../mcl_heads/models/mcl_heads_floor67_5.obj | 42 +++++++++++ 4 files changed, 192 insertions(+), 8 deletions(-) create mode 100644 mods/ITEMS/mcl_heads/models/mcl_heads_floor22_5.obj create mode 100644 mods/ITEMS/mcl_heads/models/mcl_heads_floor45.obj create mode 100644 mods/ITEMS/mcl_heads/models/mcl_heads_floor67_5.obj diff --git a/mods/ITEMS/mcl_heads/init.lua b/mods/ITEMS/mcl_heads/init.lua index 14f79bfa9..25f1b9d2f 100644 --- a/mods/ITEMS/mcl_heads/init.lua +++ b/mods/ITEMS/mcl_heads/init.lua @@ -11,6 +11,9 @@ end mcl_heads = {} +-- rotations of head nodes within a quadrant (0° ≤ θ ≤ 90°) +mcl_heads.FLOOR_DEGREES = { [0]='', '22_5', '45', '67_5', } + -- box of head nodes mcl_heads.FLOOR_BOX = { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, } @@ -50,6 +53,38 @@ mcl_heads.deftemplate_floor = { on_secondary_use = equip_armor, } +mcl_heads.deftemplate_floor_angled = { + drawtype = "mesh", + selection_box = { + type = "fixed", + fixed = mcl_heads.FLOOR_BOX, + }, + collision_box = { + type = "fixed", + fixed = mcl_heads.FLOOR_BOX, + }, + groups = { + handy = 1, + head = 1, + deco_block = 1, + dig_by_piston = 1, + not_in_creative_inventory = 1, + }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + paramtype = "light", + paramtype2 = "facedir", + stack_max = 64, + sunlight_propagates = true, + sounds = mcl_sounds.node_sound_defaults{ + footstep = {name="default_hard_footstep", gain=0.3}, + }, + is_ground_content = false, + + _doc_items_create_entry = false, + _mcl_blast_resistance = 1, + _mcl_hardness = 1, +} + function mcl_heads.deftemplate_floor.on_rotate(pos, node, user, mode, new_param2) if mode == screwdriver.ROTATE_AXIS then node.name = node.name .. "_wall" @@ -80,16 +115,30 @@ function mcl_heads.deftemplate_floor.on_place(itemstack, placer, pointed_thing) local dir = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z} local wdir = minetest.dir_to_wallmounted(dir) - -- place floor mob head - if wdir == 0 or wdir == 1 then - return minetest.item_place(itemstack, placer, pointed_thing) - end - - -- place wall mob head local itemstring = itemstack:get_name() local placestack = ItemStack(itemstack) - placestack:set_name(itemstring .."_wall") - itemstack = minetest.item_place(placestack, placer, pointed_thing, wdir) + + -- place wall head node (elsewhere) + if wdir ~= 0 and wdir ~= 1 then + placestack:set_name(itemstring .."_wall") + itemstack = minetest.item_place(placestack, placer, pointed_thing, wdir) + -- place floor head node (floor and ceiling) + else + local fdir = minetest.dir_to_facedir(dir) + + -- determine the head node rotation based on player's yaw (in cw direction from North/Z+) + local yaw = math.pi*2 - placer:get_look_horizontal() + + local rotation_level = math.min(math.max(math.round((yaw / (math.pi*2)) * 16), 0), 15) + placestack:set_name(itemstring ..mcl_heads.FLOOR_DEGREES[rotation_level % 4]) + + -- determine the head node face direction based on rotation level + fdir = math.floor(rotation_level / 4) + + itemstack = minetest.item_place(placestack, placer, pointed_thing, fdir) + end + + -- restore item from angled and wall head nodes itemstack:set_name(itemstring) return itemstack end @@ -174,6 +223,15 @@ function mcl_heads.register_head(head_def) _mcl_armor_texture = head_def.armor_texture })) + -- register the angled floor head nodes + for i, d in ipairs(mcl_heads.FLOOR_DEGREES) do + minetest.register_node(name ..d, table.update(table.copy(mcl_heads.deftemplate_floor_angled), { + mesh = "mcl_heads_floor" ..d ..".obj", + tiles = { head_def.armor_texture }, + drop = name, + })) + end + -- register the wall head node minetest.register_node(name .."_wall", table.update(table.copy(mcl_heads.deftemplate_wall), { -- The head textures are based off the textures of an actual mob. diff --git a/mods/ITEMS/mcl_heads/models/mcl_heads_floor22_5.obj b/mods/ITEMS/mcl_heads/models/mcl_heads_floor22_5.obj new file mode 100644 index 000000000..8e48015fc --- /dev/null +++ b/mods/ITEMS/mcl_heads/models/mcl_heads_floor22_5.obj @@ -0,0 +1,42 @@ +# Blender v2.93.9 OBJ File: 'mcl_heads_floor_0.blend' +# www.blender.org +mtllib mcl_heads_floor22_5.mtl +o Cube.001 +v -0.326641 -0.500000 0.135299 +v -0.326641 0.000000 0.135299 +v -0.135299 -0.500000 -0.326641 +v -0.135299 0.000000 -0.326641 +v 0.135299 -0.500000 0.326641 +v 0.135299 0.000000 0.326641 +v 0.326641 -0.500000 -0.135299 +v 0.326641 0.000000 -0.135299 +vt 0.875000 0.500000 +vt 0.875000 0.750000 +vt 0.750000 0.750000 +vt 0.750000 0.500000 +vt 0.625000 0.750000 +vt 0.625000 0.500000 +vt 0.500000 0.750000 +vt 0.500000 0.500000 +vt 1.000000 0.500000 +vt 1.000000 0.750000 +vt 0.875000 0.750000 +vt 0.875000 1.000000 +vt 0.750000 1.000000 +vt 0.750000 0.750000 +vt 0.750000 1.000000 +vt 0.625000 1.000000 +vn -0.9239 0.0000 -0.3827 +vn 0.3827 0.0000 -0.9239 +vn 0.9239 0.0000 0.3827 +vn -0.3827 0.0000 0.9239 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +usemtl Material.001 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/4/2 4/3/2 8/5/2 7/6/2 +f 7/6/3 8/5/3 6/7/3 5/8/3 +f 5/9/4 6/10/4 2/2/4 1/1/4 +f 3/11/5 7/12/5 5/13/5 1/14/5 +f 8/5/6 4/3/6 2/15/6 6/16/6 diff --git a/mods/ITEMS/mcl_heads/models/mcl_heads_floor45.obj b/mods/ITEMS/mcl_heads/models/mcl_heads_floor45.obj new file mode 100644 index 000000000..6300d4484 --- /dev/null +++ b/mods/ITEMS/mcl_heads/models/mcl_heads_floor45.obj @@ -0,0 +1,42 @@ +# Blender v2.93.9 OBJ File: 'mcl_heads_floor_0.blend' +# www.blender.org +mtllib mcl_heads_floor45.mtl +o Cube.002 +v -0.353553 -0.500000 0.000000 +v -0.353553 0.000000 0.000000 +v 0.000000 -0.500000 -0.353553 +v 0.000000 0.000000 -0.353553 +v 0.000000 -0.500000 0.353553 +v 0.000000 0.000000 0.353553 +v 0.353553 -0.500000 0.000000 +v 0.353553 0.000000 0.000000 +vt 0.875000 0.500000 +vt 0.875000 0.750000 +vt 0.750000 0.750000 +vt 0.750000 0.500000 +vt 0.625000 0.750000 +vt 0.625000 0.500000 +vt 0.500000 0.750000 +vt 0.500000 0.500000 +vt 1.000000 0.500000 +vt 1.000000 0.750000 +vt 0.875000 0.750000 +vt 0.875000 1.000000 +vt 0.750000 1.000000 +vt 0.750000 0.750000 +vt 0.750000 1.000000 +vt 0.625000 1.000000 +vn -0.7071 0.0000 -0.7071 +vn 0.7071 0.0000 -0.7071 +vn 0.7071 0.0000 0.7071 +vn -0.7071 0.0000 0.7071 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +usemtl Material.002 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/4/2 4/3/2 8/5/2 7/6/2 +f 7/6/3 8/5/3 6/7/3 5/8/3 +f 5/9/4 6/10/4 2/2/4 1/1/4 +f 3/11/5 7/12/5 5/13/5 1/14/5 +f 8/5/6 4/3/6 2/15/6 6/16/6 diff --git a/mods/ITEMS/mcl_heads/models/mcl_heads_floor67_5.obj b/mods/ITEMS/mcl_heads/models/mcl_heads_floor67_5.obj new file mode 100644 index 000000000..0fe5567e3 --- /dev/null +++ b/mods/ITEMS/mcl_heads/models/mcl_heads_floor67_5.obj @@ -0,0 +1,42 @@ +# Blender v2.93.9 OBJ File: 'mcl_heads_floor_0.blend' +# www.blender.org +mtllib mcl_heads_floor67_5.mtl +o Cube.003 +v -0.326641 -0.500000 -0.135299 +v -0.326641 0.000000 -0.135299 +v 0.135299 -0.500000 -0.326641 +v 0.135299 0.000000 -0.326641 +v -0.135299 -0.500000 0.326641 +v -0.135299 0.000000 0.326641 +v 0.326641 -0.500000 0.135299 +v 0.326641 0.000000 0.135299 +vt 0.875000 0.500000 +vt 0.875000 0.750000 +vt 0.750000 0.750000 +vt 0.750000 0.500000 +vt 0.625000 0.750000 +vt 0.625000 0.500000 +vt 0.500000 0.750000 +vt 0.500000 0.500000 +vt 1.000000 0.500000 +vt 1.000000 0.750000 +vt 0.875000 0.750000 +vt 0.875000 1.000000 +vt 0.750000 1.000000 +vt 0.750000 0.750000 +vt 0.750000 1.000000 +vt 0.625000 1.000000 +vn -0.3827 0.0000 -0.9239 +vn 0.9239 0.0000 -0.3827 +vn 0.3827 0.0000 0.9239 +vn -0.9239 0.0000 0.3827 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +usemtl Material.003 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/4/2 4/3/2 8/5/2 7/6/2 +f 7/6/3 8/5/3 6/7/3 5/8/3 +f 5/9/4 6/10/4 2/2/4 1/1/4 +f 3/11/5 7/12/5 5/13/5 1/14/5 +f 8/5/6 4/3/6 2/15/6 6/16/6 From 29d221eed58664c4877e0af1cc5791946b485eb0 Mon Sep 17 00:00:00 2001 From: iliekprogrammar Date: Thu, 11 Aug 2022 17:15:39 +0800 Subject: [PATCH 3/4] [heads] remove unnecessarily duplicative textures these textures are unnecessary to texture the head nodes. we can reuse the available armor texture for both the headgear/helmet and the nodes. --- mods/ITEMS/mcl_heads/init.lua | 48 ++++++++---------- .../textures/mcl_heads_creeper_node.png | Bin 676 -> 0 bytes .../textures/mcl_heads_skeleton_node.png | Bin 432 -> 0 bytes .../textures/mcl_heads_steve_node.png | Bin 1852 -> 0 bytes .../mcl_heads_wither_skeleton_node.png | Bin 432 -> 0 bytes .../textures/mcl_heads_zombie_node.png | Bin 1112 -> 0 bytes 6 files changed, 22 insertions(+), 26 deletions(-) delete mode 100644 mods/ITEMS/mcl_heads/textures/mcl_heads_creeper_node.png delete mode 100644 mods/ITEMS/mcl_heads/textures/mcl_heads_skeleton_node.png delete mode 100644 mods/ITEMS/mcl_heads/textures/mcl_heads_steve_node.png delete mode 100644 mods/ITEMS/mcl_heads/textures/mcl_heads_wither_skeleton_node.png delete mode 100644 mods/ITEMS/mcl_heads/textures/mcl_heads_zombie_node.png diff --git a/mods/ITEMS/mcl_heads/init.lua b/mods/ITEMS/mcl_heads/init.lua index 25f1b9d2f..a971d7b91 100644 --- a/mods/ITEMS/mcl_heads/init.lua +++ b/mods/ITEMS/mcl_heads/init.lua @@ -189,10 +189,9 @@ end --- @class HeadDef --- @field name string identifier for node ---- @field texture string texture filename for node +--- @field texture string armor texture for node --- @field description string translated description --- @field longdesc string translated doc description ---- @field armor_texture string texture filename for armor --- @field range_mob string name of mob affected by range reduction --- @field range_factor number factor of range reduction @@ -210,24 +209,25 @@ function mcl_heads.register_head(head_def) tiles = { -- Note: bottom texture is overlaid over top texture to get rid of possible transparency. -- This is required for skeleton skull and wither skeleton skull. - "[combine:16x16:-4,4=" ..head_def.texture, -- top - "([combine:16x16:-4,4=" ..head_def.texture..")^([combine:16x16:-12,4="..head_def.texture..")", -- bottom - "[combine:16x16:-12,0=" ..head_def.texture, -- left - "[combine:16x16:4,0=" ..head_def.texture, -- right - "[combine:16x16:-20,0=" ..head_def.texture, -- back - "[combine:16x16:-4,0=" ..head_def.texture, -- front + -- Note: -x coords go right per-pixel, -y coords go down per-pixel + "[combine:16x16:-36,4=" ..head_def.texture, -- top + "([combine:16x16:-36,4=" ..head_def.texture..")^([combine:16x16:-44,4="..head_def.texture..")", -- bottom + "[combine:16x16:-28,0=" ..head_def.texture, -- left + "[combine:16x16:-44,0=" ..head_def.texture, -- right + "[combine:16x16:-52,0=" ..head_def.texture, -- back + "[combine:16x16:-36,0=" ..head_def.texture, -- front }, _mcl_armor_mob_range_mob = head_def.range_mob, _mcl_armor_mob_range_factor = head_def.range_factor, - _mcl_armor_texture = head_def.armor_texture + _mcl_armor_texture = head_def.texture })) -- register the angled floor head nodes for i, d in ipairs(mcl_heads.FLOOR_DEGREES) do minetest.register_node(name ..d, table.update(table.copy(mcl_heads.deftemplate_floor_angled), { mesh = "mcl_heads_floor" ..d ..".obj", - tiles = { head_def.armor_texture }, + tiles = { head_def.texture }, drop = name, })) end @@ -235,15 +235,16 @@ function mcl_heads.register_head(head_def) -- register the wall head node minetest.register_node(name .."_wall", table.update(table.copy(mcl_heads.deftemplate_wall), { -- The head textures are based off the textures of an actual mob. + -- Note: -x coords go right per-pixel, -y coords go down per-pixel tiles = { - { name = "[combine:16x16:-4,-4=" ..head_def.texture, align_style = "world" }, -- front - { name = "[combine:16x16:-20,-4="..head_def.texture, align_style = "world" }, -- back - { name = "[combine:16x16:-8,-4=" ..head_def.texture, align_style = "world" }, -- left - { name = "[combine:16x16:0,-4=" ..head_def.texture, align_style = "world" }, -- right - { name = "([combine:16x16:-4,0=" ..head_def.texture ..")^[transformR180", align_style = "node" }, -- top + { name = "[combine:16x16:-36,-4=" ..head_def.texture, align_style = "world" }, -- front + { name = "[combine:16x16:-52,-4="..head_def.texture, align_style = "world" }, -- back + { name = "[combine:16x16:-40,-4=" ..head_def.texture, align_style = "world" }, -- right + { name = "[combine:16x16:-32,-4=" ..head_def.texture, align_style = "world" }, -- left + { name = "([combine:16x16:-36,0=" ..head_def.texture ..")^[transformR180", align_style = "node" }, -- top -- Note: bottom texture is overlaid over top texture to get rid of possible transparency. -- This is required for skeleton skull and wither skeleton skull. - { name = "([combine:16x16:-4,8=" ..head_def.texture ..")^([combine:16x16:-12,8=" ..head_def.texture..")", align_style = "node" }, -- bottom + { name = "([combine:16x16:-36,0=" ..head_def.texture ..")^([combine:16x16:-44,8=" ..head_def.texture..")", align_style = "node" }, -- bottom }, drop = name, })) @@ -253,20 +254,18 @@ end mcl_heads.register_head{ name = "zombie", - texture = "mcl_heads_zombie_node.png", + texture = "mcl_heads_zombie.png", description = S("Zombie Head"), longdesc = S("A zombie head is a small decorative block which resembles the head of a zombie. It can also be worn as a helmet, which reduces the detection range of zombies by 50%."), - armor_texture = "mcl_heads_zombie.png", range_mob = "mobs_mc:zombie", range_factor = 0.5, } mcl_heads.register_head{ name = "creeper", - texture = "mcl_heads_creeper_node.png", + texture = "mcl_heads_creeper.png", description = S("Creeper Head"), longdesc = S("A creeper head is a small decorative block which resembles the head of a creeper. It can also be worn as a helmet, which reduces the detection range of creepers by 50%."), - armor_texture = "mcl_heads_creeper.png", range_mob = "mobs_mc:creeper", range_factor = 0.5, } @@ -274,26 +273,23 @@ mcl_heads.register_head{ -- Original Minecraft name: “Head” mcl_heads.register_head{ name = "steve", - texture = "mcl_heads_steve_node.png", + texture = "mcl_heads_steve.png", description = S("Human Head"), longdesc = S("A human head is a small decorative block which resembles the head of a human (i.e. a player character). It can also be worn as a helmet for fun, but does not offer any protection."), - armor_texture = "mcl_heads_steve.png", } mcl_heads.register_head{ name = "skeleton", - texture = "mcl_heads_skeleton_node.png", + texture = "mcl_heads_skeleton.png", description = S("Skeleton Skull"), longdesc = S("A skeleton skull is a small decorative block which resembles the skull of a skeleton. It can also be worn as a helmet, which reduces the detection range of skeletons by 50%."), - armor_texture = "mcl_heads_skeleton.png", range_mob = "mobs_mc:skeleton", range_factor = 0.5, } mcl_heads.register_head{ name = "wither_skeleton", - texture = "mcl_heads_wither_skeleton_node.png", + texture = "mcl_heads_wither_skeleton.png", description = S("Wither Skeleton Skull"), longdesc = S("A wither skeleton skull is a small decorative block which resembles the skull of a wither skeleton. It can also be worn as a helmet for fun, but does not offer any protection."), - armor_texture = "mcl_heads_wither_skeleton.png", } diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_creeper_node.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_creeper_node.png deleted file mode 100644 index 99b432ac67db7900cdbf4ad0075288fc59381168..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 676 zcmV;V0$crwP)-`Z<|gO2k=b4ojZ{2kvo1$J@UYc88LTiDHF~+Rm6Mu)TyY) z)R98Q*dPn_-@rrTf3D`-AS1co>B0Mm-}Vfd=lD;shQj@r z=MP=K%+%+sOqzF4(1Q0sBlbzNR~_(}zx;9zR2k=Df%Q8Wu}9MAZS;pe~+|*}NsHN*0S20Cu^Tfnz`KKSvxyq6ppYQpH`&%FbSA)AI&P#j{ zEpT7M!uLGe{&dgj#vN!-3ss8UX$mJz*JQ9Xz3A08w_{U-L#z%-ldW1XNd=Aa+;G!+ zY^6SGuusaj1;+XaQ=pkHuZ<8zP@yF?5DS#qYVr3js4GSLmU6IB={i%m6L^=M0E4(X ztqq}ZU6;plw-PE-qB;T2PT<&QnFd|{)4*V;PXs zW{(&H*w76z*mOpEpa`yi2KIRB0^3G205+WS9(WoJUQFM;vB^5TJ+`k2tb1Tmi=c8% zpV5~w3}1%65j^&Q{9j5;_^N10000< KMNUMnLSTaNDmEqn diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_skeleton_node.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_skeleton_node.png deleted file mode 100644 index 0af86cd6a5e79a56e21ea9fb18cc64e40cc99731..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 432 zcmV;h0Z;ykP)J${R5dg`bu`y)-C>?L6Z|>8%S`W(g^ikPBD@yH8E*mntaAu zcznz}1{I2thXU5v#kha}?&~+K5epVD{}i@B_kY5|3RMzVFX;-2*hBHW0lC2STmMVr zKWsL9I+itc6*MJd;SkHb)N>5@jH;x82s% zY!-&87AznHm}Cy#Ny{cUw?-+P`FPHr{SV?mvoMBdq0XXU4yB|URd0YO_m99_C)6JJ z%eHGm;qcZbv`h;m9!N4xSQ2L1gtxha7CQTy4doCh5IbXCdn?d5_mTK}d$EL1lsvZ= anE3-#<3ZF1Q5;kN0000bbSMJ~EDEo$_TqK^Ox z8bCex;P%oMNP7v;A~~dh+f#wUMu7lD^DycbP+KcSYQ*xzZDYxjNkvQ1B$wRfl7wZm z2WnTl%N0dcX)MiUzsKx{o%!bfpPBWsg*=j!ng>S)xRtqs`zeKkeE-xl9pC@vTNixn zV(HsTK?(Xb@VRK1224q9iFN>zr2;w�taCojsSmVH z=sP$vKq{5MsMaVJHyFHBsiGTo0A4x$MbDRiaQ^qGdX2UFO=5SOj=iHtA4XB~Em8~% zRt*t}h*ZioQmI6XLvreag}|-M9oE)AzEr7l=;0JXD2QCG@oXwZ`cR6X=#AxHd}oTK zd4#$}>$nb$79!<+BT5F3z5A4)O5sF2O9^73<&oIm%HMV4mRyHn_{ zBf)HDl~Sc@k(Mlr43F%iqP9N%;-5d_bIB-TTmsOR{&4Qwym9Go0Ic0@QmRzZ%2mn*jp@^qynboM;t=yZyCdcomEDmAe)q~(n?fXF zUd*sJ^5tw`e49w@3ECSGvPJsJV(W;=>S`v|I^2wXeRtEm3*Vgi8IF$6B3`? zTtKRoo=HbYy989{cZe%dlTnnFxS!1AZl3&^sF9RjMRJ0P%? z7AAAR-+ihh0!}m~5`G`o)isCyV6fK;Yljno-1q^KS8umFz{UZa!NlDE z;q`y|w)`O?iDAc$xaYDgIt;h(o5q;qx?yntc$yPUiDFT681JQTH{Q@27?b#V zfVyE=ykhE@=h(*yzt1st@BiO_iLKP`u~NI&ssv{h>V`q$Yfm%vP>iXEVx;2%#|_){ zJz;cejJjbUT+4SP+HT0WYYvD?8#itro407c{iqbCta{^hFxU&%^5g`8qTt>k-HRiyz7pa;1x$y%m{d<9) zD@&x~fvyO#o3)M+U}s)83!8I0nYr}`>2=`R?u6@?7pPAd1db#fWaid4jjtO9hFW5qySZdA*vnF({@JBLcd6_cXF(lyI?$`Ga68!4Q8k@nQQJ{L z_3qrwjzrRTA+k@aXdG3uzl{9Tt*>z^|qrjFE42HUQz%600DGTPE!Ct=GbNc00BTrL_t(| z0i}>J${R5dg`bu`y)-C>?L6Z|>8%S`W(g^ikPBD@yH8E*mntaAu zcznz}1{I2thXU5v#kha}?&~+K5epVD{}i@B_kY5|3RMzVFX;-2*hBHW0lC2STmMVr zKWsL9I+itc6*MJd;SkHb)N>5@jH;x82s% zY!-&87AznHm}Cy#Ny{cUw?-+P`FPHr{SV?mvoMBdq0XXU4yB|URd0YO_m99_C)6JJ z%eHGm;qcZbv`h;m9!N4xSQ2L1gtxha7CQTy4doCh5IbXCdn?d5_mTK}d$EL1lsvZ= anE3-#<3ZF1Q5;kN0000`LiLigq;2_Oo?wY4$Ae^wd}JpE6l5GSYwA)QF`^tQ=+= zS+qwiUS#jK%D%KDZS9)WHLKm*TJ1_p4C7*_wMMU;RkUD2YI{YHuG=glztyI}J1V*p z+GgbjN9`-FJf&vc+`p*YKJHjj%|)5)Z27V>iP+fUG`E?p*+6Ien`sx!%&v;_Y|01* zisU7WSp$9ORubeF%mDNc7ytzr{sR%|0H{&iGAM+Bf$6cQi(^OyW6k77zC{KCF4oMO z)YnD^p;{R`iVv+lUna?Z>th%4k=$yoNck(tMO8k58^!FP3Y(hOyTTmCY(`?1Yn z2uhGJj`8{Ic_z54MBumb8wJ)Y?cG1WxX*be(kQp!{Ym*I!Tl_6Sod+>QEk}9AU>a! zWx?y+4sCOeuV-plB-x;GLFlN(jvqT*L>05PbLnvTIPCcG-gMg2J#o{rH->LNYdD*M zc{8^Gx03Gbr7`DDi?aPuz3^#iSqk^PuiW)A6i``n)^KL*ii2E79Qal=xeM}FUwk&Bg6rP=>eC@V-K8Q|m~4khn~(T2@w9%`Lg8J>$A^N%yz#PxDfrt?aH)% zre)i|y!>;|U_0ZgrVmH|Gl}iJm(Iw4ycZ&mALlbAI{x<*ofQN3@jh_fsUXOE+UvHK#A1E(82 zCH&MBwH;5S*jX|U~ZV9ez$ILgY_%D9+K;Xr~}!@rrGlO-H>GTu0_f{}wEYs1Ekjki+s@*X{M zVAQ$QzL{}GgATKZs3Wgac{xA7zyI@z84OEb3NWZ#7Lh(?cYX&bzj(U(xvX Date: Thu, 11 Aug 2022 17:34:20 +0800 Subject: [PATCH 4/4] [heads] optimize textures `optipng -strip all -o7 -zm9` --- .../mcl_heads/textures/mcl_heads_steve.png | Bin 970 -> 382 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_steve.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_steve.png index 361795a52b7b2e15923bea8f1a5b76bc2f60e9cd..471a8b3c82f753601954ecb79e11ff9c28499000 100644 GIT binary patch delta 366 zcmV-!0g?X72mS((8Gi!+005OkjW) zJ}gv0FkVbKmsv=oXI7|eRkC_xwtQf}iEhV`a?YH9+pm!S|Nnex_>lkr00DGTPE!Ct z=GbNc008hwL_t&-8STMaQUXB`MZr_I3kM;B{clu>vAb`n0e?RJX80#F*hx8ZLQft+wK!Eun_6oiT#24{HJkI8ic*ICRAbur}F_8Qtb~2Da3JE25$zHR1t7!xX zbC+z86cEE$W$~tfveW4{HIfb4YJ!Vpfra4`aF|3ZxjERNh7VE7;9CtxbuqJzWMmf` zGPx|Hr`D@JZD`C19HWeR<(qkWdV0G11jM>|RXv=xo&W#< M07*qoM6N<$g8#gmK>z>% delta 959 zcmV;w13>)#0?G%F8Gi-<005$$euMx300v@9M??Vs0RI60puMM)00009a7bBm000XU z000XU0RWnu7ytkO2XskIMF-^q5dsPl66y}8000A5NkltHiDx!}}I!(>~%-}2pkckkWz-uJ%u-o+SjPM*lMr?dhO z^d}q~a~Xk;-=95H{=+Z7jUDzpG3XA+WdtNKgQm7o)e&}@ov~JTk>zywUN$dw$!*o0 zBk7Mb1f+5C4#_~9>k73k8 z=j<8Y%MmXlHVAb-ml2TVG^y0<`#WVnIdQ=bf^gRNmv;wL+g6{=18v7aCv^`vZ8-R=R@AQ=YWbp=;8?e)ABRAV! z&!(p*F^pO#DP~e(4aa8RRmG$DH}L8 z4@(9=8h=J8Qz{!_kDwd%(82$$9DCR6>*fBJ!6~f}E^P7gc`lrpqoP+Sl?^6}Dsn;L z+VTolmu`{GD`fKuSC?*aZFvQ`pfFKXDU}T>dX)=j=2*OZK1`N-VSliM4qOtf=v7SH z3zL?jh>UBa*j8upOFyk~>O>YXp9A2*MwNS;e}D4*r{}P(PSor-Lk&#Z1HDQj8N+e| ze6PEbD2j;h1z2vtv3?sL|EG1O)oQaaKZk9)#Nsi&ySqm7X_MdoHdwvCfo7H1ux+k? zv&_=%yG)Tg(Xuv_b&0FWO^g~?4f>Royk-Z-5hnQRj{c6fC5bYD6