Improve the buffer pathfinding for carts not starting directly at a buffer

master
Joachim Stolberg 2021-07-29 19:37:38 +02:00
parent e0ed34f50c
commit c946da1943
5 changed files with 76 additions and 9 deletions

View File

@ -75,7 +75,8 @@ function minecart.find_node_near_lvm(pos, radius, items)
for y = pos1.y, pos2.y do
for z = pos1.z, pos2.z do
local idx = area:indexp({x = x, y = y, z = z})
if minetest.get_name_from_content_id(data[idx]) then
local name = minetest.get_name_from_content_id(data[idx])
if name and tItems[name] then
return {x = x, y = y, z = z}
end
end
@ -305,12 +306,12 @@ function minecart.add_entitycart(pos, node_name, entity_name, vel, cargo, owner,
end
end
function minecart.start_entitycart(self, pos)
function minecart.start_entitycart(self, pos, facedir)
local route = {}
self.is_running = true
self.arrival_time = 0
self.start_pos = minecart.get_buffer_pos(pos, self.owner)
self.start_pos = minecart.get_buffer_pos(pos, self.owner) or minecart.get_next_buffer(pos, facedir)
if self.start_pos then
-- Read buffer route for the junction info
route = minecart.get_route(self.start_pos) or {}

View File

@ -252,9 +252,11 @@ local function on_entitycard_punch(self, puncher, time_from_last_punch, tool_cap
local pos = vector.round(self.object:get_pos())
if puncher then
local yaw = puncher:get_look_horizontal()
dir = minetest.yaw_to_dir(yaw)
self.object:set_rotation({x = 0, y = yaw, z = 0})
end
minecart.start_entitycart(self, pos)
local facedir = minetest.dir_to_facedir(dir or {x=0, y=0, z=0})
minecart.start_entitycart(self, pos, facedir or 0)
minecart.start_recording(self, pos)
end
end

View File

@ -47,14 +47,19 @@ function minecart.start_nodecart(pos, node_name, puncher, punch_dir)
local obj = minecart.node_to_entity(pos, node_name, entity_name)
if obj then
local entity = obj:get_luaentity()
local facedir
if puncher then
local yaw = puncher:get_look_horizontal()
entity.object:set_rotation({x = 0, y = yaw, z = 0})
local dir = minetest.yaw_to_dir(yaw)
facedir = minetest.dir_to_facedir(dir)
elseif punch_dir then
local yaw = minetest.dir_to_yaw(punch_dir)
entity.object:set_rotation({x = 0, y = yaw, z = 0})
facedir = minetest.dir_to_facedir(punch_dir)
end
minecart.start_entitycart(entity, pos)
minecart.start_entitycart(entity, pos, facedir or 0)
end
end
end

View File

@ -424,6 +424,52 @@ function minecart.delete_waypoint(pos)
end
end
-------------------------------------------------------------------------------
-- find next buffer (needed as starting position)
-------------------------------------------------------------------------------
local function get_next_waypoints(pos)
local t = get_metadata(pos)
if not t then
t = find_all_next_waypoints(pos)
end
return t
end
local function get_next_pos_and_facedir(waypoints, facedir)
local cnt = 0
local newpos, newfacedir
facedir = (facedir + 2) % 4 -- opposite dir
for i = 0, 3 do
if waypoints[i] then
cnt = cnt + 1
if i ~= facedir then -- not the same way back
newpos = vector.new(waypoints[i].pos)
newfacedir = i
end
end
end
-- no junction and valid facedir
if cnt < 3 and newfacedir then
return newpos, newfacedir
end
end
local function get_next_buffer(pos, facedir)
facedir = (facedir + 2) % 4 -- opposite dir
for i = 1,5 do -- limit search depth
local waypoints = get_next_waypoints(pos) or {}
local pos1, facedir1 = get_next_pos_and_facedir(waypoints, facedir)
if pos1 then
pos, facedir = pos1, facedir1
else
return minecart.find_node_near_lvm(pos, 1, {"minecart:buffer"})
end
end
end
carts:register_rail("minecart:rail", {
description = "Rail",
tiles = {
@ -536,13 +582,17 @@ function minecart.add_raillike_nodes(name)
lRailsExt[#lRailsExt + 1] = name
end
-- minecart.get_next_buffer(pos, facedir)
minecart.get_next_buffer = get_next_buffer
--minetest.register_lbm({
-- label = "Delete waypoints",
-- name = "minecart:del_meta",
-- nodenames = {"carts:brakerail"},
-- nodenames = {"minecart:rail", "minecart:powerrail"},
-- run_at_every_load = true,
-- action = function(pos, node)
-- del_metadata(pos)
-- end,
--})

View File

@ -29,6 +29,16 @@ end
local old_pos
local function test_get_buffer(pos, player)
local yaw = player:get_look_horizontal()
local dir = minetest.yaw_to_dir(yaw)
local facedir = minetest.dir_to_facedir(dir)
local pos1 = minecart.get_next_buffer(pos, facedir)
if pos1 then
minecart.set_marker(pos1, "buffer", 1.2, 10)
end
end
local function test_get_route(pos, node, player)
local yaw = player:get_look_horizontal()
local dir = minetest.yaw_to_dir(yaw)
@ -67,9 +77,8 @@ end
local function click_left(itemstack, placer, pointed_thing)
if pointed_thing.type == "node" then
local pos = pointed_thing.under
local node = minetest.get_node(pos)
if node.name == "carts:rail" or node.name == "carts:powerrail" then
test_get_route(pos, node, placer)
if minecart.is_rail(pos) then
test_get_buffer(pos, placer)
end
end
end