--Todo make lift go up and down! doors.register_door("lifter:door", { tiles = {{ name = "lifter_door.png", backface_culling = true }}, description = "Lift Door", inventory_image = "lifter_item_door.png", groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, recipe = { {"group:stick", "group:stick", "group:stick"}, {"group:stick", "doors:door_wood", "group:stick"}, {"group:stick", "group:stick", "group:stick"}, } }) -- should only be ignore if there's not generated map local function get_far_node(pos) local node = minetest.get_node(pos) if node.name == "ignore" then minetest.get_voxel_manip():read_from_map(pos, pos) node = minetest.get_node(pos) end return node end local function fetch_lift(pos, node, clicker, rel, i, open_door, plus) local wnode = get_far_node({x=pos.x+1, y=pos.y+i, z=pos.z}) local snode = get_far_node({x=pos.x-1, y=pos.y+i, z=pos.z}) local anode = get_far_node({x=pos.x, y=pos.y+i, z=pos.z+1}) local dnode = get_far_node({x=pos.x, y=pos.y+i, z=pos.z-1}) if wnode.name ~= "lifter:lift" and snode.name ~= "lifter:lift" and anode.name ~= "lifter:lift" and dnode.name ~= "lifter:lift" then if wnode.name ~= "air" and snode.name ~= "air" and anode.name ~= "air" and dnode.name ~= "air" and wnode.name ~= "bones:bones" and snode.name ~= "bones:bones" and anode.name ~= "bones:bones" and dnode.name ~= "bones:bones" and wnode.name ~= "default:torch" and snode.name ~= "default:torch" and anode.name ~= "default:torch" and dnode.name ~= "default:torch" and wnode.name ~= "lifter:block" and snode.name ~= "lifter:block" and anode.name ~= "lifter:block" and dnode.name ~= "lifter:block" then print("lift not found, no air") return end local test = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y+i, z=pos.z-1}, {x=pos.x+1, y=pos.y+i, z=pos.z+1}, "air") if #test == 9 then print( "lift not found, too much air") return end if i%20 == 0 then minetest.after(1, fetch_lift, pos, node, clicker, rel, i+plus, open_door, plus) else fetch_lift(pos, node, clicker, rel, i+plus, open_door, plus) end else local foundpos if wnode.name == "lifter:lift" then local name = minetest.get_node({x=pos.x+1, y=pos.y+rel, z=pos.z}).name if name == "air" or name == "ignore" or name == "bones:bones" then minetest.remove_node({x=pos.x+1, y=pos.y+i, z=pos.z}) minetest.add_node({x=pos.x+1, y=pos.y+rel, z=pos.z}, {name="lifter:lift"}) foundpos = {x=pos.x+1, y=pos.y+i, z=pos.z} else print("lift blocked") end end if snode.name == "lifter:lift" then local name = minetest.get_node({x=pos.x-1, y=pos.y+rel, z=pos.z}).name if name == "air" or name == "ignore" or name == "bones:bones" then minetest.remove_node({x=pos.x-1, y=pos.y+i, z=pos.z}) minetest.add_node({x=pos.x-1, y=pos.y+rel, z=pos.z}, {name="lifter:lift"}) foundpos = {x=pos.x-1, y=pos.y+i, z=pos.z} else print("lift blocked") end end if anode.name == "lifter:lift" then local name = minetest.get_node({x=pos.x, y=pos.y+rel, z=pos.z+1}).name if name == "air" or name == "ignore" or name == "bones:bones" then minetest.remove_node({x=pos.x, y=pos.y+i, z=pos.z+1}) minetest.add_node({x=pos.x, y=pos.y+rel, z=pos.z+1}, {name="lifter:lift"}) foundpos = {x=pos.x, y=pos.y+i, z=pos.z+1} else print("lift blocked") end end if dnode.name == "lifter:lift" then local name = minetest.get_node({x=pos.x, y=pos.y+rel, z=pos.z-1}).name if name == "air" or name == "ignore" or name == "bones:bones" then minetest.remove_node({x=pos.x, y=pos.y+i, z=pos.z-1}) minetest.add_node({x=pos.x, y=pos.y+rel, z=pos.z-1}, {name="lifter:lift"}) foundpos = {x=pos.x, y=pos.y+i, z=pos.z-1} else print("lift blocked") end end if foundpos ~= nil then foundpos.y = foundpos.y-1 local name = minetest.get_node(foundpos).name if name == "lifter:block" then minetest.remove_node(foundpos) end end open_door(pos,node,clicker) end end local b1rc = minetest.registered_nodes["lifter:door_a"].on_rightclick --local t2rc = minetest.registered_nodes["lifter:door_t_2"].on_rightclick minetest.override_item("lifter:door_a", { on_rightclick = function(pos, node, clicker) if string.sub(node.name, -2) == "_a" then if clicker:is_player() then minetest.chat_send_player(clicker:get_player_name(), "You called for a lift...") end fetch_lift(pos, node, clicker, -1, 0, b1rc, 1) fetch_lift(pos, node, clicker, -1, 0, b1rc, -1) -- minetest.after(5, b1rc, pos, node, clicker) else b1rc(pos, node, player) end end }) minetest.register_abm({ nodenames = {"lifter:door_b"}, interval = 8, chance = 1, catch_up = false, action = function(pos, node) minetest.after(1, b1rc, pos, node, nil) end }) local b2rc = minetest.registered_nodes["lifter:door_b"].on_rightclick minetest.register_node("lifter:lift", { tiles = {"lifter.png"}, description = "Lift", drawtype = "normal", paramtype = "light", groups = {crumbly=3}, on_rightclick = function(pos, node, player, itemstack, pointed_thing) local obj = minetest.add_entity(pos, "lifter:travelling_lift") minetest.remove_node(pos) if not player then return end obj:get_luaentity().driver = player player:set_attach(obj, "", {x=0, y=15, z=0}, {x=0, y=0, z=0}) player:set_eye_offset({x=0, y=6, z=0},{x=0, y=0, z=0}) local door = minetest.find_node_near(pos, 2, "lifter:door_b") if door then b2rc(door, minetest.get_node(door), player) end local support = minetest.find_node_near(pos, 2, "lifter:block") if support then minetest.set_node(support, {name="air"}) end end, }) minetest.register_node("lifter:block", { tiles = {"default_wood.png"}, description = "Lift Support", drawtype = "normal", paramtype = "light", groups = {crumbly=3}, drop = "", }) minetest.register_entity("lifter:travelling_lift", { physical = true, collide_with_objects = true, collisionbox = {-0.5,-0.5,-0.5, 0.5,2.5,0.5}, visual = "cube", textures = {"lifter.png", "lifter.png", "lifter.png", "lifter.png", "lifter.png", "lifter.png"}, --visual_size = {x=1, y=1}, driver = nil, direction = 0, exiting = false, on_punch = function(self, dtime) end, on_step = function(self, dtime) local exit = false -- Turn to actual sand when collides to ground or just move local pos = self.object:getpos() local bcp = {x=pos.x, y=pos.y-0.7, z=pos.z} -- Position of bottom center point local bcn = minetest.get_node(bcp) local bcd = minetest.registered_nodes[bcn.name] -- Note: walkable is in the node definition, not in item groups local np = {x=bcp.x, y=bcp.y+1, z=bcp.z} if not self.driver then print("lost driver!") minetest.add_node(np, {name="lifter:lift"}) self.object:remove() nodeupdate(np) return end local ctrl = self.driver:get_player_control() if ctrl.jump then self.direction = 1 end if ctrl.sneak then self.direction = -1 end if ctrl.aux1 then self.direction = 0 self.object:setvelocity({x=0, y=0, z=0}) end pos.y = pos.y+1 local nex = 1 local wnode = minetest.get_node({x=pos.x+1, y=pos.y, z=pos.z}) local wbnode = minetest.get_node({x=pos.x+1, y=pos.y-nex, z=pos.z}) local snode = minetest.get_node({x=pos.x-1, y=pos.y, z=pos.z}) local sbnode = minetest.get_node({x=pos.x-1, y=pos.y-nex, z=pos.z}) local anode = minetest.get_node({x=pos.x, y=pos.y, z=pos.z+1}) local abnode = minetest.get_node({x=pos.x, y=pos.y-nex, z=pos.z+1}) local dnode = minetest.get_node({x=pos.x, y=pos.y, z=pos.z-1}) local dbnode = minetest.get_node({x=pos.x, y=pos.y-nex, z=pos.z-1}) if self.direction ~= 0 and not ctrl.jump and not ctrl.sneak then if (wnode.name == "air" and wbnode.name ~= "air") or (snode.name == "air" and sbnode.name ~= "air") or (anode.name == "air" and abnode.name ~= "air") or (dnode.name == "air" and dbnode.name ~= "air") then self.direction = 0 self.object:setvelocity({x=0, y=0, z=0}) self.object:setacceleration({x=0, y=0, z=0}) end if (wnode.name:find("door") and not wbnode.name:find("door")) or (snode.name:find("door") and not sbnode.name:find("door")) or (anode.name:find("door") and not abnode.name:find("door")) or (dnode.name:find("door") and not dbnode.name:find("door")) then self.direction = 0 self.object:setvelocity({x=0, y=0, z=0}) self.object:setacceleration({x=0, y=0, z=0}) end end if wnode.name == "air" and snode.name == "air" and anode.name == "air" and dnode.name == "air" then if self.direction >= 0 then self.direction = 0 self.object:setvelocity({x=0, y=0, z=0}) else self.object:setacceleration({x=0, y=-10, z=0}) end end local vel = self.object:getvelocity() if vector.equals(vel, {x=0,y=0,z=0}) then if ctrl.up or ctrl.down or ctrl.left or ctrl.right then exit = true end local npos = self.object:getpos() if self.direction == 1 then npos.y = npos.y+0.5 if minetest.get_node({x=npos.x, y=npos.y+2.5, z=npos.z}).name ~= "air" then npos.y = npos.y-0.5 end end if self.direction == -1 then npos.y = npos.y-1 if minetest.get_node(npos).name ~= "air" then npos.y = npos.y+0.5 end end self.object:setpos(vector.round(npos)) end if exit and not self.exiting then local door = minetest.find_node_near(np, 2, "lifter:door_a") if door then b1rc(door, minetest.get_node(door), self.driver) end -- Create node and remove entity minetest.add_node(np, {name="lifter:lift"}) nodeupdate(np) np.y = np.y-1 if minetest.get_node(np).name == "air" then minetest.add_node(np, {name="lifter:block"}) end self.exiting = true minetest.after(0.2, function(self) if self.driver then self.exiting = false self.driver:set_detach() self.driver:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0}) pos.y = pos.y self.driver:setpos(pos) self.object:remove() end end, self) return end if ctrl.jump or ctrl.sneak then -- Set gravity self.object:setacceleration({x=0, y=self.direction*5, z=0}) else self.object:setacceleration({x=0, y=0, z=0}) end end }) minetest.register_craft({ output = "lifter:lift", recipe = { {"group:wood", "group:stick", "group:wood"}, {"group:wood", "default:mese", "group:wood"}, {"group:wood", "group:stick", "group:wood"}, }, })