Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DO NOT MERGE: Pathfinder jump clearance #41

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 72 additions & 52 deletions working_villagers/pathfinder.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
local pathfinder = {}

local debug_pathfinder = true

--[[
minetest.get_content_id(name)
minetest.registered_nodes
Expand Down Expand Up @@ -46,6 +48,7 @@ local function get_distance_to_neighbor(start_pos, end_pos)
return (14 * distX + 10 * (distZ - distX)) * (distY + 1)
end
end

local function walkable(node)
if string.find(node.name,"doors:") then
return false
Expand All @@ -58,12 +61,13 @@ local function walkable(node)
end
end

local function check_clearance(cpos, x, z, height) --TODO: this is unused
-- Check if we have @height clear nodes above cpos.
-- We already checked that cpos is clear.
local function check_clearance(cpos, height)
for i = 1, height do
local n_name = minetest.get_node({x = cpos.x + x, y = cpos.y + i, z = cpos.z + z}).name
local c_name = minetest.get_node({x = cpos.x, y = cpos.y + i, z = cpos.z}).name
--print(i, n_name, c_name)
if walkable(n_name) or walkable(c_name) then
local hpos = {x=cpos.x, y=cpos.y+i, z=cpos.z}
local node = minetest.get_node(hpos)
if walkable(node) then
return false
end
end
Expand Down Expand Up @@ -99,6 +103,8 @@ local function get_neighbor_ground_level(pos, jump_height, fall_height)
end

local function get_neighbors(current_pos, entity_height, entity_jump_height, entity_fear_height)
-- check to see if we can jump in the current pos
local can_jump = check_clearance(current_pos, entity_height + entity_jump_height)
local neighbors = {}
local neighbors_index = 1
for z = -1, 1 do
Expand All @@ -107,67 +113,78 @@ local function get_neighbors(current_pos, entity_height, entity_jump_height, ent
local neighbor = minetest.get_node(neighbor_pos)
local neighbor_ground_level = get_neighbor_ground_level(neighbor_pos, entity_jump_height, entity_fear_height)
local neighbor_clearance = false
if neighbor_ground_level then
-- print(neighbor_ground_level.y - current_pos.y)
-- minetest.set_node(neighbor_ground_level, {name = "default:dry_shrub"})
local node_above_head = minetest.get_node(
{x = current_pos.x, y = current_pos.y + entity_height, z = current_pos.z})
if neighbor_ground_level.y - current_pos.y > 0 and not(walkable(node_above_head)) then
local height = -1
repeat
height = height + 1
local node = minetest.get_node(
{x = neighbor_ground_level.x,
y = neighbor_ground_level.y + height,
z = neighbor_ground_level.z})
until walkable(node) or height > entity_height
if height >= entity_height then
neighbor_clearance = true
end
elseif neighbor_ground_level.y - current_pos.y > 0 and walkable(node_above_head) then
neighbors[neighbors_index] = {
hash = nil,
pos = nil,
clear = nil,
walkable = nil,
}
else
local height = -1
repeat
height = height + 1
local node = minetest.get_node(
{x = neighbor_ground_level.x,
y = current_pos.y + height,
z = neighbor_ground_level.z})
until walkable(node) or height > entity_height
if height >= entity_height then
neighbor_clearance = true
end
-- did we find a walkable node within range with a non-walkable node above?
if neighbor_ground_level and can_jump or current_pos.y >= neighbor_ground_level.y then
-- check headroom, if we are jumping, we need extra
local needed_height = entity_height
if neighbor_ground_level.y > current_pos.y then
needed_height = needed_height + entity_jump_height - (neighbor_ground_level.y - current_pos.y)
end

neighbor_clearance = check_clearance(neighbor_pos, needed_height)
end
if neighbor_clearance and neighbor_ground_level then
neighbors[neighbors_index] = {
hash = minetest.hash_node_position(neighbor_ground_level),
pos = neighbor_ground_level,
clear = neighbor_clearance,
walkable = walkable(neighbor),
hash = minetest.hash_node_position(neighbor_ground_level),
pos = neighbor_ground_level,
clear = true,
walkable = true, -- FIXME: clear and walkable are always the same
}
else
neighbors[neighbors_index] = {
hash = nil,
pos = nil,
clear = nil,
walkable = nil,
hash = nil,
pos = nil,
clear = nil,
walkable = nil,
}
end
neighbors_index = neighbors_index + 1
end
end
end -- for x
end -- for z
return neighbors
end

--TODO: path to the nearest of multiple endpoints
-- or first path nearest to the endpoint

-- illustrate the path -- adapted from minetest's pathfinder test.
local function show_particles(path)
local prev = path[1]
for s=1, #path do
local pos = path[s]
local t
if s == #path then
t = "testpathfinder_waypoint_end.png"
elseif s == 1 then
t = "testpathfinder_waypoint_start.png"
else
local tn = "testpathfinder_waypoint.png"
if pos.y ~= prev.y then
if pos.x == prev.x and pos.z == prev.z then
if pos.y > prev.y then
tn = "testpathfinder_waypoint_up.png"
else
tn = "testpathfinder_waypoint_down.png"
end
else
tn = "testpathfinder_waypoint_jump.png"
end
end
local c = math.floor(((#path-s)/#path)*255)
t = string.format("%s^[multiply:#%02x%02x00", tn, 0xFF-c, c)
end
minetest.add_particle({
pos = pos,
expirationtime = 5 + 0.2 * s,
playername = "singleplayer",
glow = minetest.LIGHT_MAX,
texture = t,
size = 3,
})
prev = pos
end
end


function pathfinder.find_path(pos, endpos, entity)
--print("searching for a path to:" .. minetest.pos_to_string(endpos))
local start_index = minetest.hash_node_position(pos)
Expand Down Expand Up @@ -232,6 +249,9 @@ function pathfinder.find_path(pos, endpos, entity)
print("path's length is "..#path.." but reverse path has length "..#reverse_path)
end
--print("path length: "..#reverse_path)
if debug_pathfinder then
show_particles(path)
end
return reverse_path,path
end

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.