From 76991fcba9d54d71acd5ec60ca212897b2e1dfb9 Mon Sep 17 00:00:00 2001 From: Michieal Date: Fri, 4 Nov 2022 09:23:40 +0000 Subject: [PATCH] Pre-review Item frames code * Cleaned up all of the code, checked to make sure that there were no erraneous debug logging. * To enable debugging, turn it on in the api by changing the following line in item_frames_api.lua: mcl_itemframes.DEBUG = false -- set to true to see debug output. * Made the standard Item Frame and the new Glow Frame use the frames API. Added in backwards compatibility mode. * Made frames pop out items into the world on the old frames' entities when they are a hidden / broken entity. (Part of the backwards compatibility.) * Tested locally. Should be fully functional and ready for review. --- mods/ITEMS/mcl_itemframes/init.lua | 68 +- mods/ITEMS/mcl_itemframes/item_frames_API.lua | 671 ++++++++---------- 2 files changed, 326 insertions(+), 413 deletions(-) diff --git a/mods/ITEMS/mcl_itemframes/init.lua b/mods/ITEMS/mcl_itemframes/init.lua index 1ad51e1563..47cd95348a 100644 --- a/mods/ITEMS/mcl_itemframes/init.lua +++ b/mods/ITEMS/mcl_itemframes/init.lua @@ -3,16 +3,24 @@ local modpath = minetest.get_modpath(modname) local S = minetest.get_translator(minetest.get_current_modname()) -if 1 == 1 then - minetest.log("action", "[mcl_itemframes] initialized.") -end - -- mcl_itemframes API dofile(modpath .. "/item_frames_API.lua") -mcl_itemframes.create_base_frames() +-- actual api initialization. +mcl_itemframes.create_base_definitions() --- Register the base item_frame's recipes. +-- necessary to maintain compatibility amongst older versions. +mcl_itemframes.backwards_compatibility () + +-- test for the create custom frame +mcl_itemframes.create_custom_frame("false", "item_frame", false, + "mcl_itemframes_item_frame.png", mcl_colors.WHITE, "Item Frame", + "Can hold an item.") +mcl_itemframes.create_custom_frame("false", "glow_item_frame", true, + "mcl_itemframes_glow_item_frame.png", mcl_colors.WHITE, "Glowing Item Frame", + "Can hold an item and glows.") + +-- Register the base frame's recipes. -- was going to make it a specialized function, but minetest refuses to play nice. minetest.register_craft({ output = "mcl_itemframes:item_frame", @@ -29,20 +37,20 @@ minetest.register_craft({ recipe = { 'mcl_mobitems:glow_ink_sac', 'mcl_itemframes:item_frame' }, }) +--[[ green frames just for testing +mcl_itemframes.create_custom_frame("false", "my_regular_frame", false, + "mcl_itemframes_item_frame.png", mcl_colors.DARK_GREEN, "A Green frame", + "My Green Frame") +mcl_itemframes.create_custom_frame("false", "my_glowing_frame", true, + "mcl_itemframes_glow_item_frame.png", mcl_colors.DARK_GREEN, "A Green glowing frame", + "My Green glowing Frame") --- test for the create custom frame -mcl_itemframes.create_custom_frame("false", "my_regular_frame", false, "mcl_itemframes_item_frame.png", mcl_colors.DARK_GREEN, "A Green frame", "My Green Frame") -mcl_itemframes.create_custom_frame("false", "my_glowing_frame", true, "mcl_itemframes_glow_item_frame.png", mcl_colors.DARK_GREEN, "A Green glowing frame", "My Green glowing Frame") - -if 1 == 1 then - minetest.log("action", "registering custom frame recipes [start].") -end minetest.register_craft({ output = "mcl_itemframes:my_regular_frame", recipe = { - { "mcl_core:stick", "mcl_core:stick", "mcl_core:stick" }, - { "mcl_core:stick", "mcl_core:stick", "mcl_core:stick" }, - { "mcl_core:stick", "mcl_core:stick", "mcl_core:stick" }, + { "", "mcl_core:stick", "" }, + { "mcl_core:stick", "", "mcl_core:stick" }, + { "", "mcl_core:stick", "" }, } }) @@ -51,30 +59,4 @@ minetest.register_craft({ output = "mcl_itemframes:my_glowing_frame", recipe = { "mcl_mobitems:glow_ink_sac", "mcl_itemframes:my_regular_frame" }, }) -if 1 == 1 then - minetest.log("action", "registering custom frame recipes [finished].") -end - --- for compatibility: -minetest.register_lbm({ - label = "Update legacy item frames", - name = "mcl_itemframes:update_legacy_item_frames", - nodenames = { "itemframes:frame" }, - action = function(pos, node) - -- Swap legacy node, then respawn entity - node.name = "mcl_itemframes:item_frame" - local meta = minetest.get_meta(pos) - local item = meta:get_string("item") - minetest.swap_node(pos, node) - if item ~= "" then - local itemstack = ItemStack(minetest.deserialize(meta:get_string("itemdata"))) - local inv = meta:get_inventory() - inv:set_size("main", 1) - if not itemstack:is_empty() then - inv:set_stack("main", 1, itemstack) - end - end - mcl_itemframes.update_item_entity(pos, node) - end, -}) -minetest.register_alias("itemframes:frame", "mcl_itemframes:item_frame") +--]] diff --git a/mods/ITEMS/mcl_itemframes/item_frames_API.lua b/mods/ITEMS/mcl_itemframes/item_frames_API.lua index 43b4fd5183..fe9b62149a 100644 --- a/mods/ITEMS/mcl_itemframes/item_frames_API.lua +++ b/mods/ITEMS/mcl_itemframes/item_frames_API.lua @@ -11,22 +11,23 @@ mcl_itemframes.frames_registered = {} mcl_itemframes.frames_registered.glowing = {} mcl_itemframes.frames_registered.standard = {} +-- Set to true to get all of the DEBUG messages. +mcl_itemframes.DEBUG = false + +if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] initialized.") +end + local S = minetest.get_translator(minetest.get_current_modname()) local table = table -local DEBUG = false - local pairs = pairs -if 1 == 1 then +if mcl_itemframes.DEBUG then minetest.log("action", "[mcl_itemframes] API initialized.") end local VISUAL_SIZE = 0.3 local facedir = {} -facedir[0] = { x = 0, y = 0, z = 1 } -facedir[1] = { x = 1, y = 0, z = 0 } -facedir[2] = { x = 0, y = 0, z = -1 } -facedir[3] = { x = -1, y = 0, z = 0 } local pi = math.pi local glow_amount = 6 -- LIGHT_MAX is 15, but the items aren't supposed to be a light source. @@ -150,19 +151,30 @@ local remove_item_entity = function(pos, node) end end - if 1 == 1 then + if mcl_itemframes.DEBUG then minetest.log("action", "mcl_itemframes] remove_item_entity: " .. found_name_to_use .. "'s displayed item.") end - if node.name == "mcl_itemframes:item_frame" or node.name == "mcl_itemframes:glow_item_frame" or node.name == found_name_to_use then + -- node.name == "mcl_itemframes:item_frame" or node.name == "mcl_itemframes:glow_item_frame" or + if node.name == found_name_to_use then for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0.5)) do local entity = obj:get_luaentity() if entity then - if entity.name == "mcl_itemframes:item" or entity.name == "mcl_itemframes:map" or - entity.name == "mcl_itemframes:glow_item" or entity.name == "mcl_itemframes:glow_map" then + -- remove old entities + if entity.name == "mcl_itemframes:item" or entity.name == "mcl_itemframes:glow_item" or entity.name == "mcl_itemframes:map" or entity.name == "mcl_itemframes:glow_map" then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local item = inv:get_stack("main", 1) + if not item:is_empty() then + if (node.name == found_name_to_use) then + minetest.add_item(pos, item) + end + meta:set_string("infotext", "") + end obj:remove() - elseif entity.name == found_name_to_use .. "_item" or entity.name == found_name_to_use .. "_map" then - if 1 == 1 then + end + if entity.name == found_name_to_use .. "_item" or entity.name == found_name_to_use .. "_map" then + if mcl_itemframes.DEBUG then minetest.log("action", "mcl_itemframes] remove_item_entity: " .. entity.name .. "-- the item.") end obj:remove() @@ -173,70 +185,8 @@ local remove_item_entity = function(pos, node) end mcl_itemframes.update_item_entity = function(pos, node, param2) - if 1 == 1 then - minetest.log("action", "[mcl_itemframes] Update_Item_Entity:\nPosition: " .. dump(pos) .. "\nNode: " .. dump(node)) - end - remove_item_entity(pos, node) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - local item = inv:get_stack("main", 1) - if not item:is_empty() then - if not param2 then - param2 = node.param2 - end - if node.name == "mcl_itemframes:item_frame" or node.name == "mcl_itemframes:glow_item_frame" then - local posad = facedir[param2] - pos.x = pos.x + posad.x * 6.5 / 16 - pos.y = pos.y + posad.y * 6.5 / 16 - pos.z = pos.z + posad.z * 6.5 / 16 - end - - local yaw = pi * 2 - param2 * pi / 2 - local map_id = item:get_meta():get_string("mcl_maps:id") - local map_id_entity = {} - local map_id_lua = {} - - if map_id == "" then - if node.name == "mcl_itemframes:item_frame" then - map_id_entity = minetest.add_entity(pos, "mcl_itemframes:item") - elseif node.name == "mcl_itemframes:glow_item_frame" then - map_id_entity = minetest.add_entity(pos, "mcl_itemframes:glow_item") - end - map_id_lua = map_id_entity:get_luaentity() - map_id_lua._nodename = node.name - local itemname = item:get_name() - if itemname == "" or itemname == nil then - map_id_lua._texture = "blank.png" - map_id_lua._scale = 1 - else - map_id_lua._texture = itemname - local def = minetest.registered_items[itemname] - map_id_lua._scale = def and def.wield_scale and def.wield_scale.x or 1 - end - map_id_lua:_update_texture() - if node.name == "mcl_itemframes:item_frame" or node.name == "mcl_itemframes:glow_item_frame" then - map_id_entity:set_yaw(yaw) - end - else - if node.name == "mcl_itemframes:item_frame" then - map_id_entity = minetest.add_entity(pos, "mcl_itemframes:map", map_id) - elseif node.name == "mcl_itemframes:glow_item_frame" then - map_id_entity = minetest.add_entity(pos, "mcl_itemframes:glow_map", map_id) - end - map_id_entity:set_yaw(yaw) - end - - -- finally, set the rotation (roll) of the displayed object. - local roll = meta:get_int("roll", 0) - set_roll(map_id_entity, roll) - - end -end - -mcl_itemframes.update_generic_item_entity = function(pos, node, param2) - - if 1 == 1 then + if mcl_itemframes.DEBUG then minetest.log("action", "[mcl_itemframes] Update_Generic_Item:\nPosition: " .. dump(pos) .. "\nNode: " .. dump(node)) end @@ -288,7 +238,7 @@ mcl_itemframes.update_generic_item_entity = function(pos, node, param2) pos.y = pos.y + pos_adj.y * 6.5 / 16 pos.z = pos.z + pos_adj.z * 6.5 / 16 - if 1 == 1 then + if mcl_itemframes.DEBUG then minetest.log("[mcl_itemframes] Update_Generic_Item:\nFound Name in Registry: " .. found_name_to_use) end end @@ -299,15 +249,15 @@ mcl_itemframes.update_generic_item_entity = function(pos, node, param2) if map_id == "" then -- handle regular items placed into custom frame. - if 1 == 1 then + if mcl_itemframes.DEBUG then minetest.log("action", "[mcl_itemframes] Update_Generic_Item:\nAdding entity: " .. node.name .. "_item") end + if node.name == found_name_to_use then map_id_entity = minetest.add_entity(pos, node.name .. "_item") else - local debugs_string = "[mcl_itemframes] Update_Generic_Item:\nCouldn't find node name in registry: " - minetest.log("error", debugs_string .. found_name_to_use "\nregistry: " .. dump(mcl_itemframes.frames_registered)) - + local debug_string = "[mcl_itemframes] Update_Generic_Item:\nCouldn't find node name in registry: " + minetest.log("error", debug_string .. found_name_to_use "\nregistry: " .. dump(mcl_itemframes.frames_registered)) return end @@ -326,7 +276,7 @@ mcl_itemframes.update_generic_item_entity = function(pos, node, param2) local def = minetest.registered_items[itemname] map_id_lua._scale = def and def.wield_scale and def.wield_scale.x or 1 end - if 1 == 1 then + if mcl_itemframes.DEBUG then minetest.log("action", "[mcl_itemframes] Update_Generic_Item: item's name: " .. itemname) end map_id_lua:_update_texture() @@ -337,7 +287,7 @@ mcl_itemframes.update_generic_item_entity = function(pos, node, param2) end else -- handle map items placed into custom frame. - if 1 == 1 then + if mcl_itemframes.DEBUG then minetest.log("action", "[mcl_itemframes] Update_Generic_Item: Placing map in a " .. found_name_to_use .. " frame.") end @@ -353,26 +303,7 @@ mcl_itemframes.update_generic_item_entity = function(pos, node, param2) local roll = meta:get_int("roll", 0) set_roll(map_id_entity, roll) end -end -local drop_item = function(pos, node, meta, clicker) - local cname = "" - if clicker and clicker:is_player() then - cname = clicker:get_player_name() - end - if not minetest.is_creative_enabled(cname) then - if (node.name == "mcl_itemframes:item_frame" or node.name == "mcl_itemframes:glow_item_frame") then - local inv = meta:get_inventory() - local item = inv:get_stack("main", 1) - if not item:is_empty() then - minetest.add_item(pos, item) - end - end - end - - meta:set_string("infotext", "") - meta:set_int("roll", 0) - remove_item_entity(pos, node) end function mcl_itemframes.drop_generic_item(pos, node, meta, clicker) @@ -417,227 +348,9 @@ function mcl_itemframes.drop_generic_item(pos, node, meta, clicker) end -mcl_itemframes.item_frame_base = { - description = S("Item Frame"), - _tt_help = S("Can hold an item"), - _doc_items_longdesc = S("Item frames are decorative blocks in which items can be placed."), - _doc_items_usagehelp = S("Just place any item on the item frame. Use the item frame again to retrieve the item."), - drawtype = "mesh", - is_ground_content = false, - mesh = "mcl_itemframes_itemframe1facedir.obj", - selection_box = { type = "fixed", fixed = { -6 / 16, -6 / 16, 7 / 16, 6 / 16, 6 / 16, 0.5 } }, - collision_box = { type = "fixed", fixed = { -6 / 16, -6 / 16, 7 / 16, 6 / 16, 6 / 16, 0.5 } }, - tiles = { "mcl_itemframes_item_frame_back.png", "mcl_itemframes_item_frame_back.png", "mcl_itemframes_item_frame_back.png", "mcl_itemframes_item_frame_back.png", "default_wood.png", "mcl_itemframes_item_frame_back.png" }, - inventory_image = "mcl_itemframes_item_frame.png", - wield_image = "mcl_itemframes_item_frame.png", - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = true, - groups = { dig_immediate = 3, deco_block = 1, dig_by_piston = 1, container = 7, attached_node_facedir = 1 }, - sounds = mcl_sounds.node_sound_defaults(), - node_placement_prediction = "", - - on_timer = function(pos) - local inv = minetest.get_meta(pos):get_inventory() - local stack = inv:get_stack("main", 1) - local itemname = stack:get_name() - if minetest.get_item_group(itemname, "clock") > 0 then - local new_name = "mcl_clock:clock_" .. (mcl_worlds.clock_works(pos) and mcl_clock.old_time or mcl_clock.random_frame) - if itemname ~= new_name then - stack:set_name(new_name) - inv:set_stack("main", 1, stack) - local node = minetest.get_node(pos) - if node.name == "mcl_itemframes:item_frame" or node.name == "mcl_itemframes:glow_item_frame" then - mcl_itemframes.update_item_entity(pos, node, node.param2) - else - mcl_itemframes.update_generic_item_entity(pos, node, node.param2) - end - - end - minetest.get_node_timer(pos):start(1.0) - end - end, - - on_place = function(itemstack, placer, pointed_thing) - if pointed_thing.type ~= "node" then - return itemstack - end - - -- Use pointed node's on_rightclick function first, if present - local node = minetest.get_node(pointed_thing.under) - 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(pointed_thing.under, node, placer, itemstack) or itemstack - end - end - - return minetest.item_place(itemstack, placer, pointed_thing, minetest.dir_to_facedir(vector.direction(pointed_thing.above, pointed_thing.under))) - end, - - on_construct = function(pos) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - inv:set_size("main", 1) - end, - - on_rightclick = function(pos, node, clicker, itemstack) - if not itemstack then - return - end - local pname = clicker:get_player_name() - if minetest.is_protected(pos, pname) then - minetest.record_protection_violation(pos, pname) - return - end - local meta = minetest.get_meta(pos) - - if node.name == "mcl_itemframes:item_frame" or node.name == "mcl_itemframes:glow_item_frame" then - drop_item(pos, node, meta, clicker) - else - mcl_itemframes.drop_generic_item(pos, node, meta, clicker) - end - - local inv = meta:get_inventory() - if itemstack:is_empty() then - remove_item_entity(pos, node) - meta:set_string("infotext", "") - inv:set_stack("main", 1, "") - return itemstack - end - local put_itemstack = ItemStack(itemstack) - put_itemstack:set_count(1) - local itemname = put_itemstack:get_name() - if minetest.get_item_group(itemname, "compass") > 0 then - put_itemstack:set_name(mcl_compass.get_compass_itemname(pos, minetest.dir_to_yaw(minetest.facedir_to_dir(node.param2)), put_itemstack)) - end - if minetest.get_item_group(itemname, "clock") > 0 then - minetest.get_node_timer(pos):start(1.0) - end - - inv:set_stack("main", 1, put_itemstack) - if node.name == "mcl_itemframes:item_frame" or node.name == "mcl_itemframes:glow_item_frame" then - mcl_itemframes.update_item_entity(pos, node) - else - mcl_itemframes.update_generic_item_entity(pos, node) - end - - -- Add node infotext when item has been named - local imeta = itemstack:get_meta() - local iname = imeta:get_string("name") - if iname then - meta:set_string("infotext", iname) - end - - if not minetest.is_creative_enabled(clicker:get_player_name()) then - itemstack:take_item() - end - return itemstack - end, - - allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - local name = player:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return 0 - else - return count - end - end, - - allow_metadata_inventory_take = function(pos, listname, index, stack, player) - local name = player:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return 0 - else - return stack:get_count() - end - end, - - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local name = player:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return 0 - else - return stack:get_count() - end - end, - - on_destruct = function(pos) - local meta = minetest.get_meta(pos) - local node = minetest.get_node(pos) - - if node.name == "mcl_itemframes:item_frame" or node.name == "mcl_itemframes:glow_item_frame" then - drop_item(pos, node, meta) -- originally had ", clicker" too. Except, clicker doesn't exist in the context. - else - mcl_itemframes.drop_generic_item(pos, node, meta) - end - end, - - on_rotate = function(pos, node, user, mode, param2) - --local meta = minetest.get_meta(pos) - local node = minetest.get_node(pos) - - local objs = nil - local name_found = false - local found_name_to_use = "" - name_found = false - found_name_to_use = "" - - for k, v in pairs(mcl_itemframes.frames_registered.glowing) do - if node.name == v then - name_found = true - found_name_to_use = v - break - end - end - - -- try to cut down on excess looping, if possible. - if name_found == false then - for k, v in pairs(mcl_itemframes.frames_registered.standard) do - if node.name == v then - name_found = true - found_name_to_use = v - break - end - end - end - - if node.name == found_name_to_use then - objs = minetest.get_objects_inside_radius(pos, 0.5) - else - return -- short circuit if it's somehow not the right thing. - end - - if objs then - if mode == screwdriver.ROTATE_FACE or mode == screwdriver.ROTATE_AXIS then - for _, obj in ipairs(objs) do - if obj and obj:get_luaentity() then - local obj_name = obj:get_luaentity().name - if obj_name == "mcl_itemframes:item" or obj_name == "mcl_itemframes:glow_item" then - if mode == screwdriver.ROTATE_AXIS then - update_roll(obj, pos) - end - break - elseif obj_name == found_name_to_use .. "_item" then - if mode == screwdriver.ROTATE_AXIS then - update_roll(obj, pos) - end - break - end - end - end - return false - end - end - end, -} - ---- reworked to set up the base item definitions, and to register them for item and glow_item. +--- reworked to set up the base item definitions. function mcl_itemframes.create_base_item_entity() - if 1 == 1 then + if mcl_itemframes.DEBUG then minetest.log("action", "[mcl_itemframes] create_item_entity.") end @@ -703,7 +416,7 @@ function mcl_itemframes.create_base_item_entity() textures = { "blank.png" }, }, on_activate = function(self, staticdata) - if 1 == 1 then + if mcl_itemframes.DEBUG then minetest.log("action", "[mcl_itemframes] map_item:on_activate.") end update_map_texture(self, staticdata) @@ -714,40 +427,26 @@ function mcl_itemframes.create_base_item_entity() end, } - local glow_frame_item = table.copy(frame_item_base) - glow_frame_item.glow = glow_amount - local glow_frame_map_item = table.copy(map_item_base) - glow_frame_map_item.name = "mcl_itemframes:glow_map" - - minetest.register_entity("mcl_itemframes:glow_item", glow_frame_item) - minetest.register_entity("mcl_itemframes:glow_map", glow_frame_map_item) - minetest.register_entity("mcl_itemframes:item", frame_item_base) - minetest.register_entity("mcl_itemframes:map", map_item_base) - end function mcl_itemframes.create_custom_items(name, has_glow) - + local custom_frame_item = table.copy(frame_item_base) + local custom_frame_map_item = table.copy(map_item_base) if has_glow then - local glow_frame_item = table.copy(frame_item_base) - local glow_frame_map_item = table.copy(map_item_base) - glow_frame_map_item.glow = glow_amount - glow_frame_item.glow = glow_amount - - minetest.register_entity(name .. "_item", glow_frame_item) - minetest.register_entity(name .. "_map", glow_frame_map_item) - if 1 == 1 then + custom_frame_map_item.glow = glow_amount + custom_frame_item.glow = glow_amount + if mcl_itemframes.DEBUG then minetest.log("action", "\n[mcl_itemframes] create_custom_item_entity: glow name: " .. name .. "_item") minetest.log("action", "[mcl_itemframes] create_custom_item_entity: glow name: " .. name .. "_map\n") end else - minetest.register_entity(name .. "_item", frame_item_base) - minetest.register_entity(name .. "_map", map_item_base) - if 1 == 1 then + if mcl_itemframes.DEBUG then minetest.log("action", "\n[mcl_itemframes] create_custom_item_entity: name: " .. name .. "_item") minetest.log("action", "[mcl_itemframes] create_custom_item_entity: name: " .. name .. "_map\n") end end + minetest.register_entity(name .. "_item", custom_frame_item) + minetest.register_entity(name .. "_map", custom_frame_map_item) end function mcl_itemframes.update_frame_registry(modname, name, has_glow) @@ -786,6 +485,11 @@ function mcl_itemframes.create_custom_frame(modname, name, has_glow, tiles, colo name = "" end + if name == "" then + minetest.log("error", "attempted to create an item frame WITHOUT a name!") + return + end + if has_glow == nil or has_glow == "" then has_glow = false end @@ -797,7 +501,7 @@ function mcl_itemframes.create_custom_frame(modname, name, has_glow, tiles, colo local working_name = "mcl_itemframes:" .. name - if 1 == 1 then + if mcl_itemframes.DEBUG then minetest.log("action", "[mcl_itemframes] create_custom_frame: " .. working_name) minetest.log("action", "[mcl_itemframes] create_custom_frame - calling create_custom_items " .. working_name) end @@ -824,8 +528,7 @@ function mcl_itemframes.create_custom_frame(modname, name, has_glow, tiles, colo end --- the local version is for the base glow & base frame. -local function create_register_lbm(name) +function mcl_itemframes.custom_register_lbm(name) -- FIXME: Item entities can get destroyed by /clearobjects -- glow frame @@ -840,46 +543,274 @@ local function create_register_lbm(name) }) end -function mcl_itemframes.custom_register_lbm(name) - -- FIXME: Item entities can get destroyed by /clearobjects - -- glow frame - minetest.register_lbm({ - label = "Respawn item frame item entities", - name = "mcl_itemframes:respawn_entities", - nodenames = { name }, - run_at_every_load = true, - action = function(pos, node) - mcl_itemframes.update_generic_item_entity(pos, node) - end, - }) - -end - -function mcl_itemframes.create_base_frames() - if 1 == 1 then - minetest.log("action", "[mcl_itemframes] create_frames.") +function mcl_itemframes.create_base_definitions() + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] create_base_definitions.") end + -- set up the facedir information. + facedir[0] = { x = 0, y = 0, z = 1 } + facedir[1] = { x = 1, y = 0, z = 0 } + facedir[2] = { x = 0, y = 0, z = -1 } + facedir[3] = { x = -1, y = 0, z = 0 } + + mcl_itemframes.item_frame_base = { + description = S("Item Frame"), + _tt_help = S("Can hold an item"), + _doc_items_longdesc = S("Item frames are decorative blocks in which items can be placed."), + _doc_items_usagehelp = S("Just place any item on the item frame. Use the item frame again to retrieve the item."), + drawtype = "mesh", + is_ground_content = false, + mesh = "mcl_itemframes_itemframe1facedir.obj", + selection_box = { type = "fixed", fixed = { -6 / 16, -6 / 16, 7 / 16, 6 / 16, 6 / 16, 0.5 } }, + collision_box = { type = "fixed", fixed = { -6 / 16, -6 / 16, 7 / 16, 6 / 16, 6 / 16, 0.5 } }, + tiles = { "mcl_itemframes_item_frame_back.png", "mcl_itemframes_item_frame_back.png", "mcl_itemframes_item_frame_back.png", "mcl_itemframes_item_frame_back.png", "default_wood.png", "mcl_itemframes_item_frame_back.png" }, + inventory_image = "mcl_itemframes_item_frame.png", + wield_image = "mcl_itemframes_item_frame.png", + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + groups = { dig_immediate = 3, deco_block = 1, dig_by_piston = 1, container = 7, attached_node_facedir = 1 }, + sounds = mcl_sounds.node_sound_defaults(), + node_placement_prediction = "", + + on_timer = function(pos) + local inv = minetest.get_meta(pos):get_inventory() + local stack = inv:get_stack("main", 1) + local itemname = stack:get_name() + if minetest.get_item_group(itemname, "clock") > 0 then + local new_name = "mcl_clock:clock_" .. (mcl_worlds.clock_works(pos) and mcl_clock.old_time or mcl_clock.random_frame) + if itemname ~= new_name then + stack:set_name(new_name) + inv:set_stack("main", 1, stack) + local node = minetest.get_node(pos) + mcl_itemframes.update_item_entity(pos, node, node.param2) + + end + minetest.get_node_timer(pos):start(1.0) + end + end, + + on_place = function(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + + -- Use pointed node's on_rightclick function first, if present + local node = minetest.get_node(pointed_thing.under) + 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(pointed_thing.under, node, placer, itemstack) or itemstack + end + end + + return minetest.item_place(itemstack, placer, pointed_thing, minetest.dir_to_facedir(vector.direction(pointed_thing.above, pointed_thing.under))) + end, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size("main", 1) + end, + + on_rightclick = function(pos, node, clicker, itemstack) + if not itemstack then + return + end + local pname = clicker:get_player_name() + if minetest.is_protected(pos, pname) then + minetest.record_protection_violation(pos, pname) + return + end + local meta = minetest.get_meta(pos) + mcl_itemframes.drop_generic_item(pos, node, meta, clicker) + + local inv = meta:get_inventory() + if itemstack:is_empty() then + remove_item_entity(pos, node) + meta:set_string("infotext", "") + inv:set_stack("main", 1, "") + return itemstack + end + local put_itemstack = ItemStack(itemstack) + put_itemstack:set_count(1) + local itemname = put_itemstack:get_name() + if minetest.get_item_group(itemname, "compass") > 0 then + put_itemstack:set_name(mcl_compass.get_compass_itemname(pos, minetest.dir_to_yaw(minetest.facedir_to_dir(node.param2)), put_itemstack)) + end + if minetest.get_item_group(itemname, "clock") > 0 then + minetest.get_node_timer(pos):start(1.0) + end + + inv:set_stack("main", 1, put_itemstack) + mcl_itemframes.update_item_entity(pos, node) + + -- Add node infotext when item has been named + local imeta = itemstack:get_meta() + local iname = imeta:get_string("name") + if iname then + meta:set_string("infotext", iname) + end + + if not minetest.is_creative_enabled(clicker:get_player_name()) then + itemstack:take_item() + end + return itemstack + end, + + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + else + return count + end + end, + + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + else + return stack:get_count() + end + end, + + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + else + return stack:get_count() + end + end, + + on_destruct = function(pos) + local meta = minetest.get_meta(pos) + local node = minetest.get_node(pos) + + mcl_itemframes.drop_generic_item(pos, node, meta) + + end, + + on_rotate = function(pos, node, user, mode, param2) + --local meta = minetest.get_meta(pos) + local node = minetest.get_node(pos) + + local objs = nil + local name_found = false + local found_name_to_use = "" + name_found = false + found_name_to_use = "" + + for k, v in pairs(mcl_itemframes.frames_registered.glowing) do + if node.name == v then + name_found = true + found_name_to_use = v + break + end + end + + -- try to cut down on excess looping, if possible. + if name_found == false then + for k, v in pairs(mcl_itemframes.frames_registered.standard) do + if node.name == v then + name_found = true + found_name_to_use = v + break + end + end + end + + if node.name == found_name_to_use then + objs = minetest.get_objects_inside_radius(pos, 0.5) + else + return -- short circuit if it's somehow not the right thing. + end + + if objs then + if mode == screwdriver.ROTATE_FACE or mode == screwdriver.ROTATE_AXIS then + for _, obj in ipairs(objs) do + if obj and obj:get_luaentity() then + local obj_name = obj:get_luaentity().name + if obj_name == found_name_to_use .. "_item" then + if mode == screwdriver.ROTATE_AXIS then + update_roll(obj, pos) + end + break + end + end + end + return false + end + end + end, + } + -- make the base items for the base frames. mcl_itemframes.create_base_item_entity() - minetest.register_node("mcl_itemframes:item_frame", mcl_itemframes.item_frame_base) + -- minetest.register_node("mcl_itemframes:item_frame", mcl_itemframes.item_frame_base) -- make glow frame from the base item_frame. mcl_itemframes.glow_frame_base = table.copy(mcl_itemframes.item_frame_base) - mcl_itemframes.glow_frame_base.description = S("Glow Item Frame") - mcl_itemframes.glow_frame_base._tt_help = S("Can hold an item and glows") - mcl_itemframes.glow_frame_base.longdesc = S("Glow item frames are decorative blocks in which items can be placed.") + mcl_itemframes.glow_frame_base.description = S("Glowing Item Frame") + mcl_itemframes.glow_frame_base._tt_help = S("Can hold an item and glows.") + mcl_itemframes.glow_frame_base.longdesc = S("Glowing item frames are decorative blocks in which items can be placed and made to glow.") mcl_itemframes.glow_frame_base.tiles = { "mcl_itemframes_glow_item_frame.png" } mcl_itemframes.glow_frame_base.inventory_image = "mcl_itemframes_glow_item_frame_item.png" mcl_itemframes.glow_frame_base.wield_image = "mcl_itemframes_glow_item_frame.png" mcl_itemframes.glow_frame_base.mesh = "mcl_itemframes_glow_item_frame.obj" + --[[ minetest.register_node("mcl_itemframes:glow_item_frame", mcl_itemframes.glow_frame_base) mcl_itemframes.update_frame_registry("false", "mcl_itemframes:item_frame", false) mcl_itemframes.update_frame_registry("false", "mcl_itemframes:glow_item_frame", true) create_register_lbm("mcl_itemframes:item_frame") create_register_lbm("mcl_itemframes:glow_item_frame") + --]] +end + +-- for compatibility: +function mcl_itemframes.backwards_compatibility () + minetest.register_lbm({ + label = "Update legacy item frames", + name = "mcl_itemframes:update_legacy_item_frames", + nodenames = { "itemframes:frame" }, + action = function(pos, node) + -- Swap legacy node, then respawn entity + node.name = "mcl_itemframes:item_frame" + local meta = minetest.get_meta(pos) + local item = meta:get_string("item") + minetest.swap_node(pos, node) + if item ~= "" then + local itemstack = ItemStack(minetest.deserialize(meta:get_string("itemdata"))) + local inv = meta:get_inventory() + inv:set_size("main", 1) + if not itemstack:is_empty() then + inv:set_stack("main", 1, itemstack) + end + end + mcl_itemframes.update_item_entity(pos, node) + end, + }) + minetest.register_alias("itemframes:frame", "mcl_itemframes:item_frame") + + -- To be installed when complete; adds backwards compatibility + minetest.register_alias("mcl_itemframes:item", "mcl_itemframes:item_frame_item") + minetest.register_alias("mcl_itemframes:map", "mcl_itemframes:item_frame_map") + minetest.register_alias("mcl_itemframes:glow_item", "mcl_itemframes:glow_item_frame_item") + minetest.register_alias("mcl_itemframes:glow_map", "mcl_itemframes:glow_item_frame_map") + + minetest.register_entity("mcl_itemframes:item", frame_item_base) + minetest.register_entity("mcl_itemframes:map", map_item_base) + minetest.register_entity("mcl_itemframes:glow_item", frame_item_base) + minetest.register_entity("mcl_itemframes:glow_map", map_item_base) + end