mirror of
https://github.com/mt-mods/homedecor_modpack.git
synced 2024-12-23 00:20:17 +01:00
rewrite the node stacking/expansion code, preventing a crash building on unknown nodes, and reduce table lookups and overall code
This commit is contained in:
parent
b4b281d9ea
commit
0a0c558c3a
81
homedecor/expansion.lua
Normal file
81
homedecor/expansion.lua
Normal file
@ -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
|
@ -57,8 +57,6 @@ function homedecor.table_copy(t)
|
|||||||
return nt
|
return nt
|
||||||
end
|
end
|
||||||
|
|
||||||
--
|
|
||||||
|
|
||||||
function homedecor.get_nodedef_field(nodename, fieldname)
|
function homedecor.get_nodedef_field(nodename, fieldname)
|
||||||
if not minetest.registered_nodes[nodename] then
|
if not minetest.registered_nodes[nodename] then
|
||||||
return nil
|
return nil
|
||||||
@ -66,114 +64,6 @@ function homedecor.get_nodedef_field(nodename, fieldname)
|
|||||||
return minetest.registered_nodes[nodename][fieldname]
|
return minetest.registered_nodes[nodename][fieldname]
|
||||||
end
|
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)
|
-- 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)
|
function homedecor.find_ceiling(itemstack, placer, pointed_thing)
|
||||||
@ -222,6 +112,9 @@ function homedecor.find_ceiling(itemstack, placer, pointed_thing)
|
|||||||
return isceiling, pos
|
return isceiling, pos
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- expand and unexpand decor
|
||||||
|
dofile(homedecor.modpath.."/expansion.lua")
|
||||||
|
-- glue it all together into a registration function
|
||||||
dofile(homedecor.modpath.."/registration_handler.lua")
|
dofile(homedecor.modpath.."/registration_handler.lua")
|
||||||
|
|
||||||
-- load various other components
|
-- load various other components
|
||||||
|
@ -456,7 +456,7 @@ local function reg_lamp(suffix, nxt, tilesuffix, light, color)
|
|||||||
selection_box = slamp_cbox,
|
selection_box = slamp_cbox,
|
||||||
collision_box = slamp_cbox,
|
collision_box = slamp_cbox,
|
||||||
on_place = function(itemstack, placer, pointed_thing)
|
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)
|
"homedecor:standing_lamp"..lampcolor.."_"..suffix)
|
||||||
end,
|
end,
|
||||||
on_punch = function(pos, node, puncher)
|
on_punch = function(pos, node, puncher)
|
||||||
|
@ -54,39 +54,7 @@ homedecor.register("refrigerator_steel_bottom", {
|
|||||||
fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 }
|
fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 }
|
||||||
},
|
},
|
||||||
on_place = function(itemstack, placer, pointed_thing)
|
on_place = function(itemstack, placer, pointed_thing)
|
||||||
local pos = pointed_thing.under
|
homedecor.stack_vertically(itemstack, placer, pointed_thing, "homedecor:refrigerator_steel_bottom", "homedecor:refrigerator_steel_top")
|
||||||
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
|
|
||||||
end,
|
end,
|
||||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||||
local pos2 = { x = pos.x, y=pos.y + 1, z = pos.z }
|
local pos2 = { x = pos.x, y=pos.y + 1, z = pos.z }
|
||||||
@ -97,6 +65,7 @@ homedecor.register("refrigerator_steel_bottom", {
|
|||||||
infotext=S("Refrigerator"),
|
infotext=S("Refrigerator"),
|
||||||
inventory = {
|
inventory = {
|
||||||
size=50,
|
size=50,
|
||||||
|
lockable=true,
|
||||||
formspec="size[10,10]"..
|
formspec="size[10,10]"..
|
||||||
"list[context;main;0,0;10,5;]"..
|
"list[context;main;0,0;10,5;]"..
|
||||||
"list[current_player;main;1,6;8,4;]",
|
"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 }
|
fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 }
|
||||||
},
|
},
|
||||||
on_place = function(itemstack, placer, pointed_thing)
|
on_place = function(itemstack, placer, pointed_thing)
|
||||||
local pos = pointed_thing.under
|
homedecor.stack_vertically(itemstack, placer, pointed_thing, "homedecor:refrigerator_white_bottom", "homedecor:refrigerator_white_top")
|
||||||
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
|
|
||||||
end,
|
end,
|
||||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||||
local pos2 = { x = pos.x, y=pos.y + 1, z = pos.z }
|
local pos2 = { x = pos.x, y=pos.y + 1, z = pos.z }
|
||||||
|
Loading…
Reference in New Issue
Block a user