Repair vectors in cart data, mostly fix train movement bugs (still possible to have a furnace minecart flip, without the train also flipping)

This commit is contained in:
teknomunk 2024-04-08 19:38:13 +00:00
parent 52904ef5e0
commit a48c58a244
4 changed files with 27 additions and 18 deletions

View file

@ -358,7 +358,8 @@ end
function mod.get_cart_position(cart_staticdata) function mod.get_cart_position(cart_staticdata)
local data = cart_staticdata local data = cart_staticdata
if not data.connected_at then return end if not data then return nil end
if not data.connected_at then return nil end
return vector.add(data.connected_at, vector.multiply(data.dir or vector.zero(), data.distance or 0)) return vector.add(data.connected_at, vector.multiply(data.dir or vector.zero(), data.distance or 0))
end end

View file

@ -14,6 +14,7 @@ local update_train = mod.update_train
local link_cart_ahead = mod.link_cart_ahead local link_cart_ahead = mod.link_cart_ahead
local update_cart_orientation = mod.update_cart_orientation local update_cart_orientation = mod.update_cart_orientation
local get_cart_data = mod.get_cart_data local get_cart_data = mod.get_cart_data
local get_cart_position = mod.get_cart_position
local function detach_minecart(self) local function detach_minecart(self)
local staticdata = self._staticdata local staticdata = self._staticdata
@ -118,7 +119,8 @@ local function handle_cart_collision(cart1, prev_pos, next_dir)
local dirty = false local dirty = false
for uuid,v in pairs(carts) do for uuid,v in pairs(carts) do
-- Clean up dead carts -- Clean up dead carts
if not get_cart_data(uuid) then local data = get_cart_data(uuid)
if not data then
carts[uuid] = nil carts[uuid] = nil
dirty = true dirty = true
uuid = nil uuid = nil
@ -138,13 +140,9 @@ local function handle_cart_collision(cart1, prev_pos, next_dir)
minetest.log("action","cart #"..cart1._staticdata.uuid.." collided with cart #"..cart_uuid.." at "..tostring(pos)) minetest.log("action","cart #"..cart1._staticdata.uuid.." collided with cart #"..cart_uuid.." at "..tostring(pos))
local cart2_aoid = mcl_util.get_active_object_id_from_uuid(cart_uuid)
local cart2 = minetest.luaentities[cart2_aoid]
if not cart2 then return end
-- Standard Collision Handling -- Standard Collision Handling
local cart1_staticdata = cart1._staticdata local cart1_staticdata = cart1._staticdata
local cart2_staticdata = cart2._staticdata local cart2_staticdata = get_cart_data(cart_uuid)
local u1 = cart1_staticdata.velocity local u1 = cart1_staticdata.velocity
local u2 = cart2_staticdata.velocity local u2 = cart2_staticdata.velocity
@ -153,7 +151,7 @@ local function handle_cart_collision(cart1, prev_pos, next_dir)
--print("u1="..tostring(u1)..",u2="..tostring(u2)) --print("u1="..tostring(u1)..",u2="..tostring(u2))
if u2 == 0 and u1 < 4 and train_length(cart1) < MAX_TRAIN_LENGTH then if u2 == 0 and u1 < 4 and train_length(cart1) < MAX_TRAIN_LENGTH then
link_cart_ahead(cart1, cart2) link_cart_ahead(cart1, {_staticdata=cart2_staticdata})
cart2_staticdata.dir = mcl_minecarts:get_rail_direction(cart2_staticdata.connected_at, cart1_staticdata.dir) cart2_staticdata.dir = mcl_minecarts:get_rail_direction(cart2_staticdata.connected_at, cart1_staticdata.dir)
cart2_staticdata.velocity = cart1_staticdata.velocity cart2_staticdata.velocity = cart1_staticdata.velocity
return return

View file

@ -16,6 +16,13 @@ local function get_cart_data(uuid)
if not data then if not data then
cart_data_fail_cache[uuid] = true cart_data_fail_cache[uuid] = true
return nil return nil
else
-- Repair broken data
if not data.distance then data.distance = 0 end
if data.distance == 0/0 then data.distance = 0 end
if data.distance == -0/0 then data.distance = 0 end
data.dir = vector.new(data.dir)
data.connected_at = vector.new(data.connected_at)
end end
cart_data[uuid] = data cart_data[uuid] = data

View file

@ -72,13 +72,14 @@ function mod.update_train(cart)
-- Do no special processing if the cart is not part of a train -- Do no special processing if the cart is not part of a train
if not staticdata.ahead and not staticdata.behind then return end if not staticdata.ahead and not staticdata.behind then return end
-- Calculate the average velocity of all train cars -- Calculate the maximum velocity of all train cars
local sum_velocity = 0 local velocity = 0
local count = 0
for cart in train_cars(cart) do for cart in train_cars(cart) do
if cart.velocity or 0 > velocity then velocity = velocity + (cart.velocity or 0)
velocity = cart.velocity count = count + 1
end
end end
velocity = velocity / count
print("Using velocity "..tostring(velocity)) print("Using velocity "..tostring(velocity))
-- Set the entire train to the average velocity -- Set the entire train to the average velocity
@ -86,17 +87,19 @@ function mod.update_train(cart)
for c in train_cars(cart) do for c in train_cars(cart) do
local e = 0 local e = 0
local separation local separation
local cart_velocity = velocity
if behind then if behind then
separation = distance_between_cars(behind, c) separation = distance_between_cars(behind, c)
local e = 0 local e = 0
if separation > 1.25 then if separation > 1.6 then
velocity = velocity * 0.9 cart_velocity = velocity * 0.9
elseif separation < 1.15 then elseif separation < 1.15 then
velocity = velocity * 1.1 cart_velocity = velocity * 1.1
end end
end end
print(tostring(c.behind).."->"..c.uuid.."->"..tostring(c.ahead).."("..tostring(separation)..") setting cart #"..c.uuid.." velocity to "..tostring(velocity)) print(tostring(c.behind).."->"..c.uuid.."->"..tostring(c.ahead).."("..tostring(separation)..") setting cart #"..
c.velocity = velocity c.uuid.." velocity from "..tostring(c.velocity).." to "..tostring(cart_velocity))
c.velocity = cart_velocity
behind = c behind = c
end end