From b4a0ae9c56e2156c298b28ebdca19fd1486b3c69 Mon Sep 17 00:00:00 2001 From: teknomunk Date: Mon, 11 Mar 2024 08:57:43 +0000 Subject: [PATCH] Add diagonal track movement on zig-zag track, rewrite mcl_minecarts:get_rail_direction --- mods/ENTITIES/mcl_minecarts/functions.lua | 134 ++++++++++------------ 1 file changed, 60 insertions(+), 74 deletions(-) diff --git a/mods/ENTITIES/mcl_minecarts/functions.lua b/mods/ENTITIES/mcl_minecarts/functions.lua index 587bbd281..9ea7de40a 100644 --- a/mods/ENTITIES/mcl_minecarts/functions.lua +++ b/mods/ENTITIES/mcl_minecarts/functions.lua @@ -46,90 +46,76 @@ function mcl_minecarts:is_rail(pos, railtype) return minetest.get_item_group(node, "connect_to_raillike") == railtype end -function mcl_minecarts:check_front_up_down(pos, dir_, check_down, railtype) - local dir = vector.new(dir_) - -- Front - dir.y = 0 - local cur = vector.add(pos, dir) - if mcl_minecarts:is_rail(cur, railtype) then - return dir +--[[ + Returns a string description of a direction, with optional _up/_down suffix +]] +function mcl_minecarts:name_from_dir(dir, vertical) + local res = "" + + 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 - -- Up - if check_down then - 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 + + return res 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) local pos = vector.round(pos_) - local cur - local left_check, right_check = true, true - -- Calculate left, right and back - local left = vector.new(-dir.z, dir.y, dir.x) + -- Diagonal conversion + 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 back = vector.new(-dir.x, dir.y, -dir.z) + local up = vector.new(0,1,0) - if ctrl then - if old_switch == 1 then - left_check = false - elseif old_switch == 2 then - right_check = false - end - 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 + -- Perform checks + for _,check in ipairs(rail_checks) do + local check_dir = dir * check[1] + right * check[2] + up * check[3] + local check_pos = pos + check_dir + if mcl_minecarts:is_rail(check_pos,railtype) then + return check_dir 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) end