From a6afae440fe45b7304510a24b818808048aa6a08 Mon Sep 17 00:00:00 2001 From: Coethium Date: Mon, 8 Aug 2016 15:01:43 +0200 Subject: [PATCH] All-in-one patch (see ext description) * Removed PilzAdam's carts * Replaced by SmallJoker's Boost_cart (https://github.com/SmallJoker/boost_cart) * Modified to fully replace carts * Modified for MFF : - desactivate mesecons - power_rail: accelerate, max_speed set in init.lua - brake_rail: deccelerate, min_speed set in init.lua (so the cart doesn't stop and runs at very low speed) - default:rail / rail_cooper : no friction, keep the current speed - no collision (avoid the "walled_in" bug) --- mods/carts/README.txt | 34 +- mods/carts/depends.txt | 2 + mods/carts/detector.lua | 58 ++ mods/carts/functions.lua | 267 ++++-- mods/carts/init.lua | 891 +++++++----------- mods/carts/models/cart.png | Bin 210 -> 216 bytes mods/carts/models/cart.x | 0 mods/carts/rails.lua | 297 +++--- mods/carts/textures/cart_bottom.png | Bin mods/carts/textures/cart_side.png | Bin 144 -> 147 bytes mods/carts/textures/cart_top.png | Bin mods/carts/textures/carts_rail_brk.png | Bin 438 -> 577 bytes mods/carts/textures/carts_rail_copper.png | Bin 437 -> 0 bytes .../textures/carts_rail_copper_crossing.png | Bin 388 -> 0 bytes .../textures/carts_rail_copper_curved.png | Bin 374 -> 0 bytes .../textures/carts_rail_copper_t_junction.png | Bin 374 -> 0 bytes mods/carts/textures/carts_rail_cp.png | Bin 0 -> 522 bytes .../textures/carts_rail_crossing_brk.png | Bin 387 -> 549 bytes .../carts/textures/carts_rail_crossing_cp.png | Bin 0 -> 495 bytes .../textures/carts_rail_crossing_dtc.png | Bin 0 -> 621 bytes .../textures/carts_rail_crossing_dtc_on.png | Bin 0 -> 654 bytes .../textures/carts_rail_crossing_pwr.png | Bin 398 -> 458 bytes .../carts/textures/carts_rail_crossing_ss.png | Bin 0 -> 463 bytes .../textures/carts_rail_crossing_tour.png | Bin 416 -> 0 bytes mods/carts/textures/carts_rail_curved_brk.png | Bin 378 -> 537 bytes mods/carts/textures/carts_rail_curved_cp.png | Bin 0 -> 488 bytes mods/carts/textures/carts_rail_curved_dtc.png | Bin 0 -> 578 bytes .../textures/carts_rail_curved_dtc_on.png | Bin 0 -> 575 bytes mods/carts/textures/carts_rail_curved_pwr.png | Bin 387 -> 443 bytes mods/carts/textures/carts_rail_curved_ss.png | Bin 0 -> 450 bytes .../carts/textures/carts_rail_curved_tour.png | Bin 391 -> 0 bytes mods/carts/textures/carts_rail_dtc.png | Bin 0 -> 542 bytes mods/carts/textures/carts_rail_dtc_on.png | Bin 0 -> 559 bytes mods/carts/textures/carts_rail_pwr.png | Bin 442 -> 498 bytes mods/carts/textures/carts_rail_ss.png | Bin 0 -> 514 bytes .../textures/carts_rail_t_junction_brk.png | Bin 375 -> 538 bytes .../textures/carts_rail_t_junction_cp.png | Bin 0 -> 496 bytes .../textures/carts_rail_t_junction_dtc.png | Bin 0 -> 607 bytes .../textures/carts_rail_t_junction_dtc_on.png | Bin 0 -> 621 bytes .../textures/carts_rail_t_junction_pwr.png | Bin 385 -> 539 bytes .../textures/carts_rail_t_junction_ss.png | Bin 0 -> 439 bytes .../textures/carts_rail_t_junction_tour.png | Bin 398 -> 0 bytes mods/carts/textures/carts_rail_tour.png | Bin 453 -> 0 bytes .../textures/default_rail_t_junction.png | Bin 0 -> 476 bytes mods/carts/trash.lua.old | 104 -- 45 files changed, 746 insertions(+), 907 deletions(-) mode change 100755 => 100644 mods/carts/README.txt mode change 100755 => 100644 mods/carts/depends.txt create mode 100644 mods/carts/detector.lua mode change 100755 => 100644 mods/carts/functions.lua mode change 100755 => 100644 mods/carts/init.lua mode change 100755 => 100644 mods/carts/models/cart.png mode change 100755 => 100644 mods/carts/models/cart.x mode change 100755 => 100644 mods/carts/textures/cart_bottom.png mode change 100755 => 100644 mods/carts/textures/cart_side.png mode change 100755 => 100644 mods/carts/textures/cart_top.png mode change 100755 => 100644 mods/carts/textures/carts_rail_brk.png delete mode 100755 mods/carts/textures/carts_rail_copper.png delete mode 100755 mods/carts/textures/carts_rail_copper_crossing.png delete mode 100755 mods/carts/textures/carts_rail_copper_curved.png delete mode 100755 mods/carts/textures/carts_rail_copper_t_junction.png create mode 100644 mods/carts/textures/carts_rail_cp.png mode change 100755 => 100644 mods/carts/textures/carts_rail_crossing_brk.png create mode 100644 mods/carts/textures/carts_rail_crossing_cp.png create mode 100644 mods/carts/textures/carts_rail_crossing_dtc.png create mode 100644 mods/carts/textures/carts_rail_crossing_dtc_on.png mode change 100755 => 100644 mods/carts/textures/carts_rail_crossing_pwr.png create mode 100644 mods/carts/textures/carts_rail_crossing_ss.png delete mode 100755 mods/carts/textures/carts_rail_crossing_tour.png mode change 100755 => 100644 mods/carts/textures/carts_rail_curved_brk.png create mode 100644 mods/carts/textures/carts_rail_curved_cp.png create mode 100644 mods/carts/textures/carts_rail_curved_dtc.png create mode 100644 mods/carts/textures/carts_rail_curved_dtc_on.png mode change 100755 => 100644 mods/carts/textures/carts_rail_curved_pwr.png create mode 100644 mods/carts/textures/carts_rail_curved_ss.png delete mode 100755 mods/carts/textures/carts_rail_curved_tour.png create mode 100644 mods/carts/textures/carts_rail_dtc.png create mode 100644 mods/carts/textures/carts_rail_dtc_on.png mode change 100755 => 100644 mods/carts/textures/carts_rail_pwr.png create mode 100644 mods/carts/textures/carts_rail_ss.png mode change 100755 => 100644 mods/carts/textures/carts_rail_t_junction_brk.png create mode 100644 mods/carts/textures/carts_rail_t_junction_cp.png create mode 100644 mods/carts/textures/carts_rail_t_junction_dtc.png create mode 100644 mods/carts/textures/carts_rail_t_junction_dtc_on.png mode change 100755 => 100644 mods/carts/textures/carts_rail_t_junction_pwr.png create mode 100644 mods/carts/textures/carts_rail_t_junction_ss.png delete mode 100755 mods/carts/textures/carts_rail_t_junction_tour.png delete mode 100755 mods/carts/textures/carts_rail_tour.png create mode 100644 mods/carts/textures/default_rail_t_junction.png delete mode 100644 mods/carts/trash.lua.old diff --git a/mods/carts/README.txt b/mods/carts/README.txt old mode 100755 new mode 100644 index 61efae61..7440b151 --- a/mods/carts/README.txt +++ b/mods/carts/README.txt @@ -1,17 +1,20 @@ -Minetest 0.4 mod: carts -======================= -by PilzAdam -This version is modified by Kilarin (Donald Hines), all changes CC-0 -modifications include: - New Controls:LEFT or RIGHT to switch track at junction - DOWN for hand break - JUMP lock the users view to the view of the cart - SNEAK unlock the users view from the cart - Touring Rails: Try to maintain a speed of 4.5 - Chat notification of controls when cart is placed - Track rail count in debug.txt - punch by driver patch from spillz - get_voxel when hit ignore patch by minermoder27 +Minetest mod: carts for MFF +=========================== + +Based on boost_cart and modified to fully *replace* carts (@Coethium) + - desactivate mesecons + - power_rail: accelerate, max_speed set in init.lua + - brake_rail: deccelerate, min_speed set in init.lua (so the cart doesn't stop and runs at very low speed) + - default:rail / rail_cooper : no friction, keep the current speed + - no collision (avoid the "walled_in" bug) + + + +Boost_cart +========== + +Based on (and fully compatible with) the mod "carts" by PilzAdam +Target: Run smoothly and do not use too much CPU License of source code: ----------------------- @@ -31,6 +34,3 @@ kddekadenz: Zeg9: cart.x cart.png - -rarkenin: - cart_rail_*.png diff --git a/mods/carts/depends.txt b/mods/carts/depends.txt old mode 100755 new mode 100644 index 4ad96d51..bfb43dfb --- a/mods/carts/depends.txt +++ b/mods/carts/depends.txt @@ -1 +1,3 @@ default +mesecons? +moreores? \ No newline at end of file diff --git a/mods/carts/detector.lua b/mods/carts/detector.lua new file mode 100644 index 00000000..a2182543 --- /dev/null +++ b/mods/carts/detector.lua @@ -0,0 +1,58 @@ +local mesecons_rules = mesecon.rules.flat + +function carts:turnoff_detector_rail(pos) + local node = minetest.get_node(pos) + if minetest.get_item_group(node.name, "detector_rail") == 1 then + if node.name == "carts:detectorrail_on" then --has not been dug + minetest.swap_node(pos, {name = "carts:detectorrail", param2=node.param2}) + end + mesecon.receptor_off(pos, mesecons_rules) + end +end + +function carts:signal_detector_rail(pos) + local node = minetest.get_node(pos) + if minetest.get_item_group(node.name, "detector_rail") ~= 1 then + return + end + + if node.name == "carts:detectorrail" then + minetest.swap_node(pos, {name = "carts:detectorrail_on", param2=node.param2}) + end + mesecon.receptor_on(pos, mesecons_rules) + minetest.after(0.5, carts.turnoff_detector_rail, carts, pos) +end + +carts:register_rail("carts:detectorrail", { + description = "Detector rail", + tiles = { + "carts_rail_dtc.png", "carts_rail_curved_dtc.png", + "carts_rail_t_junction_dtc.png", "carts_rail_crossing_dtc.png" + }, + groups = carts:get_rail_groups({detector_rail = 1}), + + mesecons = {receptor = {state = "off", rules = mesecons_rules}}, +}) + +carts:register_rail("carts:detectorrail_on", { + description = "Detector rail ON (you hacker you)", + tiles = { + "carts_rail_dtc_on.png", "carts_rail_curved_dtc_on.png", + "carts_rail_t_junction_dtc_on.png", "carts_rail_crossing_dtc_on.png" + }, + groups = carts:get_rail_groups({ + detector_rail = 1, not_in_creative_inventory = 1 + }), + drop = "carts:detectorrail", + + mesecons = {receptor = {state = "on", rules = mesecons_rules}}, +}) + +minetest.register_craft({ + output = "carts:detectorrail 6", + recipe = { + {"default:steel_ingot", "mesecons:wire_00000000_off", "default:steel_ingot"}, + {"default:steel_ingot", "group:stick", "default:steel_ingot"}, + {"default:steel_ingot", "mesecons:wire_00000000_off", "default:steel_ingot"}, + }, +}) diff --git a/mods/carts/functions.lua b/mods/carts/functions.lua old mode 100755 new mode 100644 index f45ace01..6d8a972e --- a/mods/carts/functions.lua +++ b/mods/carts/functions.lua @@ -1,89 +1,226 @@ - --- --- Helper functions --- - -cart_func = {} - -function cart_func:get_sign(z) +function carts:get_sign(z) if z == 0 then return 0 else - return z/math.abs(z) + return z / math.abs(z) end end --- Returns the velocity as a unit vector --- The smaller part of the vector will be turned to 0 -function cart_func:velocity_to_dir(v) +function carts:manage_attachment(player, status, obj) + if not player then + return + end + local player_name = player:get_player_name() + if default.player_attached[player_name] == status then + return + end + default.player_attached[player_name] = status + + if status then + player:set_attach(obj, "", {x=0, y=6, z=0}, {x=0, y=0, z=0}) + player:set_eye_offset({x=0, y=-4, z=0},{x=0, y=-4, z=0}) + else + player:set_detach() + player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0}) + end +end + +function carts:velocity_to_dir(v) if math.abs(v.x) > math.abs(v.z) then - return {x=cart_func:get_sign(v.x), y=cart_func:get_sign(v.y), z=0} + return {x=carts:get_sign(v.x), y=carts:get_sign(v.y), z=0} else - return {x=0, y=cart_func:get_sign(v.y), z=cart_func:get_sign(v.z)} + return {x=0, y=carts:get_sign(v.y), z=carts:get_sign(v.z)} end end -function cart_func:is_rail(p) - local nn = minetest.get_node(p).name - --print("*!* is_rail p x=",p.x," y=",p.y," z=",p.z," nn=",nn," group rail=", minetest.get_item_group(nn, "rail")) - if nn == "ignore" then - nn=cart_func:get_content_voxel(p) - print("carts: is_rail hit ignore, trying again with get_content: now nn=",nn," group rail=", minetest.get_item_group(nn, "rail"),"p x=",p.x," y=",p.y," z=",p.z) - end - return minetest.get_item_group(nn, "rail") ~= 0 -end - -function cart_func:check_rail_in_direction(pos, dir) - local p = cart_func.v3:add(pos, dir) - if cart_func:is_rail(p) then +function carts:is_rail(pos, railtype) + local node = minetest.get_node(pos).name + if node == "ignore" then + local vm = minetest.get_voxel_manip() + local emin, emax = vm:read_from_map(pos, pos) + local area = VoxelArea:new{ + MinEdge = emin, + MaxEdge = emax, + } + local data = vm:get_data() + local vi = area:indexp(pos) + node = minetest.get_name_from_content_id(data[vi]) + end + if minetest.get_item_group(node, "rail") == 0 then + return false + end + if not railtype then return true - else - return false end -end -- cart:check_rail_in_direction - - -function cart_func:is_int(z) - z = math.abs(z) - return math.abs(math.floor(z+0.5)-z) <= 0.1 + return minetest.get_item_group(node, "connect_to_raillike") == railtype end -cart_func.v3 = {} +function carts:check_front_up_down(pos, dir_, check_up, railtype) + local dir = vector.new(dir_) + local cur = nil -function cart_func.v3:add(v1, v2) - return {x=v1.x+v2.x, y=v1.y+v2.y, z=v1.z+v2.z} + -- Front + dir.y = 0 + cur = vector.add(pos, dir) + if carts:is_rail(cur, railtype) then + return dir + end + -- Up + if check_up then + dir.y = 1 + cur = vector.add(pos, dir) + if carts:is_rail(cur, railtype) then + return dir + end + end + -- Down + dir.y = -1 + cur = vector.add(pos, dir) + if carts:is_rail(cur, railtype) then + return dir + end + return nil end -function cart_func.v3:copy(v) - return {x=v.x, y=v.y, z=v.z} +function carts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype) + local pos = vector.round(pos_) + local cur = nil + local left_check, right_check = true, true + + -- Check left and right + local left = {x=0, y=0, z=0} + local right = {x=0, y=0, z=0} + if dir.z ~= 0 and dir.x == 0 then + left.x = -dir.z + right.x = dir.z + elseif dir.x ~= 0 and dir.z == 0 then + left.z = dir.x + right.z = -dir.x + end + + 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 = carts: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 = carts:check_front_up_down(pos, right, false, railtype) + if cur then + return cur, 2 + end + right_check = true + end + end + + -- Normal + cur = carts:check_front_up_down(pos, dir, true, railtype) + if cur then + return cur + end + + -- Left, if not already checked + if left_check then + cur = carts: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 = carts:check_front_up_down(pos, right, false, railtype) + if cur then + return cur + end + end + + -- Backwards + if not old_switch then + cur = carts:check_front_up_down(pos, { + x = -dir.x, + y = dir.y, + z = -dir.z + }, true, railtype) + if cur then + return cur + end + end + + return {x=0, y=0, z=0} end -function cart_func.v3:round(v) - return { - x = math.floor(v.x+0.5), - y = math.floor(v.y+0.5), - z = math.floor(v.z+0.5), +function carts: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 = carts: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 carts: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 + if not obj_:is_player() and + obj_:get_luaentity() and + obj_:get_luaentity().name == "carts:cart" then + obj_:get_luaentity():on_punch() + end + end +end + +function carts:register_rail(name, def) + local def_default = { + drawtype = "raillike", + paramtype = "light", + sunlight_propagates = true, + is_ground_content = true, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2}, + } } + for k, v in pairs(def_default) do + def[k] = v + end + if not def.inventory_image then + def.wield_image = def.tiles[1] + def.inventory_image = def.tiles[1] + end + + minetest.register_node(name, def) end -function cart_func.v3:equal(v1, v2) - return v1.x == v2.x and v1.y == v2.y and v1.z == v2.z -end - - -function cart_func:get_content_voxel(pos) - local t1 = os.clock() - local vm = minetest.get_voxel_manip() - local pos1, pos2 = vm:read_from_map(vector.add(pos, {x=-1,y=-1,z=-1}),vector.add(pos, {x=1,y=1,z=1})) - local a = VoxelArea:new{ - MinEdge=pos1, - MaxEdge=pos2, - } - - local data = vm:get_data() - local vi = a:indexp(pos) - local railid = data[vi] - local real_name = minetest.get_name_from_content_id(railid) - print(string.format("voxel-ing rail: elapsed time: %.2fms", (os.clock() - t1) * 1000)) - return real_name +function carts:get_rail_groups(additional_groups) + -- Get the default rail groups and add more when a table is given + local groups = {dig_immediate = 2, attached_node = 1, rail = 1, connect_to_raillike = 1} + if type(additional_groups) == "table" then + for k, v in pairs(additional_groups) do + groups[k] = v + end + end + return groups end diff --git a/mods/carts/init.lua b/mods/carts/init.lua old mode 100755 new mode 100644 index b780db69..29ed6eb6 --- a/mods/carts/init.lua +++ b/mods/carts/init.lua @@ -1,594 +1,400 @@ -dofile(minetest.get_modpath("carts").."/functions.lua") -dofile(minetest.get_modpath("carts").."/rails.lua") -local cart = { - physical = true, -- Set to false to not make carts collide with other entities such as carts or the player. +carts = {} +carts.modpath = minetest.get_modpath("carts") + +-- Maximal speed of the cart in m/s +carts.speed_max = minetest.setting_get("movement_speed_walk")*3 +-- Minimal speed of the cart on brake rail +carts.brake_speed_min = minetest.setting_get("movement_speed_walk")/2 +-- Set to nil to disable punching the cart from inside (min = -1) +carts.punch_speed_min = 7 +-- 1 disable mesecons / 0 enable mesecons +carts.mesecon_disabled = 1 + + +if not carts.modpath then + error("\nWrong mod directory name! Please change it to 'carts'.\n" .. + "See also: http://dev.minetest.net/Installing_Mods") +end + +function vector.floor(v) + return { + x = math.floor(v.x), + y = math.floor(v.y), + z = math.floor(v.z) + } +end + +dofile(carts.modpath.."/functions.lua") +dofile(carts.modpath.."/rails.lua") + +if not carts.mesecon_disabled and mesecon then + dofile(carts.modpath.."/detector.lua") +end + +-- Support for non-default games +if not default.player_attached then + default.player_attached = {} +end + +carts.cart = { + physical = false, collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, visual = "mesh", mesh = "cart.x", visual_size = {x=1, y=1}, - textures = {"cart.png"}, -- Set to "invisible.png" to make the cart invisible, which is sometimes useful for videos and custom maps. + textures = {"cart.png"}, + driver = nil, - velocity = {x=0, y=0, z=0}, + punched = false, -- used to re-send velocity and position + velocity = {x=0, y=0, z=0}, -- only used on punch + old_dir = {x=1, y=0, z=0}, -- random value to start the cart on punch old_pos = nil, - old_velocity = nil, - pre_stop_dir = nil, - MAX_V = minetest.setting_get("movement_speed_walk")*3, -- Limit of the velocity (speed). default: 3 times the walk speed - TARGET_TOUR_V = 6, -- Target touring velocity, currently unused. - railcount = 0, - ignorekeypos = nil, - lockyaw = false, -- Set to true to lock camera by default. If set to false, player has to press the "jump" key to lock camera. - yawtarget = nil, - YAW_STEP = math.pi/64 -- Larger YAW_STEP makes for slower camera turning. + old_switch = 0, + railtype = nil, + attached_items = {} } -function cart:on_rightclick(clicker) +function carts.cart:on_rightclick(clicker) if not clicker or not clicker:is_player() then return end - if self.driver and clicker == self.driver then + local player_name = clicker:get_player_name() + if self.driver and player_name == self.driver then self.driver = nil - clicker:set_detach() + carts:manage_attachment(clicker, false) elseif not self.driver then - self.driver = clicker - clicker:set_attach(self.object, "", {x=0,y=5,z=0}, {x=0,y=0,z=0}) + self.driver = player_name + carts:manage_attachment(clicker, true, self.object) end end -function cart:on_activate(staticdata, dtime_s) +function carts.cart:on_activate(staticdata, dtime_s) self.object:set_armor_groups({immortal=1}) - if staticdata then - local tmp = minetest.deserialize(staticdata) - if tmp then - self.velocity = tmp.velocity - end - if tmp and tmp.pre_stop_dir then - self.pre_stop_dir = tmp.pre_stop_dir - end + if string.sub(staticdata, 1, string.len("return")) ~= "return" then + return + end + local data = minetest.deserialize(staticdata) + if not data or type(data) ~= "table" then + return + end + self.railtype = data.railtype + if data.old_dir then + self.old_dir = data.old_dir end - self.old_pos = self.object:getpos() - self.old_velocity = self.velocity end -function cart:get_staticdata() +function carts.cart:get_staticdata() return minetest.serialize({ - velocity = self.velocity, - pre_stop_dir = self.pre_stop_dir, + railtype = self.railtype, + old_dir = self.old_dir }) end --- Remove the cart if holding a tool or accelerate it -function cart:on_punch(puncher, time_from_last_punch, tool_capabilities, direction) +function carts.cart:on_punch(puncher, time_from_last_punch, tool_capabilities, direction) + local pos = self.object:getpos() + if not self.railtype then + local bar = vector.floor(vector.add(pos, 0.1)) + local node = minetest.get_node(bar).name + self.railtype = minetest.get_item_group(node, "connect_to_raillike") + end + if not puncher or not puncher:is_player() then + local cart_dir = carts:get_rail_direction(pos, self.old_dir, nil, nil, self.railtype) + if vector.equals(cart_dir, {x=0, y=0, z=0}) then + return + end + self.velocity = vector.multiply(cart_dir, 3) + self.old_pos = nil + self.punched = true return end if puncher:get_player_control().sneak then - minetest.log("action", "carts:cart removed at " .. pos_to_string(vector.round(self.object:getpos())) .. ", " .. self.railcount .. " rails travelled.") + -- Pick up cart: Drop all attachments + if self.driver then + if self.old_pos then + self.object:setpos(self.old_pos) + end + local player = minetest.get_player_by_name(self.driver) + carts:manage_attachment(player, false) + end + for _,obj_ in ipairs(self.attached_items) do + if obj_ then + obj_:set_detach() + end + end + + local leftover = puncher:get_inventory():add_item("main", "carts:cart") + if not leftover:is_empty() then + minetest.add_item(self.object:getpos(), leftover) + end self.object:remove() - local inv = puncher:get_inventory() - if minetest.setting_getbool("creative_mode") then - if not inv:contains_item("main", "carts:cart") then - inv:add_item("main", "carts:cart") - end - else - inv:add_item("main", "carts:cart") - end return end - if puncher == self.driver and (math.abs(self.velocity.x)>1 or math.abs(self.velocity.z)>1) then - return - end - - local d = cart_func:velocity_to_dir(direction) - if d.x==0 and d.z==0 then - local fd = minetest.dir_to_facedir(puncher:get_look_dir()) - if fd == 0 then - d.x = 1 - elseif fd == 1 then - d.z = -1 - elseif fd == 2 then - d.x = -1 - elseif fd == 3 then - d.z = 1 - end - end - - local s = self.velocity - if time_from_last_punch > tool_capabilities.full_punch_interval then - time_from_last_punch = tool_capabilities.full_punch_interval - end - local f = 4*(time_from_last_punch/tool_capabilities.full_punch_interval) - local v = {x=s.x+d.x*f, y=s.y, z=s.z+d.z*f} - if math.abs(v.x) < 6 and math.abs(v.z) < 6 then - self.velocity = v - else - if math.abs(self.velocity.x) < 6 and math.abs(v.x) >= 6 then - self.velocity.x = 6*cart_func:get_sign(self.velocity.x) - end - if math.abs(self.velocity.z) < 6 and math.abs(v.z) >= 6 then - self.velocity.z = 6*cart_func:get_sign(self.velocity.z) - end - end -end - --- Returns the direction as a unit vector -function cart:get_rail_direction(pos, dir) - --minetest.log("action", "get_rail_direction top pos="..pos_to_string(pos).." dir="..pos_to_string(dir)) - local fwd=cart_func.v3:copy(dir) - fwd.y=0 - local up=cart_func.v3:copy(dir) - up.y=1 - local down=cart_func.v3:copy(dir) - down.y=-1 - -- figure out left and right - local left={x=0,y=0,z=0} - local right={x=0,y=0,z=0} - if dir.z ~= 0 and dir.x == 0 then - left.x=-dir.z --left is opposite sign from z - right.x=dir.z --right is same sign as z - elseif dir.x ~= 0 and dir.z == 0 then - left.z=dir.x --left is same sign as x - right.z=-dir.x --right is opposite sign from x - end --left and right - local leftdown=cart_func.v3:copy(left) - leftdown.y=-1 - local rightdown=cart_func.v3:copy(right) - rightdown.y=-1 - --minetest.log("action", " fwd="..pos_to_string(fwd)) - --minetest.log("action", " down="..pos_to_string(down)) - --minetest.log("action", " up="..pos_to_string(up)) - --minetest.log("action", " left="..pos_to_string(left)) - --minetest.log("action", " leftdown="..pos_to_string(leftdown)) - --minetest.log("action", " right="..pos_to_string(right)) - --minetest.log("action", " rightdown="..pos_to_string(rightdown)) - - local ignorekeys=false - --ignorekeypos stores a position where we changed direction because the - --player was pressing left or right keys. once we have changed direction, - --we want to ignore those keys until you have changed to a different rail - --(otherwise you end up reversing) - --I use the ignorekeys boolean to make the key logic more readable - if self.ignorekeypos then --ignorekeypos was set - if cart_func.v3:equal(self.ignorekeypos,pos) then - ignorekeys=true --if still at same position, ignore left and right keys - else - self.ignorekeypos=nil --if ignorekeypos was set but pos does not match anymore, clear it - end - end - - local ctrl=nil - if self.driver and not ignorekeys then - ctrl = self.driver:get_player_control() - end - - if ctrl and ctrl.left then --left key pressed, check left first - if cart_func:check_rail_in_direction(pos,left) then - self.ignorekeypos=cart_func.v3:copy(pos) --ignore keys until pos changes - return left - elseif cart_func:check_rail_in_direction(pos,leftdown) then - self.ignorekeypos=cart_func.v3:copy(pos) - return leftdown - end - elseif ctrl and ctrl.right then --right key pressed, check right first - if cart_func:check_rail_in_direction(pos,right) then - self.ignorekeypos=cart_func.v3:copy(pos) - return right - elseif cart_func:check_rail_in_direction(pos,rightdown) then - self.ignorekeypos=cart_func.v3:copy(pos) - return rightdown - end - end --ctrl.left ctrl.right - - --now for normal checks - if cart_func:check_rail_in_direction(pos,fwd) then - return fwd - elseif cart_func:check_rail_in_direction(pos,down) then - return down - elseif cart_func:check_rail_in_direction(pos,up) then - return up - elseif (not ctrl or not ctrl.left) --only check left if we didnt above - and cart_func:check_rail_in_direction(pos,left) then - return left - elseif (not ctrl or not ctrl.left) - and cart_func:check_rail_in_direction(pos,leftdown) then - return leftdown - elseif (not ctrl or not ctrl.right) --only check right if we didnt above - and cart_func:check_rail_in_direction(pos,right) then - return right - elseif (not ctrl or not ctrl.right) - and cart_func:check_rail_in_direction(pos,rightdown) then - return rightdown - else - return {x=0, y=0, z=0} - end --normal rail checks -end --get_rail_direction - -function cart:calc_rail_direction(pos, vel) - local velocity = cart_func.v3:copy(vel) - local p = cart_func.v3:copy(pos) - if cart_func:is_int(p.x) and cart_func:is_int(p.z) then - - local dir = cart_func:velocity_to_dir(velocity) - local dir_old = cart_func.v3:copy(dir) - - dir = self:get_rail_direction(cart_func.v3:round(p), dir) - - local v = math.max(math.abs(velocity.x), math.abs(velocity.z)) - velocity = { - x = v * dir.x, - y = v * dir.y, - z = v * dir.z, - } - - if cart_func.v3:equal(velocity, {x=0, y=0, z=0}) and not cart_func:is_rail(p) then - - -- First try this HACK - -- Move the cart on the rail if above or under it - if cart_func:is_rail(cart_func.v3:add(p, {x=0, y=1, z=0})) and vel.y >= 0 then - p = cart_func.v3:add(p, {x=0, y=1, z=0}) - return self:calc_rail_direction(p, vel) - end - if cart_func:is_rail(cart_func.v3:add(p, {x=0, y=-1, z=0})) and vel.y <= 0 then - p = cart_func.v3:add(p, {x=0, y=-1, z=0}) - return self:calc_rail_direction(p, vel) - end - -- Now the HACK gets really dirty - if cart_func:is_rail(cart_func.v3:add(p, {x=0, y=2, z=0})) and vel.y >= 0 then - p = cart_func.v3:add(p, {x=0, y=1, z=0}) - return self:calc_rail_direction(p, vel) - end - if cart_func:is_rail(cart_func.v3:add(p, {x=0, y=-2, z=0})) and vel.y <= 0 then - p = cart_func.v3:add(p, {x=0, y=-1, z=0}) - return self:calc_rail_direction(p, vel) - end - -- NOW the hack gets even dirtier - if cart_func:is_rail(cart_func.v3:add(p, {x=0, y=3, z=0})) and vel.y >= 0 then - p = cart_func.v3:add(p, {x=0, y=1, z=0}) - return self:calc_rail_direction(p, vel) - end - if cart_func:is_rail(cart_func.v3:add(p, {x=0, y=-3, z=0})) and vel.y <= 0 then - p = cart_func.v3:add(p, {x=0, y=-1, z=0}) - return self:calc_rail_direction(p, vel) - end - if cart_func:is_rail(cart_func.v3:add(p, {x=0, y=4, z=0})) and vel.y >= 0 then - p = cart_func.v3:add(p, {x=0, y=1, z=0}) - return self:calc_rail_direction(p, vel) - end - if cart_func:is_rail(cart_func.v3:add(p, {x=0, y=-4, z=0})) and vel.y <= 0 then - p = cart_func.v3:add(p, {x=0, y=-1, z=0}) - return self:calc_rail_direction(p, vel) - end - - return {x=0, y=0, z=0}, p - end - - if not cart_func.v3:equal(dir, dir_old) then - return velocity, cart_func.v3:round(p) - end - - end - return velocity, p -end - --- built in pos_to_string doesn't handle nil. -function pos_to_string(pos) - if pos==nil then return "(nil)" - else return minetest.pos_to_string(pos) - end --poss==nil -end --pos_to_string - -function cart:on_step(dtime) - - local pos = self.object:getpos() - local dir = cart_func:velocity_to_dir(self.velocity) - - -- *!* Debug. - if self.old_pos then - local cmp_old=vector.round(self.old_pos) - local cmp_new=vector.round(pos) - if cmp_old.x~=cmp_new.x or cmp_old.y~=cmp_new.y or cmp_old.z~=cmp_new.z then - self.railcount=self.railcount+1 - -- local a = tonumber(minetest.get_meta(pos):get_string("cart_acceleration")) - -- local railtype="" - -- if a and a>0 then railtype="power" end - -- minetest.chat_send_all("-- cart pos="..pos_to_string(vector.round(pos)).." railcount="..self.railcount.." vel="..pos_to_string(self.velocity).." "..railtype) --*!*debug - end - end - -- *!* Debug. - - local ctrl=nil - if self.driver then - ctrl = self.driver:get_player_control() - if ctrl and ctrl.jump and not self.lockyaw then - self.lockyaw=true - self.yawtarget=self.object:getyaw() --- minetest.chat_send_player(self.driver:get_player_name(),"Player view locked to cart, sneak to unlock.") - elseif ctrl and ctrl.sneak and self.lockyaw then - self.lockyaw=false --- minetest.chat_send_player(self.driver:get_player_name(),"Player view unlocked from cart, jump to lock.") - end - end -- Check lockyaw if self.driver. - - if not cart_func.v3:equal(self.velocity, {x=0,y=0,z=0}) then - self.pre_stop_dir = cart_func:velocity_to_dir(self.velocity) - end - - -- Stop the cart if the velocity is nearly 0, only if on a flat railway. - if dir.y == 0 then - if math.abs(self.velocity.x) < 0.1 and math.abs(self.velocity.z) < 0.1 then - -- Start the cart if powered from mesecons. - local a = 0--tonumber(minetest.get_meta(pos):get_string("cart_acceleration")) - if a and a ~= 0 then - if self.pre_stop_dir and cart_func.v3:equal(self:get_rail_direction(self.object:getpos(), self.pre_stop_dir), self.pre_stop_dir) then - self.velocity = { - x = self.pre_stop_dir.x * 0.2, - y = self.pre_stop_dir.y * 0.2, - z = self.pre_stop_dir.z * 0.2, - } - self.old_velocity = self.velocity - return - end - for _,y in ipairs({0,-1,1}) do - for _,z in ipairs({1,-1}) do - if cart_func.v3:equal(self:get_rail_direction(self.object:getpos(), {x=0, y=y, z=z}), {x=0, y=y, z=z}) then - self.velocity = { - x = 0, - y = 0.2*y, - z = 0.2*z, - } - self.old_velocity = self.velocity - return - end - end - for _,x in ipairs({1,-1}) do - if cart_func.v3:equal(self:get_rail_direction(self.object:getpos(), {x=x, y=y, z=0}), {x=x, y=y, z=0}) then - self.velocity = { - x = 0.2*x, - y = 0.2*y, - z = 0, - } - self.old_velocity = self.velocity - return - end - end - end - end - - self.velocity = {x=0, y=0, z=0} - self.object:setvelocity(self.velocity) - self.old_velocity = self.velocity - self.old_pos = self.object:getpos() + local vel = self.object:getvelocity() + if puncher:get_player_name() == self.driver then + if math.abs(vel.x + vel.z) > carts.punch_speed_min then return end end - -- - -- Set the new moving direction - -- - - -- Recalcualte the rails that are passed since the last server step - local old_dir = cart_func:velocity_to_dir(self.old_velocity) - if old_dir.x ~= 0 then - local sign = cart_func:get_sign(pos.x-self.old_pos.x) - while true do - if sign ~= cart_func:get_sign(pos.x-self.old_pos.x) or pos.x == self.old_pos.x then - break - end - self.old_pos.x = self.old_pos.x + cart_func:get_sign(pos.x-self.old_pos.x)*0.1 - self.old_pos.y = self.old_pos.y + cart_func:get_sign(pos.x-self.old_pos.x)*0.1*old_dir.y - self.old_velocity, self.old_pos = self:calc_rail_direction(self.old_pos, self.old_velocity) - old_dir = cart_func:velocity_to_dir(self.old_velocity) - if not cart_func.v3:equal(cart_func:velocity_to_dir(self.old_velocity), dir) then - self.velocity = self.old_velocity - pos = self.old_pos - self.object:setpos(self.old_pos) - break - end - end - elseif old_dir.z ~= 0 then - local sign = cart_func:get_sign(pos.z-self.old_pos.z) - while true do - if sign ~= cart_func:get_sign(pos.z-self.old_pos.z) or pos.z == self.old_pos.z then - break - end - self.old_pos.z = self.old_pos.z + cart_func:get_sign(pos.z-self.old_pos.z)*0.1 - self.old_pos.y = self.old_pos.y + cart_func:get_sign(pos.z-self.old_pos.z)*0.1*old_dir.y - self.old_velocity, self.old_pos = self:calc_rail_direction(self.old_pos, self.old_velocity) - old_dir = cart_func:velocity_to_dir(self.old_velocity) - if not cart_func.v3:equal(cart_func:velocity_to_dir(self.old_velocity), dir) then - self.velocity = self.old_velocity - pos = self.old_pos - self.object:setpos(self.old_pos) - break - end - end + local punch_dir = carts:velocity_to_dir(puncher:get_look_dir()) + punch_dir.y = 0 + local cart_dir = carts:get_rail_direction(pos, punch_dir, nil, nil, self.railtype) + if vector.equals(cart_dir, {x=0, y=0, z=0}) then + return end - -- Calculate the new step - self.velocity, pos = self:calc_rail_direction(pos, self.velocity) - self.object:setpos(pos) - dir = cart_func:velocity_to_dir(self.velocity) - - -- Accelerate or decelerate the cart according to the pitch and acceleration of the rail node - --[[local a = tonumber(minetest.get_meta(pos):get_string("cart_acceleration")) - if not a then - a = 0 - end--]] - - -- get rail type and set acceleration - local rail = minetest.get_node(pos) - local a = 0 - if rail.name == "carts:rail_power" then a = 1 - elseif rail.name == "carts:rail_brake" then a = -1 - else a = 0 - end - --a = a*minetest.setting_get("movement_acceleration_default") -- pour plus tard - a = a*0.5 - --minetest.chat_send_all(a) - - - -- Check if down arrow is being pressed (handbrake). - if self.driver then - local ctrl = self.driver:get_player_control() - if ctrl and ctrl.down then - a=a-0.1 -- Same as uphill. - - end -- If handbrake. - end -- If self.driver. - - if self.velocity.y < 0 then - self.velocity = { - x = self.velocity.x + (a+0.13)*cart_func:get_sign(self.velocity.x), - y = self.velocity.y + (a+0.13)*cart_func:get_sign(self.velocity.y), - z = self.velocity.z + (a+0.13)*cart_func:get_sign(self.velocity.z), - } - elseif self.velocity.y > 0 then - self.velocity = { - x = self.velocity.x + (a-0.1)*cart_func:get_sign(self.velocity.x), - y = self.velocity.y + (a-0.1)*cart_func:get_sign(self.velocity.y), - z = self.velocity.z + (a-0.1)*cart_func:get_sign(self.velocity.z), - } - else - self.velocity = { - x = self.velocity.x + (a-0.0)*cart_func:get_sign(self.velocity.x), --0.03 (frottements) - y = self.velocity.y + (a-0.0)*cart_func:get_sign(self.velocity.y), - z = self.velocity.z + (a-0.0)*cart_func:get_sign(self.velocity.z), - } - - -- Place the cart exactly on top of the rail - if cart_func:is_rail(cart_func.v3:round(pos)) then - self.object:setpos({x=pos.x, y=math.floor(pos.y+0.5), z=pos.z}) - pos = self.object:getpos() - end - end - - -- Dont switch moving direction - -- Only if on flat railway - if dir.y == 0 then - if cart_func:get_sign(dir.x) ~= cart_func:get_sign(self.velocity.x) then - self.velocity.x = 0 - end - if cart_func:get_sign(dir.y) ~= cart_func:get_sign(self.velocity.y) then - self.velocity.y = 0 - end - if cart_func:get_sign(dir.z) ~= cart_func:get_sign(self.velocity.z) then - self.velocity.z = 0 - end - end - - -- Allow only one moving direction (multiply the other one with 0) - dir = cart_func:velocity_to_dir(self.velocity) - self.velocity = { - x = math.abs(self.velocity.x) * dir.x, - y = self.velocity.y, - z = math.abs(self.velocity.z) * dir.z, - } - - - -- Move cart exactly on the rail - if dir.x ~= 0 and not cart_func:is_int(pos.z) then - pos.z = math.floor(0.5+pos.z) - self.object:setpos(pos) - elseif dir.z ~= 0 and not cart_func:is_int(pos.x) then - pos.x = math.floor(0.5+pos.x) - self.object:setpos(pos) - end - - -- Limit the velocity. - if math.abs(self.velocity.x) > self.MAX_V then - self.velocity.x = self.MAX_V*cart_func:get_sign(self.velocity.x) - end - if math.abs(self.velocity.y) > self.MAX_V then - self.velocity.y = self.MAX_V*cart_func:get_sign(self.velocity.y) - end - if math.abs(self.velocity.z) > self.MAX_V then - self.velocity.z = self.MAX_V*cart_func:get_sign(self.velocity.z) - end - - self.object:setvelocity(self.velocity) - --minetest.chat_send_all(self.velocity.x.." "..self.velocity.y.." "..self.velocity.z) - - self.old_pos = self.object:getpos() - self.old_velocity = cart_func.v3:copy(self.velocity) - - local oldyaw=self.object:getyaw() - if dir.x < 0 then - self.object:setyaw(math.pi/2) - elseif dir.x > 0 then - self.object:setyaw(3*math.pi/2) - elseif dir.z < 0 then - self.object:setyaw(math.pi) - elseif dir.z > 0 then - self.object:setyaw(0) - end - - local newyaw=self.object:getyaw() - -- Now if driver and lockyaw, change drivers direction. - if self.driver and self.lockyaw then - if oldyaw~=newyaw then - self.yawtarget=newyaw -- Set new target. - -- minetest.log("action", "--Cart yawtarget set "..self.yawtarget) - end - if self.driver:get_look_yaw() == nil then - return - end - local playeryaw=self.driver:get_look_yaw()-1.57 - if playeryaw<0 then playeryaw=playeryaw+(math.pi*2) end - if self.yawtarget and playeryaw ~= self.yawtarget then - local diff = self.yawtarget - playeryaw - if diff>math.pi then - diff=diff-(2*math.pi) - elseif diff<(-math.pi) then - diff=diff+(2*math.pi) - end - local yawdir=cart_func:get_sign(diff) - local step=self.YAW_STEP - if math.abs(diff)<=self.YAW_STEP then - step=diff - self.yawtarget=nil - end - local setyaw=playeryaw+(step*yawdir) - self.driver:set_look_yaw(setyaw) - end -- Move yaw. - end -- lockyaw set. - - if dir.y == -1 then - self.object:set_animation({x=1, y=1}, 1, 0) - elseif dir.y == 1 then - self.object:set_animation({x=2, y=2}, 1, 0) - else - self.object:set_animation({x=0, y=0}, 1, 0) + local punch_interval = 1 + if tool_capabilities and tool_capabilities.full_punch_interval then + punch_interval = tool_capabilities.full_punch_interval end + time_from_last_punch = math.min(time_from_last_punch or punch_interval, punch_interval) + local f = 3 * (time_from_last_punch / punch_interval) + self.velocity = vector.multiply(cart_dir, f) + self.old_dir = cart_dir + self.old_pos = nil + self.punched = true end -minetest.register_entity("carts:cart", cart) +function carts.cart:on_step(dtime) + local vel = self.object:getvelocity() + local update = {} + if self.punched then + vel = vector.add(vel, self.velocity) + self.object:setvelocity(vel) + self.old_dir.y = 0 + elseif vector.equals(vel, {x=0, y=0, z=0}) then + return + end -minetest.register_craftitem("carts:cart", { - description = "Cart", + -- 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() + local is_slow = ((vel.x ~= 0 and math.abs(vel.x) <= carts.brake_speed_min) or + (vel.y ~= 0 and math.abs(vel.y) <= carts.brake_speed_min) or + (vel.z ~= 0 and math.abs(vel.z) <= carts.brake_speed_min)) and + string.match(minetest.get_node(pos).name, "brake") + + if self.old_pos and not self.punched then + local flo_pos = vector.round(pos) + local flo_old = vector.round(self.old_pos) + if vector.equals(flo_pos, flo_old) and not is_slow then -- Do not check one node multiple times (but check if low speed) + return + end + end + + + 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 + -- Detection for "skipping" nodes + local expected_pos = vector.add(self.old_pos, self.old_dir) + local found_path = carts:pathfinder( + pos, expected_pos, self.old_dir, ctrl, self.old_switch, self.railtype + ) + + if not found_path and not is_slow then + -- No rail found: reset back to the expected position + pos = expected_pos + update.pos = true + end + end + + local cart_dir = carts:velocity_to_dir(vel) + local max_vel = carts.speed_max + if not dir then + dir, last_switch = carts:get_rail_direction( + pos, cart_dir, ctrl, self.old_switch, self.railtype + ) + end + + local new_acc = {x=0, y=0, z=0} + local speed_mod = 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 + if dir.x ~= 0 and self.old_dir.z ~= 0 then + vel.x = dir.x * math.abs(vel.z) + vel.z = 0 + pos.z = math.floor(pos.z + 0.5) + update.pos = true + end + if dir.z ~= 0 and self.old_dir.x ~= 0 then + vel.z = dir.z * math.abs(vel.x) + vel.x = 0 + pos.x = math.floor(pos.x + 0.5) + update.pos = true + end + -- Up, down? + if dir.y ~= self.old_dir.y then + vel.y = dir.y * math.abs(vel.x + vel.z) + pos = vector.round(pos) + update.pos = true + end + + -- Slow down or speed up in slopes.. + local acc = dir.y * -1.8 + + -- MFF : Some rails have bad acceleration property, reinit them ! + -- this code would be commented when all rails will be corrected + local rail = minetest.get_node(pos) + if string.match(rail.name, "power") + then minetest.get_meta(pos):set_string("cart_acceleration", "1") + elseif string.match(rail.name, "brake") then minetest.get_meta(pos):set_string("cart_acceleration", "-1") + else minetest.get_meta(pos):set_string("cart_acceleration", "0") + end + + -- Change acceleration by rail (power/brake) + local speed_mod_string = minetest.get_meta(pos):get_string("cart_acceleration") + if speed_mod_string and speed_mod_string ~= "" + then speed_mod = tonumber(speed_mod_string) + else speed_mod = 0 + end + + if speed_mod > 0 then speed_mod = 2 + elseif speed_mod < 0 then speed_mod = -2 + else speed_mod = 0 + end + + + --[[if speed_mod_string == "halt" then --stop rail, not used in MFF + vel = {x=0, y=0, z=0} + acc = 0 + pos = vector.round(pos) + update.pos = true + update.vel = true + else--]]if speed_mod and speed_mod ~= 0 then + acc = acc + (speed_mod * 10) + else + --acc = acc - 0.4 --No friction (to be set as an option) + -- Handbrake + if ctrl and ctrl.down then + acc = acc - 1.2 + end + end + + if self.old_dir.y == 0 and not self.punched then + -- Stop the cart swing between two rail parts (handbrake) + if vector.equals(vector.multiply(self.old_dir, -1), dir) then + vel = {x=0, y=0, z=0} + acc = 0 + if self.old_pos then + pos = vector.new(self.old_pos) + update.pos = true + end + dir = vector.new(self.old_dir) + update.vel = true + end + end + + new_acc = vector.multiply(dir, acc) + end + + if not carts.mesecon_disabled and mesecon then + carts:signal_detector_rail(vector.round(pos)) + end + + + -- Limits + for _,v in ipairs({"x","y","z"}) do + if speed_mod > 0 and math.abs(vel[v]) > max_vel then + vel[v] = carts:get_sign(vel[v]) * max_vel + new_acc[v] = 0 + update.vel = true + elseif speed_mod < 0 and vel[v] ~= 0 and math.abs(vel[v]) <= carts.brake_speed_min then + vel[v] = carts:get_sign(vel[v]) * carts.brake_speed_min + new_acc[v] = 0 + update.vel = true + end + end + + self.object:setacceleration(new_acc) + self.old_pos = vector.new(pos) + if not vector.equals(dir, {x=0, y=0, z=0}) then + self.old_dir = vector.new(dir) + end + self.old_switch = last_switch + + + if self.punched then + -- Collect dropped items + for _,obj_ in ipairs(minetest.get_objects_inside_radius(pos, 1)) do + if not obj_:is_player() and + obj_:get_luaentity() and + not obj_:get_luaentity().physical_state and + obj_:get_luaentity().name == "__builtin:item" then + + obj_:set_attach(self.object, "", {x=0, y=0, z=0}, {x=0, y=0, z=0}) + self.attached_items[#self.attached_items + 1] = obj_ + end + end + self.punched = false + update.vel = true -- update player animation + end + + if not (update.vel or update.pos) then + return + end + + local yaw = 0 + if self.old_dir.x < 0 then + yaw = 0.5 + elseif self.old_dir.x > 0 then + yaw = 1.5 + elseif self.old_dir.z < 0 then + yaw = 1 + end + self.object:setyaw(yaw * math.pi) + + local anim = {x=0, y=0} + if dir.y == -1 then + anim = {x=1, y=1} + elseif dir.y == 1 then + anim = {x=2, y=2} + end + self.object:set_animation(anim, 1, 0) + + self.object:setvelocity(vel) + if update.pos then + self.object:setpos(pos) + end + update = nil +end + +minetest.register_entity(":carts:cart", carts.cart) +minetest.register_craftitem(":carts:cart", { + description = "Cart (Sneak+Click to pick up)", inventory_image = minetest.inventorycube("cart_top.png", "cart_side.png", "cart_side.png"), wield_image = "cart_side.png", on_place = function(itemstack, placer, pointed_thing) if not pointed_thing.type == "node" then return end - if cart_func:is_rail(pointed_thing.under) then - local obj=minetest.add_entity(pointed_thing.under, "carts:cart") - minetest.log("action", "carts:cart placed at " .. pos_to_string(vector.round(obj:getpos())) .. ".") --- minetest.chat_send_player(placer:get_player_name(),"Right click to ride, left click to push, sneak + left click to put back in inventory, jump to lock view to cart, sneak to unlock view from cart, move left and right to switch tracks, move backwards to apply handbrake.") - if not minetest.setting_getbool("creative_mode") then - itemstack:take_item() - end - return itemstack - elseif cart_func:is_rail(pointed_thing.above) then + if carts:is_rail(pointed_thing.under) then + minetest.add_entity(pointed_thing.under, "carts:cart") + elseif carts:is_rail(pointed_thing.above) then minetest.add_entity(pointed_thing.above, "carts:cart") - if not minetest.setting_getbool("creative_mode") then - itemstack:take_item() - end - return itemstack - end + else return end + + itemstack:take_item() + return itemstack end, }) @@ -599,10 +405,3 @@ minetest.register_craft({ {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, }, }) - - -if minetest.setting_getbool("log_mods") then - minetest.log("action", "Carbone: [carts] loaded.") -end - - diff --git a/mods/carts/models/cart.png b/mods/carts/models/cart.png old mode 100755 new mode 100644 index 3af5bb588575725702cdf1255998461699a219e8..d4b12d63ca534fbd5889e2def721946927aa4e4b GIT binary patch delta 156 zcmV;N0Av5s0oVbM7zqRe0001iRA zgOd^%r~tVjFrC5KfB^`YO*$b0GZ=ye!N9aFEffgSGLQtofE0l+h(Icp1;7qVg*)9f z6bwS(o`Va(ybq({0;`~a0j3nU0L(fh0f>VJUI5Kug#Ci9FoAuxYzNkl%xzx{Oo7u=F) zse>R2f}SG>@5z*81Epi$RHY-yY)Gy~3z+G^EX4+ez|#q%q?E90<0$A}3Sa|#Gq8(7 zShc_qf2iE9EQ+YJdPfi|UyJR2IjczT)=6dDo?8fG|fF)U0JDqp*)>NU_j22WQ%mvv4F FO#s2Q9<=}f delta 98 zcmV-o0G0Dy!50Qvv`0D$NK0Cg|`0P0`>06Lfe02gqax=}m;000SaNLh0L z01FZT01FZU(%pXi00007bV*G`2i*Y)6g4_s4%5Q`000_vMSoayQ*UN;cVTj608n9R zZgehAMN}YmGcGkQF)>H;LN@>a0dYx0K~y+T&6CSZ0#Ovk{WBuR(cD&K<14LAtHK^u zrY>}s5h^;qpFNa9i8e(jWrb8mMT>&MAn0%VI(KNUxM*byFI?`NnZw8YzVls;=68L4 zcj5JWKqcFMEq|ql_4YM<*5{O$?BiK<3fCDkIt454@>V?U*_HYtDWSGC&IQ_8OHU-S zByfSEPmj>zD6$?s@?Jes>mp>gh$Nkrppgs2R(1V>(Tk#<)PnBO>e)kbmCLBSStE$cN;bi0HC_IB}~} zs056|7+&SNID(h|D$Su|x6WkJGeWQrr)P&Rm&5^fzAkm;H6M~FGL zBA`mFxlPIg`H-NkdJuMLhslE$&0Y=CYt?~H(FVqNvNMU7{TV!#?aCc#kS{6%tGNe^ zQ59gUB`m)|nSGhgqR*hrpWTPhf|d&e=STj>gCA>VTNDSU^D$`3k(@Q4HTPDj#Cfi3Q z*HOI z42Tq}!WF8+73!lE8={pOVw4)AmD-ZE>pN3*y3=(hWa&@L)}NefFcpaM45sA+k>QL& zqnSlUvw*1BXm+vjoD!osCB}10jOUjEk;%d`lSSpGiz`i+RG2QQG+SC_w!GSWMXmYD z8uQh47V8@=H#A#rZn4_ZX0@%|dV9OguD#oyr|q`|dXBLq$S;_|;n|He28McuPEQxd z5Q*^I(^mx#1u(E2u)d?q!tsu!ynO#Z?L`g8-=EWAn8?5|fvI8ri*1Mb_n($0DQPwj_2OQ_{&0l{s_xi$n46l;(5}td%Ea=Jlqs=zw=*MOD|9hs{X7MU$ z9(xKl)jd;=>)7)@5(&&c_{tF!1D>va JF6*2UngDKYqDue( diff --git a/mods/carts/textures/carts_rail_copper.png b/mods/carts/textures/carts_rail_copper.png deleted file mode 100755 index 73963f629f9bf6ff7a8ef6ac3febbb3240d9f6c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 437 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf?Es$;S0EkZD3RhWo#G*t=_Q@% zC6nbXljS3m?IV-xE0gOdo98E+?+-+B1^%)H0dj?228BQ}P_8IIt|(BhI7q%ESgs^k zzBE|AEJVIMRK6lqzA_Am6sp1%s>2oPqZJ#Xl^SA{8l#oklC?Wib-L4aCuHeQ%+{Zr zYcLgv@(iZs1Cim3LZg{QMzesZ*l2dK@thK)IVHw(ON{520+GqWGLuE+ri&|0msFT8 zsWe+!WwyN9d_}GK${O?4br$OzEjKh#K(q^@--Fkbw&BZlSRzEKa0eX+IB*-tA z!Qt7BG$5zL)5S4FBD}Z9Rp<}{!x6Fa2#uq$-O=5<-~Eq2(i*M*WX4REh7NfVh8maC zc5n2)ZE?)1)kk6r(U>8 zPUqg^(D_9SDo1xnc5Uf)>-zNn>x}O2i!bk?3Bvlb2T^%Z29VSx~CS4OQ zQwKy5GTmvq-5I()>ADlL^(SWQPsufymS;G7ojg#TBMYDuKvsX_eWsD$`|EX3J~LR@RxXsxx0xZ*g(Wl*wmnM1XE( zED7=pW^j0RBMr#u@^odjdB10 diff --git a/mods/carts/textures/carts_rail_copper_curved.png b/mods/carts/textures/carts_rail_copper_curved.png deleted file mode 100755 index 6cfc8c2dc2c1e5f698f08e32fdd1f2de3c9e6722..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 374 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf(g2?jS0J6?C6nzVlj93Svbnx8 zd496_{;~xDKqOb_Wl$I>TNEHy6ew35BwrFNUm7e|79w8}3PcLkkt(&3ighunbuntq zvC7Ty>MaTCEs5IgNgACgn!V|oy_tFwvh^os>rcu7B7>><1~UqcW)&IDE;gQ1Vm!CR zcz&tL{4(Q(<)(|uO%_#{E&-xSv*k7BD{9PF*O{-Wvslw$adFL*uBz>(K!-Ax1o;Is zI6S+N2ISOxx;TbNNU|PeS7K&lU^x(YxX7hb&&8$p+`s>sAO#1mN;4!}*~XADnZ;o? zPjSQJezi4qOg+*w?l75%?=SeqV6ttwan4<4-rvv9zd7f?+^){uChey$y}`V8`@RPY zen#&*R8Tv8fuvgYef@ZurLN7rQ_s#nUXtF)Cc*o1a=oq=j~=`1heDuD44$rjF6*2U FngIDrfuR5Z diff --git a/mods/carts/textures/carts_rail_copper_t_junction.png b/mods/carts/textures/carts_rail_copper_t_junction.png deleted file mode 100755 index 57759193a2798bebe1899827ad4e43f53668b652..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 374 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf`~aU2S0J74DV^aZlj$v!<0F&f zE0gOhljkR!4@Ca51p#t}UIv9gGElZCP_8&gz9d+_G+3@IM7|;vh!iTr6sjXtY9kfv zVpQv5)as*^n&Z`564ZOsHT$#lCT8nT$}yOnYcM6(U|PQ6^nAk^1%@*Ujb;}c&nYpU zTVgz~#CU$G$^0_oh2^G8DomHxn6IcYUtMRurp{tbgT=))Q~qt}*$i|dV@Z%-FoVOh z8)-mJtEY=&h(vhkxlo})3?j}KyS*3e2)+}$>HpS`7pEQiZS#2&XM*5-o`UV$mOstf zI4}Q+igP)H;LN@>a0dq-2K~y+T&6C?p0znkU{WBuh zUGuezw%)CmASmo&W!ZziWrT{Z=5@7;QYg_&5lUGRl~K_{K~aC+*O{dq>7^HYa9}t) zGiN^b_nk8a!_O#3gP8V=frjC)$#Ph(eou>EjY(~j9iAqvxXRhlDLHXhbmD2(t*y^9 zGU^+{S`N#-$ve6t@i~DDs38f_*+Jxk5{hdQwwFaH0TCIB)rf@)Bo|G;|Dq=ZhS8J2 zz3Su$7uzzLDI4Anym&wK;WBH-^Nt(01qY5cM>xVq-Pc9f4-avHTu?;JFCe=jAxA!x z$cN05h{U{r6mjb&R>PKl^5CKD;s`BeoN8>xS<;4fR>o&z0xiWxy&&TxZsiEq)Em5+ z(g70}Q0SZS$B8+)AfQI9g;nYY@*z!A_aNps_LB!~s=eMwuQe|^stb(qcxx0ddmcPi z+}ayyk}o;}TXPQ>qb|T$%j;&X_7#e1$gI_$y@%+Gkqbno2L8u`Z*CvpMD?+1uK)l5 M07*qoM6N<$f~+3c3;+NC literal 0 HcmV?d00001 diff --git a/mods/carts/textures/carts_rail_crossing_brk.png b/mods/carts/textures/carts_rail_crossing_brk.png old mode 100755 new mode 100644 index 6fc3ef8673172ea048c12fca160f6a0331a54fba..f9ce303a36fc09ad1dadb55c916c9b91f1aa7205 GIT binary patch delta 535 zcmV+y0_gpN1EmCz8Gi-<001BJ|6u?C00DDSM?wIu&K&6g000DMK}|sb0I`n?{9y$E z001CkNK#Dz0D2|>0Dy!50Qvv`0D$NK0Cg|`0P0`>06Lfe02gqax=}m;000SaNLh0L z01FZT01FZU(%pXi00007bV*G`2i*Y)6g3t0-|m_K000_vMSoayQ*UN;cVTj608n9R zZgehAMN}YmGcGkQF)>H;LN@>a0aZyvK~y+TV_<-SU3<6v4-F6g59ER{E&x^oQj4Jg z*?{sOssGEWOyP=hy(NHrGqB+p27oleFia9z44sXxh5;l%2?luu>@;LAWO$1GpHplM z3y=RbVbcE>SAT%LgzN=GcrC9ngBvg{&+z|Jpnq4@ng5?xYW#nGsmcG9K=$+kh&ap( ziz-YI0a+I=12>=~Ki_00jAcNu}xk z?hM`kQ*sUdPsr8>V^|o>ECL${0d*0GFsKfd{tv>SP%jIT{9hd=0}g|UK+PqAQg8#x zkiq~X8bOjXp-u+*yU<_q|H5({(MU-m0_PoylQOngCMeHd-DdtR_9@V%j3q&S!3+-1ZlnP@ zot`d^Arj%K=eLR-VqkE-D1Jxt-McuG|Nql@-d+0}I0>#tm0?I6o5<-S*UC zQ%-MPQ;O!+$yVYgg>2SF{;-pY{~Tb)Y`Z#Um-ywgxqj=8dX+P@mNuPzw{Uw$_iWL; zzUvQ5Y^H@f+|Syo_qD7zXd<(cS%lZm;3NNdf6wNdwn|x}Rw(DuKXLXVq16`qSwZ2- N;OXk;vd$@?2>@$1jv4>} diff --git a/mods/carts/textures/carts_rail_crossing_cp.png b/mods/carts/textures/carts_rail_crossing_cp.png new file mode 100644 index 0000000000000000000000000000000000000000..b04aa638245ea9d5d691114c13a679cbf3a00218 GIT binary patch literal 495 zcmVH;LN@>a0a!^yK~y+TrBiKA!axx1DYPG4 z0Y88O2k?&}T0{j8V3b5Lv{ES0-~sT5CPpQoMn#FnJB~9eyIp88ByBS3c4zkWy*IOp zGJQJ7`>>T?1AO>a=uJ7Qq1sSV256OZ`0SXXs8&$%JIlaB0CbQCPs)4q>-idn7$+2> zMIlS5Zm+=TGR-Jc_+&{522M)y;3)8*duRX! zx!x>k&@CsJ2e){*v8M}wCift!jg%ZrDO29IG0YxPcbKi?pk!b40QxFsnO468{7f}O6D3PKq1;LXL$w?5a z^(6!7lxk^qUm}%OL`s`vGafek65B-t2Ohk6-#6dPoA(9)17H+O z1x}_CEHtotwtfi>oJ=LSSSm=40uQ?s5A)!tW!z)GLzrzU;&(0C4p|giXX=2B=9_a@*tFT+%JyZZ-Vz~3h)BREG(ZWywObkako8HU8;4ZAz zZ9F`(PX^w~L|6)xzjk_H%vzXVs6q7+-hDRlV`&*?brA%>6pNBKH(zrq5E^m%l_`ON zw-y>UV`a_8pkBqm8xw1d7PbdAA@iY=Xiygr8u5RBBytABvD;(gID78QUjsZi8>ew7 z9^&igd*#GsPKNl=l|$?`jjC6c?3AExKbIGj%L78A4cGk*{$BxbSS``T00000NkvXX Hu0mjfX+911 literal 0 HcmV?d00001 diff --git a/mods/carts/textures/carts_rail_crossing_dtc_on.png b/mods/carts/textures/carts_rail_crossing_dtc_on.png new file mode 100644 index 0000000000000000000000000000000000000000..b6f5b87e5da983cadcbfaae3272ff87d347758ac GIT binary patch literal 654 zcmV;90&)F`P)aN7U!C&$Ji-P-8E-aD9v&Lu`Oz0#eOHgOc^_Td!T{Wg+BkBk zk;^q7xES-$-P1+KR3`uyrHOi)cbSe47Fua zqUEp+3ozQ}68{yu)YsRM%@w$pahSrv-Zn7};@{VE5S>XeJ2#KDN)h>zYC%|DDKKD9)8CwAWp$06wVUxf)(;x6>xiagMC}l oe_U6k>%fGr0uvyb`scZS0Ch#+fZHTH^8f$<07*qoM6N<$f{;8RI{*Lx literal 0 HcmV?d00001 diff --git a/mods/carts/textures/carts_rail_crossing_pwr.png b/mods/carts/textures/carts_rail_crossing_pwr.png old mode 100755 new mode 100644 index 0b103f005a1000b2097737a70d8008c3f8a863ac..dc317cfb2c58a6d0e05023ddc4521a1171af8242 GIT binary patch delta 259 zcmeBUKE*siMU%6@BeIx*fm;}a85w5Hkzin8U@!6Xb!ETH$jPmuIQhigBB0Q^iK^@C z|NsAAX)3e>$Ym@E@(X5gcy=QV#7XjYcd@+AFx3Ibnd<4{7$R{w_5ATLCPoS8htgIW zMol8DEUsNw7`^{}uQw7i?zWteY8KBF!N{P(Q`+lX?`^JS|FIbtMz8mW6Uw3NiL2Z+LTsfu8hx_+fM7}JluBo2y^Muu4 zQ`KJQ=S!_?rwALF{p?xs-soH2jk_fq7TLC4t8di3v!BUwzr_0c>;Jg`UC7|+>gTe~ HDWM4f74~Jh delta 199 zcmV;&067231C9fbBmt|DO|O6HGN$qX0004WQchC0(ZA;l=biBxgh*G1N>_);)Pzab zgv-DD67Xy*;oMNLn#l~|> zP3Dyv&o4DuSZ=zg!enuU>5@tyGFw_@wyer@S(VxH8ncyk=Bw(=*VJ3=+Pm%lf1ryQ zW_CT!22zYAL4Lsu4$p3+fjCLt?k)@+tg;?J4rhT!WHAE+w=f7ZGR&GI0Tg5}@$_|N zf50xnt}l7yv-TyR&@4|E#}J9jss1;GnjCnt_a5aw7`-Q7BzDiH-~a8?QYG6b?%6Uq zb5={ofmuQsZbq#yj=3z|t;%2!R3rY#e!?{+O_`pT?n)OwyFVdQ&MBb@09X^MuK)l5 literal 0 HcmV?d00001 diff --git a/mods/carts/textures/carts_rail_crossing_tour.png b/mods/carts/textures/carts_rail_crossing_tour.png deleted file mode 100755 index 0e6cf9593805aba14bc8fb8cd83717f5f03c4aab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 416 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfx&WULS0D`pq2a+9o?>r9qOVK~iNwl4U_s14Wplm69iIWEA!}$98zelJfuE8)xia z(6w&Twk*bp3=Uijg>Ur}o-USA=)7DYl(O4(TaVVIOUW+_^julze@y-U*XH-GS98J> zgz|aCW}jZ%ZkoP*t<2m5$71(0O$?i#P;}Sk-s5+5-^!{C=UQz)P-r7}{yU%B^V{bH zLJE2FyGZx^prw85kH?(j9#r85lP9bN@+X1@aY=J%W507^>757#dm_ z7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10g0sLQvY3H^TL^?1FWs&C0~BO0@$_|N zzstxeV#cp9!9^J;Bvs-XQ4*Y=R#Ki=l**tMkeHcQqUYxtqEKe6XR2pt=>FNs9H?wX zfKP}kkOqR#@ZgF1^Xn~tcDn(2j3q&S!3+-1ZlnP@9iA?ZArg|T2icXJ83kAm+*J2! zTJJ92wBq8;-}le(09EX$VP@#ry_@mETos00lOL|*viS94N!Az64cAvDRWV<%{NH++ zeL?W-&6aB49hSeDXS>;!eeR)yADbS|n%wPo@Z6id*TmkG|C_enz$oUf+6$h`SKm+9 uFP)KB()D#}@BHImt_jU$daU^Oi9EXs_had+73+XjGI+ZBxvX@!>yDZ-VKZU)lR-rKd{7e#ytj; z=lctOF__$(b#`MVzsbh(Z)eWQm>fL#vFYKg$=zxjtgFxeYWn*u|0mbstGP|OX*1T< u?yotS7-f=}ociVSj6D5|EIsXCPTJo($z49hZ|6>sOFdovT-G@yGywpp(ownq diff --git a/mods/carts/textures/carts_rail_curved_cp.png b/mods/carts/textures/carts_rail_curved_cp.png new file mode 100644 index 0000000000000000000000000000000000000000..004ef56675e2e9610081cf3dce642e5d742b3e35 GIT binary patch literal 488 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstUx|zfk$L9 z0|PfuA-4eITIIc^Ktc8rPhVH|yNsM7X8Z~hT$F)AQYEetCBgY=CFO}lsSE*$nRz98 zey$-3WyX4@dWMGXpPkHss#XX1gt!9f|NsBHSm>GMJNy{RHX!0N2=6DD%QoQ*2Snb$0|3+ ztG6VmwpyV!V6iSgVL<+k7t!xFah z4we=kR!y^B)^2D0uy|#0!^-@ndb2ls9A3FEZjxupdhg{&V`UoVl<#`PxRZxd^glP7 QG0zopr0C8}tRsaA1 literal 0 HcmV?d00001 diff --git a/mods/carts/textures/carts_rail_curved_dtc.png b/mods/carts/textures/carts_rail_curved_dtc.png new file mode 100644 index 0000000000000000000000000000000000000000..8117c27a92edcb03681101eea2468cfebc35b8f6 GIT binary patch literal 578 zcmV-I0=@l-P)T2Y6N*5{bA0%Hzu(Wp^ZZ~Z>*mEn zGCOiaN_(#D7<^kd2%eiJb_&}>{jWH-FfRa+aI~ziwkvEl+G0y+3C4rFB$3>*-#RK8bY6KxBpfAB`+-+y zkK1B^>yJOH&18yj=&)2Yh%L;Em7MsIVd?u%W`+V~t6SeR$>s~y39P#NbXk2(q)DcJ z5giW7A8bV~Cx36DG`$pi^t4a38jYrXbzHvlRsn>%TEyG9yGSr`UYE(yy zX%i!zVRrPWtm=rF6FhELG39EvPfiX#BodBtrtJ$xCQm^M^iI7gBMf!5$o{<^YTX(y z*ILU*u<)DBI3Bl?jZ~Hs0WX=YJnkANJ(I81s*cJ%=P)}v~N{2d1C`Cn+YOnd<%j04E|82BIUV4rXzwh_^d3c^5{Li{Id_ZO< z4oi8@wiAOdn`wLl_lcgwG*SO5jxH?-KsXes=&PLyJMf{Q=+5|>De6^uI$1@~Szle<9ixjnnC(ixp} zCd_|7o;8b`(XkO0pPc1jciZ1T)8qM%CZSS@)uKRi1JJX-l{0r@Y8yo~w>R^d-2(ss N002ovPDHLkV1l%W`-pxEgMU%6@BeIx*fm;}a85w5Hkzin8U@!6Xb!ETH$jPl@BwjXW4Nz$HMAbEl n|NsBDI`sGgkjq#Sdg>l71-!+1Z#KdeE7#J8!g8YIR9G=}sn=Hk+5CE)P3Ss~N diff --git a/mods/carts/textures/carts_rail_curved_ss.png b/mods/carts/textures/carts_rail_curved_ss.png new file mode 100644 index 0000000000000000000000000000000000000000..504e31f13535afcf3da7b3e32457a07c694d9b68 GIT binary patch literal 450 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf>Hwb**Z=?jhlU4dc*$h@$mI9} zk!-H7OrD=?zQ1fi01(L)2Fex%$Q1?36$if_h7$c6*XWXNqQTx@K>t-h^!ZiP`#-a)8KSYQDjYLZewlMzf2J=ad-F zEis;7YBImfcwxEeqH>c(6{bsosM2hCjroci^VN0cYw9f4G+6A~yY2sfpmP~EEUB9S zq!>$r{DK)Ap4~_Tagw~Fdh=fL(-L zUuTlT`;S1O37#&FArhBs`>zWfGT>qH|B_bqLZv0niT&pP|EUq2=NS0!bZ^z}bz}RN zQuIeqb=%K`v`s&qwi>7{e0OuvwVU19<};T(KYOWC%Jzxu8rj!f^0yZ4@nMxZEE~Xm zUuXC2y`l@47TEi-y!z+)d~J@Q?c!z$)49jn4K?-4Z^tKEiOkp24m=_9Uiwkila@ce cg83hrjKlegEJWp(1Kq~p>FVdQ&MBb@06SEmYXATM literal 0 HcmV?d00001 diff --git a/mods/carts/textures/carts_rail_curved_tour.png b/mods/carts/textures/carts_rail_curved_tour.png deleted file mode 100755 index ef0596775b5faa425dd8be75dddc6b428aef1a3a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 391 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf>Hwb*S0D`pq2a+9UNYG}GC96L zB%A9iljkR!?=M>r07Pv_qqgofE z)*P$c9IxJzpx%pQ-{>@Zb+GgMp_I zgUa1dhDq-puH&-!;c?YMua4=>lGQWfn3wq1Km5Vy(f@k7dBkq^ON-x5PB+VUShb_2ZBI^_w6U85!}n@=eZ}iE;;1UfBF( YpS*xKRv{?i2+&dnPgg&ebxsLQ0K-&}761SM diff --git a/mods/carts/textures/carts_rail_dtc.png b/mods/carts/textures/carts_rail_dtc.png new file mode 100644 index 0000000000000000000000000000000000000000..5e2ccef19787501f0c469ea1d93a8e0c8a82e580 GIT binary patch literal 542 zcmV+(0^$9MP)95dMe;1u5bdrEhxe%Jsh8_r3Q$@6&K@FEq52gWvHyAHF>2!#U8*-2AKz zj||Cr7s6k%-h~X049VR5Y{nRXmv;xUgQsV^d3eD{tI?zazOSj)5)vysuEbDv+{CS3 zxpHq&8GxDBMK1NZL9n&MR;58(p#`m>kq9;gt>I9?WZNvSegAX4f4zd{KVtwUZ=cE< zX9jy1Pf|H{G>@kgK{@7N-VoI-ljR61j(c&ZUj|3tI0qlUlxS}jeE3`Y)@E z4RJ%LCn=s*kayhTO0b_COpo?ujnB`WVB(^dYGldznvNrRib06qqIvSu!nWfc-8?B* z$CjLfg_RA?pK*h=VhQ7EYITdJU?cDeV@r|orq^z!KUNxU+b3Z literal 0 HcmV?d00001 diff --git a/mods/carts/textures/carts_rail_dtc_on.png b/mods/carts/textures/carts_rail_dtc_on.png new file mode 100644 index 0000000000000000000000000000000000000000..e81dbe1bee83389e3236d08506b2728bd2a25eb0 GIT binary patch literal 559 zcmV+~0?_@5P) zK~y-)&62@OR8bVhfA_xU8>fLRC|uM+=nt^0grZ%oqD3I)I$A|w5W3LStP;!?1{O%+ zBHOtT3Ijn}6m2x4g@zO|TH@0g8&Mzg-psr2xOmfz7H(?eSzYdTzK?T$9H`gy%#?I? zb%^8<4k*bZon0L=Ju_u{T!6O&SM0}=Vk^&kTxoPQiGb&6_9`*45e9xlHf*f-g4}*I zr(A&79}3)TPX)iYO>w8j@mvF1LoF6e0$M{;&b0yaOB;WW_pd8x{+`yN4Lh+`oE$kZ7u9x4W-587&kwYk&|0hw>fnINa*22)kpRJ z|Nmbsev}u;Wh@Eu3ubV5b|VeMN%D4g@si`&dJM?v@^o-@~hKE!@V?lyo#)Bel1ryNfCB5f^)* zS=GL2+heC!F=uq_Y?!IP{E*?QpVwU;>-d>9A5Gu$Dma^g(=e}1>1~pl=gRv delta 192 zcmV;x06+io1G)o{Bmv%$P2ztUNk*Lj0004WQchCuFhmYsty6sRe0Ch3z%j8OlphY$Q6$4J#aV=KBMYT!FuAL4aH#5CzH=1;`Zz$`uF6mjug| z1k0BO%a?`7mxsz%gvwWj0g*ygxI%TfLVdJiL$p#uj8bE?Qd_ciXR1zjy6%K5{fXK7 zlXDHG0#Tm9w0s~koKa{rv&d)`5EUEEE;gQ1Vl=13cy5XD{8At?Sy*PWsN8gMrRkCi z(HD6g{zPiq0eWT@uX3NbjR$JPvwzXStZ@1aCciaE}Ku9LG zVE%IYju}vBmZytjh{WaIbI19b7z9`Xj>T(T>4X3F9up=%d=zI^dGq8N z1&$WYn&T{Uzp9zk?zeqC*=)x)MV~3mtx0AxGn)#Zw`{o6@zl*`gYvS&zmp4ZmK<2l zTdE`;^hs4ytBKeAQ}pXbWy83y&(~kv#4csFq@zWsb8CntFWdiL$!>S}+`d;`Vq1{b m>~$h^WtiaPx(mbe{N literal 0 HcmV?d00001 diff --git a/mods/carts/textures/carts_rail_t_junction_brk.png b/mods/carts/textures/carts_rail_t_junction_brk.png old mode 100755 new mode 100644 index e1cf55959075c734f024f13d819e6041b452b4a5..5689ffe93115c90e129f9af44c6fb8abb5879afc GIT binary patch delta 512 zcmey)G>c_|NGZx^prw85kH?(j9#r85lP9bN@+X1@aY=J%W507^>757#dm_ z7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10g0sLQvY3H^TL^?1FWs&C0~BO0@$_|N zzst-eD5>$&;=2P-NUFp&q9iy!t)x7$D3zf;ATcwqM9W0$;vtpkC7tChljS3m?IV-tC!6mtSKu#O7$8>|C|499 zR}?5$93)>FEMFEPUmhx783sfORpAQN;R^N9iVe|94KYe>$=coNx)ZYWCuY~{Pt7%$ zQD`))$Y@Rp5E;)cF`i#)vZ&m2ai!^!3ezQ(W=pHgmRFmvs5M_*XR*G~aznG_mNu*H z?KZpiZku}2t_|oqrjj7PU8 zkN^9759@Ipyg2R6Mn-K0g_MT+%Irxw*N>-s(_Y^&>FVE%(tTOI6LXluo-pKiGU+@u zddYDk!b@+O(i3fi4LaJ3f~K}Fk=3+3yif9Xb&BD%=?-@e|Gfq wyPw{d%<#GVGI#aO|9@VFX0uxIum7Geeoo+0#F=@Ifv#ilboFyt=akR{08$dV(EtDd delta 348 zcmbQm@||gdO8xu*pAc6DFi7{5&hV1S^p?r-k;(Cu$@P`V^OMa7B7fO}0J%aS3Y0Ah zlq(LBFA0_}4VEhlk*^2^B8AE@h3ZI^+DOH^7}dHMwfbnK=6Lm%1ohr@&HgOCiP`#- zattQt8cfMGn3iuiJ>PIff#HloquIsAb4u!s=av}HD>0s5YBImfcwxEek_yx1HRda7 z%vaZ$uc@t%qp*%oqb$0X~~P-%CDZT qJMMBIzsfFlM{Z&0LH(s1@4vA8W8pg)Rj9NL6oj6xelF{r5}E)8H;IG* diff --git a/mods/carts/textures/carts_rail_t_junction_cp.png b/mods/carts/textures/carts_rail_t_junction_cp.png new file mode 100644 index 0000000000000000000000000000000000000000..3da909432540ca562f514278fe55cc7a10a79642 GIT binary patch literal 496 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstUx|zfk$L9 z0|PfuA-4eITIIc^Ktc8rPhVH|yUbjIk{UlPzB>Sgq)J>PN`mv#O3D+9QW*jgGxJLH z{9Hp6%8d0)^$ZQ&KRcNNRjmu~32_C||NsAYvCxZglt^)xPVtb+^peiEeMb+1foE>q5!#~K)K=|`O;wdvJm<5Q2B~b`N}XLQm6`7s7eX04p*p; zR&0n?YKT#4OV;j8)#*;xosgwJFnzqcT5f2z+|p*Xt=)QiyG{D6Q!9ZkW-1Bt1BOr8 zz2zoC!hnD1WuO0dyRLr>mdKI;Vst0Hv;`asU7T literal 0 HcmV?d00001 diff --git a/mods/carts/textures/carts_rail_t_junction_dtc.png b/mods/carts/textures/carts_rail_t_junction_dtc.png new file mode 100644 index 0000000000000000000000000000000000000000..b154f4363cd6942531c686a22866c86f2a6e0c4b GIT binary patch literal 607 zcmV-l0-*hgP)Y=6Hyd~zk40i(k!YV6jY>8nUzq|YQf@8g&IVJP`YrVh6LOgl(=Xi8&O<{ zXf_Iy42sr`lH!X9f#Sjk6hpJI3MC7zGzRL6K4@Yxxh|$N(^TuGp3Q}G&-u^!|NmZC ziQITr4Gx7=Nk_3xlyubKP)Oy*vu=$B@chaFH}UXrH|b-VYSknS1wNl-ak)<2QrwxZ z!lGSw`@&vz>S|tS08d|i?}UwYtJ;fRxbg*W7J(3|u5PfD)@I zqzsc}A;b1*#MECRWY%nCi z{gFNw@!hSgO(7a476?(&Q6(Lfj`yeshq~QHGv2FQ5#LUIA$ZWfNEs%(YIz=ApCEG1 zAZFP4EX>l{B3Z6BXls#7{#anC tVj+ZJsbayFE&%RcI?d>dvS6d%`8WRK@(dl8G*$or002ovPDHLkV1ft(5KsUB literal 0 HcmV?d00001 diff --git a/mods/carts/textures/carts_rail_t_junction_dtc_on.png b/mods/carts/textures/carts_rail_t_junction_dtc_on.png new file mode 100644 index 0000000000000000000000000000000000000000..9fda111b95284cbc6e210c3e6de9f9cd87a4e251 GIT binary patch literal 621 zcmV-z0+RiSP))a=%7fUE}bf^1}r+MP=kXIn$8*$5JXVokb)3IC@950 zLxz_GLE}>dpY-<@7(YE4y;9X zG9!aSK9MNG79mk&aL6aw$&6ED06ZT#>Ll)#dPsx~X*D!80hdejbEQhv5=Q3B4%odb zhve+doH78Oy!^-+kNr?AeW&!J!fy9=w1!Gmuxg++w7U%lVDG>+vIB@}rVuxijCH3` zQPjro*S{S%lk4)v#zKGI2c-Yn7z_nCIqhu#Jct}#CtM=jCwtmmwDn(g8ppcRO#|SW ztDn=uuWb!x3t#AHLXVqCf~V}W-gqImk8N7P4!bTlQ~Z---Nvmf-ONVKKZXW)IP7r{ zUmVNW6hZ;~c^?u*B#I=$y>jPskJFe8_lYCo+nG;zkJ}G%Gs*r+j)_}u2wpPrn>0k+ z39l9p*cyB&He9&400000NkvXX Hu0mjf@sSL= literal 0 HcmV?d00001 diff --git a/mods/carts/textures/carts_rail_t_junction_pwr.png b/mods/carts/textures/carts_rail_t_junction_pwr.png old mode 100755 new mode 100644 index 0e156cd06c827aee5aad03f19b09a355e71f25ad..d7edaf1dc3dafda2eea9edd38aefc2c677ba2635 GIT binary patch delta 513 zcmZo5jgR3=A9lx&I`x0{IHb9znhg3{`3j3=J&| z48MRv4KElNN(~qoUL`OvSj}Ky5HFasE6@fg!CBxDS21s z-(}_!6zA31&({eQk}7eHC<)F_D=AMbN@b`INX*PD(erZ+Q7ALkGu1ORbpPyR4pcTj zz$e5NNdN!;KQufz#!({0T{^`>D$`3k%UdSPM<&}xCeKec-(Rl4U$!tnt}sxpC_t_# zP_8&gzBE|AEJVIMRK79{h!m>A6{^D(>Z27KqLmtAl-iQDyVG?iWa&@L)}NYNZ!n|K zXjYNYoDv{1o?Bu(ztm(=x#{9c(Wc zcJ1Bv|38C|#vyy48<|Ri{DK)6$|j$+0P-ezx;TbNTu$vjp2x%}!ptsQ)voeo(uOSp ztM31=mu`<0Xj-g$GnqMz!Qli$cvbeiH)icm(v{XXPWl@9qHbIE*^N2OVNV!xJehQ! z8olJW5#@Dmn$i<)gDpDRi-M-QFOk)>JiJfxcXf*8r*>)%PW8!n5Uz{On{zXqbbm9QbTgiGGoN)dpLR2$ zcQvGVHK%+xsC+l8emAUsIIMs;y1lml{{Y)-Z`S|-00DGTPE!Ct=GbNc0050iL_t(| z0aefE62dSH17M3iAnZ*kdqWw@`@b3{>CvEn`tB0jB0^Ykv7l%YVs~Dxmz#JCE))uc znHKxiK_dr}!Cw;+njg4IYds9_TCM-oL5Er;0Al`<0F>%c{14KeoicD^dgHx^Nea@6 z{Mat>zFog!z;rP)Dm^ZVSRh-yoUc3&U{iuyY6d*Y2jk5Y5gl14aR2}S07*qoM6N<$ Ef?Q~dYXATM diff --git a/mods/carts/textures/carts_rail_t_junction_ss.png b/mods/carts/textures/carts_rail_t_junction_ss.png new file mode 100644 index 0000000000000000000000000000000000000000..c1a2cb1d034719c86880029c7960e54c04c5489a GIT binary patch literal 439 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf`~aU2R}lt=(D2|GM~M`7=@bvC zOfTsyZ<#C~nQR}KJU`idf4KsG*}?$1!a%vA0J)+-x#A%C(qQ?r5c%>@`N}XLQm6`7 zs18@Ck5+7mR%(b*YD?DcPS>4~r9UxSe`>D5j6$PXMMiT<>&pIsU4&haW#79pFQCvw zPZ!4!iOaeE>_UeXc%1Kge!urp;coPY|J$z$6kXqaW#8d#4wC}C1l@ibEYOx$y7>HY zZ2t5Ijtx?VtG=|~-LaS9rWJS7)2@yy+!hcc{+J`O0{4=9XoTHT0U7Cj9>VSO3-u W5rd~0DVu+}rLnI_w53)M3I5Mzoe08j}aQb0czLh`!U-n=SW{?m~$dkXH_df4k zI{#Oxh)tJ&etP)p;x(tx1AGiyd>MruZqH)8QTQj-T8Po$rmRql i%wxX6c;Hw_{15h9&xFh-dzkuzg4NU2&t;ucLK6VaGmF>& diff --git a/mods/carts/textures/carts_rail_tour.png b/mods/carts/textures/carts_rail_tour.png deleted file mode 100755 index 32e51144a4484548e6b490a42c04acab02e7b016..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 453 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf!vLQUS0D`pq2a+XjuI*E(kUKN znO@SFUNTwUGFd({**-G4zB0LfvUz^8`Tjs8SKu#O5Fl3wM1gWe0dhrwa>YUNCBbqf z!SbcS@?|0N<)QKwq4JesK%`I=u23DWP#>+>5Utb@qtqC!)RwH>nX1#Bt~()1e`2=& zZD>)s{A^ZSB_E+iiC3-S+=KL-VPp=0G1Z zmIV0)GdMiEkp|>U@^omrlgQ#cj0k9l7# gG8EVpY?l3vxvx-Maie$BE>LWEy85}Sb4q9e0M~k>ZU6uP diff --git a/mods/carts/textures/default_rail_t_junction.png b/mods/carts/textures/default_rail_t_junction.png new file mode 100644 index 0000000000000000000000000000000000000000..fe6290577aea91b241cb13e67e6083f7918a3a0b GIT binary patch literal 476 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstUx|zfk$L9 z0|U1Z2s2)~TlWVjC{^MbQ4*Y=R#Ki=l*$m0n3-3i=jR%tP-d)Ws%L2E{@KYKsA^q+ zPlzj!{{R1fXn1gpqeP0kbc%;mrk8YG@4apG^YfJjOUgZ&o4DuSZ1=Q+;nlJ>5>Z5C6#7NtIU>Ho3E%fUtMRh zzR_|+v*ngHt8MMp+uLn+?cLVzeDWyJ#Y`nZe!##en|#&+$eZBl;us0l!pS~FGwcX5~p!r>VTeo?00 then - local vx=math.abs(self.velocity.x) - local vy=math.abs(self.velocity.y) - local vz=math.abs(self.velocity.z) - -- make v the largest of the 3 velocities - local v=vx - if vy>v then v=vy end - if vz>v then v=vz end - -- - local diff=0 - local acelordecl=0 - if v>t then - diff=v-t - acelordecl=-1 - elseif vt - --minetest.log("action", " on_step t1 v="..v.." t="..t.." diff="..diff.." a="..a.." acelordecl="..acelordecl) - --adjust for grav - if self.velocity.y<0 then --going downhill so grav will acel by extra 0.13 - --if we are decel then add an extra 0.13 to how much we need to decel - --if we are accel then subtract an extra 0.13 from how much we need to acel - diff=diff-(0.13*acelordecl) - elseif self.velocity.y>0 then --going uphill grav will decl by extra 0.10 - --if we are decel then subtract 0.1 from how much we need to decel - --if we are acel then add 0.1 to how much we need to acel - diff=diff+(0.1*acelordecl) - end -- self.velocity.y<0 - --so now diff is the difference between cart velocity (after this turns grav) - --and our target touring velocity - --minetest.log("action", "*!* on_step t2 grav v="..v.." diff="..diff.." a="..a) - if diffa*4 then - a=a*2 --if big difference, play catchup fast! - elseif diff>a*3 then - a=a*1.5 --if big difference, play catchup fast! - end --diff0--]] - - - - - ---[[minetest.register_node("carts:rail_tour", { - description = "Touring Rail", - drawtype = "raillike", - tiles = {"carts_rail_tour.png", "carts_rail_curved_tour.png", "carts_rail_t_junction_tour.png", "carts_rail_crossing_tour.png"}, - inventory_image = "carts_rail_tour.png", - wield_image = "carts_rail_tour.png", - paramtype = "light", - sunlight_propagates = true, - is_ground_content = true, - walkable = false, - selection_box = { - type = "fixed", - fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2}, - }, - groups = {bendy = 2, snappy = 1, dig_immediate = 2, rail = 1, connect_to_raillike = 1}, - - after_place_node = function(pos, placer, itemstack) - if not mesecon then - minetest.get_meta(pos):set_string("cart_acceleration", "0.5") - minetest.get_meta(pos):set_string("cart_touring_velocity", cart.TARGET_TOUR_V) - end - end, - - mesecons = { - effector = { - action_on = function(pos, node) - minetest.get_meta(pos):set_string("cart_acceleration", "0.5") - end, - - action_off = function(pos, node) - minetest.get_meta(pos):set_string("cart_acceleration", "0") - end, - }, - }, -}) ---]] ---[[minetest.register_craft({ - type = "shapeless", - output = "carts:rail_tour", - recipe = {"group:rail", "default:clay_lump"}, -})--]] ---minetest.register_alias("carts:tourrail", "carts:rail_tour") - - - - --- temporary ---[[minetest.register_abm({ - nodes = {"group:rail"}, - func = function(pos) - local name = minetest.get_node(pos).name - minetest.remove_node(pos) - minetest.place_node(pos,{name = name}) - end -})--]]