mirror of
https://github.com/Sokomine/cottages.git
synced 2026-01-11 11:35:46 +01:00
rewrite sitting/sleeping
- makes use of the modern player_api - fixes a crash due to api-change in set_physics_override - fixes eye offset issue
This commit is contained in:
2
mod.conf
2
mod.conf
@@ -1,5 +1,5 @@
|
||||
name = cottages
|
||||
description = Contains a lot of blocks that fit to medieval settlements and small cottages. Comes with hammer & anvil to repair tools. Threshing floor and handmill help process grains etc.
|
||||
optional_depends = default, farming, stairs, homedecor, intllib, trees, wool, moreblocks, unified_inventory, mcl_core
|
||||
optional_depends = default, farming, stairs, player_api, homedecor, intllib, trees, wool, moreblocks, unified_inventory, mcl_core
|
||||
author = Sokomine
|
||||
title = Blocks for building cottages.
|
||||
|
||||
@@ -98,7 +98,7 @@ minetest.register_node("cottages:sleeping_mat", {
|
||||
paramtype = 'light',
|
||||
paramtype2 = "facedir",
|
||||
walkable = false,
|
||||
groups = { snappy = 3 },
|
||||
groups = { snappy = 3, sleeping_mat = 1 },
|
||||
sounds = cottages.sounds.leaves,
|
||||
selection_box = {
|
||||
type = "wallmounted",
|
||||
@@ -132,7 +132,7 @@ minetest.register_node("cottages:sleeping_mat_head", {
|
||||
sunlight_propagates = true,
|
||||
paramtype = 'light',
|
||||
paramtype2 = "facedir",
|
||||
groups = { snappy = 3 },
|
||||
groups = { snappy = 3, sleeping_mat = 1 },
|
||||
sounds = cottages.sounds.leaves,
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
@@ -368,203 +368,145 @@ minetest.register_node("cottages:washing", {
|
||||
-- functions for sitting or sleeping
|
||||
---------------------------------------------------------------------------------------
|
||||
|
||||
cottages.allow_sit = function( player )
|
||||
cottages.allow_sit = function( player, pos )
|
||||
-- no check possible
|
||||
if( not( player.get_player_velocity )) then
|
||||
return true;
|
||||
end
|
||||
local velo = player:get_player_velocity();
|
||||
if( not( velo )) then
|
||||
if not minetest.is_player(player) then
|
||||
return false;
|
||||
end
|
||||
|
||||
local pname = player:get_player_name()
|
||||
|
||||
local p_above = minetest.get_node( {x=pos.x, y=pos.y+1, z=pos.z});
|
||||
if( not( p_above) or not( p_above.name ) or p_above.name ~= 'air' ) then
|
||||
minetest.chat_send_player( pname, "This place is too narrow for sitting. At least for you!")
|
||||
return
|
||||
end
|
||||
|
||||
local velo = player:get_player_velocity()
|
||||
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
|
||||
if vector.length(velo) < 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;
|
||||
cottages.is_bed = function(pos, node)
|
||||
if node.name == "cottages:bed_head" then
|
||||
local second_pos = vector.subtract(pos, minetest.facedir_to_dir(node.param2))
|
||||
local second_node = minetest.get_node(second_pos)
|
||||
return second_node.name == "cottages:bed_foot", second_pos
|
||||
elseif node.name == "cottages:bed_foot" then
|
||||
local second_pos = vector.add(pos, minetest.facedir_to_dir(node.param2))
|
||||
local second_node = minetest.get_node(second_pos)
|
||||
return second_node.name == "cottages:bed_head", second_pos
|
||||
elseif minetest.get_item_group(node.name, "sleeping_mat") ~= 0 then
|
||||
local search_offsets = {
|
||||
vector.new(1, 0, 0),
|
||||
vector.new(-1, 0, 0),
|
||||
vector.new(0, 0, 1),
|
||||
vector.new(0, 0, -1)
|
||||
}
|
||||
for _, offset in ipairs(search_offsets) do
|
||||
local second_pos = vector.add(pos, offset)
|
||||
local second_node = minetest.get_node(second_pos)
|
||||
if minetest.get_item_group(second_node.name, "sleeping_mat") ~= 0 then
|
||||
return true, second_pos
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local animation = default.player_get_animation( clicker );
|
||||
local pname = clicker:get_player_name();
|
||||
cottages.stand = function (player)
|
||||
local pname = player:get_player_name()
|
||||
player_api.player_attached[pname] = false
|
||||
player:set_physics_override({speed = 1, jump = 1, gravity = 1})
|
||||
player_api.set_animation(player, "stand", 30)
|
||||
end
|
||||
|
||||
if( animation and animation.animation=="sit") then
|
||||
default.player_attached[pname] = false
|
||||
cottages.sit = function (player)
|
||||
local pname = player:get_player_name()
|
||||
player_api.set_animation(player, "sit", 30)
|
||||
player:set_physics_override({speed = 0, jump = 0, gravity = 0})
|
||||
player_api.player_attached[pname] = true
|
||||
end
|
||||
|
||||
cottages.lay = function (player)
|
||||
local pname = player:get_player_name()
|
||||
player_api.set_animation(player, "lay", 30)
|
||||
player:set_physics_override({speed = 0, jump = 0, gravity = 0})
|
||||
player_api.player_attached[pname] = true
|
||||
end
|
||||
|
||||
cottages.sit_on_bench = function( pos, node, clicker, itemstack, pointed_thing )
|
||||
if not(player_api and cottages.allow_sit(clicker, pos)) then
|
||||
return;
|
||||
end
|
||||
|
||||
local animation = player_api.get_animation(clicker)
|
||||
|
||||
if (animation and animation.animation=="sit") then
|
||||
clicker:set_pos({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)
|
||||
cottages.stand(clicker, pos)
|
||||
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
|
||||
local offset = minetest.facedir_to_dir(node.param2)
|
||||
local p2 = vector.add(pos, vector.multiply(offset, 0.3))
|
||||
|
||||
clicker:set_eye_offset({x=0,y=-7,z=2}, {x=0,y=0,z=0})
|
||||
clicker:set_pos( p2 )
|
||||
default.player_set_animation(clicker, "sit", 30)
|
||||
clicker:set_physics_override(0, 0, 0)
|
||||
default.player_attached[pname] = true
|
||||
cottages.sit(clicker)
|
||||
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
|
||||
if not(player_api and cottages.allow_sit(clicker, pos)) then
|
||||
return;
|
||||
end
|
||||
|
||||
local animation = default.player_get_animation( clicker );
|
||||
local pname = clicker:get_player_name();
|
||||
local animation = player_api.get_animation(clicker)
|
||||
local pname = clicker:get_player_name()
|
||||
|
||||
local p_above = minetest.get_node( {x=pos.x, y=pos.y+1, z=pos.z});
|
||||
if( not( p_above) or not( p_above.name ) or p_above.name ~= 'air' ) then
|
||||
minetest.chat_send_player( pname, "This place is too narrow for sleeping. At least for you!");
|
||||
return;
|
||||
end
|
||||
|
||||
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';
|
||||
local is_bed, second_pos = cottages.is_bed(pos, node)
|
||||
|
||||
-- let players get back up
|
||||
if( animation and animation.animation=="lay" ) then
|
||||
default.player_attached[pname] = false
|
||||
clicker:set_pos({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;
|
||||
local player_pos = vector.copy(pos)
|
||||
local place_name = "place"
|
||||
if is_bed then
|
||||
player_pos = vector.divide(vector.add(pos, second_pos), 2)
|
||||
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' or node.name=='cottages:sleeping_mat_head') 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
|
||||
local 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' or node.name=='cottages:sleeping_mat_head' ) 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:set_pos({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:set_pos( 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.');
|
||||
if minetest.get_item_group(node.name, "sleeping_mat") ~= 0 then
|
||||
player_pos.y = player_pos.y - 0.5 + 1/16
|
||||
place_name = "mat"
|
||||
else
|
||||
minetest.chat_send_player( pname, 'Comftable, but not good enough for a nap. Right-click again if you want to get back up.');
|
||||
player_pos.y = player_pos.y + 0.3
|
||||
place_name = "bed"
|
||||
end
|
||||
|
||||
if is_bed then
|
||||
if (animation and (animation.animation=="lay")) then -- let the player up
|
||||
clicker:set_pos({x=pos.x,y=pos.y-0.5,z=pos.z})
|
||||
cottages.stand(clicker)
|
||||
minetest.chat_send_player( pname, 'That was enough sleep for now. You stand up again.');
|
||||
elseif (animation and animation.animation=="sit") then
|
||||
clicker:set_pos( player_pos )
|
||||
cottages.lay(clicker)
|
||||
minetest.chat_send_player( pname, 'You lie down and take a nap. A right-click will wake you up.');
|
||||
else
|
||||
clicker:set_pos( player_pos )
|
||||
cottages.sit(clicker)
|
||||
minetest.chat_send_player( pname, 'Aaah! What a comftable '..place_name..'. A second right-click will let you sleep.');
|
||||
end
|
||||
else
|
||||
if (animation and animation.animation=="sit") then -- let the player up
|
||||
clicker:set_pos({x=pos.x,y=pos.y-0.5,z=pos.z})
|
||||
cottages.stand(clicker)
|
||||
minetest.chat_send_player( pname, 'That was enough sitting around for now. You stand up again.')
|
||||
else
|
||||
clicker:set_pos( player_pos )
|
||||
cottages.sit(clicker)
|
||||
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
|
||||
end
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ minetest.register_node("cottages:straw_mat", {
|
||||
paramtype = 'light',
|
||||
paramtype2 = "facedir",
|
||||
walkable = false,
|
||||
groups = { hay = 3, snappy = 2, oddly_breakable_by_hand = 2, flammable=3 },
|
||||
groups = { hay = 3, snappy = 2, oddly_breakable_by_hand = 2, flammable=3 , sleeping_mat=1, },
|
||||
sounds = cottages.sounds.leaves,
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
|
||||
Reference in New Issue
Block a user