Move bed messages to HUD; Fix #1000

Elias Fleckenstein 2021-01-24 18:40:29 +01:00
parent fdfcf9ca70
commit 745b7063a5

@ -6,6 +6,8 @@ local player_in_bed = 0
local is_sp = minetest.is_singleplayer() local is_sp = minetest.is_singleplayer()
local weather_mod = minetest.get_modpath("mcl_weather") ~= nil local weather_mod = minetest.get_modpath("mcl_weather") ~= nil
local explosions_mod = minetest.get_modpath("mcl_explosions") ~= nil local explosions_mod = minetest.get_modpath("mcl_explosions") ~= nil
local huds = {}
local hud_hide_timeouts = {}
-- Helper functions -- 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_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} 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 -- No sleeping if too far away
if vector.distance(bed_pos, pos) > 2 and vector.distance(bed_pos2, pos) > 2 then 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, S("You can't sleep, the bed's too far away!")
return false
end end
for _, other_pos in pairs(mcl_beds.bed_pos) do for _, other_pos in pairs(mcl_beds.bed_pos) do
if vector.distance(bed_pos, other_pos) < 0.1 then if vector.distance(bed_pos, other_pos) < 0.1 then
minetest.chat_send_player(name, S("This bed is already occupied!")) return false, S("This bed is already occupied!")
return false
end end
end end
@ -93,8 +98,7 @@ local function lay_down(player, pos, bed_pos, state, skip)
-- sometimes reports incorrect Y speed. A velocity threshold -- sometimes reports incorrect Y speed. A velocity threshold
-- of 0.125 still seems good enough. -- of 0.125 still seems good enough.
if vector.length(player:get_velocity() or player:get_player_velocity()) > 0.125 then 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, S("You have to stop moving before going to bed!")
return false
end end
-- No sleeping if monsters nearby. -- No sleeping if monsters nearby.
@ -109,9 +113,8 @@ local function lay_down(player, pos, bed_pos, state, skip)
-- Approximation of monster detection range -- 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 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 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 end
return false
end end
end 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 def1 = minetest.registered_nodes[n1.name]
local def2 = minetest.registered_nodes[n2.name] local def2 = minetest.registered_nodes[n2.name]
if def1.walkable or def2.walkable then if def1.walkable or def2.walkable then
minetest.chat_send_player(name, S("You can't sleep, the bed is obstructed!")) return false, S("You can't sleep, the bed is obstructed!")
return false
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 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, 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)
end end
-- Check day of time and weather -- Check day of time and weather
local tod = minetest.get_timeofday() * 24000 local tod = minetest.get_timeofday() * 24000
-- Values taken from Minecraft Wiki with offset of +6000 -- 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 tod < 18541 and tod > 5458 and (not weather_mod or (mcl_weather.get_weather() ~= "thunder")) then
if spawn_changed then return false, S("You can only sleep at night or during a thunderstorm.")
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!"))
end end
mcl_beds.player[name] = 1 mcl_beds.player[name] = 1
@ -329,13 +316,18 @@ function mcl_beds.on_rightclick(pos, player, is_top)
-- move to bed -- move to bed
if not mcl_beds.player[name] then if not mcl_beds.player[name] then
local success, message
if is_top then if is_top then
lay_down(player, ppos, pos) success, message = lay_down(player, ppos, pos)
else else
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local dir = minetest.facedir_to_dir(node.param2) local dir = minetest.facedir_to_dir(node.param2)
local other = vector.add(pos, dir) 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 end
else else
lay_down(player, nil, nil, false) lay_down(player, nil, nil, false)
@ -362,6 +354,17 @@ minetest.register_on_joinplayer(function(player)
-- Make player awake on joining server -- Make player awake on joining server
meta:set_string("mcl_beds:sleeping", "false") meta:set_string("mcl_beds:sleeping", "false")
end 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, "speed", "mcl_beds:sleeping")
playerphysics.remove_physics_factor(player, "jump", "mcl_beds:sleeping") playerphysics.remove_physics_factor(player, "jump", "mcl_beds:sleeping")
update_formspecs(false) update_formspecs(false)
@ -369,7 +372,8 @@ end)
minetest.register_on_leaveplayer(function(player) minetest.register_on_leaveplayer(function(player)
local name = player:get_player_name() local name = player:get_player_name()
lay_down(player, nil, nil, false, true) huds[name] = nil
local players = minetest.get_connected_players() local players = minetest.get_connected_players()
for n, player in ipairs(players) do for n, player in ipairs(players) do
if player:get_player_name() == name then 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) mcl_beds.kick_player(player)
end end
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)