commit 3fb77635606cf080d33e68b9637e92fd669d31fd Author: tenplus1 Date: Thu Jun 3 08:46:14 2021 +0100 Initial 1.2 upload diff --git a/Changelog.txt b/Changelog.txt new file mode 100644 index 0000000..232efd4 --- /dev/null +++ b/Changelog.txt @@ -0,0 +1,24 @@ +1.0.1 beta +---------- +- Add backwards compatibility with PilzAdam's beds mod +- Fix placement +- Fix small bugs +- Prevent possible crash + +1.1 +--- +- Add fancy bed model (based on jp's model) +- Add API to register beds +- Allow players always to detach from bed (by donat-b) +- If more than 50% of players want sleep they can skip the night +- Don't show sleep dialog in singleplayer + +1.1.1 +----- +- Prevent possbile crash by trying to reposition leaving players + +1.2 +--- +- Updated to use default bed functions +- Texture check to fix beds using old api +- 'bed_sleep_divide' setting added [1 for all, 2 for half, 3 for third] diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..caa86ac --- /dev/null +++ b/README.txt @@ -0,0 +1,30 @@ +Minetest Game mod: beds +======================= +See license.txt for license information. + +Authors of source code +---------------------- +Originally by BlockMen (MIT) +Various Minetest developers and contributors (MIT) + +Authors of media (textures) +--------------------------- +BlockMen (CC BY-SA 3.0) + All textures unless otherwise noted + +JP (WTFPL) + All models unless otherwise noted + +This mod adds a bed to Minetest which allows to skip the night. +To sleep, rightclick the bed. If playing in singleplayer mode the night gets skipped +immediately. If playing multiplayer you get shown how many other players are in bed too, +if all players are sleeping the night gets skipped. The night skip can be forced if more +than 50% of the players are lying in bed and use this option. + +Another feature is a controlled respawning. If you have slept in bed (not just lying in +it) your respawn point is set to the beds location and you will respawn there after +death. +You can disable the respawn at beds by setting "enable_bed_respawn = false" in +minetest.conf. +You can disable the night skip feature by setting "enable_bed_night_skip = false" in +minetest.conf or by using the /set command in-game. diff --git a/api.lua b/api.lua new file mode 100644 index 0000000..e8022fe --- /dev/null +++ b/api.lua @@ -0,0 +1,127 @@ + +function beds.register_bed(name, def) + + local new_tiles + local new_mesh = "beds_simple_bed.obj" + + -- old api texture check + if def.tiles and def.tiles.bottom then + + new_tiles = "beds_simple_bed.png" -- default + + -- check for fancy bed + if def.nodebox and def.nodebox.bottom and #def.nodebox.bottom > 3 then + new_tiles = "beds_fancy_bed.png" + new_mesh = "beds_fancy_bed.obj" + end + end + + -- register bed node + minetest.register_node(name, { + description = def.description, + inventory_image = def.inventory_image, + wield_image = def.wield_image, + drawtype = "mesh", + mesh = def.mesh or new_mesh, + tiles = new_tiles or def.tiles, + paramtype = "light", + paramtype2 = "facedir", + stack_max = 1, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 1}, + sounds = default.node_sound_wood_defaults(), + selection_box = { + type = "fixed", + fixed = def.selectionbox, + }, + collision_box = { + type = "fixed", + fixed = def.collisionbox, + }, + + on_place = function(itemstack, placer, pointed_thing) + + local under = pointed_thing.under + local node = minetest.get_node(under) + local udef = minetest.registered_nodes[node.name] + + if udef and udef.on_rightclick + and not (placer and placer:is_player() + and placer:get_player_control().sneak) then + + return udef.on_rightclick(under, node, placer, itemstack, + pointed_thing) or itemstack + end + + local pos + + if udef and udef.buildable_to then + pos = under + else + pos = pointed_thing.above + end + + local player_name = placer and placer:get_player_name() or "" + + if minetest.is_protected(pos, player_name) + and not minetest.check_player_privs(player_name, "protection_bypass") then + + minetest.record_protection_violation(pos, player_name) + + return itemstack + end + + local node_def = minetest.registered_nodes[minetest.get_node(pos).name] + + if not node_def or not node_def.buildable_to then + return itemstack + end + + local dir = placer and placer:get_look_dir() and + minetest.dir_to_facedir(placer:get_look_dir()) or 0 + local botpos = vector.add(pos, minetest.facedir_to_dir(dir)) + + if minetest.is_protected(botpos, player_name) + and not minetest.check_player_privs(player_name, "protection_bypass") then + + minetest.record_protection_violation(botpos, player_name) + + return itemstack + end + + local botdef = minetest.registered_nodes[minetest.get_node(botpos).name] + + if not botdef or not botdef.buildable_to then + return itemstack + end + + minetest.set_node(pos, {name = name, param2 = dir}) + + if not minetest.is_creative_enabled(player_name) then + itemstack:take_item() + end + + return itemstack + end, + + on_rightclick = function(pos, node, clicker) + beds.on_rightclick(pos, clicker) + end, + + on_destruct = function(pos) + beds.remove_spawns_at(pos) + end, + + can_dig = function(pos, player) + return beds.can_dig(pos) + end + }) + + minetest.register_alias(name .. "_bottom", name) + minetest.register_alias(name .. "_top", "air") + + -- register recipe + minetest.register_craft({ + output = name, + recipe = def.recipe + }) +end diff --git a/beds.lua b/beds.lua new file mode 100644 index 0000000..d2a1034 --- /dev/null +++ b/beds.lua @@ -0,0 +1,54 @@ +-- support for MT game translation. +local S = beds.get_translator + +-- Fancy shaped bed + +beds.register_bed("beds:fancy_bed", { + description = S("Fancy Bed"), + inventory_image = "beds_bed_fancy.png", + wield_image = "beds_bed_fancy.png", + tiles = {"beds_fancy_bed.png", "default_wood.png"}, + mesh = "beds_fancy_bed.obj", + selectionbox = {-0.5, -0.5, -0.5, 0.5, 0.1875, 1.5}, + collisionbox = {-0.5, -0.5, -0.5, 0.5, 0, 1.5}, + recipe = { + {"", "", "group:stick"}, + {"wool:white", "wool:white", "wool:white"}, + {"group:wood", "group:wood", "group:wood"} + } +}) + +-- Simple shaped bed + +beds.register_bed("beds:bed", { + description = S("Simple Bed"), + inventory_image = "beds_bed.png", + wield_image = "beds_bed.png", + tiles = {"beds_simple_bed.png"}, + mesh = "beds_simple_bed.obj", + selectionbox = {-0.5, -0.5, -0.5, 0.5, 0.06, 1.5}, + collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.06, 1.5}, + recipe = { + {"wool:red", "wool:red", "wool:white"}, + {"group:wood", "group:wood", "group:wood"} + } +}) + +-- Aliases for PilzAdam's beds mod + +minetest.register_alias("beds:bed_bottom_red", "beds:bed_bottom") +minetest.register_alias("beds:bed_top_red", "beds:bed_top") + +-- Fuel + +minetest.register_craft({ + type = "fuel", + recipe = "beds:fancy_bed", + burntime = 13 +}) + +minetest.register_craft({ + type = "fuel", + recipe = "beds:bed", + burntime = 12 +}) diff --git a/functions.lua b/functions.lua new file mode 100644 index 0000000..34a4c7a --- /dev/null +++ b/functions.lua @@ -0,0 +1,370 @@ +local pi = math.pi +local is_sp = minetest.is_singleplayer() +local enable_respawn = minetest.settings:get_bool("enable_bed_respawn") + +if enable_respawn == nil then + enable_respawn = true +end + +-- support for MT game translation. +local S = beds.get_translator + +-- Helper functions + +local function get_look_yaw(pos) + + local rotation = minetest.get_node(pos).param2 + + if rotation > 3 then + rotation = rotation % 4 -- Mask colorfacedir values + end + + if rotation == 1 then + return pi / 2, rotation + elseif rotation == 3 then + return -pi / 2, rotation + elseif rotation == 0 then + return pi, rotation + else + return 0, rotation + end +end + +local function is_night_skip_enabled() + + local enable_night_skip = minetest.settings:get_bool("enable_bed_night_skip") + + if enable_night_skip == nil then + enable_night_skip = true + end + + return enable_night_skip +end + +local function check_in_beds(players) + + local in_bed = beds.player + + if not players then + players = minetest.get_connected_players() + end + + for n, player in ipairs(players) do + + local name = player:get_player_name() + + if not in_bed[name] then + return false + end + end + + return #players > 0 +end + +local function lay_down(player, pos, bed_pos, state, skip) + + local name = player:get_player_name() + local hud_flags = player:hud_get_flags() + + if not player or not name then + return + end + + -- stand up + if state ~= nil and not state then + + if not beds.player[name] then + return false -- player not in bed, do nothing + end + + beds.bed_position[name] = nil + + -- skip here to prevent sending player specific changes (used for leaving players) + if skip then + return + end + + player:set_pos(beds.pos[name]) + + -- physics, eye_offset, etc + local physics_override = beds.player[name].physics_override + + beds.player[name] = nil + + player:set_physics_override({ + speed = physics_override.speed, + jump = physics_override.jump, + gravity = physics_override.gravity + }) + + player:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0}) + player:set_look_horizontal(math.random(1, 180) / 100) + + player_api.player_attached[name] = false + hud_flags.wielditem = true + player_api.set_animation(player, "stand" , 30) + + -- lay down + else + + -- Check if bed is occupied + for _, other_pos in pairs(beds.bed_position) do + + if vector.distance(bed_pos, other_pos) < 0.1 then + + minetest.chat_send_player(name, S("This bed is already occupied!")) + + return false + end + end + + -- Check if player is moving + if vector.length(player:get_velocity()) > 0.001 then + + minetest.chat_send_player(name, + S("You have to stop moving before going to bed!")) + + return false + end + + -- Check if player is attached to an object + if player:get_attach() then + return false + end + + if beds.player[name] then + -- player already in bed, do nothing + return false + end + + beds.pos[name] = pos + beds.bed_position[name] = bed_pos + beds.player[name] = {physics_override = player:get_physics_override()} + + -- physics, eye_offset, etc + player:set_eye_offset({x = 0, y = -13, z = 0}, {x = 0, y = 0, z = 0}) + + local yaw, param2 = get_look_yaw(bed_pos) + + player:set_look_horizontal(yaw) + + local dir = minetest.facedir_to_dir(param2) + + -- p.y is just above the nodebox height of the 'Simple Bed' (the highest bed), + -- to avoid sinking down through the bed. + local p = { + x = bed_pos.x + dir.x / 2, + y = bed_pos.y + 0.07, + z = bed_pos.z + dir.z / 2 + } + + player:set_physics_override({speed = 0, jump = 0, gravity = 0}) + player:set_pos(p) + player_api.player_attached[name] = true + hud_flags.wielditem = false + player_api.set_animation(player, "lay" , 0) + end + + player:hud_set_flags(hud_flags) +end + +local function get_player_in_bed_count() + + local c = 0 + + for _, _ in pairs(beds.player) do + c = c + 1 + end + + return c +end + +local function update_formspecs(finished) + + local ges = #minetest.get_connected_players() + local player_in_bed = get_player_in_bed_count() + local is_majority = (ges / 2) < player_in_bed + local form_n + local esc = minetest.formspec_escape + + if finished then + form_n = beds.formspec .. "label[2.7,9;" .. esc(S("Good morning.")) .. "]" + else + form_n = beds.formspec .. "label[2.2,9;" .. + esc(S("@1 of @2 players are in bed", player_in_bed, ges)) .. "]" + + if is_majority and is_night_skip_enabled() then + form_n = form_n .. "button_exit[2,6;4,0.75;force;" .. + esc(S("Force night skip")) .. "]" + end + end + + for name,_ in pairs(beds.player) do + minetest.show_formspec(name, "beds_form", form_n) + end +end + + +-- Public functions + +function beds.kick_players() + + for name, _ in pairs(beds.player) do + + local player = minetest.get_player_by_name(name) + + lay_down(player, nil, nil, false) + end +end + +function beds.skip_night() + minetest.set_timeofday(0.23) +end + +function beds.on_rightclick(pos, player) + + local name = player:get_player_name() + local ppos = player:get_pos() + local tod = minetest.get_timeofday() + + if tod > 0.2 and tod < 0.805 then + + if beds.player[name] then + lay_down(player, nil, nil, false) + end + + minetest.chat_send_player(name, S("You can only sleep at night.")) + + return + end + + -- move to bed + if not beds.player[name] then + + lay_down(player, ppos, pos) + + beds.set_spawns() -- save respawn positions when entering bed + else + lay_down(player, nil, nil, false) + end + + if not is_sp then + update_formspecs(false) + end + + -- skip the night and let all players stand up + if check_in_beds() then + + minetest.after(2, function() + + if not is_sp then + update_formspecs(is_night_skip_enabled()) + end + + if is_night_skip_enabled() then + beds.skip_night() + beds.kick_players() + end + end) + end +end + +function beds.can_dig(bed_pos) + + -- Check all players in bed which one is at the expected position + for _, player_bed_pos in pairs(beds.bed_position) do + + if vector.equals(bed_pos, player_bed_pos) then + return false + end + end + + return true +end + +-- Callbacks +-- Only register respawn callback if respawn enabled +if enable_respawn then + + -- respawn player at bed if enabled and valid position is found + minetest.register_on_respawnplayer(function(player) + + local name = player:get_player_name() + local pos = beds.spawn[name] + + if pos then + player:set_pos(pos) + return true + end + end) +end + +minetest.register_on_leaveplayer(function(player) + + local name = player:get_player_name() + + lay_down(player, nil, nil, false, true) + + beds.player[name] = nil + + if check_in_beds() then + + minetest.after(2, function() + + update_formspecs(is_night_skip_enabled()) + + if is_night_skip_enabled() then + beds.skip_night() + beds.kick_players() + end + end) + end +end) + +minetest.register_on_dieplayer(function(player) + + local name = player:get_player_name() + local in_bed = beds.player + local pos = player:get_pos() + local yaw = get_look_yaw(pos) + + if in_bed[name] then + lay_down(player, nil, pos, false) + player:set_look_horizontal(yaw) + player:set_pos(pos) + end +end) + +local div = tonumber(minetest.settings:get("bed_sleep_divide")) or 2 + +minetest.register_on_player_receive_fields(function(player, formname, fields) + + if formname ~= "beds_form" then + return + end + + -- Because "Force night skip" button is a button_exit, it will set fields.quit + -- and lay_down call will change value of player_in_bed, so it must be taken + -- earlier. + local last_player_in_bed = get_player_in_bed_count() + + if fields.quit or fields.leave then + lay_down(player, nil, nil, false) + update_formspecs(false) + end + + if fields.force then + + -- check if enough players are sleeping to skip night (was half) + local is_majority = ( + #minetest.get_connected_players() / div) < last_player_in_bed + + if is_majority and is_night_skip_enabled() then + update_formspecs(true) + beds.skip_night() + beds.kick_players() + else + update_formspecs(false) + end + end +end) diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..a1a46ce --- /dev/null +++ b/init.lua @@ -0,0 +1,26 @@ +-- beds/init.lua + +-- Load support for MT game translation. +local S = minetest.get_translator("beds") +local esc = minetest.formspec_escape + +beds = {} +beds.player = {} +beds.bed_position = {} +beds.pos = {} +beds.spawn = {} +beds.get_translator = S + +beds.formspec = "size[8,11;true]" .. + "no_prepend[]" .. + "bgcolor[#080808BB;true]" .. + "button_exit[2,10;4,0.75;leave;" .. esc(S("Leave Bed")) .. "]" + +local modpath = minetest.get_modpath("beds") + +-- Load files + +dofile(modpath .. "/functions.lua") +dofile(modpath .. "/api.lua") +dofile(modpath .. "/beds.lua") +dofile(modpath .. "/spawns.lua") diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..f3c517f --- /dev/null +++ b/license.txt @@ -0,0 +1,61 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2014-2016 BlockMen +Copyright (C) 2014-2016 Various Minetest developers and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media (textures) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2014-2016 BlockMen +Copyright (C) 2018 TumeniNodes + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/locale/beds.de.tr b/locale/beds.de.tr new file mode 100644 index 0000000..3f2c959 --- /dev/null +++ b/locale/beds.de.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Schickes Bett +Simple Bed=Schlichtes Bett +This bed is already occupied!=Dieses Bett ist bereits belegt! +You have to stop moving before going to bed!=Sie müssen stehen bleiben, bevor Sie zu Bett gehen können! +Good morning.=Guten Morgen. +@1 of @2 players are in bed=@1 von @2 Spielern sind im Bett +Force night skip=Überspringen der Nacht erzwingen +You can only sleep at night.=Sie können nur nachts schlafen. +Leave Bed=Bett verlassen diff --git a/locale/beds.es.tr b/locale/beds.es.tr new file mode 100644 index 0000000..8ef0db7 --- /dev/null +++ b/locale/beds.es.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Cama de lujo +Simple Bed=Cama sencilla +This bed is already occupied!=Esta cama esta ocupada +You have to stop moving before going to bed!=Deja de moverte o no podras acostarte +Good morning.=Buenos días. +@1 of @2 players are in bed=@1 de @2 jugadores están durmiendo +Force night skip=Forzar hacer de dia +You can only sleep at night.=Sólo puedes dormir por la noche. +Leave Bed=Levantarse diff --git a/locale/beds.fr.tr b/locale/beds.fr.tr new file mode 100644 index 0000000..e1f8e56 --- /dev/null +++ b/locale/beds.fr.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Lit chic +Simple Bed=Lit simple +This bed is already occupied!= +You have to stop moving before going to bed!= +Good morning.=Bonjour. +@1 of @2 players are in bed=@1 joueur(s) sur @2 sont au lit +Force night skip=Forcer le passage de la nuit +You can only sleep at night.=Vous ne pouvez dormir que la nuit. +Leave Bed=Se lever du lit diff --git a/locale/beds.id.tr b/locale/beds.id.tr new file mode 100644 index 0000000..7bcbb5d --- /dev/null +++ b/locale/beds.id.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Ranjang Mewah +Simple Bed=Ranjang Sederhana +This bed is already occupied!= +You have to stop moving before going to bed!= +Good morning.=Selamat pagi. +@1 of @2 players are in bed=@1 dari @2 pemain sedang tidur +Force night skip=Paksa lewati malam +You can only sleep at night.=Anda hanya dapat tidur pada waktu malam. +Leave Bed=Tinggalkan Ranjang diff --git a/locale/beds.it.tr b/locale/beds.it.tr new file mode 100644 index 0000000..8f4e14e --- /dev/null +++ b/locale/beds.it.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Letto decorato +Simple Bed=Letto semplice +This bed is already occupied!= +You have to stop moving before going to bed!= +Good morning.= +@1 of @2 players are in bed= +Force night skip= +You can only sleep at night.= +Leave Bed=Alzati dal letto diff --git a/locale/beds.jbo.tr b/locale/beds.jbo.tr new file mode 100644 index 0000000..a72f686 --- /dev/null +++ b/locale/beds.jbo.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=lo selja'i ckana +Simple Bed=lo sampu ckana +This bed is already occupied!=.i lo ti ckana cu canlu +You have to stop moving before going to bed!=lo nu do cando cu sarcu lo nu do sipna +Good morning.=.i .uise'inai cerni +@1 of @2 players are in bed=.i @1 cmima be lu'i @2 le pilno cu vreta lo ckana +Force night skip=bapli le nu co'u nicte +You can only sleep at night.=.i steci le ka nicte kei fa le ka do kakne le ka sipna ca pa ckaji be ce'u +Leave Bed=cliva lo ckana diff --git a/locale/beds.ms.tr b/locale/beds.ms.tr new file mode 100644 index 0000000..4d4310a --- /dev/null +++ b/locale/beds.ms.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Katil Beragam +Simple Bed=Katil Biasa +This bed is already occupied!= +You have to stop moving before going to bed!= +Good morning.=Selamat pagi. +@1 of @2 players are in bed=@1 daripada @2 pemain sedang tidur +Force night skip=Paksa langkau malam +You can only sleep at night.=Anda hanya boleh tidur pada waktu malam. +Leave Bed=Bangun diff --git a/locale/beds.pt_BR.tr b/locale/beds.pt_BR.tr new file mode 100644 index 0000000..47fb1b9 --- /dev/null +++ b/locale/beds.pt_BR.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Cama Bonita +Simple Bed=Cama Simples +This bed is already occupied!=Esta cama já está ocupada! +You have to stop moving before going to bed!=Você precisa parar de se mover antes de ir para cama! +Good morning.=Bom dia. +@1 of @2 players are in bed=@1 de @2 jogadores estão na cama +Force night skip=Forçar o amanhecer +You can only sleep at night.=Você só pode dormir à noite +Leave Bed=Sair da Cama diff --git a/locale/beds.ru.tr b/locale/beds.ru.tr new file mode 100644 index 0000000..ac5bd2e --- /dev/null +++ b/locale/beds.ru.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Детализированная Кровать +Simple Bed=Обычная Кровать +This bed is already occupied!= +You have to stop moving before going to bed!= +Good morning.=Доброе утро. +@1 of @2 players are in bed=@1 из @2 игроков в кровати +Force night skip=Пропустить ночь +You can only sleep at night.=Вы можете спать только ночью. +Leave Bed=Встать с кровати diff --git a/locale/beds.se.tr b/locale/beds.se.tr new file mode 100644 index 0000000..b4d52ba --- /dev/null +++ b/locale/beds.se.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Fin säng +Simple Bed=Enkel Säng +This bed is already occupied!= +You have to stop moving before going to bed!= +Good morning.= God morgon. +@1 of @2 players are in bed=@1 av @2 spelar försöker sover. +Force night skip=Tvinga över natten +You can only sleep at night.=Du kan bara sova på natten. +Leave Bed=Lämna Säng diff --git a/locale/beds.sk.tr b/locale/beds.sk.tr new file mode 100644 index 0000000..37f39dd --- /dev/null +++ b/locale/beds.sk.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Pekná posteľ +Simple Bed=Jednoduchá posteľ +This bed is already occupied!= +You have to stop moving before going to bed!= +Good morning.=Dobré ráno. +@1 of @2 players are in bed=@1 z @2 hráčov sú v posteli +Force night skip=Nútene preskočiť noc +You can only sleep at night.=Môžeš spať len v noci. +Leave Bed=Opusti posteľ diff --git a/locale/beds.zh_CN.tr b/locale/beds.zh_CN.tr new file mode 100644 index 0000000..6a06e09 --- /dev/null +++ b/locale/beds.zh_CN.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=花式床 +Simple Bed=简易床 +This bed is already occupied!= +You have to stop moving before going to bed!= +Good morning.=早安! +@1 of @2 players are in bed=@2位玩家中的@1位在床上 +Force night skip=强制跳过夜晚 +You can only sleep at night.=你只能在晚上睡觉。 +Leave Bed=离开床 diff --git a/locale/beds.zh_TW.tr b/locale/beds.zh_TW.tr new file mode 100644 index 0000000..b19b481 --- /dev/null +++ b/locale/beds.zh_TW.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=花式床 +Simple Bed=簡易床 +This bed is already occupied!= +You have to stop moving before going to bed!= +Good morning.=早安! +@1 of @2 players are in bed=@2位玩家中的@1位在床上 +Force night skip=強制跳過夜晚 +You can only sleep at night.=你只能在晚上睡覺。 +Leave Bed=離開床 diff --git a/locale/template.txt b/locale/template.txt new file mode 100644 index 0000000..a965787 --- /dev/null +++ b/locale/template.txt @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed= +Simple Bed= +This bed is already occupied!= +You have to stop moving before going to bed!= +Good morning.= +@1 of @2 players are in bed= +Force night skip= +You can only sleep at night.= +Leave Bed= diff --git a/mod.conf b/mod.conf new file mode 100644 index 0000000..450ec13 --- /dev/null +++ b/mod.conf @@ -0,0 +1,3 @@ +name = beds +description = Minetest Game mod: beds +depends = default, wool diff --git a/models/beds_fancy_bed.obj b/models/beds_fancy_bed.obj new file mode 100644 index 0000000..285be20 --- /dev/null +++ b/models/beds_fancy_bed.obj @@ -0,0 +1,160 @@ +# Blender v2.69 (sub 0) OBJ File: '' +# www.blender.org +mtllib fancy_bed.mtl +o mattress_Mattress_nodebox-6_none.001_fancy_bed.png.001 +v 0.437500 -0.312500 -0.437501 +v 0.437500 -0.062500 -0.437501 +v 0.437500 -0.062500 1.437499 +v 0.437500 -0.312500 1.437499 +v -0.437500 -0.312500 -0.437501 +v -0.437500 -0.312500 1.437499 +v -0.437500 -0.062500 1.437499 +v -0.437500 -0.062500 -0.437501 +v 0.437500 -0.176793 -0.437501 +v -0.437500 -0.176793 -0.437501 +vt 0.000171 0.499972 +vt 0.000161 0.000182 +vt 0.999791 0.000253 +vt 0.999873 0.500022 +vt 0.749576 0.000208 +vt 0.749876 0.499854 +vt 0.999848 0.999750 +vt 0.000152 0.999750 +vt 0.749276 0.130648 +vt 0.000112 0.130648 +g mattress_Mattress_nodebox-6_none.001_fancy_bed.png.001_none.001_fancy_bed.png.001 +usemtl none.001_fancy_bed.png.001 +s off +f 1/1 2/2 3/3 4/4 +f 5/2 6/3 7/4 8/1 +f 4/5 3/2 7/1 6/6 +f 1/1 4/4 6/7 5/8 +f 2/1 8/2 7/3 3/4 +f 8/2 2/5 9/9 10/10 +o wood_structure_Wood_structure_nodebox-4.001_none.002 +v 0.374999 -0.375000 1.437499 +v 0.374999 -0.125000 1.437499 +v 0.374999 -0.125000 1.499999 +v 0.374999 -0.375000 1.499999 +v -0.374999 -0.375000 1.437499 +v -0.374999 -0.375000 1.499999 +v -0.374999 -0.125000 1.499999 +v -0.374999 -0.125000 1.437499 +v -0.375000 -0.500000 1.437499 +v -0.375000 0.187500 1.437499 +v -0.375000 0.187500 1.499999 +v -0.375000 -0.500000 1.499999 +v -0.500000 -0.500000 1.437499 +v -0.500000 -0.500000 1.499999 +v -0.500000 0.187500 1.499999 +v -0.500000 0.187500 1.437499 +v -0.437500 -0.375000 -0.437501 +v -0.437500 -0.125000 -0.437501 +v -0.437500 -0.125000 1.437498 +v -0.437500 -0.375000 1.437498 +v -0.500000 -0.375000 -0.437501 +v -0.500000 -0.375000 1.437498 +v -0.500000 -0.125000 1.437498 +v -0.500000 -0.125000 -0.437501 +v 0.375001 -0.000000 1.437499 +v 0.375001 0.125000 1.437499 +v 0.375001 0.125000 1.499999 +v 0.375001 -0.000000 1.499999 +v -0.375001 -0.000000 1.437499 +v -0.375001 -0.000000 1.499999 +v -0.375001 0.125000 1.499999 +v -0.375001 0.125000 1.437499 +v 0.500000 -0.500000 1.437499 +v 0.500000 0.187500 1.437499 +v 0.500000 0.187500 1.499999 +v 0.500000 -0.500000 1.499999 +v 0.375000 -0.500000 1.437499 +v 0.375000 -0.500000 1.499999 +v 0.375000 0.187500 1.499999 +v 0.375000 0.187500 1.437499 +v 0.500000 -0.375000 -0.437501 +v 0.500000 -0.125000 -0.437501 +v 0.500000 -0.125000 1.437499 +v 0.500000 -0.375000 1.437499 +v 0.437500 -0.375000 -0.437501 +v 0.437500 -0.375000 1.437499 +v 0.437500 -0.125000 1.437499 +v 0.437500 -0.125000 -0.437501 +v -0.375000 -0.500000 -0.500000 +v -0.375000 -0.065000 -0.500000 +v -0.375000 -0.065000 -0.437500 +v -0.375000 -0.500000 -0.437500 +v -0.500000 -0.500000 -0.500000 +v -0.500000 -0.500000 -0.437500 +v -0.500000 -0.065000 -0.437500 +v -0.500000 -0.065000 -0.500000 +v 0.375006 -0.375000 -0.500000 +v 0.375006 -0.125000 -0.500000 +v 0.375006 -0.125000 -0.437500 +v 0.375006 -0.375000 -0.437500 +v -0.375006 -0.375000 -0.500000 +v -0.375006 -0.375000 -0.437500 +v -0.375006 -0.125000 -0.437500 +v -0.375006 -0.125000 -0.500000 +v 0.500000 -0.500000 -0.500000 +v 0.500000 -0.065000 -0.500000 +v 0.500000 -0.065000 -0.437500 +v 0.500000 -0.500000 -0.437500 +v 0.375000 -0.500000 -0.500000 +v 0.375000 -0.500000 -0.437500 +v 0.375000 -0.065000 -0.437500 +v 0.375000 -0.065000 -0.500000 +vt 0.377610 0.378205 +vt 0.622484 0.378175 +vt 0.622515 0.623120 +vt 0.377671 0.623151 +g wood_structure_Wood_structure_nodebox-4.001_none.002_none.002 +usemtl none.002 +s off +f 59/11 60/12 61/13 62/14 +f 63/14 64/11 65/12 66/13 +f 59/11 63/14 66/13 60/12 +f 62/14 61/13 65/12 64/11 +f 59/11 62/14 64/13 63/12 +f 60/12 66/11 65/14 61/13 +f 67/11 71/12 74/13 68/14 +f 70/14 69/11 73/12 72/13 +f 67/11 70/12 72/13 71/14 +f 68/11 74/12 73/13 69/14 +f 75/11 76/12 77/13 78/14 +f 79/14 80/11 81/12 82/13 +f 75/14 79/11 82/12 76/13 +f 78/11 77/12 81/13 80/14 +f 75/11 78/12 80/13 79/14 +f 76/11 82/12 81/13 77/14 +g wood_structure_Wood_structure_nodebox-4.001_none.002_none.003 +usemtl none.003 +f 15/11 16/12 17/13 18/14 +f 11/13 15/14 18/11 12/12 +f 14/14 13/11 17/12 16/13 +f 11/14 14/11 16/12 15/13 +f 12/11 18/12 17/13 13/14 +f 19/11 20/12 21/13 22/14 +f 23/14 24/11 25/12 26/13 +f 19/14 23/11 26/12 20/13 +f 22/11 21/12 25/13 24/14 +f 19/11 22/12 24/13 23/14 +f 20/11 26/12 25/13 21/14 +f 27/14 28/11 29/12 30/13 +f 31/11 32/12 33/13 34/14 +f 27/11 30/12 32/13 31/14 +f 28/14 34/11 33/12 29/13 +f 35/11 39/12 42/13 36/14 +f 38/14 37/11 41/12 40/13 +f 35/14 38/11 40/12 39/13 +f 36/11 42/12 41/13 37/14 +f 43/11 44/12 45/13 46/14 +f 47/14 48/11 49/12 50/13 +f 43/14 47/11 50/12 44/13 +f 46/11 45/12 49/13 48/14 +f 43/11 46/12 48/13 47/14 +f 44/11 50/12 49/13 45/14 +f 51/14 52/11 53/12 54/13 +f 55/13 56/14 57/11 58/12 +f 51/11 54/12 56/13 55/14 +f 52/14 58/11 57/12 53/13 diff --git a/models/beds_simple_bed.obj b/models/beds_simple_bed.obj new file mode 100644 index 0000000..21ecfb4 --- /dev/null +++ b/models/beds_simple_bed.obj @@ -0,0 +1,32 @@ +# Blender v2.69 (sub 0) OBJ File: '' +# www.blender.org +mtllib simple_bed.mtl +o Simple_Bed +v 0.500000 -0.500000 -0.500000 +v 0.500000 0.060000 -0.500000 +v 0.500000 0.060000 1.500000 +v 0.500000 -0.500000 1.500000 +v -0.500000 -0.500000 -0.500000 +v -0.500000 -0.500000 1.500000 +v -0.500000 0.060000 1.500000 +v -0.500000 0.060000 -0.500000 +vt 0.000112 0.780442 +vt 0.000110 0.999969 +vt 0.780324 0.999889 +vt 0.780377 0.780471 +vt 0.780636 0.390284 +vt 0.999906 0.780382 +vt 0.999906 0.390284 +vt 0.780636 0.000047 +vt 0.999906 0.000094 +vt 0.390235 0.780320 +vt 0.390235 0.000071 +vt 0.000142 0.000142 +usemtl none.002 +s off +f 1/1 2/2 3/3 4/4 +f 5/1 6/4 7/3 8/2 +f 1/5 5/4 8/6 2/7 +f 4/8 3/9 7/7 6/5 +f 1/8 4/4 6/10 5/11 +f 2/11 8/12 7/1 3/10 diff --git a/screenshot.jpg b/screenshot.jpg new file mode 100644 index 0000000..a523878 Binary files /dev/null and b/screenshot.jpg differ diff --git a/settingtypes.txt b/settingtypes.txt new file mode 100644 index 0000000..d1b31a7 --- /dev/null +++ b/settingtypes.txt @@ -0,0 +1,5 @@ +enable_bed_respawn (Enable bed respawn) bool true + +enable_bed_night_skip (Enable night skip) bool true + +bed_sleep_divide (Division of players needed to skip night) float 2 diff --git a/spawns.lua b/spawns.lua new file mode 100644 index 0000000..a53b9aa --- /dev/null +++ b/spawns.lua @@ -0,0 +1,95 @@ +local world_path = minetest.get_worldpath() +local org_file = world_path .. "/beds_spawns" +local file = world_path .. "/beds_spawns" +local bkwd = false + +-- check for PA's beds mod spawns +local cf = io.open(world_path .. "/beds_player_spawns", "r") + +if cf ~= nil then + io.close(cf) + file = world_path .. "/beds_player_spawns" + bkwd = true +end + +function beds.read_spawns() + + local spawns = beds.spawn + local input = io.open(file, "r") + + if input and not bkwd then + + repeat + + local x = input:read("*n") + + if x == nil then + break + end + + local y = input:read("*n") + local z = input:read("*n") + local name = input:read("*l") + + spawns[name:sub(2)] = {x = x, y = y, z = z} + + until input:read(0) == nil + + io.close(input) + + elseif input and bkwd then + + beds.spawn = minetest.deserialize(input:read("*all")) + input:close() + beds.save_spawns() + os.rename(file, file .. ".backup") + file = org_file + end +end + +beds.read_spawns() + +function beds.save_spawns() + + if not beds.spawn then + return + end + + local data = {} + local output = io.open(org_file, "w") + + for k, v in pairs(beds.spawn) do + table.insert(data, string.format("%.1f %.1f %.1f %s\n", v.x, v.y, v.z, k)) + end + + output:write(table.concat(data)) + io.close(output) +end + +function beds.set_spawns() + + for name,_ in pairs(beds.player) do + + local player = minetest.get_player_by_name(name) + local p = player:get_pos() + + -- but don't change spawn location if borrowing a bed + if not minetest.is_protected(p, name) then + beds.spawn[name] = p + end + end + + beds.save_spawns() +end + +function beds.remove_spawns_at(pos) + + for name, p in pairs(beds.spawn) do + + if vector.equals(vector.round(p), pos) then + beds.spawn[name] = nil + end + end + + beds.save_spawns() +end diff --git a/textures/beds_bed.png b/textures/beds_bed.png new file mode 100644 index 0000000..5111a91 Binary files /dev/null and b/textures/beds_bed.png differ diff --git a/textures/beds_bed_fancy.png b/textures/beds_bed_fancy.png new file mode 100644 index 0000000..d43e6ec Binary files /dev/null and b/textures/beds_bed_fancy.png differ diff --git a/textures/beds_fancy_bed.png b/textures/beds_fancy_bed.png new file mode 100644 index 0000000..11ea830 Binary files /dev/null and b/textures/beds_fancy_bed.png differ diff --git a/textures/beds_simple_bed.png b/textures/beds_simple_bed.png new file mode 100644 index 0000000..93922ec Binary files /dev/null and b/textures/beds_simple_bed.png differ