]> git.lizzy.rs Git - dragonfireclient.git/blob - games/devtest/mods/testpathfinder/init.lua
Semi-transparent background for nametags (#10152)
[dragonfireclient.git] / games / devtest / mods / testpathfinder / init.lua
1 local S = minetest.get_translator("testpathfinder")
2
3 -- Config parameters
4
5 -- Maximum direct distance between start and end
6 local MAX_DIRECT_DISTANCE = 64
7 -- Maximum search distance
8 local MAX_SEARCH_DISTANCE = 32
9 -- Maximum permitted jump height
10 local MAX_JUMP = 1
11 -- Maximum permitted drop height
12 local MAX_DROP = 5
13 -- If true, mod won't refuse to run pathfinder even at long distances
14 local IGNORE_MAX_DISTANCE_SAFEGUARD = false
15
16 -- End of config parameters
17
18 local timer = 0
19 local algorithms = {
20         "A*_noprefetch",
21         "A*",
22         "Dijkstra",
23 }
24
25 local function find_path_for_player(player, itemstack)
26         local meta = itemstack:get_meta()
27         if not meta then
28                 return
29         end
30         local x = meta:get_int("pos_x")
31         local y = meta:get_int("pos_y")
32         local z = meta:get_int("pos_z")
33         local algo = meta:get_int("algorithm")
34         if x and y and z then
35                 local pos2 = {x=x, y=y, z=z}
36                 algo = algorithms[algo+1]
37                 local pos1 = vector.round(player:get_pos())
38                 -- Don't bother calling pathfinder for high distance to avoid freezing
39                 if (not IGNORE_MAX_DISTANCE_SAFEGUARD) and (vector.distance(pos1, pos2) > MAX_DIRECT_DISTANCE) then
40                         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))
41                         return
42                 end
43                 local str = S("Path from @1 to @2:",
44                         minetest.pos_to_string(pos1),
45                         minetest.pos_to_string(pos2))
46
47                 minetest.chat_send_player(player:get_player_name(), str)
48                 local time_start = minetest.get_us_time()
49                 local path = minetest.find_path(pos1, pos2, MAX_SEARCH_DISTANCE, MAX_JUMP, MAX_DROP, algo)
50                 local time_end = minetest.get_us_time()
51                 local time_diff = time_end - time_start
52                 str = ""
53                 if not path then
54                         minetest.chat_send_player(player:get_player_name(), S("No path!"))
55                         minetest.chat_send_player(player:get_player_name(), S("Time: @1 ms", time_diff/1000))
56                         return
57                 end
58                 for s=1, #path do
59                         str = str .. minetest.pos_to_string(path[s]) .. "\n"
60                         local t
61                         if s == #path then
62                                 t = "testpathfinder_waypoint_end.png"
63                         elseif s == 1 then
64                                 t = "testpathfinder_waypoint_start.png"
65                         else
66                                 local c = math.floor(((#path-s)/#path)*255)
67                                 t = string.format("testpathfinder_waypoint.png^[multiply:#%02x%02x00", 0xFF-c, c)
68                         end
69                         minetest.add_particle({
70                                 pos = path[s],
71                                 expirationtime = 5 + 0.2 * s,
72                                 playername = player:get_player_name(),
73                                 glow = minetest.LIGHT_MAX,
74                                 texture = t,
75                                 size = 3,
76                         })
77                 end
78                 minetest.chat_send_player(player:get_player_name(), str)
79                 minetest.chat_send_player(player:get_player_name(), S("Path length: @1", #path))
80                 minetest.chat_send_player(player:get_player_name(), S("Time: @1 ms", time_diff/1000))
81         end
82 end
83
84 local function set_destination(itemstack, user, pointed_thing)
85         if not (user and user:is_player()) then
86                 return
87         end
88         local name = user:get_player_name()
89         local obj
90         local meta = itemstack:get_meta()
91         if pointed_thing.type == "node" then
92                 local pos = pointed_thing.above
93                 meta:set_int("pos_x", pos.x)
94                 meta:set_int("pos_y", pos.y)
95                 meta:set_int("pos_z", pos.z)
96                 minetest.chat_send_player(user:get_player_name(), S("Destination set to @1", minetest.pos_to_string(pos)))
97                 return itemstack
98         end
99 end
100
101 local function find_path_or_set_algorithm(itemstack, user, pointed_thing)
102         if not (user and user:is_player()) then
103                 return
104         end
105         local ctrl = user:get_player_control()
106         -- No sneak: Find path
107         if not ctrl.sneak then
108                 find_path_for_player(user, itemstack)
109         else
110         -- Sneak: Set algorithm
111                 local meta = itemstack:get_meta()
112                 local algo = meta:get_int("algorithm")
113                 algo = (algo + 1) % #algorithms
114                 meta:set_int("algorithm", algo)
115                 minetest.chat_send_player(user:get_player_name(), S("Algorithm: @1", algorithms[algo+1]))
116                 return itemstack
117         end
118 end
119
120 -- Punch: Find path
121 -- Sneak+punch: Select pathfinding algorithm
122 -- Place: Select destination node
123 minetest.register_tool("testpathfinder:testpathfinder", {
124         description = S("Pathfinder Tester") .."\n"..
125                 S("Finds path between 2 points") .."\n"..
126                 S("Place on node: Select destination") .."\n"..
127                 S("Punch: Find path from here") .."\n"..
128                 S("Sneak+Punch: Change algorithm"),
129         inventory_image = "testpathfinder_testpathfinder.png",
130         groups = { testtool = 1, disable_repair = 1 },
131         on_use = find_path_or_set_algorithm,
132         on_secondary_use = set_destination,
133         on_place = set_destination,
134 })
135
136