- initial beta version
master
Leslie Krause 2020-03-25 01:12:00 -04:00
commit a72ba91a87
24 changed files with 847 additions and 0 deletions

185
README.txt Normal file
View File

@ -0,0 +1,185 @@
Beds Redux Mod v1.0
By Leslie E. Krause
Books Redux is a complete rewrite of the Beds mod from Minetest Game. That's right, beds
got a complete makeover from the ground up!
While striving to improve the beds mod for the JT2 server, I realized that the original
source code was becoming too unmanageable. So in January, I decided to start from scratch
developing Beds Redux with a fully revamped API and many new and exciting features both
for developers and players alike.
For more information, please visit the forum:
https://forum.minetest.net/viewtopic.php?f=9&t=24439
Repository
----------------------
Browse source code...
https://bitbucket.org/sorcerykid/beds
Download archive...
https://bitbucket.org/sorcerykid/beds/get/master.zip
https://bitbucket.org/sorcerykid/beds/get/master.tar.gz
Compatability
----------------------
Minetest 0.4.15+ required
Dependencies
----------------------
Default Mod (required)
https://github.com/minetest-game-mods/default
Wool Mod (required)
https://github.com/minetest-game-mods/wool
ActiveFormspecs Mod (required)
https://bitbucket.org/sorcerykid/formspecs
Configuration Panel Mod (required)
https://bitbucket.org/sorcerykid/config
Stairs Redo Mod (optional)
https://github.com/minetest-game-mods/stairs
Installation
----------------------
1) Unzip the archive into the mods directory of your game.
2) Rename the beds-master directory to "beds".
3) Create a file named "player_spawns.txt" in the world directory.
License of source code
----------------------------------------------------------
GNU Lesser General Public License v3 (LGPL-3.0)
Copyright (c) 2018-2020, Leslie E. Krause (leslie@searstower.org)
This program is free software; you can redistribute it and/or modify it under the terms of
the GNU Lesser General Public License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
http://www.gnu.org/licenses/lgpl-2.1.html
Multimedia License (textures, sounds, and models)
----------------------------------------------------------
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
/textures/beds_bed_fancy.png
by BlockMen
obtained from https://github.com/minetest-game-mods/beds
/textures/beds_bed_foot.png
by BlockMen
obtained from https://github.com/minetest-game-mods/beds
/textures/beds_bed_head.png
by BlockMen
obtained from https://github.com/minetest-game-mods/beds
/textures/beds_bed.png
by BlockMen
obtained from https://github.com/minetest-game-mods/beds
/textures/beds_bed_side1.png
by BlockMen
obtained from https://github.com/minetest-game-mods/beds
/textures/beds_bed_side2.png
by BlockMen
obtained from https://github.com/minetest-game-mods/beds
/textures/beds_bed_side_bottom.png
by BlockMen
obtained from https://github.com/minetest-game-mods/beds
/textures/beds_bed_side_bottom_r.png
by BlockMen
obtained from https://github.com/minetest-game-mods/beds
/textures/beds_bed_side_top.png
by BlockMen
obtained from https://github.com/minetest-game-mods/beds
/textures/beds_bed_side_top_r.png
by BlockMen
obtained from https://github.com/minetest-game-mods/beds
/textures/beds_bed_top1.png
by BlockMen
obtained from https://github.com/minetest-game-mods/beds
/textures/beds_bed_top2.png
by BlockMen
obtained from https://github.com/minetest-game-mods/beds
/textures/beds_bed_top_bottom.png
by BlockMen
obtained from https://github.com/minetest-game-mods/beds
/textures/beds_bed_top_top.png
by BlockMen
obtained from https://github.com/minetest-game-mods/beds
/textures/beds_particles.png
by Cat5TV
obtained from https://github.com/ChaosWormz/teleport-request
/textures/beds_transparent.png
by BlockMen
obtained from https://github.com/minetest-game-mods/beds
/textures/beds_sleeping.png
by Freepik
obtained from https://www.flaticon.com/free-icon/sleeping_2737073
modified by sorcerykid
/textures/beds_snooze.png
by Freepik
obtained from https://www.flaticon.com/premium-icon/star_2008109
modified by sorcerykid
/textures/beds_star.png
by Freepik
obtained from https://www.flaticon.com/premium-icon/star_2008109
modified by sorcerykid
/sounds/respawn_whoosh.ogg
by tim.kahn
obtained from https://freesound.org/people/tim.kahn/sounds/128590/
modified by sorcerykid
You are free to:
Share — copy and redistribute the material in any medium or format.
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
The licensor cannot revoke these freedoms as long as you follow the license terms.
Under the following terms:
Attribution — You must give appropriate credit, provide a link to the license, and
indicate if changes were made. You may do so in any reasonable manner, but not in any way
that suggests the licensor endorses you or your use.
No additional restrictions — You may not apply legal terms or technological measures that
legally restrict others from doing anything the license permits.
Notices:
You do not have to comply with the license for elements of the material in the public
domain or where your use is permitted by an applicable exception or limitation.
No warranties are given. The license may not give you all of the permissions necessary
for your intended use. For example, other rights such as publicity, privacy, or moral
rights may limit how you use the material.
For more details:
http://creativecommons.org/licenses/by-sa/3.0/

2
config.lua Normal file
View File

@ -0,0 +1,2 @@
can_always_sleep = false
max_action_range = 4.5

5
depends.txt Normal file
View File

@ -0,0 +1,5 @@
default
wool
config
formspecs
stairs?

655
init.lua Normal file
View File

@ -0,0 +1,655 @@
--------------------------------------------------------
-- Minetest :: Beds Redux Mod v1.0 (beds)
--
-- See README.txt for licensing and other information.
-- Copyright (c) 2016-2020, Leslie E. Krause
--
-- ./games/minetest_game/mods/beds/init.lua
--------------------------------------------------------
beds = { }
local config = minetest.load_config( {
filename = "player_spawns.txt",
spawn_pos = minetest.setting_get_pos( "static_spawnpoint" ),
} )
local world_path = minetest.get_worldpath( )
local player_sleeping_count = 0
local player_spawns = { }
local player_states = { }
---------------------
-- Private Methods --
---------------------
local function export_spawns( )
local data = minetest.serialize( player_spawns )
if not data then
error( "Could not serialize player spawn data." )
end
local file = io.open( world_path .. "/" .. config.filename, "w" )
if not file then
error( "Could not save player spawn data." )
end
file:write( data )
file:close( )
end
local function import_spawns( )
local file = io.open( world_path .. "/" .. config.filename, "r" )
if not file then
error( "Could not load player spawn data." )
end
local data = file:read( "*all" )
if data == "" then
player_spawns = { } -- initialize if empty file
else
player_spawns = minetest.deserialize( data )
if type( player_spawns ) ~= "table" then
error( "Could not deserialize player spawn data." )
end
end
file:close( )
end
local function set_spawn( name, pos )
player_spawns[ name ] = pos
end
local function unset_spawn( name )
player_spawns[ name ] = nil
end
local function is_spawn_at( spawn_pos, name )
return player_spawns[ name ] and vector.equals( player_spawns[ name ], spawn_pos )
end
local function unset_spawn_at( spawn_pos )
for name, pos in pairs( player_spawns ) do
if vector.equals( pos, spawn_pos ) then
player_spawns[ name ] = nil
end
end
end
local function open_sleep_viewer( name, pos )
local node = minetest.get_node( pos )
local ndef = minetest.registered_nodes[ node.name ]
local snooze_seq = 0
local star_list = { }
if not ndef.transforms then return end -- quick sanity check
for i = 1, 8 do
-- above moon
table.insert( star_list, { x = math.random( 0, 11 ) + 0.5, y = math.random( 0, 4 ) + 0.5 } )
end
for i = 1, 4 do
-- left of moon
table.insert( star_list, { x = math.random( 0, 3 ) + 0.5, y = math.random( 5, 8 ) + 0.5 } )
end
for i = 1, 4 do
-- right of moon
table.insert( star_list, { x = math.random( 8, 11 ) + 0.5, y = math.random( 5, 8 ) + 0.5 } )
end
local function get_random_alpha( )
return math.random( 0, 9 ) * 11
end
local function get_formspec( )
local player_count = #minetest.get_connected_players( )
local formspec = "size[12,15;true]" ..
"bgcolor[#080808BB;true]" ..
"image[4.5,5.5;4.0,3.8;beds_sleeping.png]" ..
"button_exit[3.0,12.0;2.5,0.7;leave;Wake Up]" ..
string.format( "button[6.5,12.0;2.5,0.7;%s]",
is_spawn_at( pos, name ) and "unset_home;Unset Home" or "set_home;Set Home"
) ..
string.format( "label[3.8,11.0;%d of %d players are currently sleeping]", player_sleeping_count, player_count )
if player_sleeping_count >= player_count / 2 then
formspec = formspec ..
"button_exit[4.0,10.0;4.0,0.7;skip_night;Skip Night]"
end
for i, v in ipairs( star_list ) do
formspec = formspec ..
string.format( "image[%0.1f,%0.1f;0.3,0.3;beds_star.png^[colorize:#000000%02d]",
v.x, v.y, get_random_alpha( )
)
end
for i = 0, 2 do
formspec = formspec ..
string.format( "image[%0.1f,%0.1f;%0.1f,%0.1f;beds_snooze.png^[colorize:#000000%02d]",
6.5 + i / 2, 5.5 - i / 2, 0.5 - i / 10, 0.5 - i / 10, snooze_seq % 3 == i and 22 or 99
)
end
snooze_seq = snooze_seq + 1
return formspec
end
local function on_close( state, player, fields )
if fields.quit == minetest.FORMSPEC_SIGEXIT then
beds.stand_up( name )
elseif fields.quit == minetest.FORMSPEC_SIGTIME then
if beds.to_daypart( ).half == "nighttime" or config.can_always_sleep then
minetest.update_form( name, get_formspec( ) )
else
minetest.destroy_form( name )
minetest.chat_send_player( name, string.format( "Good morning, %s!", name ) )
beds.stand_up( name )
end
end
if fields.set_home then
set_spawn( name, pos )
minetest.chat_send_player( name, "Your assigned active spawnpoint is " .. minetest.pos_to_string( pos ) .. "." )
minetest.update_form( name, get_formspec( ) )
elseif fields.unset_home then
unset_spawn( name )
minetest.chat_send_player( name, "Your assigned static spawnpoint is " .. minetest.pos_to_string( config.spawn_pos ) .. "." )
minetest.update_form( name, get_formspec( ) )
elseif fields.skip_night then
minetest.set_timeofday( 0.25 )
minetest.chat_send_player( name, string.format( "Good morning, %s!", name ) )
beds.stand_up( name )
end
end
minetest.create_form( nil, name, get_formspec( ), on_close )
minetest.get_form_timer( name ).start( 1.5 )
end
local function play_respawn_fx( pos )
local id = minetest.add_particlespawner( {
amount = 30,
time = 2.0,
minpos = vector.offset_y( pos, 1.5 ),
maxpos = pos,
minvel = { x = -1.0, y = 0.0, z = -1.0 },
maxvel = { x = 1.0, y = 1.0, z = 1.0 },
minacc = vector.origin,
maxacc = vector.origin,
minexptime = 0.8,
maxexptime = 1.2,
minsize = 2.5,
maxsize = 2.5,
collisiondetection = false,
vertical = false,
texture = "beds_particles.png",
} )
-- https://freesound.org/people/tim.kahn/sounds/128590/
minetest.sound_play( "respawn_whoosh", { pos = pos, gain = 0.3, max_hear_distance = 20 } )
end
local function apply_physics_override( pos, player, override )
player:setpos( vector.add( pos, override.pos ) )
player:set_look_yaw( override.yaw )
player:set_eye_offset( vector.new( 0, override.off, 0 ), vector.origin )
player:set_physics_override( { speed = 0, jump = 0, gravity = 0 } )
player:hud_set_flags( { wielditem = false } )
end
local function clear_physics_override( pos, player, base_pos )
if base_pos then
player:setpos( vector.add( pos, base_pos ) )
end
player:set_eye_offset( vector.origin, vector.origin )
player:set_physics_override( { speed = 1, jump = 1, gravity = 1 } )
player:hud_set_flags( { wielditem = true } )
end
--------------------
-- Public Methods --
--------------------
beds.sit_down = function ( name, pos )
if player_states[ name ] or default.player_attached[ name ] then return end
local player = minetest.get_player_by_name( name )
local node = minetest.get_node( pos )
local transforms = minetest.registered_nodes[ node.name ].transforms
if not transforms or not transforms.sitting then return end -- quick sanity check for properties
-- prevent the player from sitting on air
apply_physics_override( pos, player, transforms.sitting[ node.param2 ] )
default.player_set_animation( player, "sit", 30 )
default.player_attached[ name ] = true
player_states[ name ] = { type = "sit", pos = pos, obj = player }
end
beds.lay_down = function ( name, pos )
if player_states[ name ] or default.player_attached[ name ] then return end
local player = minetest.get_player_by_name( name )
local node = minetest.get_node( pos )
local transforms = minetest.registered_nodes[ node.name ].transforms
if not transforms or not transforms.laying then return end -- quick sanity check for properties
-- prevent the player from sitting on air
apply_physics_override( pos, player, transforms.laying[ node.param2 ] )
default.player_set_animation( player, "lay", 0 )
default.player_attached[ name ] = true
player_sleeping_count = player_sleeping_count + 1
player_states[ name ] = { type = "lay", pos = pos, obj = player }
end
beds.stand_up = function ( name, is_kick )
if not player_states[ name ] then return end
local player = minetest.get_player_by_name( name )
local pos = player_states[ name ].pos
local node = minetest.get_node( pos )
local ndef = minetest.registered_nodes[ node.name ]
clear_physics_override( pos, player,
player:get_hp( ) > 0 and ndef.base_spawn_pos or ndef.base_death_pos )
if not is_kick then
default.player_set_animation( player, "stand", 30 )
default.player_attached[ name ] = false
end
if player_states[ name ].type == "lay" then
player_sleeping_count = player_sleeping_count - 1
end
player_states[ name ] = nil
end
beds.to_daypart = function ( time )
-- by half:
-- * 6am - 6pm (daytime)
-- * 6pm - 6am (nighttime)
-- by quarter:
-- * 6am - noon (morning)
-- * noon - 6pm (afternoon)
-- * 6pm - midnight (evening)
-- * midnight - 6am (overnight)
local quarter, half
if time == nil then time = minetest.get_timeofday( ) end
if time < 0.25 then
quarter = "overnight"
elseif time < 0.5 then
quarter = "morning"
elseif time < 0.75 then
quarter = "afternoon"
else
quarter = "evening"
end
if time < 0.25 or time > 0.75 then
half = "nighttime"
else
half = "daytime"
end
return { quarter = quarter, half = half }
end
beds.is_occupied = function ( pos )
for name, data in pairs( player_states ) do
if vector.equals( data.pos, pos ) then
return true
end
end
return false
end
beds.get_spawn_pos = function ( name )
return player_spawns[ name ] or config.spawn_pos
end
--------------------------
-- Registered Callbacks --
--------------------------
local on_respawnplayer = core.registered_on_respawnplayers[ 1 ] -- hack to override builtin respawn callback
core.registered_on_respawnplayers[ 1 ] = function ( player )
local name = player:get_player_name( )
local pos = player:getpos( )
local spawn_pos = player_spawns[ name ]
if not spawn_pos then
-- send player to static spawnpoint if no assigned bed
return on_respawnplayer( player )
end
-- force load the relevant mapblock
VoxelManip( ):read_from_map( spawn_pos, spawn_pos )
local node = minetest.get_node( spawn_pos )
local base_spawn_pos = minetest.registered_nodes[ node.name ].base_spawn_pos
if not base_spawn_pos then
-- send player to static spawnpoint if bed is missing
minetest.log( "error", "Missing bed at " .. minetest.pos_to_string( spawn_pos ) .. ", found " .. node.name .. " instead" )
return on_respawnplayer( player )
end
minetest.log( "action", "Moving " .. name .. " from " .. minetest.pos_to_string( pos ) .. " to active spawnpoint" )
player:setpos( vector.add( spawn_pos, base_spawn_pos ) )
play_respawn_fx( spawn_pos )
return true
end
minetest.register_on_dieplayer( function ( player )
local name = player:get_player_name( )
beds.stand_up( name )
end )
minetest.register_on_leaveplayer( function ( player )
local name = player:get_player_name( )
beds.stand_up( name, true )
end )
minetest.register_on_shutdown( function( )
export_spawns( )
end )
------------------------------
-- Registered Chat Commands --
------------------------------
core.register_chatcommand( "home", {
description = "Show the coordinates of your assigned spawnpoint",
func = function( name )
local pos = player_spawns[ name ] or config.spawn_pos
return true, "Your assigned " .. ( player_spawns[ name ] and "active" or "static" ) .. " spawnpoint is " .. minetest.pos_to_string( pos ) .. "."
end,
} )
-------------------------
-- Register Globalstep --
-------------------------
minetest.register_globalstep( function( dtime )
if not next( player_states ) then return end
for name, state in pairs( player_states ) do
local controls = state.obj:get_player_control( )
if controls.sneak or controls.up or controls.down or controls.left or controls.right then
beds.stand_up( name )
end
end
end )
-------------------------
-- Registration Helper --
-------------------------
function beds.register_bed( name, def )
minetest.register_node( name .. "_bottom", {
description = def.description,
inventory_image = def.inventory_image,
wield_image = def.wield_image,
drawtype = "nodebox",
tiles = def.tiles.bottom,
paramtype = "light",
paramtype2 = "facedir",
stack_max = 1,
override_sneak = true,
groups = { snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 1 },
sounds = default.node_sound_wood_defaults( ),
node_box = {
type = "fixed",
fixed = def.nodebox.bottom,
},
selection_box = {
type = "fixed",
fixed = def.selectionbox,
},
base_spawn_pos = def.base_spawn_pos,
transforms = def.transforms,
can_dig = function( pos, player )
if beds.is_occupied( pos ) then
minetest.chat_send_player( player:get_player_name( ), "This bed is currently occupied." )
return false
end
return true
end,
after_place_node = function( pos )
local node = minetest.get_node_or_nil( pos )
if node then
local dir = minetest.facedir_to_dir( node.param2 )
local top_pos = vector.offset( pos, dir.x, 0, dir.z )
local top_node = minetest.get_node( top_pos )
local top_def = minetest.registered_items[ top_node.name ]
if top_def and top_def.buildable_to then
minetest.set_node( top_pos, {
name = string.gsub( node.name, "_bottom$", "_top" ),
param2 = node.param2
} )
return false
end
end
minetest.remove_node( pos )
return true
end,
after_dig_node = function( pos, old_node, old_meta, player )
local dir = minetest.facedir_to_dir( old_node.param2 )
local top_pos = vector.offset( pos, dir.x, 0, dir.z )
local top_node = minetest.get_node( top_pos )
local name = player:get_player_name( )
if minetest.get_item_group( top_node.name, "bed" ) == 2 and old_node.param2 == top_node.param2 then
minetest.remove_node( top_pos )
end
if is_spawn_at( pos, name ) then
minetest.chat_send_player( name, "Your assigned static spawnpoint is " .. minetest.pos_to_string( config.spawn_pos ) .. "." )
end
unset_spawn_at( pos )
end,
on_rightclick = function( pos, node, player )
local name = player:get_player_name( )
if player:get_player_control( ).sneak then
-- holding sneak updates the spawnpoint
if not is_spawn_at( pos, name ) then
minetest.chat_send_player( name, "Your assigned active spawnpoint is " .. minetest.pos_to_string( pos ) .. "." )
set_spawn( name, pos )
else
minetest.chat_send_player( name, "Your assigned static spawnpoint is " .. minetest.pos_to_string( config.spawn_pos ) .. "." )
unset_spawn( name )
end
elseif vector.equals( player:get_player_velocity( ), vector.origin ) then
-- only lay down if player is motionless and bed is unoccupied
if beds.is_occupied( pos ) then
minetest.chat_send_player( name, "This bed is already occupied." )
elseif vector.distance( pos, player:getpos( ) ) > config.max_action_range then
minetest.chat_send_player( name, "This bed is too far away." )
elseif beds.to_daypart( ).half == "nighttime" or config.can_always_sleep then
beds.lay_down( name, pos )
open_sleep_viewer( name, pos )
else
beds.sit_down( name, pos )
end
end
end,
on_blast = function ( pos ) end,
} )
minetest.register_node( name .. "_top", {
drawtype = "nodebox",
tiles = def.tiles.top,
paramtype = "light",
paramtype2 = "facedir",
groups = { snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 2 },
sounds = default.node_sound_wood_defaults( ),
node_box = {
type = "fixed",
fixed = def.nodebox.top,
},
selection_box = {
type = "fixed",
fixed = { 0, 0, 0, 0, 0, 0 },
},
on_blast = function ( pos ) end -- not affected by explosions
} )
minetest.register_alias( name, name .. "_bottom" )
-- register recipe
minetest.register_craft( {
output = name,
recipe = def.recipe
} )
end
beds.register_bed( "beds:fancy_bed", {
description = "Fancy Bed",
inventory_image = "beds_bed_fancy.png",
wield_image = "beds_bed_fancy.png",
tiles = {
bottom = {
"beds_bed_top1.png",
"default_wood.png",
"beds_bed_side1.png",
"beds_bed_side1.png^[transformFX",
"default_wood.png",
"beds_bed_foot.png",
},
top = {
"beds_bed_top2.png",
"default_wood.png",
"beds_bed_side2.png",
"beds_bed_side2.png^[transformFX",
"beds_bed_head.png",
"default_wood.png",
}
},
nodebox = {
bottom = {
{ -0.5, -0.5, -0.5, -0.375, -0.065, -0.4375 },
{ 0.375, -0.5, -0.5, 0.5, -0.065, -0.4375 },
{ -0.5, -0.375, -0.5, 0.5, -0.125, -0.4375 },
{ -0.5, -0.375, -0.5, -0.4375, -0.125, 0.5 },
{ 0.4375, -0.375, -0.5, 0.5, -0.125, 0.5 },
{ -0.4375, -0.3125, -0.4375, 0.4375, -0.0625, 0.5 },
},
top = {
{ -0.5, -0.5, 0.4375, -0.375, 0.1875, 0.5 },
{ 0.375, -0.5, 0.4375, 0.5, 0.1875, 0.5 },
{ -0.5, 0, 0.4375, 0.5, 0.125, 0.5 },
{ -0.5, -0.375, 0.4375, 0.5, -0.125, 0.5 },
{ -0.5, -0.375, -0.5, -0.4375, -0.125, 0.5 },
{ 0.4375, -0.375, -0.5, 0.5, -0.125, 0.5 },
{ -0.4375, -0.3125, -0.5, 0.4375, -0.0625, 0.4375 },
}
},
selectionbox = { -0.5, -0.5, -0.5, 0.5, 0.06, 1.5 },
base_spawn_pos = { x = 0, y = -0.5, z = 0 },
transforms = {
sitting = {
[0] = { yaw = 3.15, pos = { x = 0, y = 0, z = 0 }, off = -7 },
[1] = { yaw = 7.9, pos = { x = 0, y = 0, z = 0 }, off = -7 },
[2] = { yaw = 6.28, pos = { x = 0, y = 0, z = 0 }, off = -7 },
[3] = { yaw = 4.75, pos = { x = 0, y = 0, z = 0 }, off = -7 },
},
laying = {
[0] = { yaw = 3.15, pos = { x = 0, y = 0, z = 0.5 }, off = -13 },
[1] = { yaw = 7.9, pos = { x = 0.5, y = 0, z = 0 }, off = -13 },
[2] = { yaw = 6.28, pos = { x = 0, y = 0, z = -0.5 }, off = -13 },
[3] = { yaw = 4.75, pos = { x = -0.5, y = 0, z = 0 }, off = -13 },
}
},
recipe = {
{ "group:wool", "group:wool", "group:stick" },
{ "group:wood", "group:wood", "group:wood" },
},
} )
beds.register_bed( "beds:bed", {
description = "Simple Bed",
inventory_image = "beds_bed.png",
wield_image = "beds_bed.png",
tiles = {
bottom = {
"beds_bed_top_bottom.png^[transformR90",
"default_wood.png",
"beds_bed_side_bottom_r.png",
"beds_bed_side_bottom_r.png^[transformfx",
"beds_transparent.png",
"beds_bed_side_bottom.png"
},
top = {
"beds_bed_top_top.png^[transformR90",
"default_wood.png",
"beds_bed_side_top_r.png",
"beds_bed_side_top_r.png^[transformfx",
"beds_bed_side_top.png",
"beds_transparent.png",
}
},
nodebox = {
bottom = { -0.5, -0.5, -0.5, 0.5, 0.06, 0.5 },
top = { -0.5, -0.5, -0.5, 0.5, 0.06, 0.5 },
},
selectionbox = { -0.5, -0.5, -0.5, 0.5, 0.06, 1.5 },
base_spawn_pos = { x = 0, y = -0.5, z = 0 }, -- respawn inside bed to account for low clearances
transforms = {
sitting = {
[0] = { yaw = 3.15, pos = { x = 0, y = 0.1, z = 0 }, off = -7 },
[1] = { yaw = 7.9, pos = { x = 0, y = 0.1, z = 0 }, off = -7 },
[2] = { yaw = 6.28, pos = { x = 0, y = 0.1, z = 0 }, off = -7 },
[3] = { yaw = 4.75, pos = { x = 0, y = 0.1, z = 0 }, off = -7 },
},
laying = {
[0] = { yaw = 3.15, pos = { x = 0, y = 0.1, z = 0.5 }, off = -13 },
[1] = { yaw = 7.9, pos = { x = 0.5, y = 0.1, z = 0 }, off = -13 },
[2] = { yaw = 6.28, pos = { x = 0, y = 0.1, z = -0.5 }, off = -13 },
[3] = { yaw = 4.75, pos = { x = -0.5, y = 0.1, z = 0 }, off = -13 },
}
},
recipe = {
{ "group:wool", "group:wool", "group:wool" },
{ "group:wood", "group:wood", "group:wood" }
},
} )
-------------------
import_spawns( )

BIN
sounds/respawn_whoosh.ogg Normal file

Binary file not shown.

BIN
textures/beds_bed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 B

BIN
textures/beds_bed_fancy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

BIN
textures/beds_bed_foot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 B

BIN
textures/beds_bed_head.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 B

BIN
textures/beds_bed_side1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 B

BIN
textures/beds_bed_side2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 611 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 596 B

BIN
textures/beds_bed_top1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 583 B

BIN
textures/beds_bed_top2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 616 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 495 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

BIN
textures/beds_particles.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 B

BIN
textures/beds_sleeping.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 709 B

BIN
textures/beds_snooze.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

BIN
textures/beds_star.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 B