diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index a80e8ed663..9b4857e292 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -468,32 +468,36 @@ mobs:register_mob("mobs_mc:enderman", { else -- Attempt to randomly teleport enderman local pos = self.object:get_pos() - -- Find all solid nodes below air in a 65×65×65 cuboid centered on the enderman - local nodes = minetest.find_nodes_in_area_under_air(vector.subtract(pos, 32), vector.add(pos, 32), {"group:solid", "group:cracky", "group:crumbly"}) - local telepos - if nodes ~= nil then - if #nodes > 0 then - -- Up to 64 attempts to teleport - for n=1, math.min(64, #nodes) do - local r = pr:next(1, #nodes) - local nodepos = nodes[r] - local node_ok = true - -- Selected node needs to have 3 nodes of free space above - for u=1, 3 do - local node = minetest.get_node({x=nodepos.x, y=nodepos.y+u, z=nodepos.z}) - if minetest.registered_nodes[node.name].walkable then - node_ok = false + -- Up to 8 top-level attempts to teleport + for n=1, 8 do + local node_ok = false + -- We need to add (or subtract) different random numbers to each vector component, so it couldn't be done with a nice single vector.add() or .subtract(): + local randomCube = vector.new( pos.x + 8*(pr:next(0,16)-8), pos.y + 8*(pr:next(0,16)-8), pos.z + 8*(pr:next(0,16)-8) ) + local nodes = minetest.find_nodes_in_area_under_air(vector.subtract(randomCube, 4), vector.add(randomCube, 4), {"group:solid", "group:cracky", "group:crumbly"}) + if nodes ~= nil then + if #nodes > 0 then + -- Up to 8 low-level (in total up to 8*8 = 64) attempts to teleport + for n=1, math.min(8, #nodes) do + local r = pr:next(1, #nodes) + local nodepos = nodes[r] + node_ok = true + for u=1, 3 do + local node = minetest.get_node({x=nodepos.x, y=nodepos.y+u, z=nodepos.z}) + if minetest.registered_nodes[node.name].walkable then + node_ok = false + break + end + end + if node_ok then + self.object:set_pos({x=nodepos.x, y=nodepos.y+1, z=nodepos.z}) break end end - if node_ok then - telepos = {x=nodepos.x, y=nodepos.y+1, z=nodepos.z} - end - end - if telepos then - self.object:set_pos(telepos) end end + if node_ok then + break + end end end end,