123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646 |
- screwdriver = screwdriver or {}
- local tmp = {}
- local should_return_item = minetest.settings:get_bool("itemframes.return_item", false)
- local log_actions = minetest.settings:get_bool("itemframes.log_actions", false)
- -- item entity
- minetest.register_entity("itemframes:item", {
- hp_max = 1,
- visual = "wielditem",
- visual_size = {x = 0.33, y = 0.33},
- collisionbox = {0, 0, 0, 0, 0, 0},
- physical = false,
- textures = {"air"},
- static_save = false,
- on_activate = function(self, staticdata)
- if tmp.nodename and tmp.texture then
- self.nodename = tmp.nodename ; tmp.nodename = nil
- self.texture = tmp.texture ; tmp.texture = nil
- self.glow = tmp.glow ; tmp.glow = nil
- else
- 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]
- self.glow = data[3]
- end
- end
- end
- if self.texture then
- self.object:set_properties({textures = {self.texture}})
- end
- if self.nodename == "itemframes:pedestal" then
- self.object:set_properties({automatic_rotate = 1})
- end
- if self.glow then
- self.object:set_properties({glow = self.glow})
- end
- end,
- get_staticdata = function(self)
- if self.nodename and self.texture then
- return self.nodename .. ";" .. self.texture .. ";" .. (self.glow or "")
- end
- return ""
- end,
- on_blast = function(self, damage)
- return false, false, {}
- end
- })
- -- helper table
- local facedir = {
- [0] = {x = 0, y = 0, z = 1},
- [12] = {x = 0, y = 0, z = 1},
- [16] = {x = 0, y = 0, z = 1},
- [20] = {x = 0, y = 0, z = 1},
- [1] = {x = 1, y = 0, z = 0},
- [5] = {x = 1, y = 0, z = 0},
- [9] = {x = 1, y = 0, z = 0},
- [23] = {x = 1, y = 0, z = 0},
- [2] = {x = 0, y = 0, z = -1},
- [14] = {x = 0, y = 0, z = -1},
- [18] = {x = 0, y = 0, z = -1},
- [22] = {x = 0, y = 0, z = -1},
- [3] = {x = -1, y = 0, z = 0},
- [7] = {x = -1, y = 0, z = 0},
- [11] = {x = -1, y = 0, z = 0},
- [21] = {x = -1, y = 0, z = 0},
- [4] = -0.4, -- flat frames
- [10] = -0.4,
- [13] = -0.4,
- [19] = -0.4,
- [8] = 0.4, -- upside down flat frames
- [6] = 0.4,
- [15] = 0.4,
- [17] = 0.4
- }
- -- remove entities
- local remove_item = function(pos, ntype)
- local ypos = 0
- if ntype == "pedestal" then
- ypos = 1
- end
- local objs = minetest.get_objects_inside_radius({
- x = pos.x, y = pos.y + ypos, z = pos.z}, 0.5)
- if objs then
- for _, obj in pairs(objs) do
- if obj and obj:get_luaentity()
- and obj:get_luaentity().name == "itemframes:item" then
- obj:remove()
- end
- end
- end
- end
- -- update entity
- local update_item = function(pos, ntype, node)
- remove_item(pos, ntype)
- local meta = minetest.get_meta(pos)
- if not meta then return end
- local item = meta:get_string("item")
- if item == "" then return end
- local pitch = 0
- local p2 = node.param2
- if ntype == "frame" then
- local posad = facedir[p2]
- if not posad then return end
- if type(posad) == "table" then
- 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
- else
- pitch = 4.7
- pos.y = pos.y + posad
- end
- elseif ntype == "pedestal" then
- pos.y = pos.y + 12 / 16 + 0.33
- end
- tmp.nodename = node.name
- tmp.texture = ItemStack(item):get_name()
- local def = core.registered_items[item]
- tmp.glow = def and def.light_source
- local e = minetest.add_entity(pos, "itemframes:item")
- if ntype == "frame" then
- --local yaw = math.pi * 2 - node.param2 * math.pi / 2
- local yaw = 6.28 - p2 * 1.57
- e:set_rotation({
- x = pitch, -- pitch
- y = yaw, -- yaw
- z = 0 -- roll
- })
- end
- end
- -- remove entity and drop as item
- local drop_item = function(pos, ntype, metadata)
- local meta = metadata or minetest.get_meta(pos)
- if not meta then return end
- local item = meta:get_string("item")
- meta:set_string("item", "")
- if item ~= "" then
- remove_item(pos, ntype)
- if ntype == "pedestal" then
- pos.y = pos.y + 1
- end
- minetest.add_item(pos, item)
- end
- end
- -- return item to a player's inventory
- local return_item = function(pos, ntype, metadata, clicker, itemstack)
- local meta = metadata or minetest.get_meta(pos)
- if not meta then return end
- local item = meta:get_string("item")
- if item == "" then return end
- local remaining = itemstack:add_item(item)
- if remaining:is_empty() then
- meta:set_string("item", "")
- remove_item(pos, ntype)
- return itemstack
- end
- local inv = clicker:get_inventory()
- if not inv then
- drop_item(pos, ntype, metadata)
- return
- end
- remaining = inv:add_item("main", remaining)
- if remaining:is_empty() then
- meta:set_string("item", "")
- remove_item(pos, ntype)
- else
- drop_item(pos, ntype, metadata)
- end
- end
- -- on_place helper function
- local frame_place = function(itemstack, placer, pointed_thing)
- if pointed_thing.type ~= "node" then return end
- local above = pointed_thing.above
- local under = pointed_thing.under
- local dir = {
- x = under.x - above.x,
- y = under.y - above.y,
- z = under.z - above.z
- }
- local wdir = minetest.dir_to_wallmounted(dir)
- local placer_pos = placer:get_pos()
- if placer_pos then
- dir = {
- x = above.x - placer_pos.x,
- y = above.y - placer_pos.y,
- z = above.z - placer_pos.z
- }
- end
- local fdir = minetest.dir_to_facedir(dir)
- local p2 = fdir
- if wdir == 0 then
- p2 = 8
- elseif wdir == 1 then
- p2 = 4
- end
- return minetest.item_place(itemstack, placer, pointed_thing, p2)
- end
- -- action logging helper
- local function show_msg(message)
- if log_actions then
- minetest.log("action", message)
- end
- end
- -- itemframe node and recipe
- minetest.register_node("itemframes:frame",{
- description = "Item frame",
- drawtype = "nodebox",
- node_box = {
- type = "fixed",
- fixed = {-0.5, -0.5, 7/16, 0.5, 0.5, 0.5}
- },
- selection_box = {
- type = "fixed",
- fixed = {-0.5, -0.5, 7/16, 0.5, 0.5, 0.5}
- },
- tiles = {"itemframes_frame.png"},
- inventory_image = "itemframes_frame.png",
- wield_image = "itemframes_frame.png",
- paramtype = "light",
- paramtype2 = "facedir",
- sunlight_propagates = true,
- groups = {choppy = 2, dig_immediate = 2, flammable = 2},
- sounds = default.node_sound_defaults(),
- on_place = frame_place,
- after_place_node = function(pos, placer, itemstack)
- local meta = minetest.get_meta(pos)
- meta:set_string("infotext","Item frame (right-click to add or remove item)")
- end,
- on_rightclick = function(pos, node, clicker, itemstack)
- if not itemstack
- or minetest.is_protected(pos, clicker:get_player_name()) then
- return
- end
- local meta = minetest.get_meta(pos)
- if not meta then return end
- if meta:get_string("item") ~= "" then
- show_msg(clicker:get_player_name()
- .. " removed " .. meta:get_string("item")
- .. " from Itemframe at " .. minetest.pos_to_string(pos))
- if should_return_item then
- return return_item(pos, "frame", meta, clicker, itemstack)
- else
- drop_item(pos, "frame", meta)
- end
- else
- local s = itemstack:take_item()
- meta:set_string("item", s:to_string())
- update_item(pos, "frame", node)
- show_msg(clicker:get_player_name()
- .. " inserted " .. meta:get_string("item")
- .. " into Itemframe at " .. minetest.pos_to_string(pos))
- return itemstack
- end
- end,
- on_destruct = function(pos)
- drop_item(pos, "frame")
- end,
- on_punch = function(pos, node, puncher)
- update_item(pos, "frame", node)
- end,
- on_blast = function(pos, intensity)
- drop_item(pos, "frame")
- minetest.add_item(pos, {name = "itemframes:frame"})
- minetest.remove_node(pos)
- end,
- on_burn = function(pos)
- drop_item(pos, "frame")
- minetest.remove_node(pos)
- end
- })
- minetest.register_craft({
- output = "itemframes:frame",
- recipe = {
- {"default:stick", "default:stick", "default:stick"},
- {"default:stick", "default:paper", "default:stick"},
- {"default:stick", "default:stick", "default:stick"}
- }
- })
- -- invisible itemframe node and recipe
- minetest.register_node("itemframes:frame_invis",{
- description = "Invisible Item frame",
- drawtype = "nodebox",
- node_box = {
- type = "fixed",
- fixed = {-0.5, -0.5, 7/16, 0.5, 0.5, 0.5}
- },
- selection_box = {
- type = "fixed",
- fixed = {-0.5, -0.5, 7/16, 0.5, 0.5, 0.5}
- },
- tiles = {"itemframes_clear.png"},
- inventory_image = "itemframes_frame_invis.png",
- wield_image = "itemframes_frame_invis.png",
- paramtype = "light",
- paramtype2 = "facedir",
- sunlight_propagates = true,
- use_texture_alpha = "clip",
- groups = {choppy = 2, dig_immediate = 2, flammable = 2},
- sounds = default.node_sound_defaults(),
- on_place = frame_place,
- after_place_node = function(pos, placer, itemstack)
- local meta = minetest.get_meta(pos)
- meta:set_string("infotext","Item frame (right-click to add or remove item)")
- end,
- on_rightclick = function(pos, node, clicker, itemstack)
- if not itemstack
- or minetest.is_protected(pos, clicker:get_player_name()) then
- return
- end
- local meta = minetest.get_meta(pos)
- if not meta then return end
- if meta:get_string("item") ~= "" then
- show_msg(clicker:get_player_name()
- .. " removed " .. meta:get_string("item")
- .. " from Itemframe at " .. minetest.pos_to_string(pos))
- if should_return_item then
- return return_item(pos, "frame", meta, clicker, itemstack)
- else
- drop_item(pos, "frame", meta)
- end
- else
- local s = itemstack:take_item()
- meta:set_string("item", s:to_string())
- update_item(pos, "frame", node)
- show_msg(clicker:get_player_name()
- .. " inserted " .. meta:get_string("item")
- .. " into Itemframe at " .. minetest.pos_to_string(pos))
- return itemstack
- end
- end,
- on_destruct = function(pos)
- drop_item(pos, "frame")
- end,
- on_punch = function(pos, node, puncher)
- update_item(pos, "frame", node)
- end,
- on_blast = function(pos, intensity)
- drop_item(pos, "frame")
- minetest.add_item(pos, {name = "itemframes:frame_invis"})
- minetest.remove_node(pos)
- end,
- on_burn = function(pos)
- drop_item(pos, "frame")
- minetest.remove_node(pos)
- end
- })
- minetest.register_craft({
- output = "itemframes:frame_invis",
- recipe = {
- {"default:glass", "default:glass", "default:glass"},
- {"default:glass", "default:paper", "default:glass"},
- {"default:glass", "default:glass", "default:glass"}
- }
- })
- -- pedestal node and recipe
- minetest.register_node("itemframes:pedestal",{
- description = "Pedestal",
- drawtype = "nodebox",
- node_box = {
- type = "fixed", fixed = {
- {-7/16, -8/16, -7/16, 7/16, -7/16, 7/16}, -- bottom plate
- {-6/16, -7/16, -6/16, 6/16, -6/16, 6/16}, -- bottom plate (upper)
- {-0.25, -6/16, -0.25, 0.25, 11/16, 0.25}, -- pillar
- {-7/16, 11/16, -7/16, 7/16, 12/16, 7/16}, -- top plate
- }
- },
- selection_box = {
- type = "fixed",
- fixed = {-7/16, -0.5, -7/16, 7/16, 12/16, 7/16}
- },
- tiles = {"itemframes_pedestal_top.png","itemframes_pedestal_btm.png","itemframes_pedestal.png"},
- paramtype = "light",
- groups = {cracky = 3},
- sounds = default.node_sound_defaults(),
- on_rotate = screwdriver.disallow,
- after_place_node = function(pos, placer, itemstack)
- local meta = minetest.get_meta(pos)
- meta:set_string("infotext","Pedestal (right-click to add or remove item)")
- end,
- on_rightclick = function(pos, node, clicker, itemstack)
- if not itemstack
- or minetest.is_protected(pos, clicker:get_player_name()) then
- return
- end
- local meta = minetest.get_meta(pos)
- if not meta then return end
- if meta:get_string("item") ~= "" then
- show_msg(clicker:get_player_name()
- .. " removed " .. meta:get_string("item")
- .. " from Pedestal at " .. minetest.pos_to_string(pos))
- if should_return_item then
- return return_item(pos, "pedestal", meta, clicker, itemstack)
- else
- drop_item(pos, "pedestal", meta)
- end
- else
- local s = itemstack:take_item()
- meta:set_string("item", s:to_string())
- update_item(pos, "pedestal", node)
- show_msg(clicker:get_player_name()
- .. " inserted " .. meta:get_string("item")
- .. " into Pedestal at " .. minetest.pos_to_string(pos))
- return itemstack
- end
- end,
- on_destruct = function(pos)
- drop_item(pos, "pedestal")
- end,
- on_punch = function(pos, node, puncher)
- update_item(pos, "pedestal", node)
- end,
- on_blast = function(pos, intensity)
- drop_item(pos, "pedestal")
- minetest.add_item(pos, {name = "itemframes:pedestal"})
- minetest.remove_node(pos)
- end
- })
- minetest.register_craft({
- output = "itemframes:pedestal",
- recipe = {
- {"default:stone", "default:stone", "default:stone"},
- {"", "default:stone", ""},
- {"default:stone", "default:stone", "default:stone"}
- }
- })
- -- automatically restore entities lost from frames/pedestals
- -- due to /clearobjects or similar
- minetest.register_lbm({
- label = "Restore itemframe entities",
- name = "itemframes:restore_entities",
- nodenames = {"itemframes:frame", "itemframes:pedestal", "itemframes:frame_invis"},
- run_at_every_load = true,
- action = function(pos, node)
- local ypos = 0
- local ntype = "frame"
- if node.name == "itemframes:pedestal" then
- ypos = 1
- ntype = "pedestal"
- end
- pos.y = pos.y + ypos
- local objs = minetest.get_objects_inside_radius(pos, 0.5)
- for _, obj in ipairs(objs) do
- local e = obj:get_luaentity()
- if e and e.name == "itemframes:item" then
- return
- end
- end
- pos.y = pos.y - ypos
- update_item(pos, ntype, node)
- end
- })
- -- stop mesecon pistons from pushing itemframe and pedestals
- if minetest.get_modpath("mesecons_mvps") then
- mesecon.register_mvps_stopper("itemframes:frame")
- mesecon.register_mvps_stopper("itemframes:frame_invis")
- mesecon.register_mvps_stopper("itemframes:pedestal")
- end
- print("[MOD] Itemframes loaded")
|