1 function carts:get_sign(z)
9 function carts:manage_attachment(player, obj)
13 local status = obj ~= nil
14 local player_name = player:get_player_name()
15 if player_api.player_attached[player_name] == status then
18 player_api.player_attached[player_name] = status
21 player:set_attach(obj, "", {x=0, y=-4.5, z=0}, {x=0, y=0, z=0})
22 player:set_eye_offset({x=0, y=-4, z=0},{x=0, y=-4, z=0})
25 player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0})
29 function carts:velocity_to_dir(v)
30 if math.abs(v.x) > math.abs(v.z) then
31 return {x=carts:get_sign(v.x), y=carts:get_sign(v.y), z=0}
33 return {x=0, y=carts:get_sign(v.y), z=carts:get_sign(v.z)}
37 function carts:is_rail(pos, railtype)
38 local node = minetest.get_node(pos).name
39 if node == "ignore" then
40 local vm = minetest.get_voxel_manip()
41 local emin, emax = vm:read_from_map(pos, pos)
42 local area = VoxelArea:new{
46 local data = vm:get_data()
47 local vi = area:indexp(pos)
48 node = minetest.get_name_from_content_id(data[vi])
50 if minetest.get_item_group(node, "rail") == 0 then
56 return minetest.get_item_group(node, "connect_to_raillike") == railtype
59 function carts:check_front_up_down(pos, dir_, check_up, railtype)
60 local dir = vector.new(dir_)
65 cur = vector.add(pos, dir)
66 if carts:is_rail(cur, railtype) then
72 cur = vector.add(pos, dir)
73 if carts:is_rail(cur, railtype) then
79 cur = vector.add(pos, dir)
80 if carts:is_rail(cur, railtype) then
86 function carts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
87 local pos = vector.round(pos_)
89 local left_check, right_check = true, true
91 -- Check left and right
92 local left = {x=0, y=0, z=0}
93 local right = {x=0, y=0, z=0}
94 if dir.z ~= 0 and dir.x == 0 then
97 elseif dir.x ~= 0 and dir.z == 0 then
102 local straight_priority = ctrl and dir.y ~= 0
104 -- Normal, to disallow rail switching up- & downhill
105 if straight_priority then
106 cur = self:check_front_up_down(pos, dir, true, railtype)
113 if old_switch == 1 then
115 elseif old_switch == 2 then
118 if ctrl.left and left_check then
119 cur = self:check_front_up_down(pos, left, false, railtype)
125 if ctrl.right and right_check then
126 cur = self:check_front_up_down(pos, right, false, railtype)
135 if not straight_priority then
136 cur = self:check_front_up_down(pos, dir, true, railtype)
142 -- Left, if not already checked
144 cur = carts:check_front_up_down(pos, left, false, railtype)
150 -- Right, if not already checked
152 cur = carts:check_front_up_down(pos, right, false, railtype)
159 if not old_switch then
160 cur = carts:check_front_up_down(pos, {
170 return {x=0, y=0, z=0}
173 function carts:pathfinder(pos_, old_pos, old_dir, distance, ctrl,
176 local pos = vector.round(pos_)
177 if vector.equals(old_pos, pos) then
181 local pf_pos = vector.round(old_pos)
182 local pf_dir = vector.new(old_dir)
183 distance = math.min(carts.path_distance_max,
184 math.floor(distance + 1))
186 for i = 1, distance do
187 pf_dir, pf_switch = self:get_rail_direction(
188 pf_pos, pf_dir, ctrl, pf_switch or 0, railtype)
190 if vector.equals(pf_dir, {x=0, y=0, z=0}) then
192 return pf_pos, pf_dir
195 pf_pos = vector.add(pf_pos, pf_dir)
197 if vector.equals(pf_pos, pos) then
198 -- Success! Cart moved on correctly
202 -- Not found. Put cart to predicted position
203 return pf_pos, pf_dir
206 function carts:register_rail(name, def_overwrite, railparams)
208 drawtype = "raillike",
210 sunlight_propagates = true,
211 is_ground_content = false,
215 fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
217 sounds = default.node_sound_metal_defaults()
219 for k, v in pairs(def_overwrite) do
222 if not def.inventory_image then
223 def.wield_image = def.tiles[1]
224 def.inventory_image = def.tiles[1]
228 carts.railparams[name] = table.copy(railparams)
231 minetest.register_node(name, def)
234 function carts:get_rail_groups(additional_groups)
235 -- Get the default rail groups and add more when a table is given
240 connect_to_raillike = minetest.raillike_group("rail")
242 if type(additional_groups) == "table" then
243 for k, v in pairs(additional_groups) do