diff --git a/api.lua b/api.lua index 33873e6..686a04c 100644 --- a/api.lua +++ b/api.lua @@ -25,7 +25,7 @@ local use_cmi = minetest.global_exists("cmi") mobs = { mod = "redo", - version = "20230208", + version = "20230227", intllib = S, invis = minetest.global_exists("invisibility") and invisibility or {} } @@ -85,6 +85,31 @@ local peaceful_player_enabled = settings:get_bool("enable_peaceful_player") local mob_smooth_rotate = settings:get_bool("mob_smooth_rotate") ~= false local active_mobs = 0 +-- pathfinding settings +local pathfinding_enable = settings:get_bool("mob_pathfinding_enable") or true +-- Use pathfinder mod if available +local pathfinder_enable = settings:get_bool("mob_pathfinder_enable") or true +-- how long before stuck mobs start searching +local pathfinding_stuck_timeout = tonumber(settings:get("mob_pathfinding_stuck_timeout")) or 3.0 +-- how long will mob follow path before giving up +local pathfinding_stuck_path_timeout = tonumber(settings:get("mob_pathfinding_stuck_path_timeout")) or 5.0 +-- which algorithm to use, Dijkstra(default) or A*_noprefetch or A* +-- fix settings not allowing "*" +local pathfinding_algorithm = settings:get("mob_pathfinding_algorithm") or "Dijkstra" + +if pathfinding_algorithm == "AStar_noprefetch" then + pathfinding_algorithm = "A*_noprefetch" +elseif pathfinding_algorithm == "AStar" then + pathfinding_algorithm = "A*" +end + +-- max search distance from search positions (default 16) +local pathfinding_searchdistance = tonumber(settings:get("mob_pathfinding_searchdistance") or 16) +-- max jump height (default 4) +local pathfinding_max_jump = tonumber(settings:get("mob_pathfinding_max_jump") or 4) +-- max drop height (default 6) +local pathfinding_max_drop = tonumber(settings:get("mob_pathfinding_max_drop") or 6) + -- Peaceful mode message so players will know there are no monsters if peaceful_only then minetest.register_on_joinplayer(function(player) @@ -96,11 +121,6 @@ end -- calculate aoc range for mob count local aoc_range = tonumber(settings:get("active_block_range")) * 16 --- pathfinding settings -local enable_pathfinding = true -local stuck_timeout = 3 -- how long before stuck mod starts searching -local stuck_path_timeout = 5 -- how long will mob follow path before giving up - -- default nodes --local node_fire = "fire:basic_flame" --local node_permanent_flame = "fire:permanent_flame" @@ -1699,7 +1719,7 @@ function mob_class:smart_mobs(s, p, dist, dtime) end -- can see target! end - if self.path.stuck_timer > stuck_timeout and not self.path.following then + if self.path.stuck_timer > pathfinding_stuck_timeout and not self.path.following then use_pathfind = true self.path.stuck_timer = 0 @@ -1715,7 +1735,7 @@ function mob_class:smart_mobs(s, p, dist, dtime) end, self) end - if self.path.stuck_timer > stuck_path_timeout and self.path.following then + if self.path.stuck_timer > pathfinding_stuck_path_timeout and self.path.following then use_pathfind = true self.path.stuck_timer = 0 @@ -1767,24 +1787,24 @@ function mob_class:smart_mobs(s, p, dist, dtime) p1.y = floor(p1.y + 0.5) p1.z = floor(p1.z + 0.5) - local dropheight = 6 + local dropheight = pathfinding_max_drop if self.fear_height ~= 0 then dropheight = self.fear_height end local jumpheight = 0 - if self.jump and self.jump_height >= 4 then - jumpheight = min(ceil(self.jump_height / 4), 4) + if self.jump and self.jump_height >= pathfinding_max_jump then + jumpheight = min(ceil(self.jump_height / pathfinding_max_jump), pathfinding_max_jump) elseif self.stepheight > 0.5 then jumpheight = 1 end - if pathfinder_mod then + if pathfinder_mod and pathfinder_enable then self.path.way = pathfinder.find_path(s, p1, self, dtime) else - self.path.way = minetest.find_path(s, p1, 16, jumpheight, - dropheight, "Dijkstra") + self.path.way = minetest.find_path(s, p1, pathfinding_searchdistance, jumpheight, + dropheight, pathfinding_algorithm) end --[[ -- show path using particles @@ -1873,7 +1893,7 @@ function mob_class:smart_mobs(s, p, dist, dtime) end -- will try again in 2 second - self.path.stuck_timer = stuck_timeout - 2 + self.path.stuck_timer = pathfinding_stuck_timeout - 2 elseif s.y < p1.y and (not self.fly) then self:do_jump() --add jump to pathfinding @@ -2492,7 +2512,7 @@ function mob_class:do_states(dtime) local pos = self.object:get_pos() - -- dont damage anything if area protected or next to water + -- dont damage anything if area protected or next to waterpathfinding_max_jump if minetest.find_node_near(pos, 1, {"group:water"}) or minetest.is_protected(pos, "") then @@ -2594,7 +2614,7 @@ function mob_class:do_states(dtime) -- path finding by rnd if self.pathfinding -- only if mob has pathfinding enabled - and enable_pathfinding then + and pathfinding_enable then self:smart_mobs(s, p, dist, dtime) end diff --git a/api.txt b/api.txt index 279747f..ce6173f 100644 --- a/api.txt +++ b/api.txt @@ -755,6 +755,15 @@ External Settings for "minetest.conf" mob for obstructions before spawning, otherwise it defaults to checking the height of the mob only. 'mob_smooth_rotate' Enables smooth rotation when mobs turn by default. + 'mob_pathfinding_enable' Enable pathfinding. + 'mob_pathfinder_enable' Use pathfinder mod if available. + 'mob_pathfinding_stuck_timeout' How long before stuck mobs start searching. (default 3.0) + 'mob_pathfinding_stuck_path_timeout' How long will mob follow path before giving up. (default 5.0) + 'mob_pathfinding_algorithm' Which pathfinding algorithm to use Dijkstra (default), A*_noprefetch (AStar_noprefetch) or A* (AStar) + (A* names differ cause Minetest doesn´t allow "*" in settings) + 'mob_pathfinding_searchdistance' max search distance from search positions (default 16) + 'mob_pathfinding_max_jump' max jump height for pathfinding (default 4) + 'mob_pathfinding_max_drop' max drop height for pathfinding (default 6) Players can override the spawn chance for each mob registered by adding a line to their minetest.conf file with a new value, the lower the value the more each diff --git a/settingtypes.txt b/settingtypes.txt index 37bbce9..d912ea1 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -42,3 +42,25 @@ enable_peaceful_player (Mobs do not attack peaceful player without reason) bool # Enable mobs smooth rotation mob_smooth_rotate (Smooth rotation for mobs) bool true + +[Pathfinding] +# Enable pathfinding (default Enabled) +mob_pathfinding_enable (Enable pathfinding) bool true +# Use pathfinder mod if available (default Enabled) +mob_pathfinder_enable (Use pathfinder mod if available) bool true +# How long before stuck mobs starts searching (default 3.0) +mob_pathfinding_stuck_timeout (How long before stuck mobs start searching) float 3.0 +# How long will mob follow path before giving up (default 5.0) +mob_pathfinding_stuck_path_timeout (How long will mob follow path before giving up) float 5.0 +# Which pathfinding algorithm to use +# - Dijkstra (default) +# - A*_noprefetch (AStar_noprefetch) +# - A* (AStar) +# (A* names differ cause Minetest doesn´t allow "*" in settings) +mob_pathfinding_algorithm (pathfinding algorithm) enum Dijkstra Dijkstra,AStar_noprefetch,AStar +# max search distance from search positions (default 16) +mob_pathfinding_searchdistance (path search distance) int 16 +# max jump height for pathfinding (default 4) +mob_pathfinding_max_jump (path max jump height) int 4 +# max drop height for pathfinding (default 6) +mob_pathfinding_max_drop (path max drop height) int 6