diff options
Diffstat (limited to 'boost_cart')
-rw-r--r-- | boost_cart/functions.lua | 23 | ||||
-rw-r--r-- | boost_cart/init.lua | 61 |
2 files changed, 58 insertions, 26 deletions
diff --git a/boost_cart/functions.lua b/boost_cart/functions.lua index a06f34d..bcbbaa0 100644 --- a/boost_cart/functions.lua +++ b/boost_cart/functions.lua @@ -157,6 +157,29 @@ function boost_cart:get_rail_direction(pos_, dir, ctrl, old_switch, railtype) return {x=0, y=0, z=0} end +function boost_cart:pathfinder(pos_, expected_pos, old_dir, ctrl, pf_switch, railtype) + local pos = vector.round(pos_) + local pf_pos = vector.round(expected_pos) + local pf_dir = vector.new(old_dir) + + for i = 1, 3 do + if vector.equals(pf_pos, pos) then + -- Success! Cart moved on correctly + return true + end + + pf_dir, pf_switch = boost_cart:get_rail_direction(pf_pos, pf_dir, ctrl, pf_switch, railtype) + if vector.equals(pf_dir, {x=0, y=0, z=0}) then + -- No way forwards + return false + end + + pf_pos = vector.add(pf_pos, pf_dir) + end + -- Cart not found + return false +end + function boost_cart:boost_rail(pos, amount) minetest.get_meta(pos):set_string("cart_acceleration", tostring(amount)) for _,obj_ in ipairs(minetest.get_objects_inside_radius(pos, 0.5)) do diff --git a/boost_cart/init.lua b/boost_cart/init.lua index e1363c7..42ea48c 100644 --- a/boost_cart/init.lua +++ b/boost_cart/init.lua @@ -4,7 +4,7 @@ boost_cart.modpath = minetest.get_modpath("boost_cart") -- Maximal speed of the cart in m/s boost_cart.speed_max = 10 --- Set to nil to disable punching the cart from inside +-- Set to nil to disable punching the cart from inside (min = -1) boost_cart.punch_speed_min = 7 @@ -103,6 +103,7 @@ function boost_cart.cart:on_punch(puncher, time_from_last_punch, tool_capabiliti end if puncher:get_player_control().sneak then + -- Pick up cart: Drop all attachments if self.driver then if self.old_pos then self.object:setpos(self.old_pos) @@ -124,10 +125,9 @@ function boost_cart.cart:on_punch(puncher, time_from_last_punch, tool_capabiliti return end - local vel = self.object:getvelocity() if puncher:get_player_name() == self.driver then - if math.abs(vel.x + vel.z) > (boost_cart.punch_speed_min or -1) then + if math.abs(vel.x + vel.z) > boost_cart.punch_speed_min then return end end @@ -162,40 +162,44 @@ function boost_cart.cart:on_step(dtime) return end - local dir, last_switch = nil, nil + -- dir: New moving direction of the cart + -- last_switch: Currently pressed L/R key, used to ignore the key on the next rail node + local dir, last_switch local pos = self.object:getpos() + if self.old_pos and not self.punched then - local flo_pos = vector.floor(pos) - local flo_old = vector.floor(self.old_pos) + local flo_pos = vector.round(pos) + local flo_old = vector.round(self.old_pos) if vector.equals(flo_pos, flo_old) then + -- Do not check one node multiple times return end end - local ctrl, player = nil, nil + local ctrl, player + + -- Get player controls if self.driver then player = minetest.get_player_by_name(self.driver) if player then ctrl = player:get_player_control() end end + if self.old_pos then - local diff = vector.subtract(self.old_pos, pos) - for _,v in ipairs({"x","y","z"}) do - if math.abs(diff[v]) > 1.1 then - local expected_pos = vector.add(self.old_pos, self.old_dir) - dir, last_switch = boost_cart:get_rail_direction(pos, self.old_dir, ctrl, self.old_switch, self.railtype) - if vector.equals(dir, {x=0, y=0, z=0}) then - dir = false - pos = vector.new(expected_pos) - update.pos = true - end - break - end + -- Detection for "skipping" nodes + local expected_pos = vector.add(self.old_pos, self.old_dir) + local found_path = boost_cart:pathfinder(pos, expected_pos, self.old_dir, ctrl, self.old_switch, self.railtype) + + if not found_path then + -- No rail found: reset back to the expected position + pos = expected_pos + update.pos = true end end if vel.y == 0 then + -- Stop cart completely (do not swing) for _,v in ipairs({"x", "z"}) do if vel[v] ~= 0 and math.abs(vel[v]) < 0.9 then vel[v] = 0 @@ -213,6 +217,8 @@ function boost_cart.cart:on_step(dtime) local new_acc = {x=0, y=0, z=0} if vector.equals(dir, {x=0, y=0, z=0}) then vel = {x=0, y=0, z=0} + pos = vector.round(pos) + update.pos = true update.vel = true else -- If the direction changed @@ -248,7 +254,8 @@ function boost_cart.cart:on_step(dtime) end end end - acc = acc + (speed_mod * 8) + -- Try to make it similar to the original carts mod + acc = acc + (speed_mod * 10) else acc = acc - 0.4 -- Handbrake @@ -261,21 +268,23 @@ function boost_cart.cart:on_step(dtime) end if mesecon then - boost_cart:signal_detector_rail(vector.floor(pos)) + boost_cart:signal_detector_rail(vector.round(pos)) end - self.object:setacceleration(new_acc) - self.old_pos = vector.new(pos) - self.old_dir = vector.new(dir) - self.old_switch = last_switch - -- Limits for _,v in ipairs({"x","y","z"}) do if math.abs(vel[v]) > max_vel then vel[v] = boost_cart:get_sign(vel[v]) * max_vel + new_acc[v] = 0 update.vel = true end end + + self.object:setacceleration(new_acc) + self.old_pos = vector.new(pos) + self.old_dir = vector.new(dir) + self.old_switch = last_switch + if self.punched then -- Collect dropped items |