forked from VoxeLibre/VoxeLibre
Teach mobs how to not walk into danger ... kinda
This commit is contained in:
parent
61e148ac2e
commit
d923f71c92
|
@ -265,6 +265,35 @@ function mobs:set_animation(self, anim)
|
||||||
set_animation(self, anim)
|
set_animation(self, anim)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Returns true is node can deal damage to self
|
||||||
|
local is_node_dangerous = function(self, nodename)
|
||||||
|
local nn = nodename
|
||||||
|
if self.water_damage > 0 then
|
||||||
|
if minetest.get_item_group(nn, "water") ~= 0 then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if self.lava_damage > 0 then
|
||||||
|
if minetest.get_item_group(nn, "lava") ~= 0 then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if self.fire_damage > 0 then
|
||||||
|
if minetest.get_item_group(nn, "fire") ~= 0 then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if minetest.registered_nodes[nn].drowning > 0 then
|
||||||
|
if self.breath_max ~= -1 then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if minetest.registered_nodes[nn].damage_per_second > 0 then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- check line of sight (BrunoMine)
|
-- check line of sight (BrunoMine)
|
||||||
local line_of_sight = function(self, pos1, pos2, stepsize)
|
local line_of_sight = function(self, pos1, pos2, stepsize)
|
||||||
|
@ -618,8 +647,8 @@ local within_limits = function(pos, radius)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- is mob facing a cliff
|
-- is mob facing a cliff or danger
|
||||||
local is_at_cliff = function(self)
|
local is_at_cliff_or_danger = function(self)
|
||||||
|
|
||||||
if self.fear_height == 0 then -- 0 for no falling protection!
|
if self.fear_height == 0 then -- 0 for no falling protection!
|
||||||
return false
|
return false
|
||||||
|
@ -631,12 +660,20 @@ local is_at_cliff = function(self)
|
||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
local ypos = pos.y + self.collisionbox[2] -- just above floor
|
local ypos = pos.y + self.collisionbox[2] -- just above floor
|
||||||
|
|
||||||
if minetest.line_of_sight(
|
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, z = pos.z + dir_z},
|
||||||
{x = pos.x + dir_x, y = ypos - self.fear_height, z = pos.z + dir_z}
|
{x = pos.x + dir_x, y = ypos - self.fear_height, z = pos.z + dir_z})
|
||||||
, 1) then
|
if free_fall then
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
else
|
||||||
|
local bnode = minetest.get_node(blocker)
|
||||||
|
local danger = is_node_dangerous(self, bnode.name)
|
||||||
|
if danger then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
local def = minetest.registered_nodes[bnode.name]
|
||||||
|
return (not def and def.walkable)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
@ -728,7 +765,7 @@ local do_env_damage = function(self)
|
||||||
local nodef = minetest.registered_nodes[self.standing_in]
|
local nodef = minetest.registered_nodes[self.standing_in]
|
||||||
|
|
||||||
-- rain
|
-- rain
|
||||||
if self.rain_damage and mod_weather then
|
if self.rain_damage > 0 and mod_weather then
|
||||||
if mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) then
|
if mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) then
|
||||||
|
|
||||||
self.health = self.health - self.rain_damage
|
self.health = self.health - self.rain_damage
|
||||||
|
@ -741,7 +778,7 @@ local do_env_damage = function(self)
|
||||||
pos.y = pos.y + 1 -- for particle effect position
|
pos.y = pos.y + 1 -- for particle effect position
|
||||||
|
|
||||||
-- water damage
|
-- water damage
|
||||||
if self.water_damage
|
if self.water_damage > 0
|
||||||
and nodef.groups.water then
|
and nodef.groups.water then
|
||||||
|
|
||||||
if self.water_damage ~= 0 then
|
if self.water_damage ~= 0 then
|
||||||
|
@ -755,7 +792,7 @@ local do_env_damage = function(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- lava damage
|
-- lava damage
|
||||||
elseif self.lava_damage
|
elseif self.lava_damage > 0
|
||||||
and (nodef.groups.lava) then
|
and (nodef.groups.lava) then
|
||||||
|
|
||||||
if self.lava_damage ~= 0 then
|
if self.lava_damage ~= 0 then
|
||||||
|
@ -769,7 +806,7 @@ local do_env_damage = function(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- fire damage
|
-- fire damage
|
||||||
elseif self.fire_damage
|
elseif self.fire_damage > 0
|
||||||
and (nodef.groups.fire) then
|
and (nodef.groups.fire) then
|
||||||
|
|
||||||
if self.fire_damage ~= 0 then
|
if self.fire_damage ~= 0 then
|
||||||
|
@ -1900,7 +1937,7 @@ local do_states = function(self, dtime)
|
||||||
if self.walk_chance ~= 0
|
if self.walk_chance ~= 0
|
||||||
and self.facing_fence ~= true
|
and self.facing_fence ~= true
|
||||||
and random(1, 100) <= self.walk_chance
|
and random(1, 100) <= self.walk_chance
|
||||||
and is_at_cliff(self) == false then
|
and is_at_cliff_or_danger(self) == false then
|
||||||
|
|
||||||
set_velocity(self, self.walk_velocity)
|
set_velocity(self, self.walk_velocity)
|
||||||
self.state = "walk"
|
self.state = "walk"
|
||||||
|
@ -1934,18 +1971,12 @@ local do_states = function(self, dtime)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local is_in_danger = false
|
||||||
if lp then
|
if lp then
|
||||||
local def = minetest.registered_nodes[self.standing_in]
|
|
||||||
local def2 = minetest.registered_nodes[self.standing_on]
|
|
||||||
-- If mob in or on dangerous block, look for land
|
-- If mob in or on dangerous block, look for land
|
||||||
if (self.breath_max ~= -1
|
if (is_node_dangerous(self, self.standing_in) or
|
||||||
and (def.drowning > 0 or def2.drowning > 0))
|
is_node_dangerous(self, self.standing_on)) then
|
||||||
or (self.lava_damage
|
is_in_danger = true
|
||||||
and (def.groups.lava or def2.groups.lava))
|
|
||||||
or (self.water_damage
|
|
||||||
and (def.groups.water or def2.groups.water))
|
|
||||||
or (self.fire_damage
|
|
||||||
and (def.groups.fire or def2.groups.fire)) then
|
|
||||||
|
|
||||||
lp = minetest.find_node_near(s, 5, {"group:solid"})
|
lp = minetest.find_node_near(s, 5, {"group:solid"})
|
||||||
|
|
||||||
|
@ -1988,11 +2019,13 @@ local do_states = function(self, dtime)
|
||||||
yaw = set_yaw(self, yaw, 8)
|
yaw = set_yaw(self, yaw, 8)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- stand for great fall in front
|
-- stand for great fall or danger or fence in front
|
||||||
local temp_is_cliff = is_at_cliff(self)
|
local cliff_or_danger = false
|
||||||
|
if is_in_danger then
|
||||||
|
cliff_or_danger = is_at_cliff_or_danger(self)
|
||||||
|
end
|
||||||
if self.facing_fence == true
|
if self.facing_fence == true
|
||||||
or temp_is_cliff
|
or cliff_or_danger
|
||||||
or random(1, 100) <= 30 then
|
or random(1, 100) <= 30 then
|
||||||
|
|
||||||
set_velocity(self, 0)
|
set_velocity(self, 0)
|
||||||
|
@ -2019,7 +2052,7 @@ local do_states = function(self, dtime)
|
||||||
|
|
||||||
-- stop after 5 seconds or when at cliff
|
-- stop after 5 seconds or when at cliff
|
||||||
if self.runaway_timer > 5
|
if self.runaway_timer > 5
|
||||||
or is_at_cliff(self) then
|
or is_at_cliff_or_danger(self) then
|
||||||
self.runaway_timer = 0
|
self.runaway_timer = 0
|
||||||
set_velocity(self, 0)
|
set_velocity(self, 0)
|
||||||
self.state = "stand"
|
self.state = "stand"
|
||||||
|
@ -2264,7 +2297,7 @@ local do_states = function(self, dtime)
|
||||||
smart_mobs(self, s, p, dist, dtime)
|
smart_mobs(self, s, p, dist, dtime)
|
||||||
end
|
end
|
||||||
|
|
||||||
if is_at_cliff(self) then
|
if is_at_cliff_or_danger(self) then
|
||||||
|
|
||||||
set_velocity(self, 0)
|
set_velocity(self, 0)
|
||||||
set_animation(self, "stand")
|
set_animation(self, "stand")
|
||||||
|
|
Loading…
Reference in New Issue