local player_in_bed = 0 local guy local hand local old_yaw = 0 local function get_dir(pos) local btop = "beds:bed_top" if minetest.env:get_node({x=pos.x+1,y=pos.y,z=pos.z}).name == btop then return 7.9 elseif minetest.env:get_node({x=pos.x-1,y=pos.y,z=pos.z}).name == btop then return 4.75 elseif minetest.env:get_node({x=pos.x,y=pos.y,z=pos.z+1}).name == btop then return 3.15 elseif minetest.env:get_node({x=pos.x,y=pos.y,z=pos.z-1}).name == btop then return 6.28 end end function plock(start, max, tick, player, yaw) if start+tick < max then player:set_look_pitch(-1.2) player:set_look_yaw(yaw) minetest.after(tick, plock, start+tick, max, tick, player, yaw) else player:set_look_pitch(0) if old_yaw ~= 0 then minetest.after(0.1+tick, function() player:set_look_yaw(old_yaw) end) end end end function exit(pos) local npos = minetest.env:find_node_near(pos, 1, "beds:bed_bottom") if npos ~= nil then pos = npos end if minetest.env:get_node({x=pos.x+1,y=pos.y,z=pos.z}).name == "air" then return {x=pos.x+1,y=pos.y,z=pos.z} elseif minetest.env:get_node({x=pos.x-1,y=pos.y,z=pos.z}).name == "air" then return {x=pos.x-1,y=pos.y,z=pos.z} elseif minetest.env:get_node({x=pos.x,y=pos.y,z=pos.z+1}).name == "air" then return {x=pos.x,y=pos.y,z=pos.z+1} elseif minetest.env:get_node({x=pos.x,y=pos.y,z=pos.z-1}).name == "air" then return {x=pos.x,y=pos.y,z=pos.z-1} else return {x=pos.x,y=pos.y,z=pos.z} end end minetest.register_node("beds:bed_bottom", { description = "Bed", inventory_image = "beds_bed.png", wield_image = "beds_bed.png", wield_scale = {x=0.8,y=2.5,z=1.3}, drawtype = "nodebox", tiles = {"beds_bed_top_bottom.png^[transformR90", "default_wood.png", "beds_bed_side_bottom_r.png", "beds_bed_side_bottom_r.png^[transformfx", "beds_bed_leer.png", "beds_bed_side_bottom.png"}, paramtype = "light", paramtype2 = "facedir", stack_max = 1, groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3}, sounds = default.node_sound_wood_defaults(), node_box = { type = "fixed", fixed = {-0.5, -0.5, -0.5, 0.5, 0.06, 0.5}, }, selection_box = { type = "fixed", fixed = {-0.5, -0.5, -0.5, 0.5, 0.06, 1.5}, }, after_place_node = function(pos, placer, itemstack) local node = minetest.env:get_node(pos) local param2 = node.param2 local npos = {x=pos.x, y=pos.y, z=pos.z} if param2 == 0 then npos.z = npos.z+1 elseif param2 == 1 then npos.x = npos.x+1 elseif param2 == 2 then npos.z = npos.z-1 elseif param2 == 3 then npos.x = npos.x-1 end if minetest.registered_nodes[minetest.env:get_node(npos).name].buildable_to == true and minetest.env:get_node({x=npos.x, y=npos.y-1, z=npos.z}).name ~= "air" then minetest.env:set_node(npos, {name="beds:bed_top", param2 = param2}) else minetest.env:dig_node(pos) return true end end, on_destruct = function(pos) pos = minetest.env:find_node_near(pos, 1, "beds:bed_top") if pos ~= nil then minetest.env:remove_node(pos) end end, on_rightclick = function(pos, node, clicker, itemstack) if not clicker:is_player() then return end if minetest.env:get_timeofday() > 0.2 and minetest.env:get_timeofday() < 0.805 then minetest.chat_send_all("You can only sleep at night") return else clicker:set_physics_override(0,0,0) old_yaw = clicker:get_look_yaw() guy = clicker clicker:set_look_yaw(get_dir(pos)) minetest.chat_send_all("Good night") plock(0,2,0.1,clicker, get_dir(pos)) end if not clicker:get_player_control().sneak then local meta = minetest.env:get_meta(pos) local param2 = node.param2 if param2 == 0 then pos.z = pos.z+1 elseif param2 == 1 then pos.x = pos.x+1 elseif param2 == 2 then pos.z = pos.z-1 elseif param2 == 3 then pos.x = pos.x-1 end if clicker:get_player_name() == meta:get_string("player") then if param2 == 0 then pos.x = pos.x-1 elseif param2 == 1 then pos.z = pos.z+1 elseif param2 == 2 then pos.x = pos.x+1 elseif param2 == 3 then pos.z = pos.z-1 end pos.y = pos.y-0.5 clicker:setpos(pos) meta:set_string("player", "") player_in_bed = player_in_bed-1 elseif meta:get_string("player") == "" then pos.y = pos.y-0.5 clicker:setpos(pos) meta:set_string("player", clicker:get_player_name()) player_in_bed = player_in_bed+1 end end end }) minetest.register_node("beds:bed_top", { drawtype = "nodebox", tiles = {"beds_bed_top_top.png^[transformR90", "beds_bed_leer.png", "beds_bed_side_top_r.png", "beds_bed_side_top_r.png^[transformfx", "beds_bed_side_top.png", "beds_bed_leer.png"}, paramtype = "light", paramtype2 = "facedir", groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3}, sounds = default.node_sound_wood_defaults(), node_box = { type = "fixed", fixed = {-0.5, -0.5, -0.5, 0.5, 0.06, 0.5}, }, selection_box = { type = "fixed", fixed = {0, 0, 0, 0, 0, 0}, }, }) minetest.register_alias("beds:bed", "beds:bed_bottom") minetest.register_craft({ output = "beds:bed", recipe = { {"group:wool", "group:wool", "group:wool", }, {"group:wood", "group:wood", "group:wood", } } }) beds_player_spawns = {} local file = io.open(minetest.get_worldpath().."/beds_player_spawns", "r") if file then beds_player_spawns = minetest.deserialize(file:read("*all")) file:close() end local timer = 0 local wait = false minetest.register_globalstep(function(dtime) if timer<2 then timer = timer+dtime return end timer = 0 local players = #minetest.get_connected_players() if players == player_in_bed and players ~= 0 then if minetest.env:get_timeofday() < 0.2 or minetest.env:get_timeofday() > 0.805 then if not wait then minetest.after(2, function() minetest.env:set_timeofday(0.23) wait = false guy:set_physics_override(1,1,1) guy:setpos(exit(guy:getpos())) end) wait = true for _,player in ipairs(minetest.get_connected_players()) do beds_player_spawns[player:get_player_name()] = player:getpos() end local file = io.open(minetest.get_worldpath().."/beds_player_spawns", "w") if file then file:write(minetest.serialize(beds_player_spawns)) file:close() end end end end end) minetest.register_on_respawnplayer(function(player) local name = player:get_player_name() if beds_player_spawns[name] then player:setpos(beds_player_spawns[name]) return true end end) minetest.register_abm({ nodenames = {"beds:bed_bottom"}, interval = 1, chance = 1, action = function(pos, node) local meta = minetest.env:get_meta(pos) if meta:get_string("player") ~= "" then local param2 = node.param2 if param2 == 0 then pos.z = pos.z+1 elseif param2 == 1 then pos.x = pos.x+1 elseif param2 == 2 then pos.z = pos.z-1 elseif param2 == 3 then pos.x = pos.x-1 end local player = minetest.env:get_player_by_name(meta:get_string("player")) if player == nil then meta:set_string("player", "") player_in_bed = player_in_bed-1 return end local player_pos = player:getpos() player_pos.x = math.floor(0.5+player_pos.x) player_pos.y = math.floor(0.5+player_pos.y) player_pos.z = math.floor(0.5+player_pos.z) if pos.x ~= player_pos.x or pos.y ~= player_pos.y or pos.z ~= player_pos.z then meta:set_string("player", "") player_in_bed = player_in_bed-1 return end end end }) if minetest.setting_get("log_mods") then minetest.log("action", "beds loaded") end