diff --git a/mods/mtg/beds/README.txt b/mods/mtg/beds/README.txt new file mode 100644 index 0000000..5c452da --- /dev/null +++ b/mods/mtg/beds/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 Game developers and contributors (MIT) + +Authors of media (textures) +--------------------------- +BlockMen (CC BY-SA 3.0) + All textures unless otherwise noted + +TumeniNodes (CC BY-SA 3.0) + beds_bed_under.png + +This mod adds a bed which allows players to skip the night. +To sleep, right click on 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 half 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/mods/mtg/beds/api.lua b/mods/mtg/beds/api.lua new file mode 100644 index 0000000..2214465 --- /dev/null +++ b/mods/mtg/beds/api.lua @@ -0,0 +1,204 @@ +-- Removes a node without calling on on_destruct() +-- We use this to mess with bed nodes without causing unwanted recursion. +local function remove_no_destruct(pos) + minetest.swap_node(pos, {name = "air"}) + minetest.remove_node(pos) -- Now clear the meta + minetest.check_for_falling(pos) +end + +--- returns the position of the other bed half (or nil on failure) +local function get_other_bed_pos(pos, n) + local node = core.get_node(pos) + local dir = core.facedir_to_dir(node.param2) + if not dir then + return -- There are 255 possible param2 values. Ignore bad ones. + end + local other + if n == 2 then + other = vector.subtract(pos, dir) + elseif n == 1 then + other = vector.add(pos, dir) + else + return nil + end + + local onode = core.get_node(other) + if onode.param2 == node.param2 and core.get_item_group(onode.name, "bed") ~= 0 then + return other + end + return nil +end + +local function destruct_bed(pos, n) + local other = get_other_bed_pos(pos, n) + if other then + remove_no_destruct(other) + beds.remove_spawns_at(other) + end + beds.remove_spawns_at(pos) +end + +function beds.register_bed(name, def) + minetest.register_node(name .. "_bottom", { + description = def.description, + inventory_image = def.inventory_image, + wield_image = def.wield_image, + drawtype = "nodebox", + tiles = def.tiles.bottom, + use_texture_alpha = "clip", + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = false, + stack_max = 1, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 1}, + sounds = def.sounds or default.node_sound_wood_defaults(), + node_box = { + type = "fixed", + fixed = def.nodebox.bottom, + }, + selection_box = { + type = "fixed", + fixed = def.selectionbox, + }, + + 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 .. "_bottom", param2 = dir}) + minetest.set_node(botpos, {name = name .. "_top", param2 = dir}) + + if not minetest.is_creative_enabled(player_name) then + itemstack:take_item() + end + return itemstack + end, + + on_destruct = function(pos) + destruct_bed(pos, 1) + end, + + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + beds.on_rightclick(pos, clicker) + return itemstack + end, + + on_rotate = function(pos, node, user, _, new_param2) + local dir = minetest.facedir_to_dir(node.param2) + if not dir then + return false + end + -- old position of the top node + local p = vector.add(pos, dir) + local node2 = minetest.get_node_or_nil(p) + if not node2 or minetest.get_item_group(node2.name, "bed") ~= 2 or + node.param2 ~= node2.param2 then + return false + end + if minetest.is_protected(p, user:get_player_name()) then + minetest.record_protection_violation(p, user:get_player_name()) + return false + end + if new_param2 % 32 > 3 then + return false + end + -- new position of the top node + local newp = vector.add(pos, minetest.facedir_to_dir(new_param2)) + local node3 = minetest.get_node_or_nil(newp) + local node_def = node3 and minetest.registered_nodes[node3.name] + if not node_def or not node_def.buildable_to then + return false + end + if minetest.is_protected(newp, user:get_player_name()) then + minetest.record_protection_violation(newp, user:get_player_name()) + return false + end + node.param2 = new_param2 + remove_no_destruct(p) + minetest.set_node(pos, node) + minetest.set_node(newp, {name = name .. "_top", param2 = new_param2}) + return true + end, + can_dig = function(pos, player) + return beds.can_dig(pos) + end, + }) + + minetest.register_node(name .. "_top", { + drawtype = "nodebox", + tiles = def.tiles.top, + use_texture_alpha = "clip", + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 2, + not_in_creative_inventory = 1}, + sounds = def.sounds or default.node_sound_wood_defaults(), + drop = "", + node_box = { + type = "fixed", + fixed = def.nodebox.top, + }, + selection_box = { + type = "fixed", + -- Small selection box to allow digging stray top nodes + fixed = {-0.3, -0.3, -0.3, 0.3, -0.1, 0.3}, + }, + on_destruct = function(pos) + destruct_bed(pos, 2) + end, + can_dig = function(pos, player) + local other = get_other_bed_pos(pos, 2) + return (not other) or beds.can_dig(other) + end, + }) + + minetest.register_alias(name, name .. "_bottom") + + minetest.register_craft({ + output = name, + recipe = def.recipe + }) +end diff --git a/mods/mtg/beds/beds.lua b/mods/mtg/beds/beds.lua new file mode 100644 index 0000000..e905107 --- /dev/null +++ b/mods/mtg/beds/beds.lua @@ -0,0 +1,109 @@ +-- beds/beds.lua + +-- 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 = { + bottom = { + "beds_bed_top1.png", + "beds_bed_under.png", + "beds_bed_side1.png", + "beds_bed_side1.png^[transformFX", + "beds_bed_foot.png", + "beds_bed_foot.png", + }, + top = { + "beds_bed_top2.png", + "beds_bed_under.png", + "beds_bed_side2.png", + "beds_bed_side2.png^[transformFX", + "beds_bed_head.png", + "beds_bed_head.png", + } + }, + nodebox = { + bottom = { + {-0.5, -0.5, -0.5, -0.375, -0.065, -0.4375}, + {0.375, -0.5, -0.5, 0.5, -0.065, -0.4375}, + {-0.5, -0.375, -0.5, 0.5, -0.125, -0.4375}, + {-0.5, -0.375, -0.5, -0.4375, -0.125, 0.5}, + {0.4375, -0.375, -0.5, 0.5, -0.125, 0.5}, + {-0.4375, -0.3125, -0.4375, 0.4375, -0.0625, 0.5}, + }, + top = { + {-0.5, -0.5, 0.4375, -0.375, 0.1875, 0.5}, + {0.375, -0.5, 0.4375, 0.5, 0.1875, 0.5}, + {-0.5, 0, 0.4375, 0.5, 0.125, 0.5}, + {-0.5, -0.375, 0.4375, 0.5, -0.125, 0.5}, + {-0.5, -0.375, -0.5, -0.4375, -0.125, 0.5}, + {0.4375, -0.375, -0.5, 0.5, -0.125, 0.5}, + {-0.4375, -0.3125, -0.5, 0.4375, -0.0625, 0.4375}, + } + }, + selectionbox = {-0.5, -0.5, -0.5, 0.5, 0.06, 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 = { + bottom = { + "beds_bed_top_bottom.png^[transformR90", + "beds_bed_under.png", + "beds_bed_side_bottom_r.png", + "beds_bed_side_bottom_r.png^[transformFX", + "blank.png", + "beds_bed_side_bottom.png" + }, + top = { + "beds_bed_top_top.png^[transformR90", + "beds_bed_under.png", + "beds_bed_side_top_r.png", + "beds_bed_side_top_r.png^[transformFX", + "beds_bed_side_top.png", + "blank.png", + } + }, + nodebox = { + bottom = {-0.5, -0.5, -0.5, 0.5, 0.0625, 0.5}, + top = {-0.5, -0.5, -0.5, 0.5, 0.0625, 0.5}, + }, + selectionbox = {-0.5, -0.5, -0.5, 0.5, 0.0625, 1.5}, + recipe = { + {"wool:white", "wool:white", "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_bottom", + burntime = 13, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "beds:bed_bottom", + burntime = 12, +}) diff --git a/mods/mtg/beds/functions.lua b/mods/mtg/beds/functions.lua new file mode 100644 index 0000000..5fb5cd0 --- /dev/null +++ b/mods/mtg/beds/functions.lua @@ -0,0 +1,354 @@ +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 + +-- Physics override management mods (shadow the global variable) +local player_monoids = core.get_modpath("player_monoids") and player_monoids +local pova = core.get_modpath("pova") and pova + +if player_monoids and not player_monoids.speed.checkout_branch then + -- This function exists since 2025-05-17 + core.log("warning", "[beds] player_monoids is too old, thus not supported.") + player_monoids = nil +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 set_physics_override(player, put_to_bed) + local IDENTIFIER = "beds:lie" + local OVERRIDES = {speed = 0, jump = 0, gravity = 0} + + local name = player:get_player_name() + local pdata = beds.player[name] + + if put_to_bed then -- Freeze player + if player_monoids then + for k, v in pairs(OVERRIDES) do + local monoid = player_monoids[k] + pdata["monoid_branch_" .. k] = monoid:get_active_branch(player) + -- Change the "context" of the physics overrides + local branch = monoid:checkout_branch(player, IDENTIFIER) + branch:add_change(player, v) + end + elseif pova then + pova.add_override(name, "force", OVERRIDES) + pova.do_override(player) + else + -- Directly use engine API. May conflict with other mods. + pdata.physics_override = player:get_physics_override() + player:set_physics_override(OVERRIDES) + end + else -- Unfreeze player + if player_monoids then + for k, _ in pairs(OVERRIDES) do + local monoid = player_monoids[k] + monoid:checkout_branch(player, pdata["monoid_branch_" .. k]) + monoid:get_branch(IDENTIFIER):delete(player) + end + elseif pova then + pova.del_override(name, "force") + pova.do_override(player) + else + -- Restore the changed fields + player:set_physics_override({ + speed = pdata.physics_override.speed, + jump = pdata.physics_override.jump, + gravity = pdata.physics_override.gravity + }) + end + end +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 + -- player not in bed, do nothing + return false + 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 + set_physics_override(player, false) + beds.player[name] = nil + 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.05 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.player[name] = {} + beds.pos[name] = pos + beds.bed_position[name] = bed_pos + + 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 + } + set_physics_override(player, true) + 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 + +local update_scheduled = false +local function schedule_update() + if update_scheduled then + -- there already is an update scheduled; don't schedule more to prevent races + return + end + update_scheduled = true + minetest.after(2, function() + update_scheduled = false + if not is_sp then + update_formspecs(is_night_skip_enabled()) + end + if is_night_skip_enabled() then + -- skip the night and let all players stand up + beds.skip_night() + beds.kick_players() + end + end) +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 > beds.day_interval.start and tod < beds.day_interval.finish 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 + + if check_in_beds() then + schedule_update() + 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 valid position is found + spawn.register_on_spawn(function(player, is_new) + local pos = beds.spawn[player:get_player_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 + schedule_update() + 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) + +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 + local is_majority = (#minetest.get_connected_players() / 2) < 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/mods/mtg/beds/init.lua b/mods/mtg/beds/init.lua new file mode 100644 index 0000000..14ced8b --- /dev/null +++ b/mods/mtg/beds/init.lua @@ -0,0 +1,31 @@ +-- 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")) .. "]" + +beds.day_interval = { + start = 0.2, + finish = 0.805, +} + +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/mods/mtg/beds/license.txt b/mods/mtg/beds/license.txt new file mode 100644 index 0000000..383047d --- /dev/null +++ b/mods/mtg/beds/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 Game 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/mods/mtg/beds/locale/beds.bg.tr b/mods/mtg/beds/locale/beds.bg.tr new file mode 100644 index 0000000..ac34959 --- /dev/null +++ b/mods/mtg/beds/locale/beds.bg.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/mods/mtg/beds/locale/beds.da.tr b/mods/mtg/beds/locale/beds.da.tr new file mode 100644 index 0000000..22d3890 --- /dev/null +++ b/mods/mtg/beds/locale/beds.da.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Luksuriøs seng +Simple Bed=Simpel seng +This bed is already occupied!=Denne seng er allerede taget! +You have to stop moving before going to bed!=Du skal stoppe med at bevæge dig før du går i seng! +Good morning.=God morgen. +@1 of @2 players are in bed=@1 af @2 spillere er i seng +Force night skip=Tvungen natte-overspring +You can only sleep at night.=Du kan kun sove om natten. +Leave Bed=Stå ud af sengen diff --git a/mods/mtg/beds/locale/beds.de.tr b/mods/mtg/beds/locale/beds.de.tr new file mode 100644 index 0000000..3f2c959 --- /dev/null +++ b/mods/mtg/beds/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/mods/mtg/beds/locale/beds.eo.tr b/mods/mtg/beds/locale/beds.eo.tr new file mode 100644 index 0000000..3a4ad2f --- /dev/null +++ b/mods/mtg/beds/locale/beds.eo.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Luksa lito +Simple Bed=Simpla lito +This bed is already occupied!=Tiu lito jam estas okupata! +You have to stop moving before going to bed!=Vi ĉesu moviĝi por enlitiĝi! +Good morning.=Bonan matenon. +@1 of @2 players are in bed=@1 el @2 ludantoj estas en lito +Force night skip=Devigi noktan salton +You can only sleep at night.=Vi povas dormi nur nokte. +Leave Bed=Ellitiĝi diff --git a/mods/mtg/beds/locale/beds.es.tr b/mods/mtg/beds/locale/beds.es.tr new file mode 100644 index 0000000..8ef0db7 --- /dev/null +++ b/mods/mtg/beds/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/mods/mtg/beds/locale/beds.eu.tr b/mods/mtg/beds/locale/beds.eu.tr new file mode 100644 index 0000000..ef0e25e --- /dev/null +++ b/mods/mtg/beds/locale/beds.eu.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Luxuzko ohea +Simple Bed=Ohe arrunta +This bed is already occupied!=Ohe hau okupatuta dago +You have to stop moving before going to bed!=Utzi mugitzeari edo ezingo zara oheratu! +Good morning.=Egun on. +@1 of @2 players are in bed=@2 jokalaritik @1 lo daude +Force night skip=Behartu egunez egitera +You can only sleep at night.=Gauez bakarrik egin dezakezu lo. +Leave Bed=Jaiki diff --git a/mods/mtg/beds/locale/beds.fr.tr b/mods/mtg/beds/locale/beds.fr.tr new file mode 100644 index 0000000..43c06e3 --- /dev/null +++ b/mods/mtg/beds/locale/beds.fr.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Lit chic +Simple Bed=Lit simple +This bed is already occupied!=Ce lit est déjà occupé ! +You have to stop moving before going to bed!=Vous devez arrêter de bouger avant de vous coucher ! +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/mods/mtg/beds/locale/beds.hu.tr b/mods/mtg/beds/locale/beds.hu.tr new file mode 100644 index 0000000..074a475 --- /dev/null +++ b/mods/mtg/beds/locale/beds.hu.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Szép ágy +Simple Bed=Egyszerű ágy +This bed is already occupied!=Ez az ágy már foglalt! +You have to stop moving before going to bed!=Meg kell állnod, mielőtt lefeküdhetnél! +Good morning.=Jó reggelt. +@1 of @2 players are in bed=@2 játékosból @1 van ágyban +Force night skip=Éjszaka átugrása +You can only sleep at night.=Csak éjszaka aludhatsz. +Leave Bed=Ágy elhagyása diff --git a/mods/mtg/beds/locale/beds.id.tr b/mods/mtg/beds/locale/beds.id.tr new file mode 100644 index 0000000..d87c933 --- /dev/null +++ b/mods/mtg/beds/locale/beds.id.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Ranjang Mewah +Simple Bed=Ranjang Sederhana +This bed is already occupied!=Ranjang telah terisi! +You have to stop moving before going to bed!=Anda harus diam untuk tidur! +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 bisa tidur pada waktu malam. +Leave Bed=Tinggalkan Ranjang diff --git a/mods/mtg/beds/locale/beds.it.tr b/mods/mtg/beds/locale/beds.it.tr new file mode 100644 index 0000000..8f4e14e --- /dev/null +++ b/mods/mtg/beds/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/mods/mtg/beds/locale/beds.ja.tr b/mods/mtg/beds/locale/beds.ja.tr new file mode 100644 index 0000000..5034456 --- /dev/null +++ b/mods/mtg/beds/locale/beds.ja.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/mods/mtg/beds/locale/beds.jbo.tr b/mods/mtg/beds/locale/beds.jbo.tr new file mode 100644 index 0000000..a72f686 --- /dev/null +++ b/mods/mtg/beds/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/mods/mtg/beds/locale/beds.lv.tr b/mods/mtg/beds/locale/beds.lv.tr new file mode 100644 index 0000000..cea63ff --- /dev/null +++ b/mods/mtg/beds/locale/beds.lv.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Skaista gulta +Simple Bed=Gulta +This bed is already occupied!=Šī gulta jau ir aizņemta! +You have to stop moving before going to bed!=Jums jāapstājas lai gulētu! +Good morning.=Labrīt. +@1 of @2 players are in bed=@1 no @2 spēlētājiem guļ gultās +Force night skip=Izlaist nakti +You can only sleep at night.=Jūs variet gulēt tikai naktī. +Leave Bed=Celties no gultas diff --git a/mods/mtg/beds/locale/beds.ms.tr b/mods/mtg/beds/locale/beds.ms.tr new file mode 100644 index 0000000..b197b63 --- /dev/null +++ b/mods/mtg/beds/locale/beds.ms.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Katil Beragam +Simple Bed=Katil Biasa +This bed is already occupied!=Katil ini sudah diduduki! +You have to stop moving before going to bed!=Anda perlu berhenti bergerak sebelum tidur! +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=Tinggalkan Katil diff --git a/mods/mtg/beds/locale/beds.pl.tr b/mods/mtg/beds/locale/beds.pl.tr new file mode 100644 index 0000000..2bc03c6 --- /dev/null +++ b/mods/mtg/beds/locale/beds.pl.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Fantazyjne łóżko +Simple Bed=Proste łóżko +This bed is already occupied!=To łóżko jest już zajęte! +You have to stop moving before going to bed!=Musisz się zatrzymać aby wejść do łóżka +Good morning.=Dzień dobry. +@1 of @2 players are in bed=@1 z @2 graczy śpią +Force night skip=Wymuś pominięcie nocy +You can only sleep at night.=Możesz spać tylko w nocy. +Leave Bed=Opuść łóżko diff --git a/mods/mtg/beds/locale/beds.pt_BR.tr b/mods/mtg/beds/locale/beds.pt_BR.tr new file mode 100644 index 0000000..47fb1b9 --- /dev/null +++ b/mods/mtg/beds/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/mods/mtg/beds/locale/beds.ru.tr b/mods/mtg/beds/locale/beds.ru.tr new file mode 100644 index 0000000..7c1b536 --- /dev/null +++ b/mods/mtg/beds/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/mods/mtg/beds/locale/beds.sk.tr b/mods/mtg/beds/locale/beds.sk.tr new file mode 100644 index 0000000..5f31f0f --- /dev/null +++ b/mods/mtg/beds/locale/beds.sk.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Pekná posteľ +Simple Bed=Jednoduchá posteľ +This bed is already occupied!=Táto posteľ je už obsadená +You have to stop moving before going to bed!=Predtým ako si ľahneš do postele, sa musíš prestať pohybovať! +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/mods/mtg/beds/locale/beds.sv.tr b/mods/mtg/beds/locale/beds.sv.tr new file mode 100644 index 0000000..3b737b4 --- /dev/null +++ b/mods/mtg/beds/locale/beds.sv.tr @@ -0,0 +1,10 @@ +# textdomain: beds +Fancy Bed=Fin säng +Simple Bed=Enkel säng +This bed is already occupied!=Den här sängen används redan! +You have to stop moving before going to bed!=Du måste stanna innan du kan lägga dig! +Good morning.=God morgon. +@1 of @2 players are in bed=@1 av @2 spelare försöker sova. +Force night skip=Tvinga att hoppa över natt +You can only sleep at night.=Du kan bara sova på natten. +Leave Bed=Lämna säng diff --git a/mods/mtg/beds/locale/beds.uk.tr b/mods/mtg/beds/locale/beds.uk.tr new file mode 100644 index 0000000..c9db693 --- /dev/null +++ b/mods/mtg/beds/locale/beds.uk.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/mods/mtg/beds/locale/beds.zh_CN.tr b/mods/mtg/beds/locale/beds.zh_CN.tr new file mode 100644 index 0000000..7e6cfc7 --- /dev/null +++ b/mods/mtg/beds/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/mods/mtg/beds/locale/beds.zh_TW.tr b/mods/mtg/beds/locale/beds.zh_TW.tr new file mode 100644 index 0000000..a0428b4 --- /dev/null +++ b/mods/mtg/beds/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/mods/mtg/beds/locale/template.txt b/mods/mtg/beds/locale/template.txt new file mode 100644 index 0000000..a965787 --- /dev/null +++ b/mods/mtg/beds/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/mods/mtg/beds/mod.conf b/mods/mtg/beds/mod.conf new file mode 100644 index 0000000..9113230 --- /dev/null +++ b/mods/mtg/beds/mod.conf @@ -0,0 +1,4 @@ +name = beds +description = Minetest Game mod: beds +depends = default, wool, spawn +optional_depends = player_monoids, pova diff --git a/mods/mtg/beds/spawns.lua b/mods/mtg/beds/spawns.lua new file mode 100644 index 0000000..1a2ce81 --- /dev/null +++ b/mods/mtg/beds/spawns.lua @@ -0,0 +1,72 @@ +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/mods/mtg/beds/textures/beds_bed.png b/mods/mtg/beds/textures/beds_bed.png new file mode 100644 index 0000000..d4b02e7 Binary files /dev/null and b/mods/mtg/beds/textures/beds_bed.png differ diff --git a/mods/mtg/beds/textures/beds_bed_fancy.png b/mods/mtg/beds/textures/beds_bed_fancy.png new file mode 100644 index 0000000..1c9fde9 Binary files /dev/null and b/mods/mtg/beds/textures/beds_bed_fancy.png differ diff --git a/mods/mtg/beds/textures/beds_bed_foot.png b/mods/mtg/beds/textures/beds_bed_foot.png new file mode 100644 index 0000000..af510bb Binary files /dev/null and b/mods/mtg/beds/textures/beds_bed_foot.png differ diff --git a/mods/mtg/beds/textures/beds_bed_head.png b/mods/mtg/beds/textures/beds_bed_head.png new file mode 100644 index 0000000..b98b110 Binary files /dev/null and b/mods/mtg/beds/textures/beds_bed_head.png differ diff --git a/mods/mtg/beds/textures/beds_bed_side1.png b/mods/mtg/beds/textures/beds_bed_side1.png new file mode 100644 index 0000000..8ded54f Binary files /dev/null and b/mods/mtg/beds/textures/beds_bed_side1.png differ diff --git a/mods/mtg/beds/textures/beds_bed_side2.png b/mods/mtg/beds/textures/beds_bed_side2.png new file mode 100644 index 0000000..a6bdb99 Binary files /dev/null and b/mods/mtg/beds/textures/beds_bed_side2.png differ diff --git a/mods/mtg/beds/textures/beds_bed_side_bottom.png b/mods/mtg/beds/textures/beds_bed_side_bottom.png new file mode 100644 index 0000000..ed80f75 Binary files /dev/null and b/mods/mtg/beds/textures/beds_bed_side_bottom.png differ diff --git a/mods/mtg/beds/textures/beds_bed_side_bottom_r.png b/mods/mtg/beds/textures/beds_bed_side_bottom_r.png new file mode 100644 index 0000000..2d86532 Binary files /dev/null and b/mods/mtg/beds/textures/beds_bed_side_bottom_r.png differ diff --git a/mods/mtg/beds/textures/beds_bed_side_top.png b/mods/mtg/beds/textures/beds_bed_side_top.png new file mode 100644 index 0000000..04b2ba1 Binary files /dev/null and b/mods/mtg/beds/textures/beds_bed_side_top.png differ diff --git a/mods/mtg/beds/textures/beds_bed_side_top_r.png b/mods/mtg/beds/textures/beds_bed_side_top_r.png new file mode 100644 index 0000000..c3c07b1 Binary files /dev/null and b/mods/mtg/beds/textures/beds_bed_side_top_r.png differ diff --git a/mods/mtg/beds/textures/beds_bed_top1.png b/mods/mtg/beds/textures/beds_bed_top1.png new file mode 100644 index 0000000..2b3ae8d Binary files /dev/null and b/mods/mtg/beds/textures/beds_bed_top1.png differ diff --git a/mods/mtg/beds/textures/beds_bed_top2.png b/mods/mtg/beds/textures/beds_bed_top2.png new file mode 100644 index 0000000..b80353c Binary files /dev/null and b/mods/mtg/beds/textures/beds_bed_top2.png differ diff --git a/mods/mtg/beds/textures/beds_bed_top_bottom.png b/mods/mtg/beds/textures/beds_bed_top_bottom.png new file mode 100644 index 0000000..43dcc64 Binary files /dev/null and b/mods/mtg/beds/textures/beds_bed_top_bottom.png differ diff --git a/mods/mtg/beds/textures/beds_bed_top_top.png b/mods/mtg/beds/textures/beds_bed_top_top.png new file mode 100644 index 0000000..9b3d08f Binary files /dev/null and b/mods/mtg/beds/textures/beds_bed_top_top.png differ diff --git a/mods/mtg/beds/textures/beds_bed_under.png b/mods/mtg/beds/textures/beds_bed_under.png new file mode 100644 index 0000000..1a67367 Binary files /dev/null and b/mods/mtg/beds/textures/beds_bed_under.png differ