Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

beds: add option bed_night_skip_above_percent & enable_bed_in_the_daytime #2892

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion mods/beds/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 = <n>" 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.
105 changes: 74 additions & 31 deletions mods/beds/functions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -144,33 +151,82 @@ 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 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 is_majority = (ges / 2) < player_in_bed
local tod = minetest.get_timeofday()

local form_n
local form_n = beds.formspec
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;" ..
if force_morning or (tod >= 0.23 and tod <= 0.375) then -- <= ~9:00
form_n = form_n .. "label[2.7,9;" .. esc(S("Good morning.")) .. "]"
elseif not is_night() then
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_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
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)
end
end

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
end

-- Public functions

function beds.kick_players()
if enable_bed_in_the_daytime then
return
end
for name, _ in pairs(beds.player) do
local player = minetest.get_player_by_name(name)
lay_down(player, nil, nil, false)
Expand All @@ -184,9 +240,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
Expand All @@ -207,17 +262,14 @@ function beds.on_rightclick(pos, player)
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)
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)
Expand Down Expand Up @@ -248,15 +300,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
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)
Expand Down Expand Up @@ -288,8 +332,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()
Expand Down