summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSokomine <wegwerf@anarres.dyndns.org>2015-07-31 23:58:32 +0200
committerSokomine <wegwerf@anarres.dyndns.org>2015-07-31 23:58:32 +0200
commite0167dcc4fe70b0cb1a5066add5e19d8e0b75a90 (patch)
treef459be2feb1889f52214b3d1cf24b3cf70caa592
parente52dbe1d4b38c4084ba33bae9be562946ab67099 (diff)
sitting and sleeping on beds, sleeping mats and straw mats
-rw-r--r--nodes_furniture.lua239
1 files changed, 204 insertions, 35 deletions
diff --git a/nodes_furniture.lua b/nodes_furniture.lua
index 781e6bf..594c95b 100644
--- a/nodes_furniture.lua
+++ b/nodes_furniture.lua
@@ -45,6 +45,9 @@ minetest.register_node("cottages:bed_foot", {
}
},
is_ground_content = false,
+ on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
+ return cottages.sleep_in_bed( pos, node, clicker, itemstack, pointed_thing );
+ end
})
-- the bed is split up in two parts to avoid destruction of blocks on placement
@@ -77,6 +80,9 @@ minetest.register_node("cottages:bed_head", {
}
},
is_ground_content = false,
+ on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
+ return cottages.sleep_in_bed( pos, node, clicker, itemstack, pointed_thing );
+ end
})
@@ -110,6 +116,9 @@ minetest.register_node("cottages:sleeping_mat", {
}
},
is_ground_content = false,
+ on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
+ return cottages.sleep_in_bed( pos, node, clicker, itemstack, pointed_thing );
+ end
})
@@ -142,40 +151,8 @@ minetest.register_node("cottages:bench", {
},
is_ground_content = false,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
- if( not( clicker ) or not( default.player_get_animation )) then
- return;
- end
-
- local animation = default.player_get_animation( clicker );
- local pname = clicker:get_player_name();
-
- if( animation and animation.animation=="sit") then
- default.player_attached[pname] = false
- clicker:setpos({x=pos.x,y=pos.y-0.5,z=pos.z})
- clicker:set_eye_offset({x=0,y=0,z=0}, {x=0,y=0,z=0})
- clicker:set_physics_override(1, 1, 1)
- default.player_set_animation(clicker, "stand", 30)
- else
- -- the bench is not centered; prevent the player from sitting on air
- local p2 = {x=pos.x, y=pos.y, z=pos.z};
- local node = minetest.get_node( pos );
- if not( node ) or node.param2 == 0 then
- p2.z = p2.z+0.3;
- elseif node.param2 == 1 then
- p2.x = p2.x+0.3;
- elseif node.param2 == 2 then
- p2.z = p2.z-0.3;
- elseif node.param2 == 3 then
- p2.x = p2.x-0.3;
- end
-
- clicker:set_eye_offset({x=0,y=-7,z=2}, {x=0,y=0,z=0})
- clicker:setpos( p2 )
- default.player_set_animation(clicker, "sit", 30)
- clicker:set_physics_override(0, 0, 0)
- default.player_attached[pname] = true
- end
- end
+ return cottages.sit_on_bench( pos, node, clicker, itemstack, pointed_thing );
+ end,
})
@@ -353,6 +330,199 @@ minetest.register_node("cottages:washing", {
})
+---------------------------------------------------------------------------------------
+-- functions for sitting or sleeping
+---------------------------------------------------------------------------------------
+
+cottages.allow_sit = function( player )
+ local velo = player:get_player_velocity();
+ if( not( velo )) then
+ return false;
+ end
+ local max_velo = 0.0001;
+ if( math.abs(velo.x) < max_velo
+ and math.abs(velo.y) < max_velo
+ and math.abs(velo.z) < max_velo ) then
+ return true;
+ end
+ return false;
+end
+
+cottages.sit_on_bench = function( pos, node, clicker, itemstack, pointed_thing )
+ if( not( clicker ) or not( default.player_get_animation ) or not( cottages.allow_sit( clicker ))) then
+ return;
+ end
+
+ local animation = default.player_get_animation( clicker );
+ local pname = clicker:get_player_name();
+
+ if( animation and animation.animation=="sit") then
+ default.player_attached[pname] = false
+ clicker:setpos({x=pos.x,y=pos.y-0.5,z=pos.z})
+ clicker:set_eye_offset({x=0,y=0,z=0}, {x=0,y=0,z=0})
+ clicker:set_physics_override(1, 1, 1)
+ default.player_set_animation(clicker, "stand", 30)
+ else
+ -- the bench is not centered; prevent the player from sitting on air
+ local p2 = {x=pos.x, y=pos.y, z=pos.z};
+ if not( node ) or node.param2 == 0 then
+ p2.z = p2.z+0.3;
+ elseif node.param2 == 1 then
+ p2.x = p2.x+0.3;
+ elseif node.param2 == 2 then
+ p2.z = p2.z-0.3;
+ elseif node.param2 == 3 then
+ p2.x = p2.x-0.3;
+ end
+
+ clicker:set_eye_offset({x=0,y=-7,z=2}, {x=0,y=0,z=0})
+ clicker:setpos( p2 )
+ default.player_set_animation(clicker, "sit", 30)
+ clicker:set_physics_override(0, 0, 0)
+ default.player_attached[pname] = true
+ end
+end
+
+cottages.sleep_in_bed = function( pos, node, clicker, itemstack, pointed_thing )
+ if( not( clicker ) or not( node ) or not( node.name ) or not( pos ) or not( cottages.allow_sit( clicker))) then
+ return;
+ end
+
+ local animation = default.player_get_animation( clicker );
+ local pname = clicker:get_player_name();
+
+ local place_name = 'place';
+ -- if only one node is present, the player can only sit;
+ -- sleeping requires a bed head+foot or two sleeping mats
+ local allow_sleep = false;
+ local new_animation = 'sit';
+
+ -- let players get back up
+ if( animation and animation.animation=="lay" ) then
+ default.player_attached[pname] = false
+ clicker:setpos({x=pos.x,y=pos.y-0.5,z=pos.z})
+ clicker:set_eye_offset({x=0,y=0,z=0}, {x=0,y=0,z=0})
+ clicker:set_physics_override(1, 1, 1)
+ default.player_set_animation(clicker, "stand", 30)
+ minetest.chat_send_player( pname, 'That was enough sleep for now. You stand up again.');
+ return;
+ end
+
+ local second_node_pos = {x=pos.x, y=pos.y, z=pos.z};
+ -- the node that will contain the head of the player
+ local p = {x=pos.x, y=pos.y, z=pos.z};
+ -- the player's head is pointing in this direction
+ local dir = node.param2;
+ -- it would be odd to sleep in half a bed
+ if( node.name=='cottages:bed_head' ) then
+ if( node.param2==0 ) then
+ second_node_pos.z = pos.z-1;
+ elseif( node.param2==1) then
+ second_node_pos.x = pos.x-1;
+ elseif( node.param2==2) then
+ second_node_pos.z = pos.z+1;
+ elseif( node.param2==3) then
+ second_node_pos.x = pos.x+1;
+ end
+ local node2 = minetest.get_node( second_node_pos );
+ if( not( node2 ) or not( node2.param2 ) or not( node.param2 )
+ or node2.name ~= 'cottages:bed_foot'
+ or node2.param2 ~= node.param2 ) then
+ allow_sleep = false;
+ else
+ allow_sleep = true;
+ end
+ place_name = 'bed';
+
+ -- if the player clicked on the foot of the bed, locate the head
+ elseif( node.name=='cottages:bed_foot' ) then
+ if( node.param2==2 ) then
+ second_node_pos.z = pos.z-1;
+ elseif( node.param2==3) then
+ second_node_pos.x = pos.x-1;
+ elseif( node.param2==0) then
+ second_node_pos.z = pos.z+1;
+ elseif( node.param2==1) then
+ second_node_pos.x = pos.x+1;
+ end
+ local node2 = minetest.get_node( second_node_pos );
+ if( not( node2 ) or not( node2.param2 ) or not( node.param2 )
+ or node2.name ~= 'cottages:bed_head'
+ or node2.param2 ~= node.param2 ) then
+ allow_sleep = false;
+ else
+ allow_sleep = true;
+ end
+ if( allow_sleep==true ) then
+ p = {x=second_node_pos.x, y=second_node_pos.y, z=second_node_pos.z};
+ end
+ place_name = 'bed';
+
+ elseif( node.name=='cottages:sleeping_mat' or node.name=='cottages:straw_mat') then
+ place_name = 'mat';
+ dir = node.param2;
+ allow_sleep = false;
+ -- search for a second mat right next to this one
+ local offset = {{x=0,z=-1}, {x=-1,z=0}, {x=0,z=1}, {x=1,z=0}};
+ for i,off in ipairs( offset ) do
+ node2 = minetest.get_node( {x=pos.x+off.x, y=pos.y, z=pos.z+off.z} );
+ if( node2.name == 'cottages:sleeping_mat' or node2.name=='cottages:straw_mat' ) then
+ -- if a second mat is found, sleeping is possible
+ allow_sleep = true;
+ dir = i-1;
+ end
+ end
+ end
+
+ -- set the right height for the bed
+ if( place_name=='bed' ) then
+ p.y = p.y+0.4;
+ end
+ if( allow_sleep==true ) then
+ -- set the right position (middle of the bed)
+ if( dir==0 ) then
+ p.z = p.z-0.5;
+ elseif( dir==1 ) then
+ p.x = p.x-0.5;
+ elseif( dir==2 ) then
+ p.z = p.z+0.5;
+ elseif( dir==3 ) then
+ p.x = p.x+0.5;
+ end
+ end
+
+ if( default.player_attached[pname] and animation.animation=="sit") then
+ -- just changing the animation...
+ if( allow_sleep==true ) then
+ default.player_set_animation(clicker, "lay", 30)
+ clicker:set_eye_offset({x=0,y=-14,z=2}, {x=0,y=0,z=0})
+ minetest.chat_send_player( pname, 'You lie down and take a nap. A right-click will wake you up.');
+ return;
+ -- no sleeping on this place
+ else
+ default.player_attached[pname] = false
+ clicker:setpos({x=pos.x,y=pos.y-0.5,z=pos.z})
+ clicker:set_eye_offset({x=0,y=0,z=0}, {x=0,y=0,z=0})
+ clicker:set_physics_override(1, 1, 1)
+ default.player_set_animation(clicker, "stand", 30)
+ minetest.chat_send_player( pname, 'That was enough sitting around for now. You stand up again.');
+ return;
+ end
+ end
+
+
+ clicker:set_eye_offset({x=0,y=-7,z=2}, {x=0,y=0,z=0})
+ clicker:setpos( p );
+ default.player_set_animation(clicker, new_animation, 30)
+ clicker:set_physics_override(0, 0, 0)
+ default.player_attached[pname] = true
+
+ if( allow_sleep==true) then
+ minetest.chat_send_player( pname, 'Aaah! What a comftable '..place_name..'. A second right-click will let you sleep.');
+ else
+ minetest.chat_send_player( pname, 'Comftable, but not good enough for a nap. Right-click again if you want to get back up.');
+ end
+end
---------------------------------------------------------------------------------------
-- crafting receipes
@@ -423,4 +593,3 @@ minetest.register_craft({
{cottages.craftitem_steel, '', cottages.craftitem_steel},
}
})
-