Rework sitting; no longer changes player physics
This commit is contained in:
parent
06e4527ad9
commit
7a297813ca
@ -107,7 +107,6 @@ Maintenance updates:
|
|||||||
* Storage blocks now drop their inventory when exploded
|
* Storage blocks now drop their inventory when exploded
|
||||||
* Made several strings translatable
|
* Made several strings translatable
|
||||||
* Translation updates
|
* Translation updates
|
||||||
* Add support for playerphysics mod
|
|
||||||
* Add description to every setting
|
* Add description to every setting
|
||||||
* Add tooltip extensions for some interactive items (uses `tt` mod)
|
* Add tooltip extensions for some interactive items (uses `tt` mod)
|
||||||
* Add crafting guide support for `unified_inventory` mod (honey)
|
* Add crafting guide support for `unified_inventory` mod (honey)
|
||||||
|
@ -1,48 +1,76 @@
|
|||||||
local mod_playerphysics = minetest.get_modpath("playerphysics") ~= nil
|
|
||||||
local mod_player_api = minetest.get_modpath("player_api") ~= nil
|
local mod_player_api = minetest.get_modpath("player_api") ~= nil
|
||||||
|
|
||||||
|
local sitting = {}
|
||||||
|
local seats_occupied = {}
|
||||||
|
|
||||||
local function top_face(pointed_thing)
|
local function top_face(pointed_thing)
|
||||||
if not pointed_thing then return end
|
if not pointed_thing then
|
||||||
|
return
|
||||||
|
end
|
||||||
return pointed_thing.above.y > pointed_thing.under.y
|
return pointed_thing.above.y > pointed_thing.under.y
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function stand_up(player_name)
|
||||||
|
if not mod_player_api then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local player = minetest.get_player_by_name(player_name)
|
||||||
|
if not player then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
player_api.player_attached[player_name] = false
|
||||||
|
|
||||||
|
local old_anim = player_api.get_animation(player)
|
||||||
|
if old_anim and old_anim.animation == "sit" then
|
||||||
|
player_api.set_animation(player, "stand", 30)
|
||||||
|
end
|
||||||
|
|
||||||
|
local hash = minetest.hash_node_position(sitting[player_name])
|
||||||
|
seats_occupied[hash] = nil
|
||||||
|
sitting[player_name] = nil
|
||||||
|
|
||||||
|
minetest.log("action", "[xdecor] "..player_name.." stands up at "..minetest.pos_to_string(player:get_pos(), 0))
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ Used when player interacts with "sittable" node to sit down
|
||||||
|
or stand up when interacting with that node again. Should
|
||||||
|
be used in `on_rightclick` handler
|
||||||
|
* `pos`: Position where to sit down player (MUST only use integers for coordinates!)
|
||||||
|
* `node`: Node table of node to sit on
|
||||||
|
* `clicker`: Player who interacted with node (from `on_rightclick`)
|
||||||
|
* `pointed_thing`: From `on_rightclick` ]]
|
||||||
function xdecor.sit(pos, node, clicker, pointed_thing)
|
function xdecor.sit(pos, node, clicker, pointed_thing)
|
||||||
if not mod_player_api then return end
|
if not mod_player_api then
|
||||||
if not top_face(pointed_thing) then return end
|
return
|
||||||
|
end
|
||||||
|
-- Must click on top face to sit down
|
||||||
|
if not top_face(pointed_thing) then
|
||||||
|
return
|
||||||
|
end
|
||||||
local player_name = clicker:get_player_name()
|
local player_name = clicker:get_player_name()
|
||||||
local objs = minetest.get_objects_inside_radius(pos, 0.1)
|
local objs = minetest.get_objects_inside_radius(pos, 0.1)
|
||||||
local vel = clicker:get_velocity()
|
local vel = clicker:get_velocity()
|
||||||
local ctrl = clicker:get_player_control()
|
local ctrl = clicker:get_player_control()
|
||||||
|
|
||||||
for _, obj in pairs(objs) do
|
-- Stand up if sitting
|
||||||
if obj:is_player() and obj:get_player_name() ~= player_name then
|
if sitting[player_name] then
|
||||||
return
|
stand_up(player_name)
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if player_api.player_attached[player_name] then
|
-- Sit down if not sitting and not attached
|
||||||
clicker:set_pos(pos)
|
elseif not sitting[player_name] and not player_api.player_attached[player_name] and node.param2 <= 3 and
|
||||||
if mod_playerphysics then
|
|
||||||
playerphysics.remove_physics_factor(clicker, "speed", "xdecor:sit_speed")
|
|
||||||
playerphysics.remove_physics_factor(clicker, "jump", "xdecor:sit_jump")
|
|
||||||
else
|
|
||||||
clicker:set_physics_override({speed = 1, jump = 1})
|
|
||||||
end
|
|
||||||
player_api.player_attached[player_name] = false
|
|
||||||
player_api.set_animation(clicker, "stand", 30)
|
|
||||||
|
|
||||||
elseif not player_api.player_attached[player_name] and node.param2 <= 3 and
|
|
||||||
not ctrl.sneak and vector.equals(vel, vector.new()) then
|
not ctrl.sneak and vector.equals(vel, vector.new()) then
|
||||||
|
|
||||||
if mod_playerphysics then
|
-- Can't sit down on note already occupied by player
|
||||||
playerphysics.add_physics_factor(clicker, "speed", "xdecor:sit_speed", 0)
|
local hash = minetest.hash_node_position(pos)
|
||||||
playerphysics.add_physics_factor(clicker, "jump", "xdecor:sit_jump", 0)
|
if seats_occupied[hash] then
|
||||||
else
|
return
|
||||||
clicker:set_physics_override({speed = 0, jump = 0})
|
|
||||||
end
|
end
|
||||||
clicker:set_pos(pos)
|
|
||||||
player_api.player_attached[player_name] = true
|
player_api.player_attached[player_name] = true
|
||||||
player_api.set_animation(clicker, "sit", 30)
|
player_api.set_animation(clicker, "sit", 30)
|
||||||
|
sitting[player_name] = table.copy(pos)
|
||||||
|
seats_occupied[hash] = true
|
||||||
|
clicker:set_pos(pos)
|
||||||
|
|
||||||
if node.param2 == 0 then
|
if node.param2 == 0 then
|
||||||
clicker:set_look_horizontal(0)
|
clicker:set_look_horizontal(0)
|
||||||
@ -53,19 +81,61 @@ function xdecor.sit(pos, node, clicker, pointed_thing)
|
|||||||
elseif node.param2 == 3 then
|
elseif node.param2 == 3 then
|
||||||
clicker:set_look_horizontal(math.pi/2)
|
clicker:set_look_horizontal(math.pi/2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
minetest.log("action", "[xdecor] "..player_name.." sits down at "..minetest.pos_to_string(pos, 0))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Called when `digger` (a player object) wants to
|
||||||
|
-- dig a node at pos. Returns true if it's allowed,
|
||||||
|
-- false otherwise. This checks if the node at pos
|
||||||
|
-- is an occupied sittable node.
|
||||||
|
-- Can be used for the `can_dig` node function.
|
||||||
function xdecor.sit_dig(pos, digger)
|
function xdecor.sit_dig(pos, digger)
|
||||||
if not mod_player_api then
|
if not mod_player_api then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
for _, player in pairs(minetest.get_objects_inside_radius(pos, 0.1)) do
|
local hash = minetest.hash_node_position(pos)
|
||||||
if player:is_player() and
|
if seats_occupied[hash] then
|
||||||
player_api.player_attached[player:get_player_name()] then
|
return false
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Automatically cause players to stand up if they pressed a control
|
||||||
|
-- or moved away from the seat
|
||||||
|
minetest.register_globalstep(function(dtime)
|
||||||
|
local to_stand_up = {}
|
||||||
|
for player_name, sitting_pos in pairs(sitting) do
|
||||||
|
local player = minetest.get_player_by_name(player_name)
|
||||||
|
if player then
|
||||||
|
local ctrl = player:get_player_control()
|
||||||
|
if ctrl.up or ctrl.down or ctrl.left or ctrl.right or ctrl.sneak or ctrl.jump then
|
||||||
|
table.insert(to_stand_up, player_name)
|
||||||
|
elseif vector.distance(player:get_pos(), sitting_pos) > 0.55 then
|
||||||
|
table.insert(to_stand_up, player_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for s=1, #to_stand_up do
|
||||||
|
stand_up(to_stand_up[s])
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Force player to stand on death (to the seat is released)
|
||||||
|
minetest.register_on_dieplayer(function(player)
|
||||||
|
local player_name = player:get_player_name()
|
||||||
|
if sitting[player_name] then
|
||||||
|
stand_up(player_name)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
minetest.register_on_leaveplayer(function(player)
|
||||||
|
local player_name = player:get_player_name()
|
||||||
|
if sitting[player_name] then
|
||||||
|
local hash = minetest.hash_node_position(sitting[player_name])
|
||||||
|
seats_occupied[hash] = nil
|
||||||
|
sitting[player_name] = nil
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
2
mod.conf
2
mod.conf
@ -2,5 +2,5 @@ name = xdecor
|
|||||||
title = X-Decor-libre
|
title = X-Decor-libre
|
||||||
description = A libre decoration mod meant to be simple and well-featured.
|
description = A libre decoration mod meant to be simple and well-featured.
|
||||||
depends = default, bucket, doors, farming, stairs, xpanes
|
depends = default, bucket, doors, farming, stairs, xpanes
|
||||||
optional_depends = playerphysics, player_api, fire, moreblocks, mesecons, unified_inventory, tt
|
optional_depends = player_api, fire, moreblocks, mesecons, unified_inventory, tt
|
||||||
min_minetest_version = 5.7.0
|
min_minetest_version = 5.7.0
|
||||||
|
Loading…
Reference in New Issue
Block a user