Pathfinder: Allow custom climbable node
This commit is contained in:
parent
69cda93705
commit
dd863a16fd
@ -41,6 +41,9 @@ restrictions and does not cut corners.
|
|||||||
* `handler_blocking`: A function that takes a node table and returns
|
* `handler_blocking`: A function that takes a node table and returns
|
||||||
true if the node shall block the path
|
true if the node shall block the path
|
||||||
(default: same as `handler_walkable`)
|
(default: same as `handler_walkable`)
|
||||||
|
* `handler_climbable`: A function that takes a node table and returns
|
||||||
|
true if the node is considered climable
|
||||||
|
(default: if `climbing` field of node is true)
|
||||||
* `use_vmanip`: If true, nodes will be queried using a LuaVoxelManip;
|
* `use_vmanip`: If true, nodes will be queried using a LuaVoxelManip;
|
||||||
otherwise, `minetest.get_node` will be used. Required for async
|
otherwise, `minetest.get_node` will be used. Required for async
|
||||||
usage.
|
usage.
|
||||||
|
@ -22,7 +22,7 @@ local blocking_default = walkable_default
|
|||||||
-- * 1: Check if can climb up (no 'disable_jump' group)
|
-- * 1: Check if can climb up (no 'disable_jump' group)
|
||||||
-- * -1: Check if can climb down (no 'disable_descend' group)
|
-- * -1: Check if can climb down (no 'disable_descend' group)
|
||||||
-- * nil: Ignore climb restrictions
|
-- * nil: Ignore climb restrictions
|
||||||
local function climbable(node, dir)
|
local function climbable_default(node, dir)
|
||||||
local def = minetest.registered_nodes[node.name]
|
local def = minetest.registered_nodes[node.name]
|
||||||
if not def then
|
if not def then
|
||||||
return false
|
return false
|
||||||
@ -117,7 +117,7 @@ end
|
|||||||
-- and returns the final node we land *in*
|
-- and returns the final node we land *in*
|
||||||
local function drop_down(pos, drop_height, stop_at_climb, nh, get_node)
|
local function drop_down(pos, drop_height, stop_at_climb, nh, get_node)
|
||||||
local stop = function(node)
|
local stop = function(node)
|
||||||
return nh.blocking(node) or nh.walkable(node) or (stop_at_climb and climbable(node))
|
return nh.blocking(node) or nh.walkable(node) or (stop_at_climb and nh.climbable(node))
|
||||||
end
|
end
|
||||||
local dpos = table.copy(pos)
|
local dpos = table.copy(pos)
|
||||||
-- Get the first blocking or walkable node below neighbor
|
-- Get the first blocking or walkable node below neighbor
|
||||||
@ -148,13 +148,13 @@ local function get_neighbor_floor_pos(neighbor_pos, current_pos, clear_height, j
|
|||||||
-- Climb
|
-- Climb
|
||||||
if climb then
|
if climb then
|
||||||
-- If neighbor is climbable
|
-- If neighbor is climbable
|
||||||
if climbable(nnode) and not nh.blocking(nnode) then
|
if nh.climbable(nnode) and not nh.blocking(nnode) then
|
||||||
return npos
|
return npos
|
||||||
-- If node *below* neighbor is climbable
|
-- If node *below* neighbor is climbable
|
||||||
elseif not nh.blocking(nnode) then
|
elseif not nh.blocking(nnode) then
|
||||||
local bpos = vector.offset(npos, 0, -1, 0)
|
local bpos = vector.offset(npos, 0, -1, 0)
|
||||||
local bnode = get_node(bpos)
|
local bnode = get_node(bpos)
|
||||||
if climbable(bnode) and not nh.blocking(bnode) then
|
if nh.climbable(bnode) and not nh.blocking(bnode) then
|
||||||
return npos
|
return npos
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -286,6 +286,7 @@ function rp_pathfinder.find_path(pos1, pos2, searchdistance, options, timeout)
|
|||||||
local nh = {
|
local nh = {
|
||||||
walkable = options.handler_walkable or walkable_default,
|
walkable = options.handler_walkable or walkable_default,
|
||||||
blocking = options.handler_blocking or blocking_default,
|
blocking = options.handler_blocking or blocking_default,
|
||||||
|
climbable = options.handler_climbable or climbable_default,
|
||||||
}
|
}
|
||||||
local get_node
|
local get_node
|
||||||
if options.use_vmanip then
|
if options.use_vmanip then
|
||||||
@ -398,11 +399,11 @@ function rp_pathfinder.find_path(pos1, pos2, searchdistance, options, timeout)
|
|||||||
if climb then
|
if climb then
|
||||||
current_neighbor_dirs = table.copy(neighbor_dirs)
|
current_neighbor_dirs = table.copy(neighbor_dirs)
|
||||||
if respect_climb_restrictions then
|
if respect_climb_restrictions then
|
||||||
if climbable(current_node) then
|
if nh.climbable(current_node) then
|
||||||
if climbable(current_node, 1) then
|
if nh.climbable(current_node, 1) then
|
||||||
table.insert(current_neighbor_dirs, {x=0,y=1,z=0})
|
table.insert(current_neighbor_dirs, {x=0,y=1,z=0})
|
||||||
end
|
end
|
||||||
if climbable(current_node, -1) then
|
if nh.climbable(current_node, -1) then
|
||||||
table.insert(current_neighbor_dirs, {x=0,y=-1,z=0})
|
table.insert(current_neighbor_dirs, {x=0,y=-1,z=0})
|
||||||
end
|
end
|
||||||
current_max_jump = 0
|
current_max_jump = 0
|
||||||
@ -410,7 +411,7 @@ function rp_pathfinder.find_path(pos1, pos2, searchdistance, options, timeout)
|
|||||||
table.insert(current_neighbor_dirs, {x=0,y=-1,z=0})
|
table.insert(current_neighbor_dirs, {x=0,y=-1,z=0})
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if climbable(current_node) then
|
if nh.climbable(current_node) then
|
||||||
table.insert(current_neighbor_dirs, {x=0,y=1,z=0})
|
table.insert(current_neighbor_dirs, {x=0,y=1,z=0})
|
||||||
current_max_jump = 0
|
current_max_jump = 0
|
||||||
end
|
end
|
||||||
@ -420,7 +421,7 @@ function rp_pathfinder.find_path(pos1, pos2, searchdistance, options, timeout)
|
|||||||
if current_max_jump > 0 then
|
if current_max_jump > 0 then
|
||||||
local below_pos = vector.offset(current_pos, 0, -1, 0)
|
local below_pos = vector.offset(current_pos, 0, -1, 0)
|
||||||
local below_node = get_node(below_pos)
|
local below_node = get_node(below_pos)
|
||||||
if climbable(below_node) then
|
if nh.climbable(below_node) then
|
||||||
current_max_jump = 0
|
current_max_jump = 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user