diff --git a/beds/README.txt b/beds/README.txt new file mode 100644 index 0000000..380239c --- /dev/null +++ b/beds/README.txt @@ -0,0 +1,26 @@ +Minetest mod "Beds" +======================= +version: 1.1 + + +License of source code: WTFPL +----------------------------- +author: BlockMen (2013) +original author: PilzAdam + +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the Do What The Fuck You Want +To Public License, Version 2, as published by Sam Hocevar. See +http://sam.zoy.org/wtfpl/COPYING for more details. + + +--USING the mod-- +------------------ + +This mods implements Beds like known from Minecraft. You can use them to sleep at night to skip the time or to prevent attacks by evil mobs. + + +To sleep you have to "rightclick" on your bed. You can only sleep at night and get noticed when it is too early. + +After dying the player will respawn at the last bed he has slept. \ No newline at end of file diff --git a/beds/depends.txt b/beds/depends.txt new file mode 100644 index 0000000..f098279 --- /dev/null +++ b/beds/depends.txt @@ -0,0 +1,3 @@ +default + +wool diff --git a/beds/init.lua b/beds/init.lua new file mode 100644 index 0000000..bbd8b82 --- /dev/null +++ b/beds/init.lua @@ -0,0 +1,261 @@ +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 diff --git a/beds/textures/beds_bed.png b/beds/textures/beds_bed.png new file mode 100644 index 0000000..e8d0e5c Binary files /dev/null and b/beds/textures/beds_bed.png differ diff --git a/beds/textures/beds_bed_leer.png b/beds/textures/beds_bed_leer.png new file mode 100644 index 0000000..2dc0e3d Binary files /dev/null and b/beds/textures/beds_bed_leer.png differ diff --git a/beds/textures/beds_bed_side_bottom.png b/beds/textures/beds_bed_side_bottom.png new file mode 100644 index 0000000..7b20f03 Binary files /dev/null and b/beds/textures/beds_bed_side_bottom.png differ diff --git a/beds/textures/beds_bed_side_bottom_r.png b/beds/textures/beds_bed_side_bottom_r.png new file mode 100644 index 0000000..267dd45 Binary files /dev/null and b/beds/textures/beds_bed_side_bottom_r.png differ diff --git a/beds/textures/beds_bed_side_top.png b/beds/textures/beds_bed_side_top.png new file mode 100644 index 0000000..a7b4009 Binary files /dev/null and b/beds/textures/beds_bed_side_top.png differ diff --git a/beds/textures/beds_bed_side_top_r.png b/beds/textures/beds_bed_side_top_r.png new file mode 100644 index 0000000..a459f3c Binary files /dev/null and b/beds/textures/beds_bed_side_top_r.png differ diff --git a/beds/textures/beds_bed_top_bottom.png b/beds/textures/beds_bed_top_bottom.png new file mode 100644 index 0000000..4d20dea Binary files /dev/null and b/beds/textures/beds_bed_top_bottom.png differ diff --git a/beds/textures/beds_bed_top_top.png b/beds/textures/beds_bed_top_top.png new file mode 100644 index 0000000..fa8acc4 Binary files /dev/null and b/beds/textures/beds_bed_top_top.png differ