Copy upstream's pathfinding out of water, then copy & rework the cliff check into a check for land mobs to avoid water.

This commit is contained in:
MysticTempest 2020-07-31 08:35:40 -05:00
parent 23dc977cec
commit c63c92f597

View File

@ -724,6 +724,42 @@ local is_at_cliff_or_danger = function(self)
end
-- copy the 'mob facing cliff_or_danger check' from above, and rework to avoid water
local is_at_water_danger = function(self)
if not self.object:get_luaentity() then
return false
end
local yaw = self.object:get_yaw()
local dir_x = -sin(yaw) * (self.collisionbox[4] + 0.5)
local dir_z = cos(yaw) * (self.collisionbox[4] + 0.5)
local pos = self.object:get_pos()
local ypos = pos.y + self.collisionbox[2] -- just above floor
local free_fall, blocker = minetest.line_of_sight(
{x = pos.x + dir_x, y = ypos, z = pos.z + dir_z},
{x = pos.x + dir_x, y = ypos - 3, z = pos.z + dir_z})
if free_fall then
return true
else
local bnode = minetest.get_node(blocker)
local waterdanger = is_node_waterhazard(self, bnode.name)
if
waterdanger and (is_node_waterhazard(self, self.standing_in) or is_node_waterhazard(self, self.standing_on)) then
return false
elseif waterdanger and (is_node_waterhazard(self, self.standing_in) or is_node_waterhazard(self, self.standing_on)) == false then
return true
else
local def = minetest.registered_nodes[bnode.name]
return (not def and def.walkable)
end
end
return false
end
-- get node but use fallback for nil or unknown
local node_ok = function(pos, fallback)
@ -2049,40 +2085,40 @@ local do_states = function(self, dtime)
local is_in_danger = false
if lp then
local is_in_danger = false
-- if mob is flying, only check for node it is currently in (no contact with node below)
if flight_check(self) then
is_in_danger = is_node_dangerous(self, self.standing_in)
elseif (is_node_dangerous(self, self.standing_in) or
is_node_dangerous(self, self.standing_on)) or (is_node_waterhazard(self, self.standing_in) or is_node_waterhazard(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
lp = minetest.find_node_near(s, 5, {"group:solid"})
if (is_node_dangerous(self, self.standing_in) or
is_node_dangerous(self, self.standing_on)) or (is_node_waterhazard(self, self.standing_in) or is_node_waterhazard(self, self.standing_on)) and (not self.fly) then
is_in_danger = true
-- did we find land?
if lp then
-- If mob in or on dangerous block, look for land
if is_in_danger then
-- Better way to find shore - copied from upstream
lp = minetest.find_nodes_in_area_under_air(
{x = s.x - 5, y = s.y - 0.5, z = s.z - 5},
{x = s.x + 5, y = s.y + 1, z = s.z + 5},
{"group:solid"})
local vec = {
x = lp.x - s.x,
z = lp.z - s.z
}
lp = #lp > 0 and lp[random(#lp)]
yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate
-- did we find land?
if lp then
if lp.x > s.x then yaw = yaw + pi end
local vec = {
x = lp.x - s.x,
z = lp.z - s.z
}
-- 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
yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate
if lp.x > s.x then yaw = yaw + pi end
-- look towards land and move in that direction
yaw = set_yaw(self, yaw, 6)
set_velocity(self, self.walk_velocity)
end
end
-- A danger is near but mob is not inside
else
@ -3218,8 +3254,6 @@ local mob_step = function(self, dtime)
breed(self)
follow_flop(self)
if do_states(self, dtime) then
return
end
@ -3228,6 +3262,18 @@ local mob_step = function(self, dtime)
runaway_from(self)
if is_at_water_danger(self) and self.state ~= "attack" then
if random(1, 10) <= 6 then
set_velocity(self, 0)
self.state = "stand"
set_animation(self, "stand")
yaw = yaw + random(-0.5, 0.5)
yaw = set_yaw(self, yaw, 8)
end
end
follow_flop(self)
if is_at_cliff_or_danger(self) then
set_velocity(self, 0)
self.state = "stand"