diff --git a/mods/ITEMS/mcl_itemframes/README.txt b/mods/ITEMS/mcl_itemframes/README.txt index d9514a03b..c2756a1c9 100644 --- a/mods/ITEMS/mcl_itemframes/README.txt +++ b/mods/ITEMS/mcl_itemframes/README.txt @@ -1,4 +1,13 @@ -This mod is originally by Zeg9, but heavily modified for MineClone 2. +This mod has been rewritten and revamped by Michieal / Faerraven. Based on the code originally done by Zeg9, and then +heavily modified by the Mineclone 2 dev team. + +This mod now supports all the base item frame functions, like rotating the displayed item, which it didn't do before it +was rewritten. Additionally, Glow Frames have been added in, and item frames now has an API to allow new item frames to +be created in other modules. +Now requires the Screwdriver to have full functionality. + +The code is licenced under the standard MineClone 2 license for usage, with the requirement that this readme is +included in the code / module. Model created by 22i, licensed under the GNU GPLv3 . diff --git a/mods/ITEMS/mcl_itemframes/init.lua b/mods/ITEMS/mcl_itemframes/init.lua index 6fda0176e..e0c41c1f4 100644 --- a/mods/ITEMS/mcl_itemframes/init.lua +++ b/mods/ITEMS/mcl_itemframes/init.lua @@ -1,348 +1,62 @@ -mcl_itemframes = {} +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) + local S = minetest.get_translator(minetest.get_current_modname()) -local VISUAL_SIZE = 0.3 +-- mcl_itemframes API +dofile(modpath .. "/item_frames_API.lua") -minetest.register_entity("mcl_itemframes:item",{ - hp_max = 1, - visual = "wielditem", - visual_size = {x=VISUAL_SIZE, y=VISUAL_SIZE}, - physical = false, - pointable = false, - textures = { "blank.png" }, - _texture = "blank.png", - _scale = 1, +-- actual api initialization. +mcl_itemframes.create_base_definitions() - on_activate = function(self, staticdata) - if staticdata and staticdata ~= "" then - local data = staticdata:split(";") - if data and data[1] and data[2] then - self._nodename = data[1] - self._texture = data[2] - if data[3] then - self._scale = data[3] - else - self._scale = 1 - end - end - end - if self._texture then - self.object:set_properties({ - textures={self._texture}, - visual_size={x=VISUAL_SIZE/self._scale, y=VISUAL_SIZE/self._scale}, - }) - end - end, - get_staticdata = function(self) - if self._nodename and self._texture then - local ret = self._nodename .. ";" .. self._texture - if self._scale then - ret = ret .. ";" .. self._scale - end - return ret - end - return "" - end, +-- necessary to maintain compatibility amongst older versions. +mcl_itemframes.backwards_compatibility() - _update_texture = function(self) - if self._texture then - self.object:set_properties({ - textures={self._texture}, - visual_size={x=VISUAL_SIZE/self._scale, y=VISUAL_SIZE/self._scale}, - }) - end - end, -}) - -minetest.register_entity("mcl_itemframes:map", { - initial_properties = { - visual = "upright_sprite", - visual_size = {x = 1, y = 1}, - pointable = false, - physical = false, - collide_with_objects = false, - textures = {"blank.png"}, - }, - on_activate = function(self, staticdata) - self.id = staticdata - mcl_maps.load_map(self.id, function(texture) - -- will not crash even if self.object is invalid by now - self.object:set_properties({textures = {texture}}) - end) - end, - get_staticdata = function(self) - return self.id - end, -}) - - -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 remove_item_entity = function(pos, node) - if node.name == "mcl_itemframes:item_frame" then - for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0.5)) do - local entity = obj:get_luaentity() - if entity and (entity.name == "mcl_itemframes:item" or entity.name == "mcl_itemframes:map") then - obj:remove() - end - end - end -end - -local update_item_entity = function(pos, node, param2) - 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" 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 = math.pi*2 - param2 * math.pi/2 - local map_id = item:get_meta():get_string("mcl_maps:id") - if map_id == "" then - local e = minetest.add_entity(pos, "mcl_itemframes:item") - local lua = e:get_luaentity() - lua._nodename = node.name - local itemname = item:get_name() - if itemname == "" or itemname == nil then - lua._texture = "blank.png" - lua._scale = 1 - else - lua._texture = itemname - local def = minetest.registered_items[itemname] - lua._scale = def and def.wield_scale and def.wield_scale.x or 1 - end - lua:_update_texture() - if node.name == "mcl_itemframes:item_frame" then - e:set_yaw(yaw) - end - else - local e = minetest.add_entity(pos, "mcl_itemframes:map", map_id) - e:set_yaw(yaw) - end - end -end -mcl_itemframes.update_item_entity = update_item_entity - -local drop_item = function(pos, node, meta, clicker) - local cname = "" - if clicker and clicker:is_player() then - cname = clicker:get_player_name() - end - if node.name == "mcl_itemframes:item_frame" and not minetest.is_creative_enabled(cname) 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 - meta:set_string("infotext", "") - remove_item_entity(pos, node) -end - -minetest.register_node("mcl_itemframes:item_frame",{ - 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_itemframe_background.png", "mcl_itemframes_itemframe_background.png", "mcl_itemframes_itemframe_background.png", "mcl_itemframes_itemframe_background.png", "default_wood.png", "mcl_itemframes_itemframe_background.png"}, - inventory_image = "mcl_itemframes_item_frame.png", - wield_image = "mcl_itemframes_item_frame.png", - 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) - 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) - drop_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) - 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) - drop_item(pos, node, meta) - end, - on_rotate = function(pos, node, user, mode, param2) - if mode == screwdriver.ROTATE_FACE then - -- Rotate face - --local meta = minetest.get_meta(pos) - local node = minetest.get_node(pos) - - local objs = nil - if node.name == "mcl_itemframes:item_frame" then - objs = minetest.get_objects_inside_radius(pos, 0.5) - end - if objs then - for _, obj in ipairs(objs) do - if obj and obj:get_luaentity() and obj:get_luaentity().name == "mcl_itemframes:item" then - update_item_entity(pos, node, (node.param2+1) % 4) - break - end - end - end - return - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - end, -}) +-- Define the standard frames. +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", recipe = { - {"mcl_core:stick", "mcl_core:stick", "mcl_core:stick"}, - {"mcl_core:stick", "mcl_mobitems:leather", "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_mobitems:leather", "mcl_core:stick" }, + { "mcl_core:stick", "mcl_core:stick", "mcl_core:stick" }, } }) -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 - update_item_entity(pos, node) - end, +minetest.register_craft({ + type = "shapeless", + output = 'mcl_itemframes:glow_item_frame', + recipe = { 'mcl_mobitems:glow_ink_sac', 'mcl_itemframes:item_frame' }, }) --- FIXME: Item entities can get destroyed by /clearobjects -minetest.register_lbm({ - label = "Respawn item frame item entities", - name = "mcl_itemframes:respawn_entities", - nodenames = {"mcl_itemframes:item_frame"}, - run_at_every_load = true, - action = function(pos, node) - update_item_entity(pos, node) - end, +--[[ 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") + +minetest.register_craft({ + output = "mcl_itemframes:my_regular_frame", + recipe = { + { "", "mcl_core:stick", "" }, + { "mcl_core:stick", "", "mcl_core:stick" }, + { "", "mcl_core:stick", "" }, + } }) -minetest.register_alias("itemframes:frame", "mcl_itemframes:item_frame") +minetest.register_craft({ + type = "shapeless", + output = "mcl_itemframes:my_glowing_frame", + recipe = { "mcl_mobitems:glow_ink_sac", "mcl_itemframes:my_regular_frame" }, +}) +--]] diff --git a/mods/ITEMS/mcl_itemframes/item_frames_API.lua b/mods/ITEMS/mcl_itemframes/item_frames_API.lua new file mode 100644 index 000000000..bd78f33e1 --- /dev/null +++ b/mods/ITEMS/mcl_itemframes/item_frames_API.lua @@ -0,0 +1,821 @@ +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by michieal. +--- DateTime: 10/26/22 1:16 AM +--- + +mcl_itemframes = {} +mcl_itemframes.item_frame_base = {} +mcl_itemframes.glow_frame_base = {} +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 pairs = pairs + +if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] API initialized.") +end + +local VISUAL_SIZE = 0.3 +local facedir = {} +local pi = math.pi + +local glow_amount = 6 -- LIGHT_MAX is 15, but the items aren't supposed to be a light source. +local frame_item_base = {} +local map_item_base = {} + +-- Time to Fleckenstein! (it just sounds cool lol) + +--- self: the object to roll. +local function update_roll(self, pos) + + -- get the entity's metadata. + local meta = minetest.get_meta(pos) + + -- using an integer, as it's the number of 45 degree turns. ie, 0 to 7 + local current_roll = meta:get_int("roll", 0) + local new_roll = current_roll + 1 + + if new_roll == 8 then + new_roll = 0 + end + meta:set_int("roll", new_roll) + + local new_roll_deg = new_roll * 45 + + -- * `get_rotation()`: returns the rotation, a vector (radians) + local rot = self:get_rotation() + local Radians = 0 + + -- Radians = Degrees * (pi / 180) degrees to radian formula + -- Radian quick chart + -- One full revolution is equal to 2π rad (or) 360°. + -- 1° = 0.017453 radians and 1 rad = 57.2958°. + -- To convert an angle from degrees to radians, we multiply it by π/180°. + -- To convert an angle from radians to degrees, we multiply it by 180°/π. + + Radians = new_roll_deg * (pi / 180) + rot.z = Radians + + self:set_rotation(rot) + +end + +--- self: the object to roll. +--- faceDeg: 0-7, inclusive. +local function set_roll(self, faceDeg) + -- get the entity's metadata. + local meta = minetest.get_meta(self:get_pos()) + + -- using an integer, as it's the number of 45 degree turns. ie, 0 to 7 + local new_roll = faceDeg + + if new_roll >= 8 then + new_roll = 7 + end + if new_roll <= 0 then + new_roll = 0 + end + + meta:set_int("roll", new_roll) + + local new_roll_deg = new_roll * 45 + + -- * `get_rotation()`: returns the rotation, a vector (radians) + local rot = self:get_rotation() + local Radians = 0 + + -- Radians = Degrees * (pi / 180) degrees to radian formula + -- Radian quick chart + -- One full revolution is equal to 2π rad (or) 360°. + -- 1° = 0.017453 radians and 1 rad = 57.2958°. + -- To convert an angle from degrees to radians, we multiply it by π/180°. + -- To convert an angle from radians to degrees, we multiply it by 180°/π. + + Radians = new_roll_deg * (pi / 180) + + rot.z = Radians + + self:set_rotation(rot) +end + +local function update_map_texture (self, staticdata) + self.id = staticdata + local result = true + result = mcl_maps.load_map(self.id, function(texture) + -- will not crash even if self.object is invalid by now + -- update... quite possibly will screw up with each version of Minetest. >.< + if not texture then + minetest.log("error", "Failed to load the map texture using mcl_maps.") + end + + self.object:set_properties({ textures = { texture } }) + end) + if result ~= nil and result == false then + mintest.log("error", "[mcl_itemframes] Error setting up Map Item.") + end + +end + +local remove_item_entity = function(pos, node) + + local name_found = false + local 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 mcl_itemframes.DEBUG then + minetest.log("action", "mcl_itemframes] remove_item_entity: " .. found_name_to_use .. "'s displayed item.") + end + + -- 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 + -- 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() + 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() + end + end + end + end +end + +mcl_itemframes.update_item_entity = function(pos, node, param2) + + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] Update_Generic_Item:\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) + + local name_found = false + local found_name_to_use = "" + local has_glow = false + + for k, v in pairs(mcl_itemframes.frames_registered.glowing) do + if node.name == v then + name_found = true + has_glow = 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 + has_glow = false + found_name_to_use = v + break + end + end + end + + if name_found == false then + minetest.log("error", "[mcl_itemframes] Update_Generic_Item:\nFailed to find registered node:\nNode name - " .. node.name) + minetest.log("error", "[mcl_itemframes] Update_Generic_Item:\nRegistry definition:" .. dump(mcl_itemframes.frames_registered)) + return + end + + if not item:is_empty() then + -- update existing items placed. + if not param2 then + param2 = node.param2 + end + local pos_adj = facedir[param2] + + if node.name == found_name_to_use then + pos.x = pos.x + pos_adj.x * 6.5 / 16 + pos.y = pos.y + pos_adj.y * 6.5 / 16 + pos.z = pos.z + pos_adj.z * 6.5 / 16 + + if mcl_itemframes.DEBUG then + minetest.log("[mcl_itemframes] Update_Generic_Item:\nFound Name in Registry: " .. found_name_to_use) + end + 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 + -- handle regular items placed into custom frame. + 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 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 + + 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 + if has_glow then + map_id_lua.glow = glow_amount + end + 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 + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] Update_Generic_Item: item's name: " .. itemname) + end + map_id_lua:_update_texture() + if node.name == found_name_to_use then + map_id_entity:set_yaw(yaw) + else + minetest.log("error", "[mcl_itemframes] Update_Generic_Item: Failed to set Display Item's yaw. " .. node.name) + end + else + -- handle map items placed into custom frame. + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] Update_Generic_Item: Placing map in a " .. found_name_to_use .. " frame.") + end + + if node.name == found_name_to_use then + map_id_entity = minetest.add_entity(pos, found_name_to_use .. "_map", map_id) + map_id_entity:set_yaw(yaw) + else + minetest.log("error", "[mcl_itemframes] Update_Generic_Item: Failed to set Map Item in " .. found_name_to_use .. "'s frame.") + end + 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 + +function mcl_itemframes.drop_generic_item(pos, node, meta, clicker) + local name_found = false + local 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 + + 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 == found_name_to_use) 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", "") + remove_item_entity(pos, node) + +end + +--- reworked to set up the base item definitions. +function mcl_itemframes.create_base_item_entity() + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] create_item_entity.") + end + + --"mcl_itemframes:item", + frame_item_base = { + hp_max = 1, + visual = "wielditem", + visual_size = { x = VISUAL_SIZE, y = VISUAL_SIZE }, + physical = false, + pointable = false, + textures = { "blank.png" }, + _texture = "blank.png", + _scale = 1, + + on_activate = function(self, staticdata) + if staticdata and staticdata ~= "" then + local data = staticdata:split(";") + if data and data[1] and data[2] then + self._nodename = data[1] + self._texture = data[2] + if data[3] then + self._scale = data[3] + else + self._scale = 1 + end + end + end + if self._texture then + self.object:set_properties({ + textures = { self._texture }, + visual_size = { x = VISUAL_SIZE / self._scale, y = VISUAL_SIZE / self._scale }, + }) + end + end, + get_staticdata = function(self) + if self._nodename and self._texture then + local ret = self._nodename .. ";" .. self._texture + if self._scale then + ret = ret .. ";" .. self._scale + end + return ret + end + return "" + end, + + _update_texture = function(self) + if self._texture then + self.object:set_properties({ + textures = { self._texture }, + visual_size = { x = VISUAL_SIZE / self._scale, y = VISUAL_SIZE / self._scale }, + }) + end + end, + } + -- "mcl_itemframes:map", + map_item_base = { + initial_properties = { + visual = "upright_sprite", + visual_size = { x = 1, y = 1 }, + pointable = false, + physical = false, + collide_with_objects = false, + textures = { "blank.png" }, + }, + on_activate = function(self, staticdata) + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] map_item:on_activate.") + end + update_map_texture(self, staticdata) + end, + + get_staticdata = function(self) + return self.id + end, + } + +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 + 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 + 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) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + + local frame = name -- should only be called within the create_frames functions. + if has_glow == true then + table.insert(mcl_itemframes.frames_registered.glowing, frame) + else + table.insert(mcl_itemframes.frames_registered.standard, frame) + end + +end + +--- name: The name used to distinguish the item frame. Prepends "mcl_itemframes:" to the name. Example usage: +--- "glow_item_frame" creates a node named ":mcl_itemframes:glow_item_frame". +function mcl_itemframes.create_custom_frame(modname, name, has_glow, tiles, color, ttframe, description, inv_wield_image) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + if name == nil then + 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 + + if tiles == nil or tiles == "" then + minetest.log("error", "No textures passed to Create_Custom_Frame!! Exiting frame creation.") + return + end + + local working_name = "mcl_itemframes:" .. name + + 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 + + -- make any special frame items. + mcl_itemframes.create_custom_items(working_name, has_glow) + + local custom_itemframe_definition = {} + + if has_glow == false then + custom_itemframe_definition = table.copy(mcl_itemframes.item_frame_base) + else + custom_itemframe_definition = table.copy(mcl_itemframes.glow_frame_base) + end + + if inv_wield_image ~= nil and inv_wield_image ~= "" then + custom_itemframe_definition.glow_frame_base.inventory_image = { "(" .. inv_wield_image .. "^[multiply:" .. color .. ")" } + custom_itemframe_definition.glow_frame_base.wield_image = { "(" .. inv_wield_image .. "^[multiply:" .. color .. ")" } + end + + custom_itemframe_definition.tiles = { "(" .. tiles .. "^[multiply:" .. color .. ")" } + custom_itemframe_definition._tt_help = ttframe + custom_itemframe_definition.description = description + + minetest.register_node(":" .. working_name, custom_itemframe_definition) + + mcl_itemframes.update_frame_registry(modname, working_name, has_glow) + mcl_itemframes.custom_register_lbm(working_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_item_entity(pos, node) + end, + }) + +end + +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) + + -- 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("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") + + -- 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 diff --git a/mods/ITEMS/mcl_itemframes/item_frames_api_doc.txt b/mods/ITEMS/mcl_itemframes/item_frames_api_doc.txt new file mode 100644 index 000000000..7510b15b5 --- /dev/null +++ b/mods/ITEMS/mcl_itemframes/item_frames_api_doc.txt @@ -0,0 +1,36 @@ +The item frames use case is a very specific one, but... in the event that there is need for a new item frame then that +is where this api will shine. + +As long as the api has been initialized (which it does in its own init.lua) then you really only need to call one +function. That function being mcl_itemframes.create_custom_frame(modname, name, has_glow, tiles, color, ttframe, +description, inv_wield_image). Note: unlike the Signs API, this API does not automatically create the recipe for you. + +Here's an explanation of create_custom_frame and an example of using it. + +This function is responsible for creating each frame, and handling the creation of its underlying entities. + +Parameters: +* modname: Used to make sure that a specific module is installed before running the code contained within. Set to "" or + false, if there's not a mod to check for. +* name: The name used to distinguish the item frame. Prepends "mcl_itemframes:" to the name. Example usage: + "glow_item_frame" creates a node named "mcl_itemframes:glow_item_frame". +* has_glow: Does the frame cause the item within to glow? true / false. +* tiles: The image files used for the item frame's object texturing. +* color: Colorizes the frame / wield / inventory image to a specific color. Use White (#FFFFFF) to ignore. +* ttframe: The tooltip to show for the frame. +* description: The frame's description. +* inv_wield_image: Optionally the image to use as the inventory and the wield image. Colorized. set to "" or nil to use + the default frame / glow frame images. Note: must be set if you want the inventory / wield image to be colored. + +example: +-- Register the Glow Frame +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 Glow Frame's recipe +minetest.register_craft({ + type = "shapeless", + output = 'mcl_itemframes:glow_item_frame', + recipe = { 'mcl_mobitems:glow_ink_sac', 'mcl_itemframes:item_frame' }, +}) diff --git a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.de.tr b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.de.tr index 07d7812f6..b9bf40e1a 100644 --- a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.de.tr +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.de.tr @@ -1,5 +1,8 @@ # textdomain: mcl_itemframes -Item Frame=Rahmen -Item frames are decorative blocks in which items can be placed.=Rahmen sind dekorative Blöcke, in denen man Gegenstände platzieren kann. -Just place any item on the item frame. Use the item frame again to retrieve the item.=Platzieren Sie einfach einen beliebigen Gegenstand in den Rahmen. Benutzen Sie den Rahmen erneut, um den Gegenstand zurück zu erhalten. -Can hold an item=Kann einen Gegenstand halten +Item Frame=Artikel Rahmen +Item frames are decorative blocks in which items can be placed.=Artikelrahmen sind dekorative Blöcke, in denen Artikel platziert werden können. +Just place any item on the item frame. Use the item frame again to retrieve the item.=Platzieren Sie einfach einen beliebigen Gegenstand auf dem Gegenstandsrahmen. Verwenden Sie den Artikelrahmen erneut, um den Artikel abzurufen. +Can hold an item.=Kann einen Gegenstand halten. +Glowing Item Frame=Leuchtender Gegenstandsrahmen +Glowing item frames are decorative blocks in which items can be placed and made to glow.=Leuchtende Gegenstandsrahmen sind dekorative Blöcke, in denen Gegenstände platziert und zum Leuchten gebracht werden können. +Can hold an item and glows.=Kann einen Gegenstand halten und leuchtet. diff --git a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.es.tr b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.es.tr index 0803234b0..d5c3aed71 100644 --- a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.es.tr +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.es.tr @@ -1,5 +1,8 @@ # textdomain: mcl_itemframes -Item Frame=Marco +Item Frame=Cuadro de artículo Item frames are decorative blocks in which items can be placed.=Los marcos de elementos son bloques decorativos en los que se pueden colocar elementos. -Just place any item on the item frame. Use the item frame again to retrieve the item.=Simplemente coloque cualquier artículo en el marco del artículo. Use el marco del artículo nuevamente para recuperar el artículo. - +Just place any item on the item frame. Use the item frame again to retrieve the item.=Simplemente coloque cualquier elemento en el marco del elemento. Use el marco del elemento nuevamente para recuperar el elemento. +Can hold an item.=Puede contener un artículo. +Glowing Item Frame=Marco de artículo brillante +Glowing item frames are decorative blocks in which items can be placed and made to glow.=Los marcos de elementos brillantes son bloques decorativos en los que se pueden colocar elementos y hacer que brillen. +Can hold an item and glows.=Puede sostener un artículo y brilla. diff --git a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.fr.tr b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.fr.tr index 180c5555f..e847779f2 100644 --- a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.fr.tr +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.fr.tr @@ -1,5 +1,8 @@ # textdomain: mcl_itemframes -Item Frame=Cadre -Item frames are decorative blocks in which items can be placed.=Les cadres sont des blocs décoratifs dans lesquels les objets peuvent être placés. -Just place any item on the item frame. Use the item frame again to retrieve the item.=Placez simplement n'importe quel objet sur le cadre. Utilisez à nouveau le cadre décoré pour récupérer l'élément. -Can hold an item=Peut contenir un objet +Item Frame=Cadre de l'article +Item frames are decorative blocks in which items can be placed.=Les cadres d'objets sont des blocs décoratifs dans lesquels des objets peuvent être placés. +Just place any item on the item frame. Use the item frame again to retrieve the item.=Placez simplement n'importe quel élément sur le cadre de l'élément. Utilisez à nouveau le cadre de l'objet pour récupérer l'objet. +Can hold an item.=Peut contenir un objet. +Glowing Item Frame=Cadre d'objet lumineux +Glowing item frames are decorative blocks in which items can be placed and made to glow.=Les cadres d'objets lumineux sont des blocs décoratifs dans lesquels des objets peuvent être placés et rendus brillants. +Can hold an item and glows.=Peut contenir un objet et brille. diff --git a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.pl.tr b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.pl.tr index 8de889471..87b83c27d 100644 --- a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.pl.tr +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.pl.tr @@ -3,3 +3,10 @@ Item Frame=Ramka na przedmiot Item frames are decorative blocks in which items can be placed.=Ramki na przedmiot to dekoracyjne bloki w których można umieszczać przedmioty. Just place any item on the item frame. Use the item frame again to retrieve the item.=Umieść dowolny przedmiot w ramce. Użyj ramki ponownie aby odzyskać przedmiot. Can hold an item=Może przetrzymywać przedmiot +Item Frame=Rama przedmiotu +Item frames are decorative blocks in which items can be placed.=Ramki na przedmioty to klocki ozdobne, w których można umieszczać przedmioty. +Just place any item on the item frame. Use the item frame again to retrieve the item.=Wystarczy umieścić dowolny przedmiot na ramie przedmiotu. Użyj ponownie ramki elementu, aby pobrać element. +Can hold an item.=Może pomieścić przedmiot. +Glowing Item Frame=Świecąca ramka na przedmiot +Glowing item frames are decorative blocks in which items can be placed and made to glow.=Świecące ramki na przedmioty to ozdobne bloki, w których można umieścić przedmioty i sprawić, by świeciły. +Can hold an item and glows.=Może trzymać przedmiot i świeci. diff --git a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ru.tr b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ru.tr index 7d3d90cc4..bf9076815 100644 --- a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ru.tr +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ru.tr @@ -3,3 +3,10 @@ Item Frame=Рамка Item frames are decorative blocks in which items can be placed.=Рамки это декоративные блоки, в которые можно помещать предметы. Just place any item on the item frame. Use the item frame again to retrieve the item.=Просто поместите в рамку любой предмет. Используйте рамку вновь, чтобы заполучить из неё предмет обратно. Can hold an item=Может хранить предмет +Item Frame=Рамка предмета +Item frames are decorative blocks in which items can be placed.=Рамки предметов — это декоративные блоки, в которые можно помещать предметы. +Just place any item on the item frame. Use the item frame again to retrieve the item.=Просто поместите любой предмет на рамку предмета. Используйте рамку предмета снова, чтобы получить предмет. +Can hold an item.=Может держать предмет. +Glowing Item Frame=Светящаяся рамка предмета +Glowing item frames are decorative blocks in which items can be placed and made to glow.=Светящиеся рамки предметов — это декоративные блоки, в которые можно помещать предметы и заставлять их светиться. +Can hold an item and glows.=Может держать предмет и светится. diff --git a/mods/ITEMS/mcl_itemframes/locale/template.txt b/mods/ITEMS/mcl_itemframes/locale/template.txt index bacbfaa69..87cd55c65 100644 --- a/mods/ITEMS/mcl_itemframes/locale/template.txt +++ b/mods/ITEMS/mcl_itemframes/locale/template.txt @@ -3,3 +3,6 @@ Item Frame= Item frames are decorative blocks in which items can be placed.= Just place any item on the item frame. Use the item frame again to retrieve the item.= Can hold an item= +Glow Item Frame= +Glow item frames are decorative blocks in which items can be placed.= +Can hold an item and glows= diff --git a/mods/ITEMS/mcl_itemframes/mod.conf b/mods/ITEMS/mcl_itemframes/mod.conf index ff09c3bcc..f9421e657 100644 --- a/mods/ITEMS/mcl_itemframes/mod.conf +++ b/mods/ITEMS/mcl_itemframes/mod.conf @@ -1,3 +1,2 @@ name = mcl_itemframes -depends = mcl_core, mcl_sounds, mcl_compass, mcl_maps -optional_depends = screwdriver +depends = mcl_core, mcl_sounds, mcl_compass, mcl_maps, screwdriver diff --git a/mods/ITEMS/mcl_itemframes/models/mcl_itemframes_glow_item_frame.obj b/mods/ITEMS/mcl_itemframes/models/mcl_itemframes_glow_item_frame.obj new file mode 100644 index 000000000..d0a5b0c5f --- /dev/null +++ b/mods/ITEMS/mcl_itemframes/models/mcl_itemframes_glow_item_frame.obj @@ -0,0 +1,156 @@ +# Blender v2.76 (sub 0) OBJ File: 'itemframe1facedir.blend' +# www.blender.org +mtllib itemframe1facedir.mtl +o right.frame_Cube.005 +v -0.313413 -0.313413 0.435326 +v -0.313413 0.313413 0.435326 +v -0.313413 -0.313413 0.498008 +v -0.313413 0.313413 0.498008 +v -0.376095 -0.313413 0.435326 +v -0.376095 0.313413 0.435326 +v -0.376095 -0.313413 0.498008 +v -0.376095 0.313413 0.498008 +vt 0.875000 0.812500 +vt 0.812500 0.812500 +vt 0.812500 0.187500 +vt 0.875000 0.187500 +vt 1.000000 0.812500 +vt 0.937500 0.812500 +vt 0.937500 0.187500 +vt 1.000000 0.187500 +vt -0.000000 0.937500 +vt 0.062500 0.937500 +vt 0.062500 1.000000 +vt -0.000000 1.000000 +vn 1.000000 0.000000 -0.000000 +vn 0.000000 0.000000 1.000000 +vn -1.000000 0.000000 0.000000 +vn -0.000000 0.000000 -1.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 1.000000 0.000000 +usemtl None +s off +f 2/1/1 4/2/1 3/3/1 1/4/1 +f 4/1/2 8/2/2 7/3/2 3/4/2 +f 8/5/3 6/6/3 5/7/3 7/8/3 +f 6/1/4 2/2/4 1/3/4 5/4/4 +f 1/9/5 3/10/5 7/11/5 5/12/5 +f 6/9/6 8/10/6 4/11/6 2/12/6 +o left.frame_Cube.004 +v 0.376095 -0.313413 0.435326 +v 0.376095 0.313413 0.435326 +v 0.376095 -0.313413 0.498008 +v 0.376095 0.313413 0.498008 +v 0.313413 -0.313413 0.435326 +v 0.313413 0.313413 0.435326 +v 0.313413 -0.313413 0.498008 +v 0.313413 0.313413 0.498008 +vt 0.875000 0.812500 +vt 0.812500 0.812500 +vt 0.812500 0.187500 +vt 0.875000 0.187500 +vt 1.000000 0.812500 +vt 0.937500 0.812500 +vt 0.937500 0.187500 +vt 1.000000 0.187500 +vt -0.000000 0.937500 +vt 0.062500 0.937500 +vt 0.062500 1.000000 +vt -0.000000 1.000000 +vn 1.000000 0.000000 -0.000000 +vn 0.000000 0.000000 1.000000 +vn -1.000000 0.000000 0.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 1.000000 0.000000 +usemtl None +s off +f 10/13/7 12/14/7 11/15/7 9/16/7 +f 12/13/8 16/14/8 15/15/8 11/16/8 +f 16/17/9 14/18/9 13/19/9 15/20/9 +f 14/13/10 10/14/10 9/15/10 13/16/10 +f 9/21/11 11/22/11 15/23/11 13/24/11 +f 14/21/12 16/22/12 12/23/12 10/24/12 +o lower.frame_Cube.003 +v 0.376095 -0.376095 0.435326 +v 0.376095 -0.313413 0.435326 +v 0.376095 -0.376095 0.498008 +v 0.376095 -0.313413 0.498008 +v -0.376095 -0.376095 0.435326 +v -0.376095 -0.313413 0.435326 +v -0.376095 -0.376095 0.498008 +v -0.376095 -0.313413 0.498008 +vt 0.187500 0.187500 +vt 0.125000 0.187500 +vt 0.125000 0.125000 +vt 0.187500 0.125000 +vt 0.875000 0.187500 +vt 0.875000 0.125000 +vt 0.812500 0.187500 +vt 0.812500 0.125000 +vt 0.875000 0.937500 +vt 0.875000 1.000000 +vt 0.125000 1.000000 +vt 0.125000 0.937500 +vn 1.000000 0.000000 0.000000 +vn 0.000000 0.000000 1.000000 +vn -1.000000 0.000000 0.000000 +vn -0.000000 0.000000 -1.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +usemtl None +s off +f 18/25/13 20/26/13 19/27/13 17/28/13 +f 20/29/14 24/26/14 23/27/14 19/30/14 +f 24/29/15 22/31/15 21/32/15 23/30/15 +f 22/29/16 18/26/16 17/27/16 21/30/16 +f 17/33/17 19/34/17 23/35/17 21/36/17 +f 22/30/18 24/29/18 20/26/18 18/27/18 +o upper.frame_Cube.002 +v 0.376095 0.313413 0.435326 +v 0.376095 0.376095 0.435326 +v 0.376095 0.313413 0.498008 +v 0.376095 0.376095 0.498008 +v -0.376095 0.313413 0.435326 +v -0.376095 0.376095 0.435326 +v -0.376095 0.313413 0.498008 +v -0.376095 0.376095 0.498008 +vt 0.187500 0.875000 +vt 0.125000 0.875000 +vt 0.125000 0.812500 +vt 0.187500 0.812500 +vt 0.875000 0.875000 +vt 0.875000 0.812500 +vt 0.812500 0.875000 +vt 0.812500 0.812500 +vt 0.875000 0.937500 +vt 0.875000 1.000000 +vt 0.125000 1.000000 +vt 0.125000 0.937500 +vn 1.000000 0.000000 0.000000 +vn 0.000000 0.000000 1.000000 +vn -1.000000 0.000000 0.000000 +vn -0.000000 0.000000 -1.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +usemtl None +s off +f 26/37/19 28/38/19 27/39/19 25/40/19 +f 28/41/20 32/38/20 31/39/20 27/42/20 +f 32/41/21 30/43/21 29/44/21 31/42/21 +f 30/41/22 26/38/22 25/39/22 29/42/22 +f 25/45/23 27/46/23 31/47/23 29/48/23 +f 30/48/24 32/38/24 28/41/24 26/45/24 +o background_Plane +v 0.313413 -0.313413 0.466667 +v -0.313413 -0.313413 0.466667 +v 0.313413 0.313413 0.466667 +v -0.313413 0.313413 0.466667 +vt 0.187500 0.187500 +vt 0.812500 0.187500 +vt 0.812500 0.812500 +vt 0.187500 0.812500 +vn -0.000000 0.000000 -1.000000 +usemtl None +s off +f 33/49/25 34/50/25 36/51/25 35/52/25 diff --git a/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_glow_item_frame.png b/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_glow_item_frame.png new file mode 100644 index 000000000..e83b4e060 Binary files /dev/null and b/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_glow_item_frame.png differ diff --git a/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_glow_item_frame_border.png b/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_glow_item_frame_border.png new file mode 100644 index 000000000..9062c679f Binary files /dev/null and b/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_glow_item_frame_border.png differ diff --git a/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_glow_item_frame_item.png b/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_glow_item_frame_item.png new file mode 100644 index 000000000..e83b4e060 Binary files /dev/null and b/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_glow_item_frame_item.png differ diff --git a/mods/ITEMS/mcl_maps/init.lua b/mods/ITEMS/mcl_maps/init.lua index 09dcd4f95..84f4019ea 100644 --- a/mods/ITEMS/mcl_maps/init.lua +++ b/mods/ITEMS/mcl_maps/init.lua @@ -62,7 +62,7 @@ function mcl_maps.create_map(pos) local emin, emax = vm:read_from_map(minp, maxp) local data = vm:get_data() local param2data = vm:get_param2_data() - local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) + local area = VoxelArea:new({ MinEdge = emin, MaxEdge = emax }) local pixels = {} local last_heightmap for x = 1, 128 do @@ -94,7 +94,7 @@ function mcl_maps.create_map(pos) end if def.palette then local palette = palettes[texture] - color = palette and {palette = palette} + color = palette and { palette = palette } else color = texture_colors[texture] end @@ -129,7 +129,7 @@ function mcl_maps.create_map(pos) end heightmap[z] = height or minp.y pixels[z] = pixels[z] or {} - pixels[z][x] = color or {0, 0, 0} + pixels[z][x] = color or { 0, 0, 0 } end last_heightmap = heightmap end @@ -141,30 +141,43 @@ end function mcl_maps.load_map(id, callback) if id == "" or creating_maps[id] then - return + return false end local texture = "mcl_maps_map_texture_" .. id .. ".tga" + local result = true + if not loaded_maps[id] then if not minetest.features.dynamic_add_media_table then -- minetest.dynamic_add_media() blocks in -- Minetest 5.3 and 5.4 until media loads loaded_maps[id] = true - dynamic_add_media(map_textures_path .. texture, function() end) - if callback then callback(texture) end + result = dynamic_add_media(map_textures_path .. texture, function() + end) + if callback then + callback(texture) + end else -- minetest.dynamic_add_media() never blocks -- in Minetest 5.5, callback runs after load - dynamic_add_media(map_textures_path .. texture, function() + result = dynamic_add_media(map_textures_path .. texture, function() loaded_maps[id] = true - if callback then callback(texture) end + if callback then + callback(texture) + end end) end end + if result == false then + return false + end + if loaded_maps[id] then - if callback then callback(texture) end + if callback then + callback(texture) + end return texture end end @@ -213,7 +226,7 @@ local filled_def = { _doc_items_usagehelp = S("Hold the map in your hand. This will display a map on your screen."), inventory_image = "mcl_maps_map_filled.png^(mcl_maps_map_filled_markings.png^[colorize:#000000)", stack_max = 64, - groups = {not_in_creative_inventory = 1, filled_map = 1, tool = 1}, + groups = { not_in_creative_inventory = 1, filled_map = 1, tool = 1 }, } minetest.register_craftitem("mcl_maps:filled_map", filled_def) @@ -221,7 +234,7 @@ minetest.register_craftitem("mcl_maps:filled_map", filled_def) local filled_wield_def = table.copy(filled_def) filled_wield_def.use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false filled_wield_def.visual_scale = 1 -filled_wield_def.wield_scale = {x = 1, y = 1, z = 1} +filled_wield_def.wield_scale = { x = 1, y = 1, z = 1 } filled_wield_def.paramtype = "light" filled_wield_def.drawtype = "mesh" filled_wield_def.node_placement_prediction = "" @@ -239,20 +252,20 @@ if mcl_skins_enabled then local female = table.copy(filled_wield_def) female._mcl_hand_id = skin.id female.mesh = "mcl_meshhand_female.b3d" - female.tiles = {skin.texture} + female.tiles = { skin.texture } minetest.register_node("mcl_maps:filled_map_" .. skin.id, female) else local male = table.copy(filled_wield_def) male._mcl_hand_id = skin.id male.mesh = "mcl_meshhand.b3d" - male.tiles = {skin.texture} + male.tiles = { skin.texture } minetest.register_node("mcl_maps:filled_map_" .. skin.id, male) end end else filled_wield_def._mcl_hand_id = "hand" filled_wield_def.mesh = "mcl_meshhand.b3d" - filled_wield_def.tiles = {"character.png"} + filled_wield_def.tiles = { "character.png" } minetest.register_node("mcl_maps:filled_map_hand", filled_wield_def) end @@ -286,7 +299,7 @@ minetest.register_craft({ minetest.register_craft({ type = "shapeless", output = "mcl_maps:filled_map 2", - recipe = {"group:filled_map", "mcl_maps:empty_map"}, + recipe = { "group:filled_map", "mcl_maps:empty_map" }, }) local function on_craft(itemstack, player, old_craft_grid, craft_inv) @@ -310,13 +323,13 @@ minetest.register_on_joinplayer(function(player) local map_def = { hud_elem_type = "image", text = "blank.png", - position = {x = 0.75, y = 0.8}, - alignment = {x = 0, y = -1}, - offset = {x = 0, y = 0}, - scale = {x = 2, y = 2}, + position = { x = 0.75, y = 0.8 }, + alignment = { x = 0, y = -1 }, + offset = { x = 0, y = 0 }, + scale = { x = 2, y = 2 }, } local marker_def = table.copy(map_def) - marker_def.alignment = {x = 0, y = 0} + marker_def.alignment = { x = 0, y = 0 } huds[player] = { map = player:hud_add(map_def), marker = player:hud_add(marker_def), @@ -376,7 +389,7 @@ minetest.register_globalstep(function(dtime) end player:hud_change(hud.marker, "text", marker) - player:hud_change(hud.marker, "offset", {x = (6 - 140 / 2 + pos.x - minp.x) * 2, y = (6 - 140 + maxp.z - pos.z) * 2}) + player:hud_change(hud.marker, "offset", { x = (6 - 140 / 2 + pos.x - minp.x) * 2, y = (6 - 140 + maxp.z - pos.z) * 2 }) elseif maps[player] then player:hud_change(hud.map, "text", "blank.png") player:hud_change(hud.marker, "text", "blank.png")