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 44892a7e..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")*2.5, -- 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 3af5bb58..d4b12d63 Binary files a/mods/carts/models/cart.png and b/mods/carts/models/cart.png differ diff --git a/mods/carts/models/cart.x b/mods/carts/models/cart.x old mode 100755 new mode 100644 diff --git a/mods/carts/rails.lua b/mods/carts/rails.lua index f3e1f778..bf70abea 100644 --- a/mods/carts/rails.lua +++ b/mods/carts/rails.lua @@ -1,7 +1,10 @@ -minetest.register_node(":default:rail", { +minetest.register_node(":default:rail", { description = "Rail", drawtype = "raillike", - tiles = {"default_rail.png", "default_rail_curved.png", "default_rail_t_junction.png", "default_rail_crossing.png"}, + tiles = { + "default_rail.png", "default_rail_curved.png", + "default_rail_t_junction.png", "default_rail_crossing.png" + }, inventory_image = "default_rail.png", wield_image = "default_rail.png", paramtype = "light", @@ -12,184 +15,64 @@ minetest.register_node(":default:rail", { 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}, - --[[mesecons = { + groups = carts:get_rail_groups(), +}) + + +-- Copper rail + +if minetest.get_modpath("moreores") then + -- Moreores' copper rail + minetest.register_alias("carts:rail_copper", "moreores:copper_rail") +else + carts:register_rail(":carts:rail_copper", { + description = "Copper rail", + tiles = { + "carts_rail_cp.png", "carts_rail_curved_cp.png", + "carts_rail_t_junction_cp.png", "carts_rail_crossing_cp.png" + }, + groups = carts:get_rail_groups(), + }) + + minetest.register_craft({ + output = "carts:rail_copper 16", + recipe = { + {"default:copper_ingot", "group:stick", "default:copper_ingot"}, + {"default:copper_ingot", "group:stick", "default:copper_ingot"}, + {"default:copper_ingot", "group:stick", "default:copper_ingot"}, + } + }) +end + +-- Speed up + +-- Rail Power + +carts:register_rail(":carts:rail_power", { + description = "Powered rail", + tiles = { + "carts_rail_pwr.png", "carts_rail_curved_pwr.png", + "carts_rail_t_junction_pwr.png", "carts_rail_crossing_pwr.png" + }, + groups = carts:get_rail_groups(), + + after_place_node = function(pos, placer, itemstack) + if not mesecon then + minetest.get_meta(pos):set_string("cart_acceleration", "1") + end + end, + + mesecons = { effector = { - action_off = function(pos, node) - minetest.get_meta(pos):set_string("cart_acceleration", "0.5") - minetest.get_meta(pos):set_string("cart_touring_velocity", cart:get_staticdata().velocity) + action_on = function(pos, node) + carts:boost_rail(pos, 1) end, - action_on = function(pos, node) + action_off = function(pos, node) minetest.get_meta(pos):set_string("cart_acceleration", "0") end, }, - },--]] -}) - -minetest.register_node("carts:rail_copper", { - description = "Copper Rail", - drawtype = "raillike", - tiles = {"carts_rail_copper.png", "carts_rail_copper_curved.png", "carts_rail_copper_t_junction.png", "carts_rail_copper_crossing.png"}, - inventory_image = "carts_rail_copper.png", - wield_image = "carts_rail_copper.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}, -}) - -minetest.register_node("carts:rail_invisible", { - description = "Invisible Rail", - stack_max = 10000, - range = 12, - drawtype = "raillike", - tiles = {"invisible.png", "invisible.png", "invisible.png", "invisible.png"}, - inventory_image = "default_rail.png^default_steel_ingot.png", - wield_image = "default_rail.png^default_steel_ingot.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}, - }, - drop = "", - groups = {unbreakable = 1, rail = 1, connect_to_raillike = 1, not_in_creative_inventory = 1}, -}) - -minetest.register_node("carts:rail_power", { - description = "Powered Rail", - drawtype = "raillike", - tiles = {"carts_rail_pwr.png", "carts_rail_curved_pwr.png", "carts_rail_t_junction_pwr.png", "carts_rail_crossing_pwr.png"}, - inventory_image = "carts_rail_pwr.png", - wield_image = "carts_rail_pwr.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) - minetest.get_meta(pos):set_string("cart_acceleration", "1") - --minetest.get_meta(pos):set_string("cart_touring_velocity", cart:get_staticdata().velocity) - end, - - --[[mesecons = { - effector = { - action_off = function(pos, node) - minetest.get_meta(pos):set_string("cart_acceleration", "0.5") - end, - - action_on = function(pos, node) - minetest.get_meta(pos):set_string("cart_acceleration", "0") - end, - }, - },--]] -}) - -minetest.register_node("carts:rail_power_invisible", { - description = "Invisible Powered Rail", - stack_max = 10000, - range = 12, - drawtype = "raillike", - tiles = {"invisible.png", "invisible.png", "invisible.png", "invisible.png"}, - inventory_image = "default_rail.png^default_mese_crystal_fragment.png", - wield_image = "default_rail.png^default_mese_crystal_fragment.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}, - }, - drop = "", - groups = {unbreakable = 1, rail = 1, connect_to_raillike = 1, not_in_creative_inventory = 1}, - - after_place_node = function(pos, placer, itemstack) - minetest.get_meta(pos):set_string("cart_acceleration", "10") - --minetest.get_meta(pos):set_string("cart_touring_velocity", cart:get_staticdata().velocity) - end, -}) - -minetest.register_node("carts:rail_brake", { - description = "Brake Rail", - drawtype = "raillike", - tiles = {"carts_rail_brk.png", "carts_rail_curved_brk.png", "carts_rail_t_junction_brk.png", "carts_rail_crossing_brk.png"}, - inventory_image = "carts_rail_brk.png", - wield_image = "carts_rail_brk.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) - minetest.get_meta(pos):set_string("cart_acceleration", "-1") - --minetest.get_meta(pos):set_string("cart_touring_velocity", cart.TARGET_TOUR_V) - end, - - --[[mesecons = { - effector = { - action_off = function(pos, node) - minetest.get_meta(pos):set_string("cart_acceleration", "-0.2") - end, - - action_on = function(pos, node) - minetest.get_meta(pos):set_string("cart_acceleration", "0") - end, - }, - },--]] -}) - -minetest.register_node("carts:rail_brake_invisible", { - description = "Invisible Brake Rail", - stack_max = 10000, - range = 12, - drawtype = "raillike", - tiles = {"invisible.png", "invisible.png", "invisible.png", "invisible.png"}, - inventory_image = "default_rail.png^default_coal_lump.png", - wield_image = "default_rail.png^default_coal_lump.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}, - }, - drop = "", - groups = {bendy = 2, snappy = 1, dig_immediate = 2, rail = 1, connect_to_raillike = 1, not_in_creative_inventory = 1}, - - after_place_node = function(pos, placer, itemstack) - minetest.get_meta(pos):set_string("cart_acceleration", "-10") - --minetest.get_meta(pos):set_string("cart_touring_velocity", cart:get_staticdata().velocity) - end, -}) - - -minetest.register_craft({ - output = "carts:rail_copper 16", - recipe = { - {"default:copper_ingot", "group:stick", "default:copper_ingot"}, - {"default:copper_ingot", "group:stick", "default:copper_ingot"}, - {"default:copper_ingot", "group:stick", "default:copper_ingot"}, - } }) minetest.register_craft({ @@ -198,16 +81,80 @@ minetest.register_craft({ recipe = {"group:rail", "default:mese_crystal_fragment"}, }) + +-- Rail Brake + +carts:register_rail(":carts:rail_brake", { + description = "Brake rail", + tiles = { + "carts_rail_brk.png", "carts_rail_curved_brk.png", + "carts_rail_t_junction_brk.png", "carts_rail_crossing_brk.png" + }, + groups = carts:get_rail_groups(), + + after_place_node = function(pos, placer, itemstack) + if not mesecon then + minetest.get_meta(pos):set_string("cart_acceleration", "-1") + end + end, + + mesecons = { + effector = { + action_on = function(pos, node) + minetest.get_meta(pos):set_string("cart_acceleration", "-1") + end, + + action_off = function(pos, node) + minetest.get_meta(pos):set_string("cart_acceleration", "0") + end, + }, + }, +}) + minetest.register_craft({ type = "shapeless", output = "carts:rail_brake", recipe = {"group:rail", "default:coal_lump"}, }) +-- Start stop rail (temporary removed for mff) +--[[carts:register_rail("carts:startstoprail", { + description = "Start-stop rail", + tiles = { + "carts_rail_ss.png", "carts_rail_curved_ss.png", + "carts_rail_t_junction_ss.png", "carts_rail_crossing_ss.png" + }, + groups = carts:get_rail_groups(), + + after_place_node = function(pos, placer, itemstack) + if not mesecon then + minetest.get_meta(pos):set_string("cart_acceleration", "halt") + end + end, + + mesecons = { + effector = { + action_on = function(pos, node) + carts:boost_rail(pos, 0.5) + end, + + action_off = function(pos, node) + minetest.get_meta(pos):set_string("cart_acceleration", "halt") + end, + }, + }, +}) + +minetest.register_craft({ + type = "shapeless", + output = "carts:startstoprail 2", + recipe = {"carts:powerrail", "carts:brakerail"}, +})--]] + +--Alias minetest.register_alias("carts:powerrail", "carts:rail_power") minetest.register_alias("carts:power_rail", "carts:rail_power") minetest.register_alias("carts:brakerail", "carts:rail_brake") -minetest.register_alias("carts:brake_rail", "carts:rail_power") - +minetest.register_alias("carts:brake_rail", "carts:rail_brake") diff --git a/mods/carts/textures/cart_bottom.png b/mods/carts/textures/cart_bottom.png old mode 100755 new mode 100644 diff --git a/mods/carts/textures/cart_side.png b/mods/carts/textures/cart_side.png old mode 100755 new mode 100644 index 442e1acf..1bd55e7b Binary files a/mods/carts/textures/cart_side.png and b/mods/carts/textures/cart_side.png differ diff --git a/mods/carts/textures/cart_top.png b/mods/carts/textures/cart_top.png old mode 100755 new mode 100644 diff --git a/mods/carts/textures/carts_rail_brk.png b/mods/carts/textures/carts_rail_brk.png old mode 100755 new mode 100644 index 9e82db18..2717bd5a Binary files a/mods/carts/textures/carts_rail_brk.png and b/mods/carts/textures/carts_rail_brk.png differ diff --git a/mods/carts/textures/carts_rail_copper.png b/mods/carts/textures/carts_rail_copper.png deleted file mode 100755 index 73963f62..00000000 Binary files a/mods/carts/textures/carts_rail_copper.png and /dev/null differ diff --git a/mods/carts/textures/carts_rail_copper_crossing.png b/mods/carts/textures/carts_rail_copper_crossing.png deleted file mode 100755 index 3f12eec5..00000000 Binary files a/mods/carts/textures/carts_rail_copper_crossing.png and /dev/null differ 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 6cfc8c2d..00000000 Binary files a/mods/carts/textures/carts_rail_copper_curved.png and /dev/null differ 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 57759193..00000000 Binary files a/mods/carts/textures/carts_rail_copper_t_junction.png and /dev/null differ diff --git a/mods/carts/textures/carts_rail_cp.png b/mods/carts/textures/carts_rail_cp.png new file mode 100644 index 00000000..119461f6 Binary files /dev/null and b/mods/carts/textures/carts_rail_cp.png differ 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 6fc3ef86..f9ce303a Binary files a/mods/carts/textures/carts_rail_crossing_brk.png and b/mods/carts/textures/carts_rail_crossing_brk.png differ 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 00000000..b04aa638 Binary files /dev/null and b/mods/carts/textures/carts_rail_crossing_cp.png differ diff --git a/mods/carts/textures/carts_rail_crossing_dtc.png b/mods/carts/textures/carts_rail_crossing_dtc.png new file mode 100644 index 00000000..cf04f0ff Binary files /dev/null and b/mods/carts/textures/carts_rail_crossing_dtc.png differ 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 00000000..b6f5b87e Binary files /dev/null and b/mods/carts/textures/carts_rail_crossing_dtc_on.png differ 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 0b103f00..dc317cfb Binary files a/mods/carts/textures/carts_rail_crossing_pwr.png and b/mods/carts/textures/carts_rail_crossing_pwr.png differ diff --git a/mods/carts/textures/carts_rail_crossing_ss.png b/mods/carts/textures/carts_rail_crossing_ss.png new file mode 100644 index 00000000..69ee0706 Binary files /dev/null and b/mods/carts/textures/carts_rail_crossing_ss.png differ 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 0e6cf959..00000000 Binary files a/mods/carts/textures/carts_rail_crossing_tour.png and /dev/null differ diff --git a/mods/carts/textures/carts_rail_curved_brk.png b/mods/carts/textures/carts_rail_curved_brk.png old mode 100755 new mode 100644 index f8756e0e..c55183d5 Binary files a/mods/carts/textures/carts_rail_curved_brk.png and b/mods/carts/textures/carts_rail_curved_brk.png differ 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 00000000..004ef566 Binary files /dev/null and b/mods/carts/textures/carts_rail_curved_cp.png differ 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 00000000..8117c27a Binary files /dev/null and b/mods/carts/textures/carts_rail_curved_dtc.png differ diff --git a/mods/carts/textures/carts_rail_curved_dtc_on.png b/mods/carts/textures/carts_rail_curved_dtc_on.png new file mode 100644 index 00000000..032630f4 Binary files /dev/null and b/mods/carts/textures/carts_rail_curved_dtc_on.png differ diff --git a/mods/carts/textures/carts_rail_curved_pwr.png b/mods/carts/textures/carts_rail_curved_pwr.png old mode 100755 new mode 100644 index 8816131a..4aef5ddf Binary files a/mods/carts/textures/carts_rail_curved_pwr.png and b/mods/carts/textures/carts_rail_curved_pwr.png differ 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 00000000..504e31f1 Binary files /dev/null and b/mods/carts/textures/carts_rail_curved_ss.png differ 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 ef059677..00000000 Binary files a/mods/carts/textures/carts_rail_curved_tour.png and /dev/null differ diff --git a/mods/carts/textures/carts_rail_dtc.png b/mods/carts/textures/carts_rail_dtc.png new file mode 100644 index 00000000..5e2ccef1 Binary files /dev/null and b/mods/carts/textures/carts_rail_dtc.png differ 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 00000000..e81dbe1b Binary files /dev/null and b/mods/carts/textures/carts_rail_dtc_on.png differ diff --git a/mods/carts/textures/carts_rail_pwr.png b/mods/carts/textures/carts_rail_pwr.png old mode 100755 new mode 100644 index 7d44a800..f346a024 Binary files a/mods/carts/textures/carts_rail_pwr.png and b/mods/carts/textures/carts_rail_pwr.png differ diff --git a/mods/carts/textures/carts_rail_ss.png b/mods/carts/textures/carts_rail_ss.png new file mode 100644 index 00000000..489e7fe5 Binary files /dev/null and b/mods/carts/textures/carts_rail_ss.png differ 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 e1cf5595..5689ffe9 Binary files a/mods/carts/textures/carts_rail_t_junction_brk.png and b/mods/carts/textures/carts_rail_t_junction_brk.png differ 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 00000000..3da90943 Binary files /dev/null and b/mods/carts/textures/carts_rail_t_junction_cp.png differ 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 00000000..b154f436 Binary files /dev/null and b/mods/carts/textures/carts_rail_t_junction_dtc.png differ 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 00000000..9fda111b Binary files /dev/null and b/mods/carts/textures/carts_rail_t_junction_dtc_on.png differ 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 0e156cd0..d7edaf1d Binary files a/mods/carts/textures/carts_rail_t_junction_pwr.png and b/mods/carts/textures/carts_rail_t_junction_pwr.png differ 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 00000000..c1a2cb1d Binary files /dev/null and b/mods/carts/textures/carts_rail_t_junction_ss.png differ diff --git a/mods/carts/textures/carts_rail_t_junction_tour.png b/mods/carts/textures/carts_rail_t_junction_tour.png deleted file mode 100755 index c650f29e..00000000 Binary files a/mods/carts/textures/carts_rail_t_junction_tour.png and /dev/null differ diff --git a/mods/carts/textures/carts_rail_tour.png b/mods/carts/textures/carts_rail_tour.png deleted file mode 100755 index 32e51144..00000000 Binary files a/mods/carts/textures/carts_rail_tour.png and /dev/null differ 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 00000000..fe629057 Binary files /dev/null and b/mods/carts/textures/default_rail_t_junction.png differ diff --git a/mods/carts/trash.lua.old b/mods/carts/trash.lua.old deleted file mode 100644 index c778a46a..00000000 --- a/mods/carts/trash.lua.old +++ /dev/null @@ -1,104 +0,0 @@ - --[[local t = tonumber(minetest.get_meta(pos):get_string("cart_touring_velocity")) - if not t then t=0 end - t = 0 - if t>0 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 -})--]]