diff --git a/init.lua b/init.lua index f76c4b8..bb23c0d 100644 --- a/init.lua +++ b/init.lua @@ -29,144 +29,6 @@ dofile(modpath.."/door_models.lua") -- the good stuff! -local function isSolid(pos,adj) - local adj = {x=adj[1],y=adj[2],z=adj[3]} - local node = minetest.get_node(vector.add(pos,adj)) - if node then - local idef = minetest.registered_nodes[minetest.get_node(vector.add(pos,adj)).name] - if idef then - return idef.walkable - end - end - return false -end - -local function countSolids(pos,node,level) - local solids = 0 - for x = -1, 1 do - for z = -1, 1 do - local y = 0 - if node.param2 == 5 then - y = -level - else - y = level - end - -- special cases when x == z == 0 - if x == 0 and z == 0 then - if level == 1 then - -- when looking past the trap door, cannot be solid in center - if isSolid(pos,{x,y,z}) then - return false - end - -- no else. it doesn't matter if x == y == z is solid, that's us. - end - elseif isSolid(pos,{x,y,z}) then - solids = solids + 1 - end - end - end - return solids -end - -local function calculateClosed(pos) - local node = minetest.get_node(pos) - -- the door is considered closed if it is closing off something. - - local solids = 0 - local direction = node.param2 % 6 - local isTrap = direction == 0 or direction == 5 - if isTrap then - -- the trap door is considered closed when all nodes on its sides are solid - -- or all nodes in the 3x3 above/below it are solid except the center - for level = 0, 1 do - local fail = false - local solids = countSolids(pos,node,level) - if solids == 8 then - return true - end - end - return false - else - -- the door is considered closed when the nodes on its sides are solid - -- or the 3 nodes in its facing direction are solid nonsolid solid - - -- sorry I dunno the math to figure whether to x or z - if direction == 1 or direction == 2 then - if isSolid(pos,{0,0,-1}) and isSolid(pos,{0,0,1}) then - if string.find(node.name,'_bottom_') then - return calculateClosed({x=pos.x,y=pos.y+1,z=pos.z}) - else - return true - end - end - local x - if direction == 1 then - x = 1 - else - x = -1 - end - if isSolid(pos,{x,0,-1}) and not isSolid(pos,{x,0,0}) and isSolid(pos,{x,0,1}) then - if string.find(node.name,'_bottom_') then - return calculateClosed({x=pos.x,y=pos.y+1,z=pos.z}) - else - return true - end - end - return false - else - -- direction == 3 or 4 - if isSolid(pos,{-1,0,0}) and isSolid(pos,{1,0,0}) then - if string.find(node.name,'_bottom_') then - return calculateClosed({x=pos.x,y=pos.y+1,z=pos.z}) - else - return true - end - end - local z - if direction == 3 then - z = 1 - else - z = -1 - end - if isSolid(pos,{-1,0,z}) and not isSolid(pos,{0,0,z}) and isSolid(pos,{1,0,z}) then - if string.find(node.name,'_bottom_') then - return calculateClosed({x=pos.x,y=pos.y+1,z=pos.z}) - else - return true - end - end - return false - end - error("What direction is this???",direction) - end -end - --- isClosed flag, is 0 or 1 0 = open, 1 = closed -local function getClosed(pos) - local isClosed = minetest.get_meta(pos):get_string('closed') - if isClosed=='' then - if calculateClosed(pos) then - return true - else - return false - end - else - isClosed = tonumber(isClosed) - -- may be closed or open (1 or 0) - return isClosed == 1 - end -end - -local function addDoorNode(pos,def,isClosed) - if isClosed then - isClosed = 1 - else - isClosed = 0 - end - minetest.add_node(pos, def) - minetest.get_meta(pos):set_int('closed',isClosed) -end - local sides = {"left", "right"} local rsides = {"right", "left"} @@ -284,13 +146,6 @@ for i in ipairs(sides) do on_rightclick = function(pos, node, clicker) autoclose_doors.flip_door(pos, node, clicker, doorname, side) end, - -- both left and right doors may be used for open or closed doors - -- so they have to have both action_on and action_off and just - -- check when that action is invoked if to continue - - on_punch = function(pos, node, puncher) - minetest.get_meta(pos):set_string('closed',nil) - end, drop = "autoclose_doors:"..doorname.."_bottom_left", mesecons = { effector = { @@ -376,6 +231,7 @@ function autoclose_doors.place_door(itemstack, placer, pointed_thing, name, forc local def = { name = "autoclose_doors:"..name.."_bottom_"..side, param2=fdir} addDoorNode(pos1, def, true) minetest.add_node(pos2, { name = "autoclose_doors:"..name.."_top_"..side, param2=fdir}) + minetest.get_meta(pos1):set_string('closed', true) if not autoclose_doors.expect_infinite_stacks then itemstack:take_item() return itemstack @@ -389,9 +245,11 @@ end -- also adjusting param2 so the node is at 90 degrees. function autoclose_doors.flip_door(pos, node, player, name, side, isClosed) - if isClosed == nil then - isClosed = getClosed(pos) - end + + if isClosed == nil then + isClosed = minetest.get_meta(pos):get_string('closed') or false + end + -- this is where we swap the isClosed status! -- i.e. if isClosed, we're adding an open door -- and if not isClosed, a closed door @@ -425,9 +283,9 @@ function autoclose_doors.flip_door(pos, node, player, name, side, isClosed) addDoorNode(pos,{ name = "autoclose_doors:"..name.."_bottom_"..rside, param2=nfdir },isClosed) - local timer = minetest.get_node_timer(pos) + minetest.get_meta(pos):set_string('closed', isClosed) if not isClosed then - timer:start(10) + minetest.get_node_timer(pos):start(10) end end