123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- --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, clicker)
- 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:get_pos()
- 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:set_velocity({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:set_velocity({x=0, y=0, z=0})
- self.object:set_acceleration({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:set_velocity({x=0, y=0, z=0})
- self.object:set_acceleration({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:set_velocity({x=0, y=0, z=0})
- else
- self.object:set_acceleration({x=0, y=-10, z=0})
- end
- end
-
- local vel = self.object:get_velocity()
- 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:get_pos()
- 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:set_pos(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:set_pos(pos)
-
- self.object:remove()
- end
- end, self)
-
- return
- end
-
- if ctrl.jump or ctrl.sneak then
- -- Set gravity
- self.object:set_acceleration({x=0, y=self.direction*5, z=0})
- else
- self.object:set_acceleration({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"},
- },
- })
|