mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-11-28 05:21:05 +01:00
Add diagonal track movement on zig-zag track, rewrite mcl_minecarts:get_rail_direction
This commit is contained in:
parent
37d07b6201
commit
b4a0ae9c56
1 changed files with 60 additions and 74 deletions
|
@ -46,90 +46,76 @@ function mcl_minecarts:is_rail(pos, railtype)
|
||||||
return minetest.get_item_group(node, "connect_to_raillike") == railtype
|
return minetest.get_item_group(node, "connect_to_raillike") == railtype
|
||||||
end
|
end
|
||||||
|
|
||||||
function mcl_minecarts:check_front_up_down(pos, dir_, check_down, railtype)
|
--[[
|
||||||
local dir = vector.new(dir_)
|
Returns a string description of a direction, with optional _up/_down suffix
|
||||||
-- Front
|
]]
|
||||||
dir.y = 0
|
function mcl_minecarts:name_from_dir(dir, vertical)
|
||||||
local cur = vector.add(pos, dir)
|
local res = ""
|
||||||
if mcl_minecarts:is_rail(cur, railtype) then
|
|
||||||
return dir
|
if dir.z == 1 then res = res .. "n" end
|
||||||
|
if dir.z == -1 then res = res .. "s" end
|
||||||
|
|
||||||
|
if dir.x == -1 then res = res .. "w" end
|
||||||
|
if dir.x == 1 then res = res .. "e" end
|
||||||
|
|
||||||
|
if vertical then
|
||||||
|
if dir.y == 1 then res = res .. "_up" end
|
||||||
|
if dir.y == 1 then res = res .. "_down" end
|
||||||
end
|
end
|
||||||
-- Up
|
|
||||||
if check_down then
|
return res
|
||||||
dir.y = 1
|
|
||||||
cur = vector.add(pos, dir)
|
|
||||||
if mcl_minecarts:is_rail(cur, railtype) then
|
|
||||||
return dir
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Down
|
|
||||||
dir.y = -1
|
|
||||||
cur = vector.add(pos, dir)
|
|
||||||
if mcl_minecarts:is_rail(cur, railtype) then
|
|
||||||
return dir
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--[[
|
||||||
|
An array of (u,v,w) positions to check. Actual direction is u * dir + v * right + w * vector.new(0,1,0)
|
||||||
|
]]
|
||||||
|
local rail_checks = {
|
||||||
|
{ 1, 0, 0 }, -- forwards
|
||||||
|
{ 1, 0, 1 }, -- forwards and up
|
||||||
|
{ 1, 0, -1 }, -- forwards and down
|
||||||
|
|
||||||
|
{ 1, 1, 0 }, -- diagonal left
|
||||||
|
{ 0, 1, 0 }, -- left
|
||||||
|
{ 0, 1, 1 }, -- left and up
|
||||||
|
{ 0, 1, -1 }, -- left and down
|
||||||
|
|
||||||
|
{ 1, -1, 0 }, -- diagonal right
|
||||||
|
{ 0, -1, 0 }, -- right
|
||||||
|
{ 0, -1, 1 }, -- right and up
|
||||||
|
{ 0, -1, -1 }, -- right and down
|
||||||
|
|
||||||
|
{ -1, 0, 0 }, -- backwards
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Rotate diagonal directions 45 degrees clockwise
|
||||||
|
local diagonal_convert = {
|
||||||
|
nw = vector.new( 0,0, 1), -- north
|
||||||
|
ne = vector.new( 1,0, 0), -- east
|
||||||
|
se = vector.new( 0,0,-1), -- south
|
||||||
|
sw = vector.new(-1,0, 0), -- west
|
||||||
|
}
|
||||||
|
|
||||||
function mcl_minecarts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
|
function mcl_minecarts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
|
||||||
local pos = vector.round(pos_)
|
local pos = vector.round(pos_)
|
||||||
local cur
|
|
||||||
local left_check, right_check = true, true
|
|
||||||
|
|
||||||
-- Calculate left, right and back
|
-- Diagonal conversion
|
||||||
local left = vector.new(-dir.z, dir.y, dir.x)
|
if dir.x ~= 0 and dir.z ~= 0 then
|
||||||
|
dir = diagonal_convert[ mcl_minecarts:name_from_dir(dir, false) ]
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Calculate coordinate space
|
||||||
local right = vector.new( dir.z, dir.y, -dir.x)
|
local right = vector.new( dir.z, dir.y, -dir.x)
|
||||||
local back = vector.new(-dir.x, dir.y, -dir.z)
|
local up = vector.new(0,1,0)
|
||||||
|
|
||||||
if ctrl then
|
-- Perform checks
|
||||||
if old_switch == 1 then
|
for _,check in ipairs(rail_checks) do
|
||||||
left_check = false
|
local check_dir = dir * check[1] + right * check[2] + up * check[3]
|
||||||
elseif old_switch == 2 then
|
local check_pos = pos + check_dir
|
||||||
right_check = false
|
if mcl_minecarts:is_rail(check_pos,railtype) then
|
||||||
end
|
return check_dir
|
||||||
if ctrl.left and left_check then
|
|
||||||
cur = mcl_minecarts:check_front_up_down(pos, left, false, railtype)
|
|
||||||
if cur then
|
|
||||||
return cur, 1
|
|
||||||
end
|
|
||||||
left_check = false
|
|
||||||
end
|
|
||||||
if ctrl.right and right_check then
|
|
||||||
cur = mcl_minecarts:check_front_up_down(pos, right, false, railtype)
|
|
||||||
if cur then
|
|
||||||
return cur, 2
|
|
||||||
end
|
|
||||||
right_check = true
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Normal
|
|
||||||
cur = mcl_minecarts:check_front_up_down(pos, dir, true, railtype)
|
|
||||||
if cur then
|
|
||||||
return cur
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Left, if not already checked
|
|
||||||
if left_check then
|
|
||||||
cur = mcl_minecarts:check_front_up_down(pos, left, false, railtype)
|
|
||||||
if cur then
|
|
||||||
return cur
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Right, if not already checked
|
|
||||||
if right_check then
|
|
||||||
cur = mcl_minecarts:check_front_up_down(pos, right, false, railtype)
|
|
||||||
if cur then
|
|
||||||
return cur
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Backwards
|
|
||||||
if not old_switch then
|
|
||||||
cur = mcl_minecarts:check_front_up_down(pos, back, true, railtype)
|
|
||||||
if cur then
|
|
||||||
return cur
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return vector.new(0,0,0)
|
return vector.new(0,0,0)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue