diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index cf3913af..4a4a56bb 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -300,11 +300,6 @@ end -- Returns true is node can deal damage to self local is_node_dangerous = function(self, nodename) local nn = nodename - if self.fly then - if not minetest.get_item_group(nn, self.fly_in) then - return true - end - end if self.water_damage > 0 then if minetest.get_item_group(nn, "water") ~= 0 then return true @@ -322,10 +317,7 @@ local is_node_dangerous = function(self, nodename) end if minetest.registered_nodes[nn].drowning > 0 then if self.breath_max ~= -1 then - -- check if the mob is water-breathing _and_ the block is water; only return true if neither is the case - if not self.breathes_in_water and minetest.get_item_group(nn, "water") ~= 0 then - return true - end + return true end end if minetest.registered_nodes[nn].damage_per_second > 0 then @@ -2021,12 +2013,8 @@ local do_states = function(self, dtime) if (self.water_damage > 0 and self.lava_damage > 0) or self.breath_max ~= -1 then - -- water-breathing mobs don't have to avoid water, but air - if self.breathes_in_water then - lp = minetest.find_node_near(s, 1, {"air", "group:lava"}) - else - lp = minetest.find_node_near(s, 1, {"group:water", "group:lava"}) - end + + lp = minetest.find_node_near(s, 1, {"group:water", "group:lava"}) elseif self.water_damage > 0 then @@ -2044,76 +2032,49 @@ local do_states = function(self, dtime) local is_in_danger = false if lp then - -- if mob is flying, only check the block it is inside - if self.fly then - if is_node_dangerous(self, self.standing_in) then - is_in_danger = true - end - elseif is_node_dangerous(self, self.standing_in) or is_node_dangerous(self, self.standing_on) then - is_in_danger = true - end -- If mob in or on dangerous block, look for land - if is_in_danger then - local tab_lp = nil - if self.breathes_in_water and self.fly then - tab_lp = minetest.find_nodes_in_area({x=s.x-1, y=s.y-1, z=s.z-1}, {x=s.x+1, y=s.y+1, z=s.z+1}, {"group:water"}) - elseif minetest.get_item_group(self.standing_in, "water") then - tab_lp = minetest.find_nodes_in_area_under_air({x=s.x-1, y=s.y-self.fear_height, z=s.z-1}, {x=s.x+1, y=s.y-1, z=s.z+1}, {"group:solid"}) - elseif not self.jump then - tab_lp = minetest.find_nodes_in_area_under_air({x=s.x-1, y=s.y-1, z=s.z-1}, {x=s.x+1, y=s.y-1, z=s.z+1}, {"group:solid"}) - else - tab_lp = minetest.find_nodes_in_area_under_air({x=s.x-1, y=s.y-self.fear_height, z=s.z-1}, {x=s.x+1, y=s.y+(self.jump_height - 1), z=s.z+1}, {"group:solid"}) - end + if (is_node_dangerous(self, self.standing_in) or + is_node_dangerous(self, self.standing_on)) then + is_in_danger = true + + lp = minetest.find_node_near(s, 5, {"group:solid"}) -- did we find land? - if #tab_lp >= 1 then - for index, lp in ipairs(tab_lp) do - - local nn = minetest.get_node(lp).name - local node_above_ok = false - - local y_difference = lp.y - s.y - local y_difference_ok = false - - if y_difference <= 0 then - y_difference_ok = true - elseif (y_difference <= self.jump_height) and not minetest.get_item_group(nn, "water") then - y_difference_ok = true - end - - -- is the chosen destination safe and walkable? - if not is_node_dangerous(self, nn) and minetest.registered_nodes[nn].walkable and y_difference_ok then - -- check node at y + 2 above - local lp_above = {x = lp.x, y = lp.y + 1, z = lp.z} - local nn_above = minetest.get_node(lp_above).name - if self.breath_max ~= -1 and self.breathes_in_water and minetest.get_item_group(nn_above, "water") then - -- for water-breathing mobs water is accepted - node_above_ok = true - elseif nn_above == "air" then - -- in any other case there should be air, so the block can be stepped on - node_above_ok = true + if lp then + local nn = minetest.get_node(lp).name + if is_node_dangerous(self, nn) then + -- is the chosen destination safe? Retry if not (max 10 iterations) + local i = 0 + while i < 10 do + if lp then + nn = minetest.get_node(lp).name + minetest.log("Found solid block: " .. nn) + if not is_node_dangerous(self, nn) then break end - - if node_above_ok then - local vec = { - x = lp.x - s.x, - z = lp.z - s.z - } - - yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate - - if lp.x > s.x then yaw = yaw + pi end - - -- look towards land and jump/move in that direction - yaw = set_yaw(self, yaw, 6) - do_jump(self) - set_velocity(self, self.walk_velocity) - break - else - yaw = yaw + random(-0.5, 0.5) + -- look for solid node 5 blocks around the mob's position + elseif i < 5 then + lp = minetest.find_node_near(s, 5, {"group:solid"}) + -- after 5 iterations double search radius + elseif i < 10 then + lp = minetest.find_node_near(s, 10, {"group:solid"}) end + i = i + 1 end end + + local vec = { + x = lp.x - s.x, + z = lp.z - s.z + } + + yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate + + if lp.x > s.x then yaw = yaw + pi end + + -- look towards land and jump/move in that direction + yaw = set_yaw(self, yaw, 6) + do_jump(self) + set_velocity(self, self.walk_velocity) else yaw = yaw + random(-0.5, 0.5) end