Add bed.is_valid_bed; make bed API public for real
This commit is contained in:
parent
eef9bbc5d5
commit
1cdd1e2081
@ -48,7 +48,7 @@ Mods with documented APIs:
|
|||||||
|
|
||||||
* `rp_armor`: Armor information
|
* `rp_armor`: Armor information
|
||||||
* `rp_achievements`: Add and trigger achievements
|
* `rp_achievements`: Add and trigger achievements
|
||||||
* `rp_bed`: Get, set and unset (re)spawn position
|
* `rp_bed`: Get, set and unset (re)spawn position; query bed info
|
||||||
* `rp_crafting`: Add crafting recipes
|
* `rp_crafting`: Add crafting recipes
|
||||||
* `rp_default`: Sapling helpers, biome information
|
* `rp_default`: Sapling helpers, biome information
|
||||||
* `rp_door`: Add doors
|
* `rp_door`: Add doors
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# API documentation for `rp_bed`
|
# API documentation for `rp_bed`
|
||||||
|
|
||||||
This simple API allows setting some stuff related to (re)spawning.
|
This simple API allows setting some stuff related to (re)spawning
|
||||||
|
and also query info about the bed itself.
|
||||||
|
|
||||||
## Function reference
|
## Function reference
|
||||||
|
|
||||||
@ -21,3 +22,15 @@ it's already used by the player.
|
|||||||
|
|
||||||
Clears the bed (re)spawn position of `player`. The player will respawn
|
Clears the bed (re)spawn position of `player`. The player will respawn
|
||||||
according to the default Minetest rules.
|
according to the default Minetest rules.
|
||||||
|
|
||||||
|
### `bed.is_valid_bed(pos)`
|
||||||
|
|
||||||
|
Returns true if the node at `pos` is part of a valid bed.
|
||||||
|
|
||||||
|
A bed is valid if:
|
||||||
|
|
||||||
|
* It consists of 2 nodes, a 'head' and a 'foot'
|
||||||
|
* Both nodes 'connect' to each other to form a complete bed
|
||||||
|
* Both nodes have the same `param2`
|
||||||
|
|
||||||
|
Single 'bed' nodes (without a matching other piece) count as invalid.
|
||||||
|
@ -5,26 +5,26 @@
|
|||||||
|
|
||||||
local S = minetest.get_translator("rp_bed")
|
local S = minetest.get_translator("rp_bed")
|
||||||
|
|
||||||
local bed = {}
|
bed = {}
|
||||||
|
|
||||||
local DEFAULT_BED_COLOR = rp_paint.COLOR_AZURE_BLUE
|
local DEFAULT_BED_COLOR = rp_paint.COLOR_AZURE_BLUE
|
||||||
|
|
||||||
-- Per-user data table
|
-- Per-user data table
|
||||||
|
|
||||||
bed.userdata = {}
|
local bed_userdata = {}
|
||||||
bed.userdata.saved = {}
|
bed_userdata.saved = {}
|
||||||
bed.userdata.temp = {}
|
bed_userdata.temp = {}
|
||||||
|
|
||||||
-- List of occupied beds, indexed by node position hash
|
-- List of occupied beds, indexed by node position hash
|
||||||
bed.occupied_beds = {}
|
local occupied_beds = {}
|
||||||
|
|
||||||
-- Returns <spawn position> of `player` or
|
-- Returns <spawn position> of `player` or
|
||||||
-- nil if if there is no spawn active
|
-- nil if if there is no spawn active
|
||||||
bed.get_spawn = function(player)
|
bed.get_spawn = function(player)
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
local spawn
|
local spawn
|
||||||
if bed.userdata.saved[name].spawn_pos then
|
if bed_userdata.saved[name].spawn_pos then
|
||||||
spawn = bed.userdata.saved[name].spawn_pos
|
spawn = bed_userdata.saved[name].spawn_pos
|
||||||
end
|
end
|
||||||
return spawn
|
return spawn
|
||||||
end
|
end
|
||||||
@ -35,11 +35,11 @@ end
|
|||||||
-- it's already used by the player.
|
-- it's already used by the player.
|
||||||
bed.set_spawn = function(player, spawn_pos)
|
bed.set_spawn = function(player, spawn_pos)
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
local old_spawn_pos = bed.userdata.saved[name].spawn_pos
|
local old_spawn_pos = bed_userdata.saved[name].spawn_pos
|
||||||
if old_spawn_pos and vector.equals(spawn_pos, old_spawn_pos) then
|
if old_spawn_pos and vector.equals(spawn_pos, old_spawn_pos) then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
bed.userdata.saved[name].spawn_pos = table.copy(spawn_pos)
|
bed_userdata.saved[name].spawn_pos = table.copy(spawn_pos)
|
||||||
minetest.log("action", "[rp_bed] Respawn position of "..name.." set to "..minetest.pos_to_string(spawn_pos, 1))
|
minetest.log("action", "[rp_bed] Respawn position of "..name.." set to "..minetest.pos_to_string(spawn_pos, 1))
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@ -47,7 +47,27 @@ end
|
|||||||
-- Unsets the bed spawn position of `player`
|
-- Unsets the bed spawn position of `player`
|
||||||
bed.unset_spawn = function(player)
|
bed.unset_spawn = function(player)
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
bed.userdata.saved[name].spawn_pos = nil
|
bed_userdata.saved[name].spawn_pos = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns true if pos has a valid bed
|
||||||
|
bed.is_valid_bed = function(pos)
|
||||||
|
local node = minetest.get_node(pos)
|
||||||
|
local dir = minetest.fourdir_to_dir(node.param2)
|
||||||
|
if node.name == "rp_bed:bed_head" then
|
||||||
|
local neighbor = vector.subtract(pos, dir)
|
||||||
|
local nnode = minetest.get_node(neighbor)
|
||||||
|
if nnode.name == "rp_bed:bed_foot" and nnode.param2 == node.param2 then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
elseif node.name == "rp_bed:bed_foot" then
|
||||||
|
local neighbor = vector.add(pos, dir)
|
||||||
|
local nnode = minetest.get_node(neighbor)
|
||||||
|
if nnode.name == "rp_bed:bed_head" and nnode.param2 == node.param2 then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Savefile
|
-- Savefile
|
||||||
@ -79,14 +99,14 @@ end
|
|||||||
-- Returns name of player in bed at pos or nil if not occupied
|
-- Returns name of player in bed at pos or nil if not occupied
|
||||||
local function get_player_in_bed(pos)
|
local function get_player_in_bed(pos)
|
||||||
local hash = minetest.hash_node_position(pos)
|
local hash = minetest.hash_node_position(pos)
|
||||||
local playername = bed.occupied_beds[hash]
|
local playername = occupied_beds[hash]
|
||||||
return playername
|
return playername
|
||||||
end
|
end
|
||||||
-- Assign a player to the bed at pos.
|
-- Assign a player to the bed at pos.
|
||||||
-- If playername==nil, bed will be unassigned.
|
-- If playername==nil, bed will be unassigned.
|
||||||
local function set_bed_occupier(pos, playername)
|
local function set_bed_occupier(pos, playername)
|
||||||
local hash = minetest.hash_node_position(pos)
|
local hash = minetest.hash_node_position(pos)
|
||||||
bed.occupied_beds[hash] = playername
|
occupied_beds[hash] = playername
|
||||||
end
|
end
|
||||||
|
|
||||||
local function put_player_in_bed(player)
|
local function put_player_in_bed(player)
|
||||||
@ -96,11 +116,11 @@ local function put_player_in_bed(player)
|
|||||||
|
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
|
|
||||||
if not is_bed_node(bed.userdata.temp[name].node_pos) then
|
if not is_bed_node(bed_userdata.temp[name].node_pos) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
player:set_pos(bed.userdata.temp[name].sleep_pos)
|
player:set_pos(bed_userdata.temp[name].sleep_pos)
|
||||||
|
|
||||||
player_effects.apply_effect(player, "inbed")
|
player_effects.apply_effect(player, "inbed")
|
||||||
|
|
||||||
@ -125,11 +145,11 @@ local function clear_bed_status(player)
|
|||||||
end
|
end
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
|
|
||||||
bed.userdata.temp[name].in_bed = false
|
bed_userdata.temp[name].in_bed = false
|
||||||
if bed.userdata.temp[name].node_pos then
|
if bed_userdata.temp[name].node_pos then
|
||||||
set_bed_occupier(bed.userdata.temp[name].node_pos, nil)
|
set_bed_occupier(bed_userdata.temp[name].node_pos, nil)
|
||||||
end
|
end
|
||||||
bed.userdata.temp[name].node_pos = nil
|
bed_userdata.temp[name].node_pos = nil
|
||||||
|
|
||||||
player_effects.remove_effect(player, "inbed")
|
player_effects.remove_effect(player, "inbed")
|
||||||
|
|
||||||
@ -152,7 +172,7 @@ local function take_player_from_bed(player)
|
|||||||
end
|
end
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
|
|
||||||
local was_in_bed = bed.userdata.temp[name].in_bed == true
|
local was_in_bed = bed_userdata.temp[name].in_bed == true
|
||||||
if was_in_bed then
|
if was_in_bed then
|
||||||
minetest.log("action", "[rp_bed] "..name.." was taken from bed")
|
minetest.log("action", "[rp_bed] "..name.." was taken from bed")
|
||||||
end
|
end
|
||||||
@ -167,7 +187,7 @@ end
|
|||||||
local function save_bed()
|
local function save_bed()
|
||||||
local f = io.open(bed_file, "w")
|
local f = io.open(bed_file, "w")
|
||||||
|
|
||||||
f:write(minetest.serialize(bed.userdata.saved))
|
f:write(minetest.serialize(bed_userdata.saved))
|
||||||
|
|
||||||
io.close(f)
|
io.close(f)
|
||||||
|
|
||||||
@ -186,7 +206,7 @@ local function load_bed()
|
|||||||
local f = io.open(bed_file, "r")
|
local f = io.open(bed_file, "r")
|
||||||
|
|
||||||
if f then
|
if f then
|
||||||
bed.userdata.saved = minetest.deserialize(f:read("*all"))
|
bed_userdata.saved = minetest.deserialize(f:read("*all"))
|
||||||
|
|
||||||
io.close(f)
|
io.close(f)
|
||||||
else
|
else
|
||||||
@ -211,12 +231,12 @@ end
|
|||||||
local function on_joinplayer(player)
|
local function on_joinplayer(player)
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
|
|
||||||
if not bed.userdata.saved[name] then
|
if not bed_userdata.saved[name] then
|
||||||
bed.userdata.saved[name] = {
|
bed_userdata.saved[name] = {
|
||||||
spawn_pos = nil,
|
spawn_pos = nil,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
bed.userdata.temp[name] = {
|
bed_userdata.temp[name] = {
|
||||||
in_bed = false,
|
in_bed = false,
|
||||||
node_pos = nil,
|
node_pos = nil,
|
||||||
sleep_pos = nil,
|
sleep_pos = nil,
|
||||||
@ -228,12 +248,12 @@ end
|
|||||||
|
|
||||||
local function on_leaveplayer(player)
|
local function on_leaveplayer(player)
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
if bed.userdata.temp[name] then
|
if bed_userdata.temp[name] then
|
||||||
bed.userdata.temp[name].in_bed = false
|
bed_userdata.temp[name].in_bed = false
|
||||||
if bed.userdata.temp[name].node_pos then
|
if bed_userdata.temp[name].node_pos then
|
||||||
set_bed_occupier(bed.userdata.temp[name].node_pos, nil)
|
set_bed_occupier(bed_userdata.temp[name].node_pos, nil)
|
||||||
end
|
end
|
||||||
bed.userdata.temp[name].node_pos = nil
|
bed_userdata.temp[name].node_pos = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -347,12 +367,12 @@ end
|
|||||||
|
|
||||||
local function on_dieplayer(player)
|
local function on_dieplayer(player)
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
if bed.userdata.temp[name] then
|
if bed_userdata.temp[name] then
|
||||||
bed.userdata.temp[name].in_bed = false
|
bed_userdata.temp[name].in_bed = false
|
||||||
if bed.userdata.temp[name].node_pos then
|
if bed_userdata.temp[name].node_pos then
|
||||||
set_bed_occupier(bed.userdata.temp[name].node_pos, nil)
|
set_bed_occupier(bed_userdata.temp[name].node_pos, nil)
|
||||||
end
|
end
|
||||||
bed.userdata.temp[name].node_pos = nil
|
bed_userdata.temp[name].node_pos = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -370,7 +390,7 @@ local function on_globalstep(dtime)
|
|||||||
local sleeping_players = 0
|
local sleeping_players = 0
|
||||||
|
|
||||||
local in_bed = {}
|
local in_bed = {}
|
||||||
for name, data in pairs(bed.userdata.temp) do
|
for name, data in pairs(bed_userdata.temp) do
|
||||||
if data.in_bed then
|
if data.in_bed then
|
||||||
local player = minetest.get_player_by_name(name)
|
local player = minetest.get_player_by_name(name)
|
||||||
if player then
|
if player then
|
||||||
@ -417,7 +437,7 @@ local function on_punchplayer(player)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
if bed.userdata.temp[name].in_bed then
|
if bed_userdata.temp[name].in_bed then
|
||||||
take_player_from_bed(player)
|
take_player_from_bed(player)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -428,7 +448,7 @@ local function on_player_hpchange(player, hp_change)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
if bed.userdata.temp[name].in_bed then
|
if bed_userdata.temp[name].in_bed then
|
||||||
take_player_from_bed(player)
|
take_player_from_bed(player)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -597,7 +617,7 @@ minetest.register_node(
|
|||||||
if clicker_name == sleeper_name then
|
if clicker_name == sleeper_name then
|
||||||
take_player_from_bed(clicker)
|
take_player_from_bed(clicker)
|
||||||
elseif sleeper_name == nil and not rp_player.player_attached[clicker_name]
|
elseif sleeper_name == nil and not rp_player.player_attached[clicker_name]
|
||||||
and bed.userdata.temp[clicker_name].in_bed == false then
|
and bed_userdata.temp[clicker_name].in_bed == false then
|
||||||
if not minetest.settings:get_bool("bed_enable", true) then
|
if not minetest.settings:get_bool("bed_enable", true) then
|
||||||
minetest.chat_send_player(clicker_name, minetest.colorize("#FFFF00", S("Sleeping is disabled.")))
|
minetest.chat_send_player(clicker_name, minetest.colorize("#FFFF00", S("Sleeping is disabled.")))
|
||||||
return itemstack
|
return itemstack
|
||||||
@ -640,16 +660,16 @@ minetest.register_node(
|
|||||||
|
|
||||||
local yaw = (-(node.param2 / 2.0) * math.pi) + math.pi
|
local yaw = (-(node.param2 / 2.0) * math.pi) + math.pi
|
||||||
|
|
||||||
bed.userdata.temp[clicker_name].in_bed = true
|
bed_userdata.temp[clicker_name].in_bed = true
|
||||||
|
|
||||||
local changed = bed.set_spawn(clicker, put_pos)
|
local changed = bed.set_spawn(clicker, put_pos)
|
||||||
if changed then
|
if changed then
|
||||||
minetest.chat_send_player(clicker_name, minetest.colorize("#00FFFF", S("Respawn position set!")))
|
minetest.chat_send_player(clicker_name, minetest.colorize("#00FFFF", S("Respawn position set!")))
|
||||||
end
|
end
|
||||||
|
|
||||||
bed.userdata.temp[clicker_name].node_pos = pos
|
bed_userdata.temp[clicker_name].node_pos = pos
|
||||||
local sleep_pos = vector.add(pos, vector.divide(minetest.fourdir_to_dir(node.param2), 2))
|
local sleep_pos = vector.add(pos, vector.divide(minetest.fourdir_to_dir(node.param2), 2))
|
||||||
bed.userdata.temp[clicker_name].sleep_pos = sleep_pos
|
bed_userdata.temp[clicker_name].sleep_pos = sleep_pos
|
||||||
|
|
||||||
set_bed_occupier(pos, clicker_name)
|
set_bed_occupier(pos, clicker_name)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user