Get rail reattachment (especially after jumps) working correctly

This commit is contained in:
teknomunk 2024-04-04 18:20:14 +00:00
parent 35af50bce0
commit 8478269dd9
2 changed files with 30 additions and 4 deletions

View File

@ -98,6 +98,31 @@ mod.south = south
mod.east = east
mod.west = west
--[[
mcl_minecarts.snap_direction(dir)
returns a valid cart direction that has the smallest angle difference to `dir'
]]
local VALID_DIRECTIONS = {
north, vector.offset(north, 0, 1, 0), vector.offset(north, 0, -1, 0),
south, vector.offset(south, 0, 1, 0), vector.offset(south, 0, -1, 0),
east, vector.offset(east, 0, 1, 0), vector.offset(east, 0, -1, 0),
west, vector.offset(west, 0, 1, 0), vector.offset(west, 0, -1, 0),
}
function mod.snap_direction(dir)
dir = vector.normalize(dir)
local best = nil
local diff = -1
for _,d in pairs(VALID_DIRECTIONS) do
local dot = vector.dot(dir,d)
if dot > diff then
best = d
diff = dot
end
end
return best
end
local CONNECTIONS = { north, south, east, west }
local HORIZONTAL_STANDARD_RULES = {
[N] = { "", 0, mask = N, score = 1, can_slope = true },

View File

@ -41,7 +41,6 @@ end
local function detach_minecart(self)
local staticdata = self._staticdata
print("Detaching minecart")
staticdata.connected_at = nil
self.object:set_velocity(staticdata.dir * staticdata.velocity)
@ -453,13 +452,15 @@ local function do_detached_movement(self, dtime)
local pos_r = vector.round(self.object:get_pos())
local node = minetest.get_node(pos_r)
if minetest.get_item_group(node.name, "rail") ~= 0 then
print("Reconnected railcart at "..tostring(pos_r))
staticdata.connected_at = pos_r
staticdata.railtype = node.name
local freebody_velocity = self.object:get_velocity()
staticdata.dir = vector.normalize(freebody_velocity)
staticdata.velocity = vector.length(freebody_velocity)
staticdata.dir = mod:get_rail_direction(pos_r, mod.snap_direction(freebody_velocity))
-- Use vector projection to only keep the velocity in the new direction of movement on the rail
-- https://en.wikipedia.org/wiki/Vector_projection
staticdata.velocity = vector.dot(staticdata.dir,freebody_velocity)
-- Clear freebody movement
self.object:set_velocity(vector.new(0,0,0))