diff --git a/homedecor/expansion.lua b/homedecor/expansion.lua new file mode 100644 index 00000000..5ed80a92 --- /dev/null +++ b/homedecor/expansion.lua @@ -0,0 +1,81 @@ +-- returns the correct buildable_to node +local function get_buildable_to(pointed_thing) + local pos = pointed_thing.under + local def = minetest.registered_nodes[minetest.get_node(pos).name] + + if not def or not def.buildable_to then + pos = pointed_thing.above + def = minetest.registered_nodes[minetest.get_node(pos).name] + end + return pos, def +end + +-- abstract function checking if 2 given nodes can and may be build to a place +local function is_buildable_to(placer_name, pos, def, pos2) + local def = def or minetest.registered_nodes[minetest.get_node(pos).name] + local def2 = minetest.registered_nodes[minetest.get_node(pos2).name] + + return def and def.buildable_to and def2 and def2.buildable_to + and not minetest.is_protected(pos, placer_name) + and not minetest.is_protected(pos2, placer_name) +end + +-- place one or two nodes if and only if both can be placed +local function stack(itemstack, placer, fdir, pos, def, pos2, node1, node2) + local placer_name = placer:get_player_name() or "" + if is_buildable_to(placer_name, pos, def, pos2) then + local fdir = fdir or minetest.dir_to_facedir(placer:get_look_dir()) + minetest.set_node(pos, { name = node1, param2 = fdir }) + + if node2 then + minetest.set_node(pos2, { name = node2, param2 = fdir }) + end + + -- temporary check if this is a locked node to set its infotext + local nodename = itemstack:get_name() + if string.find(nodename, "_locked") then + local meta = minetest.get_meta(pos) + meta:set_string("owner", placer_name) + meta:set_string("infotext", S("Locked Refrigerator (owned by %s)"):format(placer_name)) + end + + if not homedecor.expect_infinite_stacks then + itemstack:take_item() + return itemstack + end + end +end + +-- Stack one node above another +-- leave the last argument nil if it's one 2m high node +function homedecor.stack_vertically(itemstack, placer, pointed_thing, node1, node2) + local pos, def = get_buildable_to(pointed_thing) + local top_pos = { x=pos.x, y=pos.y+1, z=pos.z } + + return stack(itemstack, placer, nil, pos, def, top_pos, node1, node2) +end + +-- Place one node right of or behind another +homedecor.fdir_to_right = { + { 1, 0 }, + { 0, -1 }, + { -1, 0 }, + { 0, 1 }, +} + +homedecor.fdir_to_fwd = { + { 0, 1 }, + { 1, 0 }, + { 0, -1 }, + { -1, 0 }, +} + +function homedecor.stack_sideways(itemstack, placer, pointed_thing, node1, node2, dir) + local fdir = minetest.dir_to_facedir(placer:get_look_dir()) + local fdir_transform = dir and homedecor.fdir_to_right or homedecor.fdir_to_fwd + + local pos, def = get_buildable_to(pointed_thing) + local pos2 = { x = pos.x + fdir_transform[fdir+1][1], y=pos.y, z = pos.z + fdir_transform[fdir+1][2] } + + return stack(itemstack, placer, fdir, pos, def, pos2, node1, node2) +end diff --git a/homedecor/init.lua b/homedecor/init.lua index 98d5399c..003fae30 100644 --- a/homedecor/init.lua +++ b/homedecor/init.lua @@ -57,8 +57,6 @@ function homedecor.table_copy(t) return nt end --- - function homedecor.get_nodedef_field(nodename, fieldname) if not minetest.registered_nodes[nodename] then return nil @@ -66,114 +64,6 @@ function homedecor.get_nodedef_field(nodename, fieldname) return minetest.registered_nodes[nodename][fieldname] end --- Place a two-node-tall single object (e.g. a floor lamp) - -function homedecor.place_twonode_vertical(itemstack, placer, pointed_thing, node) - local pos = pointed_thing.under - local pnode = minetest.get_node(pointed_thing.under) - local rnodedef = minetest.registered_nodes[pnode.name] - - if not rnodedef["buildable_to"] then - pos = pointed_thing.above - end - - local fdir = minetest.dir_to_facedir(placer:get_look_dir()) - local pos2 = { x = pos.x, y=pos.y + 1, z = pos.z } - - local tnode = minetest.get_node(pos) - local tnode2 = minetest.get_node(pos2) - - if homedecor.get_nodedef_field(tnode.name, "buildable_to") - and homedecor.get_nodedef_field(tnode2.name, "buildable_to") - and not minetest.is_protected(pos, placer:get_player_name()) - and not minetest.is_protected(pos2, placer:get_player_name()) then - minetest.add_node(pos, { name = node, param2 = fdir }) - if not homedecor.expect_infinite_stacks then - itemstack:take_item() - return itemstack - end - end -end - --- Stack one node above another - -function homedecor.stack_vertically(itemstack, placer, pointed_thing, node1, node2) - local pos = pointed_thing.under - local pnode = minetest.get_node(pointed_thing.under) - local rnodedef = minetest.registered_nodes[pnode.name] - - if not rnodedef["buildable_to"] then - pos = pointed_thing.above - end - - local fdir = minetest.dir_to_facedir(placer:get_look_dir()) - local pos2 = { x = pos.x, y=pos.y + 1, z = pos.z } - - local tnode = minetest.get_node(pos) - local tnode2 = minetest.get_node(pos2) - - if homedecor.get_nodedef_field(tnode.name, "buildable_to") - and homedecor.get_nodedef_field(tnode2.name, "buildable_to") - and not minetest.is_protected(pos, placer:get_player_name()) - and not minetest.is_protected(pos2, placer:get_player_name()) then - minetest.add_node(pos, { name = node1, param2 = fdir }) - minetest.add_node(pos2, { name = node2, param2 = fdir }) - if not homedecor.expect_infinite_stacks then - itemstack:take_item() - return itemstack - end - end -end - --- Place one node right of or behind another - -homedecor.fdir_to_right = { - { 1, 0 }, - { 0, -1 }, - { -1, 0 }, - { 0, 1 }, -} - -homedecor.fdir_to_fwd = { - { 0, 1 }, - { 1, 0 }, - { 0, -1 }, - { -1, 0 }, -} - -function homedecor.stack_sideways(itemstack, placer, pointed_thing, node1, node2, dir) - local pos = pointed_thing.under - local pnode = minetest.get_node(pointed_thing.under) - local rnodedef = minetest.registered_nodes[pnode.name] - - if not rnodedef["buildable_to"] then - pos = pointed_thing.above - end - - local fdir = minetest.dir_to_facedir(placer:get_look_dir()) - local pos2 - if dir then - pos2 = { x = pos.x + homedecor.fdir_to_right[fdir+1][1], y=pos.y, z = pos.z + homedecor.fdir_to_right[fdir+1][2] } - else - pos2 = { x = pos.x + homedecor.fdir_to_fwd[fdir+1][1], y=pos.y, z = pos.z + homedecor.fdir_to_fwd[fdir+1][2] } - end - - local tnode = minetest.get_node(pos) - local tnode2 = minetest.get_node(pos2) - - if homedecor.get_nodedef_field(tnode.name, "buildable_to") - and homedecor.get_nodedef_field(tnode2.name, "buildable_to") - and not minetest.is_protected(pos, placer:get_player_name()) - and not minetest.is_protected(pos2, placer:get_player_name()) then - minetest.add_node(pos, { name = node1, param2 = fdir }) - minetest.add_node(pos2, { name = node2, param2 = fdir }) - if not homedecor.expect_infinite_stacks then - itemstack:take_item() - return itemstack - end - end -end - -- Determine if the item being pointed at is the underside of a node (e.g a ceiling) function homedecor.find_ceiling(itemstack, placer, pointed_thing) @@ -222,6 +112,9 @@ function homedecor.find_ceiling(itemstack, placer, pointed_thing) return isceiling, pos end +-- expand and unexpand decor +dofile(homedecor.modpath.."/expansion.lua") +-- glue it all together into a registration function dofile(homedecor.modpath.."/registration_handler.lua") -- load various other components diff --git a/homedecor/lighting.lua b/homedecor/lighting.lua index ca67dbda..16995945 100644 --- a/homedecor/lighting.lua +++ b/homedecor/lighting.lua @@ -456,7 +456,7 @@ local function reg_lamp(suffix, nxt, tilesuffix, light, color) selection_box = slamp_cbox, collision_box = slamp_cbox, on_place = function(itemstack, placer, pointed_thing) - return homedecor.place_twonode_vertical(itemstack, placer, pointed_thing, + return homedecor.place_vertically(itemstack, placer, pointed_thing, "homedecor:standing_lamp"..lampcolor.."_"..suffix) end, on_punch = function(pos, node, puncher) diff --git a/homedecor/refrigerator.lua b/homedecor/refrigerator.lua index db9d6244..269d7342 100644 --- a/homedecor/refrigerator.lua +++ b/homedecor/refrigerator.lua @@ -54,39 +54,7 @@ homedecor.register("refrigerator_steel_bottom", { fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 } }, on_place = function(itemstack, placer, pointed_thing) - local pos = pointed_thing.under - local pnode = minetest.get_node(pointed_thing.under) - local rnodedef = minetest.registered_nodes[pnode.name] - - if not rnodedef["buildable_to"] then - pos = pointed_thing.above - end - - local fdir = minetest.dir_to_facedir(placer:get_look_dir()) - local pos2 = { x = pos.x, y=pos.y + 1, z = pos.z } - - local tnode = minetest.get_node(pos) - local tnode2 = minetest.get_node(pos2) - - if homedecor.get_nodedef_field(tnode.name, "buildable_to") - and homedecor.get_nodedef_field(tnode2.name, "buildable_to") - and not minetest.is_protected(pos, placer:get_player_name()) - and not minetest.is_protected(pos2, placer:get_player_name()) then - local nodename = itemstack:get_name() - minetest.add_node(pos, { name = nodename, param2 = fdir }) - minetest.add_node(pos2, { name = "homedecor:refrigerator_steel_top", param2 = fdir }) - - if string.find(nodename, "_locked") then - local meta = minetest.get_meta(pos) - meta:set_string("owner", placer:get_player_name() or "") - meta:set_string("infotext", S("Locked Refrigerator (owned by %s)"):format(meta:get_string("owner"))) - end - - if not homedecor.expect_infinite_stacks then - itemstack:take_item() - return itemstack - end - end + homedecor.stack_vertically(itemstack, placer, pointed_thing, "homedecor:refrigerator_steel_bottom", "homedecor:refrigerator_steel_top") end, after_dig_node = function(pos, oldnode, oldmetadata, digger) local pos2 = { x = pos.x, y=pos.y + 1, z = pos.z } @@ -97,6 +65,7 @@ homedecor.register("refrigerator_steel_bottom", { infotext=S("Refrigerator"), inventory = { size=50, + lockable=true, formspec="size[10,10]".. "list[context;main;0,0;10,5;]".. "list[current_player;main;1,6;8,4;]", @@ -140,39 +109,7 @@ homedecor.register("refrigerator_white_bottom", { fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 } }, on_place = function(itemstack, placer, pointed_thing) - local pos = pointed_thing.under - local pnode = minetest.get_node(pointed_thing.under) - local rnodedef = minetest.registered_nodes[pnode.name] - - if not rnodedef["buildable_to"] then - pos = pointed_thing.above - end - - local fdir = minetest.dir_to_facedir(placer:get_look_dir()) - local pos2 = { x = pos.x, y=pos.y + 1, z = pos.z } - - local tnode = minetest.get_node(pos) - local tnode2 = minetest.get_node(pos2) - - if homedecor.get_nodedef_field(tnode.name, "buildable_to") - and homedecor.get_nodedef_field(tnode2.name, "buildable_to") - and not minetest.is_protected(pos, placer:get_player_name()) - and not minetest.is_protected(pos2, placer:get_player_name()) then - local nodename = itemstack:get_name() - minetest.add_node(pos, { name = nodename, param2 = fdir }) - minetest.add_node(pos2, { name = "homedecor:refrigerator_white_top", param2 = fdir }) - - if string.find(nodename, "_locked") then - local meta = minetest.get_meta(pos) - meta:set_string("owner", placer:get_player_name() or "") - meta:set_string("infotext", S("Locked Refrigerator (owned by %s)"):format(meta:get_string("owner"))) - end - - if not homedecor.expect_infinite_stacks then - itemstack:take_item() - return itemstack - end - end + homedecor.stack_vertically(itemstack, placer, pointed_thing, "homedecor:refrigerator_white_bottom", "homedecor:refrigerator_white_top") end, after_dig_node = function(pos, oldnode, oldmetadata, digger) local pos2 = { x = pos.x, y=pos.y + 1, z = pos.z }