mirror of
https://git.minetest.land/MineClone2/MineClone2.git
synced 2024-12-26 11:17:30 +01:00
Merge pull request 'Hostile mobs should lose aggro if they cannot see their target' (#3682) from fix_mobs_aggressive_through_blocks into master
Reviewed-on: https://git.minetest.land/MineClone2/MineClone2/pulls/3682
This commit is contained in:
commit
5507e99582
@ -10,6 +10,8 @@ local stuck_path_timeout = 10 -- how long will mob follow path before giving up
|
|||||||
|
|
||||||
local enable_pathfinding = true
|
local enable_pathfinding = true
|
||||||
|
|
||||||
|
local TIME_TO_FORGET_TARGET = 15
|
||||||
|
|
||||||
local atann = math.atan
|
local atann = math.atan
|
||||||
local function atan(x)
|
local function atan(x)
|
||||||
if not x or x ~= x then
|
if not x or x ~= x then
|
||||||
@ -398,7 +400,8 @@ function mob_class:monster_attack()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- choose closest player to attack
|
-- choose closest player to attack
|
||||||
if dist < min_dist and not attacked_p and self:line_of_sight( sp, p, 2) == true then
|
local line_of_sight = self:line_of_sight( sp, p, 2) == true
|
||||||
|
if dist < min_dist and not attacked_p and line_of_sight then
|
||||||
min_dist = dist
|
min_dist = dist
|
||||||
min_player = player
|
min_player = player
|
||||||
end
|
end
|
||||||
@ -810,6 +813,22 @@ function mob_class:check_aggro(dtime)
|
|||||||
self._check_aggro_timer = self._check_aggro_timer + dtime
|
self._check_aggro_timer = self._check_aggro_timer + dtime
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function clear_aggro(self)
|
||||||
|
self.state = "stand"
|
||||||
|
self:set_velocity( 0)
|
||||||
|
self:set_animation( "stand")
|
||||||
|
|
||||||
|
self.attack = nil
|
||||||
|
self._aggro = nil
|
||||||
|
|
||||||
|
self.v_start = false
|
||||||
|
self.timer = 0
|
||||||
|
self.blinktimer = 0
|
||||||
|
self.path.way = nil
|
||||||
|
end
|
||||||
|
|
||||||
function mob_class:do_states_attack (dtime)
|
function mob_class:do_states_attack (dtime)
|
||||||
local yaw = self.object:get_yaw() or 0
|
local yaw = self.object:get_yaw() or 0
|
||||||
|
|
||||||
@ -823,35 +842,33 @@ function mob_class:do_states_attack (dtime)
|
|||||||
or self.attack:get_hp() <= 0
|
or self.attack:get_hp() <= 0
|
||||||
or (self.attack:is_player() and mcl_mobs.invis[ self.attack:get_player_name() ]) then
|
or (self.attack:is_player() and mcl_mobs.invis[ self.attack:get_player_name() ]) then
|
||||||
|
|
||||||
self.state = "stand"
|
clear_aggro(self)
|
||||||
self:set_velocity( 0)
|
|
||||||
self:set_animation( "stand")
|
|
||||||
|
|
||||||
self.attack = nil
|
|
||||||
self._aggro = nil
|
|
||||||
|
|
||||||
self.v_start = false
|
|
||||||
self.timer = 0
|
|
||||||
self.blinktimer = 0
|
|
||||||
self.path.way = nil
|
|
||||||
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local target_line_of_sight = self:line_of_sight(s, p, 2)
|
||||||
|
if not target_line_of_sight then
|
||||||
|
if self.target_time_lost then
|
||||||
|
local time_since_seen = os.time() - self.target_time_lost
|
||||||
|
if time_since_seen > TIME_TO_FORGET_TARGET then
|
||||||
|
self.target_time_lost = nil
|
||||||
|
clear_aggro(self)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self.target_time_lost = os.time()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self.target_time_lost = nil
|
||||||
|
end
|
||||||
|
|
||||||
-- calculate distance from mob and enemy
|
-- calculate distance from mob and enemy
|
||||||
local dist = vector.distance(p, s)
|
local dist = vector.distance(p, s)
|
||||||
|
|
||||||
if self.attack_type == "explode" then
|
if self.attack_type == "explode" then
|
||||||
|
local vec = { x = p.x - s.x, z = p.z - s.z }
|
||||||
local vec = {
|
|
||||||
x = p.x - s.x,
|
|
||||||
z = p.z - s.z
|
|
||||||
}
|
|
||||||
|
|
||||||
yaw = (atan(vec.z / vec.x) +math.pi/ 2) - self.rotate
|
yaw = (atan(vec.z / vec.x) +math.pi/ 2) - self.rotate
|
||||||
|
|
||||||
if p.x > s.x then yaw = yaw +math.pi end
|
if p.x > s.x then yaw = yaw +math.pi end
|
||||||
|
|
||||||
yaw = self:set_yaw( yaw, 0, dtime)
|
yaw = self:set_yaw( yaw, 0, dtime)
|
||||||
|
|
||||||
local node_break_radius = self.explosion_radius or 1
|
local node_break_radius = self.explosion_radius or 1
|
||||||
@ -859,20 +876,15 @@ function mob_class:do_states_attack (dtime)
|
|||||||
or (node_break_radius * 2)
|
or (node_break_radius * 2)
|
||||||
|
|
||||||
-- start timer when in reach and line of sight
|
-- start timer when in reach and line of sight
|
||||||
if not self.v_start
|
if not self.v_start and dist <= self.reach and target_line_of_sight then
|
||||||
and dist <= self.reach
|
|
||||||
and self:line_of_sight( s, p, 2) then
|
|
||||||
|
|
||||||
self.v_start = true
|
self.v_start = true
|
||||||
self.timer = 0
|
self.timer = 0
|
||||||
self.blinktimer = 0
|
self.blinktimer = 0
|
||||||
self:mob_sound("fuse", nil, false)
|
self:mob_sound("fuse", nil, false)
|
||||||
|
|
||||||
-- stop timer if out of reach or direct line of sight
|
-- stop timer if out of reach or direct line of sight
|
||||||
elseif self.allow_fuse_reset
|
elseif self.allow_fuse_reset and self.v_start
|
||||||
and self.v_start
|
and (dist >= self.explosiontimer_reset_radius or not target_line_of_sight) then
|
||||||
and (dist >= self.explosiontimer_reset_radius
|
|
||||||
or not self:line_of_sight( s, p, 2)) then
|
|
||||||
self.v_start = false
|
self.v_start = false
|
||||||
self.timer = 0
|
self.timer = 0
|
||||||
self.blinktimer = 0
|
self.blinktimer = 0
|
||||||
@ -894,25 +906,20 @@ function mob_class:do_states_attack (dtime)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if self.v_start then
|
if self.v_start then
|
||||||
|
|
||||||
self.timer = self.timer + dtime
|
self.timer = self.timer + dtime
|
||||||
self.blinktimer = (self.blinktimer or 0) + dtime
|
self.blinktimer = (self.blinktimer or 0) + dtime
|
||||||
|
|
||||||
if self.blinktimer > 0.2 then
|
if self.blinktimer > 0.2 then
|
||||||
|
|
||||||
self.blinktimer = 0
|
self.blinktimer = 0
|
||||||
|
|
||||||
if self.blinkstatus then
|
if self.blinkstatus then
|
||||||
self:remove_texture_mod("^[brighten")
|
self:remove_texture_mod("^[brighten")
|
||||||
else
|
else
|
||||||
self:add_texture_mod("^[brighten")
|
self:add_texture_mod("^[brighten")
|
||||||
end
|
end
|
||||||
|
|
||||||
self.blinkstatus = not self.blinkstatus
|
self.blinkstatus = not self.blinkstatus
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.timer > self.explosion_timer then
|
if self.timer > self.explosion_timer then
|
||||||
|
|
||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
|
|
||||||
if mobs_griefing and not minetest.is_protected(pos, "") then
|
if mobs_griefing and not minetest.is_protected(pos, "") then
|
||||||
|
Loading…
Reference in New Issue
Block a user