Mehr Mods hinzugefügt
689
mods/itemframes/init.lua
Normal file
|
@ -0,0 +1,689 @@
|
|||
|
||||
-- rotation and settings
|
||||
|
||||
local screwdriver = screwdriver or {}
|
||||
local tmp = {}
|
||||
local should_return_item = core.settings:get_bool("itemframes.return_item", false)
|
||||
local log_actions = core.settings:get_bool("itemframes.log_actions", false)
|
||||
local allow_rotate = core.settings:get_bool("itemframes.allow_rotate", false)
|
||||
|
||||
-- voxelibre/mineclonia support
|
||||
|
||||
local mcl = core.get_modpath("mcl_sounds")
|
||||
local a = {
|
||||
paper = mcl and "mcl_core:paper" or "default:paper",
|
||||
glass = mcl and "mcl_core:glass" or "default:glass",
|
||||
stick = "group:stick", stone = "group:stone"
|
||||
}
|
||||
|
||||
local sounds = nil
|
||||
|
||||
if core.get_modpath("default") then
|
||||
sounds = default.node_sound_defaults()
|
||||
elseif mcl then
|
||||
sounds = mcl_sounds.node_sound_defaults()
|
||||
end
|
||||
|
||||
-- translation support
|
||||
|
||||
local S = core.get_translator("itemframes")
|
||||
|
||||
-- remove entities
|
||||
|
||||
local function del_ent(pos, self)
|
||||
|
||||
local pos2 = vector.round(pos)
|
||||
local objs = core.get_objects_inside_radius(pos2, 0.5)
|
||||
|
||||
for _, obj in pairs(objs) do
|
||||
|
||||
if obj and (self and obj ~= self.object or not self) and obj:get_luaentity()
|
||||
and obj:get_luaentity().name == "itemframes:item" then
|
||||
obj:remove()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- item entity
|
||||
|
||||
core.register_entity("itemframes:item", {
|
||||
|
||||
initial_properties = {
|
||||
hp_max = 1,
|
||||
visual = "wielditem",
|
||||
visual_size = {x = 0.33, y = 0.33},
|
||||
collisionbox = {0, 0, 0, 0, 0, 0},
|
||||
physical = false,
|
||||
textures = {"air"}
|
||||
},
|
||||
|
||||
on_activate = function(self, staticdata)
|
||||
|
||||
local pos = self.object:get_pos() ; if not pos then return end
|
||||
|
||||
del_ent(pos, self)
|
||||
|
||||
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
|
||||
|
||||
local def = core.registered_items[self.texture]
|
||||
|
||||
if def and def._itemframe_texture
|
||||
and self.nodename ~= "itemframes:pedestal" then
|
||||
|
||||
self.object:set_properties({
|
||||
textures = {def._itemframe_texture},
|
||||
visual = "upright_sprite",
|
||||
visual_size = {x = 0.6, y = 0.6}
|
||||
})
|
||||
else
|
||||
self.object:set_properties({textures = {self.texture}})
|
||||
end
|
||||
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, pitch = 0, yaw = 0, roll = 0, nx = 12},
|
||||
[12] = {x = 0, y = 0, z = 1, pitch = 0, yaw = 0, roll = 3, nx = 16},
|
||||
[16] = {x = 0, y = 0, z = 1, pitch = 0, yaw = 0, roll = 1, nx = 20},
|
||||
[20] = {x = 0, y = 0, z = 1, pitch = 0, yaw = 0, roll = 2, nx = 0},
|
||||
|
||||
[1] = {x = 1, y = 0, z = 0, pitch = 0, yaw = 1, roll = 0, nx = 5},
|
||||
[5] = {x = 1, y = 0, z = 0, pitch = 0, yaw = 1, roll = 1, nx = 9},
|
||||
[9] = {x = 1, y = 0, z = 0, pitch = 0, yaw = 1, roll = 3, nx = 23},
|
||||
[23] = {x = 1, y = 0, z = 0, pitch = 0, yaw = 1, roll = 2, nx = 1},
|
||||
|
||||
[2] = {x = 0, y = 0, z = -1, pitch = 0, yaw = 2, roll = 0, nx = 14},
|
||||
[14] = {x = 0, y = 0, z = -1, pitch = 0, yaw = 2, roll = 1, nx = 18},
|
||||
[18] = {x = 0, y = 0, z = -1, pitch = 0, yaw = 2, roll = 3, nx = 22},
|
||||
[22] = {x = 0, y = 0, z = -1, pitch = 0, yaw = 2, roll = 2, nx = 2},
|
||||
|
||||
[3] = {x = -1, y = 0, z = 0, pitch = 0, yaw = 3, roll = 0, nx = 7},
|
||||
[7] = {x = -1, y = 0, z = 0, pitch = 0, yaw = 3, roll = 3, nx = 11},
|
||||
[11] = {x = -1, y = 0, z = 0, pitch = 0, yaw = 3, roll = 1, nx = 21},
|
||||
[21] = {x = -1, y = 0, z = 0, pitch = 0, yaw = 3, roll = 2, nx = 3},
|
||||
|
||||
[4] = {x = 0, y = -1, z = 0, pitch = -4.7, yaw = 0, roll = 0, nx = 10},
|
||||
[10] = {x = 0, y = -1, z = 0, pitch = -4.7, yaw = 2, roll = 0, nx = 13},
|
||||
[13] = {x = 0, y = -1, z = 0, pitch = -4.7, yaw = 1, roll = 0, nx = 19},
|
||||
[19] = {x = 0, y = -1, z = 0, pitch = -4.7, yaw = 3, roll = 0, nx = 4},
|
||||
|
||||
[8] = {x = 0, y = 1, z = 0, pitch = -4.7, yaw = 0, roll = 0, nx = 6},
|
||||
[6] = {x = 0, y = 1, z = 0, pitch = -4.7, yaw = 2, roll = 0, nx = 15},
|
||||
[15] = {x = 0, y = 1, z = 0, pitch = -4.7, yaw = 3, roll = 0, nx = 17},
|
||||
[17] = {x = 0, y = 1, z = 0, pitch = -4.7, yaw = 1, roll = 0, nx = 8},
|
||||
}
|
||||
|
||||
-- remove item
|
||||
|
||||
local function remove_item(pos, ntype)
|
||||
|
||||
local ypos = 0
|
||||
|
||||
if ntype == "pedestal" then ypos = 1 end
|
||||
|
||||
del_ent({x = pos.x, y = pos.y + ypos, z = pos.z})
|
||||
end
|
||||
|
||||
-- update entity
|
||||
|
||||
local function update_item(pos, ntype, node)
|
||||
|
||||
remove_item(pos, ntype)
|
||||
|
||||
local meta = core.get_meta(pos) ; if not meta then return end
|
||||
|
||||
local item = meta:get_string("item") ; if item == "" then return end
|
||||
|
||||
local pitch, yaw, roll = 0, 0, 0
|
||||
|
||||
if ntype == "frame" then
|
||||
|
||||
local p2 = node.param2
|
||||
local adjust = facedir[p2] ; if not adjust then return end
|
||||
|
||||
local raise = 6.5 / 16 -- itemframe default
|
||||
|
||||
if node and node.name == "itemframes:frame_invis" then
|
||||
raise = 6.5 / 14 -- stops floating effect
|
||||
end
|
||||
|
||||
pos.x = pos.x + adjust.x * raise
|
||||
pos.y = pos.y + adjust.y * raise
|
||||
pos.z = pos.z + adjust.z * raise
|
||||
|
||||
pitch = adjust.pitch
|
||||
yaw = 6.28 - adjust.yaw * 1.57 -- math.pi/2
|
||||
roll = 6.28 - adjust.roll * 1.57
|
||||
|
||||
elseif ntype == "pedestal" then
|
||||
|
||||
pos.y = pos.y + 1.08
|
||||
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 = core.add_entity(pos, "itemframes:item")
|
||||
|
||||
if not e then
|
||||
tmp.nodename = nil ; tmp.texture = nil ; tmp.glow = nil ; return
|
||||
end
|
||||
|
||||
if ntype == "frame" then
|
||||
e:set_rotation({x = pitch, y = yaw, z = roll})
|
||||
end
|
||||
end
|
||||
|
||||
-- remove entity and drop as item
|
||||
|
||||
local function drop_item(pos, ntype, metadata)
|
||||
|
||||
local meta = metadata or core.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)
|
||||
|
||||
meta:set_string("infotext", S("Right-click to add or remove item"))
|
||||
|
||||
if ntype == "pedestal" then pos.y = pos.y + 1 end
|
||||
|
||||
core.add_item(pos, item)
|
||||
end
|
||||
end
|
||||
|
||||
-- return item to a player's inventory
|
||||
|
||||
local function return_item(pos, ntype, metadata, clicker, itemstack)
|
||||
|
||||
local meta = metadata or core.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 function frame_place(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 = core.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 = core.dir_to_facedir(dir)
|
||||
local p2 = fdir
|
||||
|
||||
if wdir == 0 then
|
||||
p2 = 8
|
||||
elseif wdir == 1 then
|
||||
p2 = 4
|
||||
end
|
||||
|
||||
return core.item_place(itemstack, placer, pointed_thing, p2)
|
||||
end
|
||||
|
||||
-- action logging helper
|
||||
|
||||
local function show_msg(message)
|
||||
|
||||
if log_actions then core.log("action", message) end
|
||||
end
|
||||
|
||||
-- helper function to return item description
|
||||
|
||||
local function get_desc(itemname)
|
||||
|
||||
local def = core.registered_items[itemname]
|
||||
local desc = def and def.description or ""
|
||||
|
||||
return desc
|
||||
end
|
||||
|
||||
-- itemframe node and recipe
|
||||
|
||||
core.register_node("itemframes:frame",{
|
||||
description = S("Item frame"),
|
||||
drawtype = "nodebox",
|
||||
node_box = {type = "fixed", fixed = {-7/16, -7/16, 7/16, 7/16, 7/16, 0.5}},
|
||||
selection_box = {type = "fixed", fixed = {-6/16, -6/16, 7/16, 6/16, 6/16, 0.5}},
|
||||
tiles = {"itemframes_frame.png"},
|
||||
inventory_image = "itemframes_frame_inv.png",
|
||||
wield_image = "itemframes_frame_inv.png",
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
sunlight_propagates = true,
|
||||
groups = {choppy = 2, dig_immediate = 2, flammable = 2, handy = 1, axey = 1},
|
||||
sounds = sounds,
|
||||
_mcl_hardness = 0.5,
|
||||
|
||||
on_place = frame_place,
|
||||
|
||||
after_place_node = function(pos, placer, itemstack)
|
||||
|
||||
local meta = core.get_meta(pos)
|
||||
|
||||
meta:set_string("infotext", S("Right-click to add or remove item"))
|
||||
end,
|
||||
|
||||
on_rightclick = function(pos, node, clicker, itemstack)
|
||||
|
||||
if not itemstack or core.is_protected(pos, clicker:get_player_name()) then
|
||||
return
|
||||
end
|
||||
|
||||
local meta = core.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 " .. core.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()
|
||||
local item = s:to_string()
|
||||
|
||||
meta:set_string("item", item)
|
||||
meta:set_string("infotext", S("Contains: ") .. get_desc(item))
|
||||
|
||||
update_item(pos, "frame", node)
|
||||
|
||||
show_msg(clicker:get_player_name()
|
||||
.. " inserted " .. meta:get_string("item")
|
||||
.. " into Itemframe at " .. core.pos_to_string(pos))
|
||||
|
||||
return itemstack
|
||||
end
|
||||
end,
|
||||
|
||||
on_destruct = function(pos)
|
||||
drop_item(pos, "frame")
|
||||
end,
|
||||
|
||||
on_punch = function(pos, node, puncher)
|
||||
|
||||
-- rotate item inside frame when holding sneak and punching
|
||||
if puncher and puncher:get_player_control().sneak
|
||||
and (allow_rotate or not core.is_protected(pos, puncher:get_player_name())) then
|
||||
|
||||
local p2 = node.param2
|
||||
local nx = facedir[p2].nx
|
||||
|
||||
core.swap_node(pos, {name = node.name, param2 = nx})
|
||||
|
||||
node.param2 = nx
|
||||
end
|
||||
|
||||
update_item(pos, "frame", node)
|
||||
end,
|
||||
|
||||
on_blast = function(pos, intensity)
|
||||
|
||||
drop_item(pos, "frame")
|
||||
|
||||
core.add_item(pos, {name = "itemframes:frame"})
|
||||
|
||||
core.remove_node(pos)
|
||||
end,
|
||||
|
||||
on_burn = function(pos)
|
||||
|
||||
drop_item(pos, "frame")
|
||||
|
||||
core.remove_node(pos)
|
||||
end
|
||||
})
|
||||
|
||||
core.register_craft({
|
||||
output = "itemframes:frame",
|
||||
recipe = {
|
||||
{ a.stick, a.stick, a.stick },
|
||||
{ a.stick, a.paper, a.stick },
|
||||
{ a.stick, a.stick, a.stick }
|
||||
}
|
||||
})
|
||||
|
||||
-- invisible itemframe node and recipe
|
||||
|
||||
core.register_node("itemframes:frame_invis",{
|
||||
description = S("Invisible Item frame"),
|
||||
drawtype = "nodebox",
|
||||
node_box = {type = "fixed", fixed = {-7/16, -7/16, 7/16, 7/16, 7/16, 0.5}},
|
||||
selection_box = {type = "fixed", fixed = {-6/16, -6/16, 7/16, 6/16, 6/16, 0.5}},
|
||||
tiles = {"itemframes_frame_invis.png"},
|
||||
inventory_image = "itemframes_frame_invis_inv.png",
|
||||
wield_image = "itemframes_frame_invis_inv.png",
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
sunlight_propagates = true,
|
||||
use_texture_alpha = "clip",
|
||||
groups = {choppy = 2, dig_immediate = 2, flammable = 2, handy = 1, axey = 1},
|
||||
sounds = sounds,
|
||||
_mcl_hardness = 0.5,
|
||||
|
||||
on_place = frame_place,
|
||||
|
||||
after_place_node = function(pos, placer, itemstack)
|
||||
|
||||
local meta = core.get_meta(pos)
|
||||
|
||||
meta:set_string("infotext", S("Right-click to add or remove item"))
|
||||
end,
|
||||
|
||||
on_rightclick = function(pos, node, clicker, itemstack)
|
||||
|
||||
if not itemstack or core.is_protected(pos, clicker:get_player_name()) then
|
||||
return
|
||||
end
|
||||
|
||||
local meta = core.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 " .. core.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()
|
||||
local item = s:to_string()
|
||||
|
||||
meta:set_string("item", item)
|
||||
meta:set_string("infotext", S("Contains: ") .. get_desc(item))
|
||||
|
||||
update_item(pos, "frame", node)
|
||||
|
||||
show_msg(clicker:get_player_name()
|
||||
.. " inserted " .. meta:get_string("item")
|
||||
.. " into Itemframe at " .. core.pos_to_string(pos))
|
||||
|
||||
return itemstack
|
||||
end
|
||||
end,
|
||||
|
||||
on_destruct = function(pos)
|
||||
drop_item(pos, "frame")
|
||||
end,
|
||||
|
||||
on_punch = function(pos, node, puncher)
|
||||
|
||||
-- rotate item inside frame when holding sneak and punching
|
||||
if puncher and puncher:get_player_control().sneak
|
||||
and (allow_rotate or not core.is_protected(pos, puncher:get_player_name())) then
|
||||
|
||||
local p2 = node.param2
|
||||
local nx = facedir[p2].nx
|
||||
|
||||
core.swap_node(pos, {name = node.name, param2 = nx})
|
||||
node.param2 = nx
|
||||
end
|
||||
|
||||
update_item(pos, "frame", node)
|
||||
end,
|
||||
|
||||
on_blast = function(pos, intensity)
|
||||
|
||||
drop_item(pos, "frame")
|
||||
|
||||
core.add_item(pos, {name = "itemframes:frame_invis"})
|
||||
|
||||
core.remove_node(pos)
|
||||
end,
|
||||
|
||||
on_burn = function(pos)
|
||||
|
||||
drop_item(pos, "frame")
|
||||
|
||||
core.remove_node(pos)
|
||||
end
|
||||
})
|
||||
|
||||
core.register_craft({
|
||||
output = "itemframes:frame_invis",
|
||||
recipe = {
|
||||
{ a.glass, a.glass, a.glass },
|
||||
{ a.glass, a.paper, a.glass },
|
||||
{ a.glass, a.glass, a.glass }
|
||||
}
|
||||
})
|
||||
|
||||
-- pedestal node and recipe
|
||||
|
||||
core.register_node("itemframes:pedestal",{
|
||||
description = S("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, pickaxey = 1},
|
||||
sounds = sounds,
|
||||
on_rotate = screwdriver.disallow,
|
||||
_mcl_hardness = 1.5,
|
||||
|
||||
after_place_node = function(pos, placer, itemstack)
|
||||
|
||||
local meta = core.get_meta(pos)
|
||||
|
||||
meta:set_string("infotext", S("Right-click to add or remove item"))
|
||||
end,
|
||||
|
||||
on_rightclick = function(pos, node, clicker, itemstack)
|
||||
|
||||
if not itemstack or core.is_protected(pos, clicker:get_player_name()) then
|
||||
return
|
||||
end
|
||||
|
||||
local meta = core.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 " .. core.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()
|
||||
local item = s:to_string()
|
||||
|
||||
meta:set_string("item", item)
|
||||
meta:set_string("infotext", S("Contains: ") .. get_desc(item))
|
||||
|
||||
update_item(pos, "pedestal", node)
|
||||
|
||||
show_msg(clicker:get_player_name()
|
||||
.. " inserted " .. meta:get_string("item")
|
||||
.. " into Pedestal at " .. core.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)
|
||||
|
||||
local pos2 = {x = pos.x, y = pos.y, z = pos.z}
|
||||
|
||||
drop_item(pos, "pedestal")
|
||||
|
||||
core.add_item(pos2, {name = "itemframes:pedestal"})
|
||||
|
||||
core.remove_node(pos2)
|
||||
end
|
||||
})
|
||||
|
||||
core.register_craft({
|
||||
output = "itemframes:pedestal",
|
||||
recipe = {
|
||||
{ a.stone, a.stone, a.stone },
|
||||
{ "", a.stone, "" },
|
||||
{ a.stone, a.stone, a.stone }
|
||||
}
|
||||
})
|
||||
|
||||
-- automatically restore entities lost from frames/pedestals
|
||||
-- due to /clearobjects or similar
|
||||
|
||||
core.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
|
||||
|
||||
del_ent(pos)
|
||||
|
||||
pos.y = pos.y - ypos
|
||||
|
||||
update_item(pos, ntype, node)
|
||||
end
|
||||
})
|
||||
|
||||
-- stop mesecon pistons from pushing itemframe and pedestals
|
||||
|
||||
if core.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")
|
7
mods/itemframes/mod.conf
Normal file
|
@ -0,0 +1,7 @@
|
|||
name = itemframes
|
||||
description = Adds item frames and pedestals to showcase items.
|
||||
optional_depends = mesecons_mvps, default, mcl_core, mcl_sounds
|
||||
min_minetest_version = 5.0
|
||||
release = 30939
|
||||
author = TenPlus1
|
||||
title = Item Frames and Pedestals
|
40
mods/itemframes/readme.md
Normal file
|
@ -0,0 +1,40 @@
|
|||
Item Frames mod for minetest
|
||||
|
||||
This mod differs from Zeg's original and the one included in homedecor modpack in that no one person owns the itemframe or pedestals, they are protected with minetest.is_protected() so can have multiple owners or none at all... Items that have a light source will glow when placed in frames/pedestals.
|
||||
|
||||
Right-click to add or remove an item from a frame or pedestal, please note that if an item already has on_rightclick registered then it cannot be added to either. Punch frame or pedestal to force update if items do not appear.
|
||||
|
||||
Itemframes can be rotated with a screwdriver which includes sitting flat on a surface, punch to update item inside. You can also hold sneak and punch to rotate item inside frame.
|
||||
|
||||
License was originally WTFPL although the codebase has changed so much I've reclassified as MIT License for simplicity and school use, and textures are CC-BY-3.0.
|
||||
|
||||
|
||||
Settings
|
||||
--------
|
||||
|
||||
Change 'itemframes.return_item' setting to true if you want items to drop back into player inventory when removed (thanks fluxionary).
|
||||
|
||||
Change 'itemframes.log_actions' setting to true if you want to log player actions when inserting or removing items from a frame or pedestal.
|
||||
|
||||
Itemframe items can be rotated by holding sneak and punching frame, but in a protected area this is limited to the owner unless "itemframes.allow_rotate" setting is true.
|
||||
|
||||
|
||||
Texture Override
|
||||
----------------
|
||||
|
||||
If a node has the _itemframe_texture string set then the itemframe will show that image instead of the item's own wielditem (mainly for 3d items that may not look good in frames) e.g.
|
||||
|
||||
This shows furnaces inside an itemframe as a flat image:
|
||||
|
||||
minetest.override_item("default:furnace", {
|
||||
_itemframe_texture = "default_furnace_front.png"
|
||||
})
|
||||
|
||||
This shows furance inside an itemframe as a 3D styled flat image:
|
||||
|
||||
minetest.override_item("default:furnace", {
|
||||
_itemframe_texture = minetest.inventorycube(
|
||||
"default_furnace_top.png",
|
||||
"default_furnace_side.png",
|
||||
"default_furnace_front.png")
|
||||
})
|
BIN
mods/itemframes/screenshot.jpg
Normal file
After Width: | Height: | Size: 190 KiB |
7
mods/itemframes/settingtypes.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
# If false, the item will always just be dropped on the ground.
|
||||
itemframes.return_item (return placed item to the player's inventory on right-click) bool false
|
||||
|
||||
# if false, inserting and removing items from frames and pedestals will not be logged
|
||||
itemframes.log_actions (log player actions when using itemframes and pedestals) bool false
|
||||
|
||||
itemframes.allow_rotate (Allow item rotation in protected areas) bool false
|
BIN
mods/itemframes/textures/itemframes_frame.png
Normal file
After Width: | Height: | Size: 339 B |
BIN
mods/itemframes/textures/itemframes_frame_inv.png
Normal file
After Width: | Height: | Size: 338 B |
BIN
mods/itemframes/textures/itemframes_frame_invis.png
Normal file
After Width: | Height: | Size: 103 B |
BIN
mods/itemframes/textures/itemframes_frame_invis_inv.png
Normal file
After Width: | Height: | Size: 170 B |
BIN
mods/itemframes/textures/itemframes_pedestal.png
Normal file
After Width: | Height: | Size: 245 B |
BIN
mods/itemframes/textures/itemframes_pedestal_btm.png
Normal file
After Width: | Height: | Size: 143 B |
BIN
mods/itemframes/textures/itemframes_pedestal_top.png
Normal file
After Width: | Height: | Size: 226 B |