From 745b7063a5fe5db8957c9645a8c1a9677d449c8c Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 24 Jan 2021 18:40:29 +0100 Subject: [PATCH] Move bed messages to HUD; Fix #1000 --- mods/ITEMS/mcl_beds/functions.lua | 80 +++++++++++++++++++------------ 1 file changed, 50 insertions(+), 30 deletions(-) diff --git a/mods/ITEMS/mcl_beds/functions.lua b/mods/ITEMS/mcl_beds/functions.lua index 917b1123dc..8c5c08f92e 100644 --- a/mods/ITEMS/mcl_beds/functions.lua +++ b/mods/ITEMS/mcl_beds/functions.lua @@ -6,6 +6,8 @@ local player_in_bed = 0 local is_sp = minetest.is_singleplayer() local weather_mod = minetest.get_modpath("mcl_weather") ~= nil local explosions_mod = minetest.get_modpath("mcl_explosions") ~= nil +local huds = {} +local hud_hide_timeouts = {} -- Helper functions @@ -75,16 +77,19 @@ local function lay_down(player, pos, bed_pos, state, skip) bed_pos2 = {x = bed_pos.x - dir.x, y = bed_pos.y, z = bed_pos.z - dir.z} bed_center = {x = bed_pos.x - dir.x/2, y = bed_pos.y + 0.1, z = bed_pos.z - dir.z/2} + -- save respawn position when entering bed + if minetest.get_modpath("mcl_spawn") and mcl_spawn.set_spawn_pos(player, bed_pos, false) then + minetest.chat_send_player(name, S("New respawn position set!")) + end + -- No sleeping if too far away if vector.distance(bed_pos, pos) > 2 and vector.distance(bed_pos2, pos) > 2 then - minetest.chat_send_player(name, S("You can't sleep, the bed's too far away!")) - return false + return false, S("You can't sleep, the bed's too far away!") end for _, other_pos in pairs(mcl_beds.bed_pos) do if vector.distance(bed_pos, other_pos) < 0.1 then - minetest.chat_send_player(name, S("This bed is already occupied!")) - return false + return false, S("This bed is already occupied!") end end @@ -93,8 +98,7 @@ local function lay_down(player, pos, bed_pos, state, skip) -- sometimes reports incorrect Y speed. A velocity threshold -- of 0.125 still seems good enough. if vector.length(player:get_velocity() or player:get_player_velocity()) > 0.125 then - minetest.chat_send_player(name, S("You have to stop moving before going to bed!")) - return false + return false, S("You have to stop moving before going to bed!") end -- No sleeping if monsters nearby. @@ -109,9 +113,8 @@ local function lay_down(player, pos, bed_pos, state, skip) -- Approximation of monster detection range if def._cmi_is_mob and ((mobname ~= "mobs_mc:pigman" and def.type == "monster" and not monster_exceptions[mobname]) or (mobname == "mobs_mc:pigman" and ent.state == "attack")) then if math.abs(bed_pos.y - obj:get_pos().y) <= 5 then - minetest.chat_send_player(name, S("You can't sleep now, monsters are nearby!")) + return false, S("You can't sleep now, monsters are nearby!") end - return false end end end @@ -154,32 +157,16 @@ local function lay_down(player, pos, bed_pos, state, skip) local def1 = minetest.registered_nodes[n1.name] local def2 = minetest.registered_nodes[n2.name] if def1.walkable or def2.walkable then - minetest.chat_send_player(name, S("You can't sleep, the bed is obstructed!")) - return false + return false, S("You can't sleep, the bed is obstructed!") elseif (def1.damage_per_second ~= nil and def1.damage_per_second > 0) or (def2.damage_per_second ~= nil and def2.damage_per_second > 0) then - minetest.chat_send_player(name, S("It's too dangerous to sleep here!")) - return false - end - - local spawn_changed = false - if minetest.get_modpath("mcl_spawn") then - -- save respawn position when entering bed - spawn_changed = mcl_spawn.set_spawn_pos(player, bed_pos, false) + return false, S("It's too dangerous to sleep here!") end -- Check day of time and weather local tod = minetest.get_timeofday() * 24000 -- Values taken from Minecraft Wiki with offset of +6000 if tod < 18541 and tod > 5458 and (not weather_mod or (mcl_weather.get_weather() ~= "thunder")) then - if spawn_changed then - minetest.chat_send_player(name, S("New respawn position set! But you can only sleep at night or during a thunderstorm.")) - else - minetest.chat_send_player(name, S("You can only sleep at night or during a thunderstorm.")) - end - return false - end - if spawn_changed then - minetest.chat_send_player(name, S("New respawn position set!")) + return false, S("You can only sleep at night or during a thunderstorm.") end mcl_beds.player[name] = 1 @@ -329,13 +316,18 @@ function mcl_beds.on_rightclick(pos, player, is_top) -- move to bed if not mcl_beds.player[name] then + local success, message if is_top then - lay_down(player, ppos, pos) + success, message = lay_down(player, ppos, pos) else local node = minetest.get_node(pos) local dir = minetest.facedir_to_dir(node.param2) local other = vector.add(pos, dir) - lay_down(player, ppos, other) + success, message = lay_down(player, ppos, other) + end + if message then + player:hud_change(huds[name], "text", message) + hud_hide_timeouts[name] = 3 end else lay_down(player, nil, nil, false) @@ -362,6 +354,17 @@ minetest.register_on_joinplayer(function(player) -- Make player awake on joining server meta:set_string("mcl_beds:sleeping", "false") end + + huds[player:get_player_name()] = player:hud_add({ + hud_elem_type = "text", + position = {x=0.5, y=1}, + offset = {x = 0, y = -210}, + alignment = {x=0, y=0}, + number = 0xFFFFFF , + text = "", + z_index = 100, + }) + playerphysics.remove_physics_factor(player, "speed", "mcl_beds:sleeping") playerphysics.remove_physics_factor(player, "jump", "mcl_beds:sleeping") update_formspecs(false) @@ -369,7 +372,8 @@ end) minetest.register_on_leaveplayer(function(player) local name = player:get_player_name() - lay_down(player, nil, nil, false, true) + huds[name] = nil + local players = minetest.get_connected_players() for n, player in ipairs(players) do if player:get_player_name() == name then @@ -408,3 +412,19 @@ minetest.register_on_player_hpchange(function(player, hp_change) mcl_beds.kick_player(player) end end) + +minetest.register_globalstep(function(dtime) + local new_timeouts = {} + for name, timeout in pairs(hud_hide_timeouts) do + timeout = timeout - dtime + if timeout <= 0 then + local player = minetest.get_player_by_name(name) + if player then + player:hud_change(huds[name], "text", "") + end + else + new_timeouts[name] = timeout + end + end + hud_hide_timeouts = new_timeouts +end)