aboutsummaryrefslogtreecommitdiff
path: root/advtrains/models/advtrains_dtrack_swlst.b3d
diff options
context:
space:
mode:
Diffstat (limited to 'advtrains/models/advtrains_dtrack_swlst.b3d')
0 files changed, 0 insertions, 0 deletions
' href='#n68'>68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
local S = minetest.get_translator("testpathfinder")

-- Config parameters

-- Maximum direct distance between start and end
local MAX_DIRECT_DISTANCE = 64
-- Maximum search distance
local MAX_SEARCH_DISTANCE = 32
-- Maximum permitted jump height
local MAX_JUMP = 1
-- Maximum permitted drop height
local MAX_DROP = 5
-- If true, mod won't refuse to run pathfinder even at long distances
local IGNORE_MAX_DISTANCE_SAFEGUARD = false

-- End of config parameters

local timer = 0
local algorithms = {
	"A*_noprefetch",
	"A*",
	"Dijkstra",
}

local function find_path_for_player(player, itemstack)
	local meta = itemstack:get_meta()
	if not meta then
		return
	end
	local x = meta:get_int("pos_x")
	local y = meta:get_int("pos_y")
	local z = meta:get_int("pos_z")
	local algo = meta:get_int("algorithm")
	if x and y and z then
		local pos2 = {x=x, y=y, z=z}
		algo = algorithms[algo+1]
		local pos1 = vector.round(player:get_pos())
		-- Don't bother calling pathfinder for high distance to avoid freezing
		if (not IGNORE_MAX_DISTANCE_SAFEGUARD) and (vector.distance(pos1, pos2) > MAX_DIRECT_DISTANCE) then
			minetest.chat_send_player(player:get_player_name(), S("Destination too far away! Set a destination (via placing) within a distance of @1 and try again!", MAX_DIRECT_DISTANCE))
			return
		end
		local str = S("Path from @1 to @2:",
			minetest.pos_to_string(pos1),
			minetest.pos_to_string(pos2))

		minetest.chat_send_player(player:get_player_name(), str)
		local time_start = minetest.get_us_time()
		local path = minetest.find_path(pos1, pos2, MAX_SEARCH_DISTANCE, MAX_JUMP, MAX_DROP, algo)
		local time_end = minetest.get_us_time()
		local time_diff = time_end - time_start
		str = ""
		if not path then
			minetest.chat_send_player(player:get_player_name(), S("No path!"))
			minetest.chat_send_player(player:get_player_name(), S("Time: @1 ms", time_diff/1000))
			return
		end
		for s=1, #path do
			str = str .. minetest.pos_to_string(path[s]) .. "\n"
			local t
			if s == #path then
				t = "testpathfinder_waypoint_end.png"
			elseif s == 1 then
				t = "testpathfinder_waypoint_start.png"
			else
				local c = math.floor(((#path-s)/#path)*255)
				t = string.format("testpathfinder_waypoint.png^[multiply:#%02x%02x00", 0xFF-c, c)
			end
			minetest.add_particle({
				pos = path[s],
				expirationtime = 5 + 0.2 * s,
				playername = player:get_player_name(),
				glow = minetest.LIGHT_MAX,
				texture = t,
				size = 3,
			})
		end
		minetest.chat_send_player(player:get_player_name(), str)
		minetest.chat_send_player(player:get_player_name(), S("Path length: @1", #path))
		minetest.chat_send_player(player:get_player_name(), S("Time: @1 ms", time_diff/1000))
	end
end

local function set_destination(itemstack, user, pointed_thing)
	if not (user and user:is_player()) then
		return
	end
	local name = user:get_player_name()
	local obj
	local meta = itemstack:get_meta()
	if pointed_thing.type == "node" then
		local pos = pointed_thing.above
		meta:set_int("pos_x", pos.x)
		meta:set_int("pos_y", pos.y)
		meta:set_int("pos_z", pos.z)
		minetest.chat_send_player(user:get_player_name(), S("Destination set to @1", minetest.pos_to_string(pos)))
		return itemstack
	end
end

local function find_path_or_set_algorithm(itemstack, user, pointed_thing)
	if not (user and user:is_player()) then
		return
	end
	local ctrl = user:get_player_control()
	-- No sneak: Find path
	if not ctrl.sneak then
		find_path_for_player(user, itemstack)
	else
	-- Sneak: Set algorithm
		local meta = itemstack:get_meta()
		local algo = meta:get_int("algorithm")
		algo = (algo + 1) % #algorithms
		meta:set_int("algorithm", algo)
		minetest.chat_send_player(user:get_player_name(), S("Algorithm: @1", algorithms[algo+1]))
		return itemstack
	end
end

-- Punch: Find path
-- Sneak+punch: Select pathfinding algorithm
-- Place: Select destination node
minetest.register_tool("testpathfinder:testpathfinder", {
	description = S("Pathfinder Tester") .."\n"..
		S("Finds path between 2 points") .."\n"..
		S("Place on node: Select destination") .."\n"..
		S("Punch: Find path from here") .."\n"..
		S("Sneak+Punch: Change algorithm"),
	inventory_image = "testpathfinder_testpathfinder.png",
	groups = { testtool = 1, disable_repair = 1 },
	on_use = find_path_or_set_algorithm,
	on_secondary_use = set_destination,
	on_place = set_destination,
})