From faea58469f1b01ec9d786491e2ca87405142862f Mon Sep 17 00:00:00 2001 From: Alexander Minges Date: Fri, 1 May 2020 18:18:35 +0200 Subject: [PATCH] refactor code; adjust checks for dangerous blocks --- mods/ENTITIES/mcl_mobs/api.lua | 66 +++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index c027ce16..cb936510 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -300,6 +300,11 @@ 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 @@ -317,7 +322,10 @@ local is_node_dangerous = function(self, nodename) end if minetest.registered_nodes[nn].drowning > 0 then if self.breath_max ~= -1 then - return true + -- 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 end end if minetest.registered_nodes[nn].damage_per_second > 0 then @@ -2013,8 +2021,12 @@ local do_states = function(self, dtime) if (self.water_damage > 0 and self.lava_damage > 0) or self.breath_max ~= -1 then - - lp = minetest.find_node_near(s, 1, {"group:water", "group:lava"}) + -- 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 elseif self.water_damage > 0 then @@ -2032,44 +2044,42 @@ local do_states = function(self, dtime) local is_in_danger = false if lp then - -- if mob is flying, check if it is in its preferred medium - if self.fly then - if minetest.get_item_group(self.standing_in, self.fly_in) then - is_in_danger = false - elseif is_node_dangerous(self, self.standing_in) then + minetest.log(self.name .. ": " .. minetest.get_node(lp).name) + -- 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 + elseif not self.fly and (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 - minetest.log(self.name .. " is in/on dangerous node " .. self.standing_on .. " or " .. self.standing_in) - minetest.log(self.water_damage) + -- minetest.log(self.name .. " is in/on dangerous node " .. self.standing_on .. " or " .. self.standing_in) lp = minetest.find_node_near(s, 5, {"group:solid"}) -- did we find land? 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 - -- 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 + -- minetest.log(self.name .. " found land: " .. nn) + + -- is the chosen destination safe and walkable? 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) and minetest.registered_nodes[nn].walkable then break end + -- 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 local vec = {