From 258b52b90613af1b2e799700ccc78c5d14508c75 Mon Sep 17 00:00:00 2001 From: nixnoxus Date: Fri, 23 Jul 2021 06:37:10 +0200 Subject: [PATCH 1/3] Add option 'enable_bed_in_the_daytime' and 'bed_night_skip_above_percent' --- mods/beds/README.txt | 8 ++++++- mods/beds/functions.lua | 49 ++++++++++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/mods/beds/README.txt b/mods/beds/README.txt index 7b35e141..475116ac 100644 --- a/mods/beds/README.txt +++ b/mods/beds/README.txt @@ -19,12 +19,18 @@ This mod adds a bed to Minetest 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. +than 50 percent of the players are lying in bed and use this option. You can change the +percent value by setting "bed_night_skip_above_percent = " in minetest.conf. + 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. + +You can enable the bed in the daytime by setting "enable_bed_in_the_daytime = yes" in +minetest.conf. Then the players stay in bed. diff --git a/mods/beds/functions.lua b/mods/beds/functions.lua index ddac52be..33780245 100644 --- a/mods/beds/functions.lua +++ b/mods/beds/functions.lua @@ -5,6 +5,8 @@ if enable_respawn == nil then enable_respawn = true end +local enable_bed_in_the_daytime = minetest.settings:get_bool("enable_bed_in_the_daytime") + -- support for MT game translation. local S = beds.get_translator @@ -34,6 +36,11 @@ local function is_night_skip_enabled() return enable_night_skip end +local function is_night() + local tod = minetest.get_timeofday() + return not (tod > 0.2 and tod < 0.805) +end + local function check_in_beds(players) local in_bed = beds.player if not players then @@ -146,19 +153,28 @@ local function get_player_in_bed_count() return c end -local function update_formspecs(finished) +local function is_above_percent(player_in_bed) + -- default: 50, range: 0..99 + local above_percent = math.min(tonumber(minetest.settings:get("bed_night_skip_above_percent")) or 50, 99); + + return (#minetest.get_connected_players() * above_percent / 100) < player_in_bed +end + +local function update_formspecs(force_morning) local ges = #minetest.get_connected_players() local player_in_bed = get_player_in_bed_count() - local is_majority = (ges / 2) < player_in_bed + local tod = minetest.get_timeofday() local form_n local esc = minetest.formspec_escape - if finished then + if force_morning or (tod >= 0.23 and tod <= 0.375) then -- <= ~9:00 form_n = beds.formspec .. "label[2.7,9;" .. esc(S("Good morning.")) .. "]" + elseif not is_night() then + form_n = beds.formspec .. "label[2.7,9;" .. esc(S("Wake up!")) .. "]" 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 + if is_above_percent(player_in_bed) and is_night_skip_enabled() then form_n = form_n .. "button_exit[2,6;4,0.75;force;" .. esc(S("Force night skip")) .. "]" end @@ -169,10 +185,21 @@ local function update_formspecs(finished) end end +local function update_formspecs_loop() + if is_sp or get_player_in_bed_count() < 1 then + return + end + update_formspecs(false) + minetest.after(2, update_formspecs_loop) +end -- Public functions function beds.kick_players() + if enable_bed_in_the_daytime then + update_formspecs(false) + return + end for name, _ in pairs(beds.player) do local player = minetest.get_player_by_name(name) lay_down(player, nil, nil, false) @@ -186,9 +213,8 @@ 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 not is_night() and not enable_bed_in_the_daytime then if beds.player[name] then lay_down(player, nil, nil, false) end @@ -206,10 +232,14 @@ function beds.on_rightclick(pos, player) if not is_sp then update_formspecs(false) + if enable_bed_in_the_daytime then + -- update formspecs for day sleepers + minetest.after(2, update_formspecs_loop) + end end -- skip the night and let all players stand up - if check_in_beds() then + if is_night() and check_in_beds() then minetest.after(2, function() if not is_sp then update_formspecs(is_night_skip_enabled()) @@ -250,7 +280,7 @@ 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 + if is_night() and check_in_beds() then minetest.after(2, function() update_formspecs(is_night_skip_enabled()) if is_night_skip_enabled() then @@ -290,8 +320,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) 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 + if is_above_percent(last_player_in_bed) and is_night_skip_enabled() then update_formspecs(true) beds.skip_night() beds.kick_players() From 6e975655bbf28cd1eb852a888b36a675efec9a40 Mon Sep 17 00:00:00 2001 From: nixnoxus Date: Fri, 23 Jul 2021 10:52:07 +0200 Subject: [PATCH 2/3] Fix single player --- mods/beds/functions.lua | 83 ++++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 34 deletions(-) diff --git a/mods/beds/functions.lua b/mods/beds/functions.lua index 33780245..8b6363da 100644 --- a/mods/beds/functions.lua +++ b/mods/beds/functions.lua @@ -160,44 +160,74 @@ local function is_above_percent(player_in_bed) return (#minetest.get_connected_players() * above_percent / 100) < player_in_bed end +local update_formspecs_loops = 0 + local function update_formspecs(force_morning) local ges = #minetest.get_connected_players() local player_in_bed = get_player_in_bed_count() local tod = minetest.get_timeofday() - local form_n + local form_n = beds.formspec local esc = minetest.formspec_escape if force_morning or (tod >= 0.23 and tod <= 0.375) then -- <= ~9:00 - form_n = beds.formspec .. "label[2.7,9;" .. esc(S("Good morning.")) .. "]" + form_n = form_n .. "label[2.7,9;" .. esc(S("Good morning.")) .. "]" elseif not is_night() then - form_n = beds.formspec .. "label[2.7,9;" .. esc(S("Wake up!")) .. "]" - else - form_n = beds.formspec .. "label[2.2,9;" .. + if (tod < 0.749) then -- < ~18:00 + form_n = form_n .. "label[2.7,9;" .. esc(S("Wake up!")) .. "]" + end + elseif not is_sp then + form_n = form_n .. "label[2.2,9;" .. esc(S("@1 of @2 players are in bed", player_in_bed, ges)) .. "]" + if is_above_percent(player_in_bed) 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 + if false then -- debug code disabled + form_n = form_n .. " " .. "label[2.2,8;" .. esc(tod*24) .. + " loop:" .. update_formspecs_loops .. + "]"; + end + for name,_ in pairs(beds.player) do minetest.show_formspec(name, "beds_form", form_n) end end -local function update_formspecs_loop() - if is_sp or get_player_in_bed_count() < 1 then - return +local function check_night_skip() + if is_night() and check_in_beds() then + minetest.after(2, function() + if not is_sp or enable_bed_in_the_daytime then + update_formspecs(is_night_skip_enabled()) + end + if is_night_skip_enabled() then + beds.skip_night() + beds.kick_players() + end + end) + return true + end + return false +end + +local function update_formspecs_loop() + if not check_night_skip() then + update_formspecs(false) + end + if get_player_in_bed_count() > 0 then + update_formspecs_loops = update_formspecs_loops + 1 + minetest.after(2, update_formspecs_loop) + else + update_formspecs_loops = 0 end - update_formspecs(false) - minetest.after(2, update_formspecs_loop) end -- Public functions function beds.kick_players() if enable_bed_in_the_daytime then - update_formspecs(false) return end for name, _ in pairs(beds.player) do @@ -232,24 +262,17 @@ function beds.on_rightclick(pos, player) if not is_sp then update_formspecs(false) - if enable_bed_in_the_daytime then - -- update formspecs for day sleepers - minetest.after(2, update_formspecs_loop) - end end -- skip the night and let all players stand up - if is_night() and 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) + check_night_skip() + + if enable_bed_in_the_daytime and update_formspecs_loops == 0 then + update_formspecs_loops = 1 + -- update formspecs for day sleepers + minetest.after(2, update_formspecs_loop) end + end function beds.can_dig(bed_pos) @@ -280,15 +303,7 @@ minetest.register_on_leaveplayer(function(player) local name = player:get_player_name() lay_down(player, nil, nil, false, true) beds.player[name] = nil - if is_night() and 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 + check_night_skip() end) minetest.register_on_dieplayer(function(player) From 8d0a931a1a09d3d1e76f72a6a9c6c748f95f4bb8 Mon Sep 17 00:00:00 2001 From: nixnoxus Date: Fri, 30 Jul 2021 18:39:26 +0200 Subject: [PATCH 3/3] fix Luacheck: mods/beds/functions.lua:189:3: unreachable code --- mods/beds/functions.lua | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/mods/beds/functions.lua b/mods/beds/functions.lua index 8b6363da..3166fa9d 100644 --- a/mods/beds/functions.lua +++ b/mods/beds/functions.lua @@ -185,11 +185,10 @@ local function update_formspecs(force_morning) end end - if false then -- debug code disabled - form_n = form_n .. " " .. "label[2.2,8;" .. esc(tod*24) .. - " loop:" .. update_formspecs_loops .. - "]"; - end + -- debug code disabled + --form_n = form_n .. " " .. "label[2.2,8;" .. esc(tod*24) .. + -- " loop:" .. update_formspecs_loops .. + -- "]"; for name,_ in pairs(beds.player) do minetest.show_formspec(name, "beds_form", form_n)