forked from mtcontrib/boost_cart
		
	Pathfinder: Auto-correct position on failure (smoother)
Dynamic pathfinder distance, depending on speed and dtime Replace various deprecated function names
This commit is contained in:
		| @@ -82,8 +82,8 @@ function cart_entity:get_staticdata() | |||||||
| end | end | ||||||
|  |  | ||||||
| function cart_entity:on_punch(puncher, time_from_last_punch, tool_capabilities, direction) | function cart_entity:on_punch(puncher, time_from_last_punch, tool_capabilities, direction) | ||||||
| 	local pos = self.object:getpos() | 	local pos = self.object:get_pos() | ||||||
| 	local vel = self.object:getvelocity() | 	local vel = self.object:get_velocity() | ||||||
| 	if not self.railtype or vector.equals(vel, {x=0, y=0, z=0}) then | 	if not self.railtype or vector.equals(vel, {x=0, y=0, z=0}) then | ||||||
| 		local node = minetest.get_node(pos).name | 		local node = minetest.get_node(pos).name | ||||||
| 		self.railtype = minetest.get_item_group(node, "connect_to_raillike") | 		self.railtype = minetest.get_item_group(node, "connect_to_raillike") | ||||||
| @@ -103,7 +103,7 @@ function cart_entity:on_punch(puncher, time_from_last_punch, tool_capabilities, | |||||||
| 		-- Pick up cart: Drop all attachments | 		-- Pick up cart: Drop all attachments | ||||||
| 		if self.driver then | 		if self.driver then | ||||||
| 			if self.old_pos then | 			if self.old_pos then | ||||||
| 				self.object:setpos(self.old_pos) | 				self.object:set_pos(self.old_pos) | ||||||
| 			end | 			end | ||||||
| 			local player = minetest.get_player_by_name(self.driver) | 			local player = minetest.get_player_by_name(self.driver) | ||||||
| 			boost_cart:manage_attachment(player, nil) | 			boost_cart:manage_attachment(player, nil) | ||||||
| @@ -150,16 +150,16 @@ function cart_entity:on_punch(puncher, time_from_last_punch, tool_capabilities, | |||||||
| end | end | ||||||
|  |  | ||||||
| function cart_entity:on_step(dtime) | function cart_entity:on_step(dtime) | ||||||
| 	local vel = self.object:getvelocity() | 	local vel = self.object:get_velocity() | ||||||
| 	if self.punched then | 	if self.punched then | ||||||
| 		vel = vector.add(vel, self.velocity) | 		vel = vector.add(vel, self.velocity) | ||||||
| 		self.object:setvelocity(vel) | 		self.object:set_velocity(vel) | ||||||
| 		self.old_dir.y = 0 | 		self.old_dir.y = 0 | ||||||
| 	elseif vector.equals(vel, {x=0, y=0, z=0}) then | 	elseif vector.equals(vel, {x=0, y=0, z=0}) then | ||||||
| 		return | 		return | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	local pos = self.object:getpos() | 	local pos = self.object:get_pos() | ||||||
| 	local update = {} | 	local update = {} | ||||||
|  |  | ||||||
| 	if self.old_pos and not self.punched then | 	if self.old_pos and not self.punched then | ||||||
| @@ -181,21 +181,27 @@ function cart_entity:on_step(dtime) | |||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	if self.old_pos then | 	local cart_dir = boost_cart:velocity_to_dir(vel) | ||||||
| 		-- Detection for "skipping" nodes | 	if self.old_pos and vector.equals(cart_dir, self.old_dir) then | ||||||
| 		local found_path = boost_cart:pathfinder( | 		-- Detection for "skipping" nodes (perhaps use average dtime?) | ||||||
| 			pos, self.old_pos, self.old_dir, ctrl, self.old_switch, self.railtype | 		-- It's sophisticated enough to take the acceleration in account | ||||||
|  | 		local acc = self.object:get_acceleration() | ||||||
|  | 		local distance = dtime * (vector.length(vel) + | ||||||
|  | 			0.5 * dtime * vector.length(acc)) | ||||||
|  |  | ||||||
|  | 		local new_pos, new_dir = boost_cart:pathfinder( | ||||||
|  | 			pos, self.old_pos, self.old_dir, distance, ctrl, | ||||||
|  | 			self.old_switch, self.railtype | ||||||
| 		) | 		) | ||||||
|  |  | ||||||
| 		if not found_path then | 		if new_pos then | ||||||
| 			-- No rail found: reset back to the expected position | 			-- No rail found: set to the expected position | ||||||
| 			pos = vector.new(self.old_pos) | 			pos = new_pos | ||||||
| 			update.pos = true | 			update.pos = true | ||||||
|  | 			cart_dir = new_dir | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	local cart_dir = boost_cart:velocity_to_dir(vel) |  | ||||||
|  |  | ||||||
| 	-- dir:         New moving direction of the cart | 	-- dir:         New moving direction of the cart | ||||||
| 	-- switch_keys: Currently pressed L/R key, used to ignore the key on the next rail node | 	-- switch_keys: Currently pressed L/R key, used to ignore the key on the next rail node | ||||||
| 	local dir, switch_keys = boost_cart:get_rail_direction( | 	local dir, switch_keys = boost_cart:get_rail_direction( | ||||||
| @@ -211,7 +217,7 @@ function cart_entity:on_step(dtime) | |||||||
| 	else | 	else | ||||||
| 		-- Direction change detected | 		-- Direction change detected | ||||||
| 		if not vector.equals(dir, self.old_dir) then | 		if not vector.equals(dir, self.old_dir) then | ||||||
| 			vel = vector.multiply(dir, math.abs(vel.x + vel.z)) | 			vel = vector.multiply(dir, vector.length(vel)) | ||||||
| 			update.vel = true | 			update.vel = true | ||||||
| 			if dir.y ~= self.old_dir.y then | 			if dir.y ~= self.old_dir.y then | ||||||
| 				pos = vector.round(pos) | 				pos = vector.round(pos) | ||||||
| @@ -300,8 +306,8 @@ function cart_entity:on_step(dtime) | |||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	self.object:setacceleration(new_acc) | 	self.object:set_acceleration(new_acc) | ||||||
| 	self.old_pos = pos | 	self.old_pos = vector.round(pos) | ||||||
| 	if not vector.equals(dir, {x=0, y=0, z=0}) then | 	if not vector.equals(dir, {x=0, y=0, z=0}) then | ||||||
| 		self.old_dir = dir | 		self.old_dir = dir | ||||||
| 	end | 	end | ||||||
| @@ -336,7 +342,7 @@ function cart_entity:on_step(dtime) | |||||||
| 	elseif self.old_dir.z < 0 then | 	elseif self.old_dir.z < 0 then | ||||||
| 		yaw = 1 | 		yaw = 1 | ||||||
| 	end | 	end | ||||||
| 	self.object:setyaw(yaw * math.pi) | 	self.object:set_yaw(yaw * math.pi) | ||||||
|  |  | ||||||
| 	local anim = {x=0, y=0} | 	local anim = {x=0, y=0} | ||||||
| 	if dir.y == -1 then | 	if dir.y == -1 then | ||||||
| @@ -346,9 +352,9 @@ function cart_entity:on_step(dtime) | |||||||
| 	end | 	end | ||||||
| 	self.object:set_animation(anim, 1, 0) | 	self.object:set_animation(anim, 1, 0) | ||||||
|  |  | ||||||
| 	self.object:setvelocity(vel) | 	self.object:set_velocity(vel) | ||||||
| 	if update.pos then | 	if update.pos then | ||||||
| 		self.object:setpos(pos) | 		self.object:set_pos(pos) | ||||||
| 	end | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
|   | |||||||
| @@ -160,33 +160,37 @@ function boost_cart:get_rail_direction(pos_, dir, ctrl, old_switch, railtype) | |||||||
| 	return {x=0, y=0, z=0} | 	return {x=0, y=0, z=0} | ||||||
| end | end | ||||||
|  |  | ||||||
| function boost_cart:pathfinder(pos_, old_pos, old_dir, ctrl, pf_switch, railtype) | function boost_cart:pathfinder(pos_, old_pos, old_dir, distance, ctrl, | ||||||
| 	if vector.equals(old_pos, pos_) then | 		pf_switch, railtype) | ||||||
| 		return true |  | ||||||
| 	end |  | ||||||
|  |  | ||||||
| 	local pos = vector.round(pos_) | 	local pos = vector.round(pos_) | ||||||
|  | 	if vector.equals(old_pos, pos) then | ||||||
|  | 		return | ||||||
|  | 	end | ||||||
|  |  | ||||||
| 	local pf_pos = vector.round(old_pos) | 	local pf_pos = vector.round(old_pos) | ||||||
| 	local pf_dir = vector.new(old_dir) | 	local pf_dir = vector.new(old_dir) | ||||||
|  | 	distance = math.min(boost_cart.path_distance_max, | ||||||
|  | 		math.floor(distance + 1)) | ||||||
|  |  | ||||||
| 	for i = 1, 3 do | 	for i = 1, distance do | ||||||
| 		pf_dir, pf_switch = boost_cart:get_rail_direction( | 		pf_dir, pf_switch = boost_cart:get_rail_direction( | ||||||
| 			pf_pos, pf_dir, ctrl, pf_switch, railtype) | 			pf_pos, pf_dir, ctrl, pf_switch, railtype) | ||||||
|  |  | ||||||
| 		if vector.equals(pf_dir, {x=0, y=0, z=0}) then | 		if vector.equals(pf_dir, {x=0, y=0, z=0}) then | ||||||
| 			-- No way forwards | 			-- No way forwards | ||||||
| 			return false | 			return pf_pos, pf_dir | ||||||
| 		end | 		end | ||||||
|  |  | ||||||
| 		pf_pos = vector.add(pf_pos, pf_dir) | 		pf_pos = vector.add(pf_pos, pf_dir) | ||||||
|  |  | ||||||
| 		if vector.equals(pf_pos, pos) then | 		if vector.equals(pf_pos, pos) then | ||||||
| 			-- Success! Cart moved on correctly | 			-- Success! Cart moved on correctly | ||||||
| 			return true | 			return | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| 	-- Cart not found | 	-- Not found. Put cart to predicted position | ||||||
| 	return false | 	return pf_pos, pf_dir | ||||||
| end | end | ||||||
|  |  | ||||||
| function boost_cart:boost_rail(pos, amount) | function boost_cart:boost_rail(pos, amount) | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								init.lua
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								init.lua
									
									
									
									
									
								
							| @@ -8,11 +8,17 @@ if not minetest.settings then | |||||||
| 		.. " (Version <= 0.4.15)") | 		.. " (Version <= 0.4.15)") | ||||||
| end | end | ||||||
|  |  | ||||||
|  | local function getNum(setting) | ||||||
|  | 	return tonumber(minetest.settings:get(setting)) | ||||||
|  | end | ||||||
|  |  | ||||||
| -- Maximal speed of the cart in m/s | -- Maximal speed of the cart in m/s | ||||||
| boost_cart.speed_max = tonumber(minetest.settings:get("boost_cart.speed_max")) or 10 | boost_cart.speed_max = getNum("boost_cart.speed_max") or 10 | ||||||
| -- Set to -1 to disable punching the cart from inside | -- Set to -1 to disable punching the cart from inside | ||||||
| boost_cart.punch_speed_max = | boost_cart.punch_speed_max = getNum("boost_cart.punch_speed_max") or 7 | ||||||
| 	tonumber(minetest.settings:get("boost_cart.punch_speed_max")) or 7 | -- Maximal distance for the path correction (for dtime peaks) | ||||||
|  | boost_cart.path_distance_max = 3 | ||||||
|  |  | ||||||
|  |  | ||||||
| -- Support for non-default games | -- Support for non-default games | ||||||
| if not default.player_attached then | if not default.player_attached then | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user