mirror of
https://codeberg.org/tenplus1/mobs_redo.git
synced 2025-02-03 20:40:23 +01:00
tidy code, stop mob attacking if player isnt seen for 11 seconds
This commit is contained in:
parent
712f7f85fd
commit
ac5486cc58
165
api.lua
165
api.lua
@ -11,7 +11,7 @@ local use_mc2 = minetest.get_modpath("mcl_core")
|
|||||||
-- Global
|
-- Global
|
||||||
mobs = {
|
mobs = {
|
||||||
mod = "redo",
|
mod = "redo",
|
||||||
version = "20231028",
|
version = "20231105",
|
||||||
translate = S,
|
translate = S,
|
||||||
invis = minetest.global_exists("invisibility") and invisibility or {},
|
invis = minetest.global_exists("invisibility") and invisibility or {},
|
||||||
node_snow = minetest.registered_aliases["mapgen_snow"]
|
node_snow = minetest.registered_aliases["mapgen_snow"]
|
||||||
@ -90,7 +90,8 @@ local pathfinder_enable = settings:get_bool("mob_pathfinder_enable") or true
|
|||||||
local pathfinding_stuck_timeout = tonumber(
|
local pathfinding_stuck_timeout = tonumber(
|
||||||
settings:get("mob_pathfinding_stuck_timeout")) or 3.0
|
settings:get("mob_pathfinding_stuck_timeout")) or 3.0
|
||||||
-- how long will mob follow path before giving up
|
-- how long will mob follow path before giving up
|
||||||
local pathfinding_stuck_path_timeout = tonumber(settings:get("mob_pathfinding_stuck_path_timeout")) or 5.0
|
local pathfinding_stuck_path_timeout = tonumber(
|
||||||
|
settings:get("mob_pathfinding_stuck_path_timeout")) or 5.0
|
||||||
-- which algorithm to use, Dijkstra(default) or A*_noprefetch or A*
|
-- which algorithm to use, Dijkstra(default) or A*_noprefetch or A*
|
||||||
-- fix settings not allowing "*"
|
-- fix settings not allowing "*"
|
||||||
local pathfinding_algorithm = settings:get("mob_pathfinding_algorithm") or "Dijkstra"
|
local pathfinding_algorithm = settings:get("mob_pathfinding_algorithm") or "Dijkstra"
|
||||||
@ -199,7 +200,7 @@ local mob_class_meta = {__index = mob_class}
|
|||||||
-- play sound
|
-- play sound
|
||||||
function mob_class:mob_sound(sound)
|
function mob_class:mob_sound(sound)
|
||||||
|
|
||||||
if sound then
|
if not sound then return end
|
||||||
|
|
||||||
-- higher pitch for a child
|
-- higher pitch for a child
|
||||||
local pitch = self.child and 1.5 or 1.0
|
local pitch = self.child and 1.5 or 1.0
|
||||||
@ -213,7 +214,6 @@ function mob_class:mob_sound(sound)
|
|||||||
max_hear_distance = (self.sounds and self.sounds.distance) or 10,
|
max_hear_distance = (self.sounds and self.sounds.distance) or 10,
|
||||||
pitch = pitch
|
pitch = pitch
|
||||||
}, true)
|
}, true)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -450,75 +450,8 @@ function mobs:set_animation(entity, anim)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- check line of sight (BrunoMine)
|
|
||||||
local function line_of_sight(self, pos1, pos2, stepsize)
|
|
||||||
|
|
||||||
stepsize = stepsize or 1
|
|
||||||
|
|
||||||
local s = minetest.line_of_sight(pos1, pos2, stepsize)
|
|
||||||
|
|
||||||
-- normal walking and flying mobs can see you through air
|
|
||||||
if s == true then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
-- New pos1 to be analyzed
|
|
||||||
local npos1 = {x = pos1.x, y = pos1.y, z = pos1.z}
|
|
||||||
|
|
||||||
local r, pos = minetest.line_of_sight(npos1, pos2, stepsize)
|
|
||||||
|
|
||||||
-- Checks the return
|
|
||||||
if r == true then return true end
|
|
||||||
|
|
||||||
-- Nodename found
|
|
||||||
local nn = minetest.get_node(pos).name
|
|
||||||
|
|
||||||
-- Target Distance (td) to travel
|
|
||||||
local td = get_distance(pos1, pos2)
|
|
||||||
|
|
||||||
-- Actual Distance (ad) traveled
|
|
||||||
local ad = 0
|
|
||||||
|
|
||||||
-- It continues to advance in the line of sight in search of a real
|
|
||||||
-- obstruction which counts as 'walkable' nodebox.
|
|
||||||
while minetest.registered_nodes[nn]
|
|
||||||
and minetest.registered_nodes[nn].walkable == false do
|
|
||||||
|
|
||||||
-- Check if you can still move forward
|
|
||||||
if td < ad + stepsize then
|
|
||||||
return true -- Reached the target
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Moves the analyzed pos
|
|
||||||
local d = get_distance(pos1, pos2)
|
|
||||||
|
|
||||||
npos1.x = ((pos2.x - pos1.x) / d * stepsize) + pos1.x
|
|
||||||
npos1.y = ((pos2.y - pos1.y) / d * stepsize) + pos1.y
|
|
||||||
npos1.z = ((pos2.z - pos1.z) / d * stepsize) + pos1.z
|
|
||||||
|
|
||||||
-- NaN checks
|
|
||||||
if d == 0
|
|
||||||
or npos1.x ~= npos1.x or npos1.y ~= npos1.y or npos1.z ~= npos1.z then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
ad = ad + stepsize
|
|
||||||
|
|
||||||
-- scan again
|
|
||||||
r, pos = minetest.line_of_sight(npos1, pos2, stepsize)
|
|
||||||
|
|
||||||
if r == true then return true end
|
|
||||||
|
|
||||||
-- New Nodename found
|
|
||||||
nn = minetest.get_node(pos).name
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- check line of sight using raycasting (thanks Astrobe)
|
-- check line of sight using raycasting (thanks Astrobe)
|
||||||
local function ray_line_of_sight(self, pos1, pos2)
|
function mob_class:line_of_sight(pos1, pos2)
|
||||||
|
|
||||||
local ray = minetest.raycast(pos1, pos2, true, false)
|
local ray = minetest.raycast(pos1, pos2, true, false)
|
||||||
local thing = ray:next()
|
local thing = ray:next()
|
||||||
@ -541,19 +474,9 @@ local function ray_line_of_sight(self, pos1, pos2)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function mob_class:line_of_sight(pos1, pos2, stepsize)
|
|
||||||
|
|
||||||
if minetest.raycast then -- only use if minetest 5.0 is detected
|
|
||||||
return ray_line_of_sight(self, pos1, pos2)
|
|
||||||
end
|
|
||||||
|
|
||||||
return line_of_sight(self, pos1, pos2, stepsize)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- global function [deprecated]
|
-- global function [deprecated]
|
||||||
function mobs:line_of_sight(entity, pos1, pos2, stepsize)
|
function mobs:line_of_sight(entity, pos1, pos2)
|
||||||
return entity:line_of_sight(pos1, pos2, stepsize)
|
return entity:line_of_sight(pos1, pos2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -715,7 +638,6 @@ end
|
|||||||
|
|
||||||
|
|
||||||
-- Thanks Wuzzy for the editable settings
|
-- Thanks Wuzzy for the editable settings
|
||||||
|
|
||||||
local HORNY_TIME = 30
|
local HORNY_TIME = 30
|
||||||
local HORNY_AGAIN_TIME = 60 * 5 -- 5 minutes
|
local HORNY_AGAIN_TIME = 60 * 5 -- 5 minutes
|
||||||
local CHILD_GROW_TIME = 60 * 20 -- 20 minutes
|
local CHILD_GROW_TIME = 60 * 20 -- 20 minutes
|
||||||
@ -1017,7 +939,7 @@ function mobs:node_ok(pos, fallback)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Returns true is node can deal damage to self
|
-- Returns true if node can deal damage to self
|
||||||
function mobs:is_node_dangerous(mob_object, nodename)
|
function mobs:is_node_dangerous(mob_object, nodename)
|
||||||
|
|
||||||
if mob_object.water_damage > 0
|
if mob_object.water_damage > 0
|
||||||
@ -1134,7 +1056,7 @@ function mob_class:do_env_damage()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- lava damage
|
-- lava damage
|
||||||
elseif self.lava_damage ~= 0 and self:is_inside("group:lava") then -- nodef.groups.lava then
|
elseif self.lava_damage ~= 0 and self:is_inside("group:lava") then
|
||||||
|
|
||||||
self.health = self.health - self.lava_damage
|
self.health = self.health - self.lava_damage
|
||||||
|
|
||||||
@ -1146,7 +1068,7 @@ function mob_class:do_env_damage()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- fire damage
|
-- fire damage
|
||||||
elseif self.fire_damage ~= 0 and self:is_inside("group:fire") then -- nodef.groups.fire then
|
elseif self.fire_damage ~= 0 and self:is_inside("group:fire") then
|
||||||
|
|
||||||
self.health = self.health - self.fire_damage
|
self.health = self.health - self.fire_damage
|
||||||
|
|
||||||
@ -1221,7 +1143,7 @@ function mob_class:do_env_damage()
|
|||||||
if self.suffocation == true then
|
if self.suffocation == true then
|
||||||
damage = 2
|
damage = 2
|
||||||
else
|
else
|
||||||
damage = (self.suffocation or 2)
|
damage = self.suffocation
|
||||||
end
|
end
|
||||||
|
|
||||||
self.health = self.health - damage
|
self.health = self.health - damage
|
||||||
@ -1331,9 +1253,7 @@ local function entity_physics(pos, radius)
|
|||||||
|
|
||||||
obj_pos = objs[n]:get_pos()
|
obj_pos = objs[n]:get_pos()
|
||||||
|
|
||||||
dist = get_distance(pos, obj_pos)
|
dist = max(1, get_distance(pos, obj_pos))
|
||||||
|
|
||||||
if dist < 1 then dist = 1 end
|
|
||||||
|
|
||||||
local damage = floor((4 / dist) * radius)
|
local damage = floor((4 / dist) * radius)
|
||||||
|
|
||||||
@ -2001,7 +1921,7 @@ function mob_class:general_attack()
|
|||||||
-- choose closest player to attack that isnt self
|
-- choose closest player to attack that isnt self
|
||||||
if dist ~= 0
|
if dist ~= 0
|
||||||
and dist < min_dist
|
and dist < min_dist
|
||||||
and self:line_of_sight(sp, p, 2) == true
|
and self:line_of_sight(sp, p) == true
|
||||||
and not is_peaceful_player(player) then
|
and not is_peaceful_player(player) then
|
||||||
min_dist = dist
|
min_dist = dist
|
||||||
min_player = player
|
min_player = player
|
||||||
@ -2037,7 +1957,6 @@ function mob_class:do_runaway_from()
|
|||||||
|
|
||||||
if is_invisible(self, pname)
|
if is_invisible(self, pname)
|
||||||
or self.owner == pname then
|
or self.owner == pname then
|
||||||
|
|
||||||
name = ""
|
name = ""
|
||||||
else
|
else
|
||||||
player = objs[n]
|
player = objs[n]
|
||||||
@ -2066,7 +1985,7 @@ function mob_class:do_runaway_from()
|
|||||||
dist = get_distance(p, s)
|
dist = get_distance(p, s)
|
||||||
|
|
||||||
-- choose closest player/mob to runaway from
|
-- choose closest player/mob to runaway from
|
||||||
if dist < min_dist and self:line_of_sight(sp, p, 2) == true then
|
if dist < min_dist and self:line_of_sight(sp, p) == true then
|
||||||
min_dist = dist
|
min_dist = dist
|
||||||
min_player = player
|
min_player = player
|
||||||
end
|
end
|
||||||
@ -2238,6 +2157,21 @@ function mob_class:dogswitch(dtime)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- stop attack
|
||||||
|
function mob_class:stop_attack()
|
||||||
|
|
||||||
|
self.attack = nil
|
||||||
|
self.following = nil
|
||||||
|
self.v_start = false
|
||||||
|
self.timer = 0
|
||||||
|
self.blinktimer = 0
|
||||||
|
self.path.way = nil
|
||||||
|
self:set_velocity(0)
|
||||||
|
self.state = "stand"
|
||||||
|
self:set_animation("stand", true)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- execute current state (stand, walk, run, attacks)
|
-- execute current state (stand, walk, run, attacks)
|
||||||
function mob_class:do_states(dtime)
|
function mob_class:do_states(dtime)
|
||||||
|
|
||||||
@ -2415,19 +2349,28 @@ function mob_class:do_states(dtime)
|
|||||||
|
|
||||||
--print(" ** stop attacking **", self.name, self.health, dist, self.view_range)
|
--print(" ** stop attacking **", self.name, self.health, dist, self.view_range)
|
||||||
|
|
||||||
self.attack = nil
|
self:stop_attack()
|
||||||
self.following = nil
|
|
||||||
self.v_start = false
|
|
||||||
self.timer = 0
|
|
||||||
self.blinktimer = 0
|
|
||||||
self.path.way = nil
|
|
||||||
self:set_velocity(0)
|
|
||||||
self.state = "stand"
|
|
||||||
self:set_animation("stand", true)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- check enemy is in sight
|
||||||
|
local in_sight = self:line_of_sight(
|
||||||
|
{x = s.x, y = s.y + 0.5, z = s.z},
|
||||||
|
{x = p.x, y = p.y + 0.5, z = p.z})
|
||||||
|
|
||||||
|
-- stop attacking when enemy not seen for 11 seconds
|
||||||
|
if not in_sight then
|
||||||
|
|
||||||
|
self.target_time_lost = (self.target_time_lost or 0) + dtime
|
||||||
|
|
||||||
|
if self.target_time_lost > 11 then
|
||||||
|
self:stop_attack()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self.target_time_lost = 0
|
||||||
|
end
|
||||||
|
|
||||||
if self.attack_type == "explode" then
|
if self.attack_type == "explode" then
|
||||||
|
|
||||||
self:yaw_to_pos(p)
|
self:yaw_to_pos(p)
|
||||||
@ -2442,7 +2385,7 @@ function mob_class:do_states(dtime)
|
|||||||
-- 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 dist <= self.reach
|
||||||
and self:line_of_sight(s, p, 2) then
|
and in_sight then
|
||||||
|
|
||||||
self.v_start = true
|
self.v_start = true
|
||||||
self.timer = 0
|
self.timer = 0
|
||||||
@ -2454,7 +2397,7 @@ function mob_class:do_states(dtime)
|
|||||||
-- 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.reach or not self:line_of_sight(s, p, 2)) then
|
and (dist > self.reach or not in_sight) then
|
||||||
|
|
||||||
--print("=== explosion timer stopped")
|
--print("=== explosion timer stopped")
|
||||||
|
|
||||||
@ -2502,10 +2445,9 @@ function mob_class:do_states(dtime)
|
|||||||
|
|
||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
|
|
||||||
-- dont damage anything if area protected or next to waterpathfinding_max_jump
|
-- dont damage anything if area protected or next to water
|
||||||
if minetest.find_node_near(pos, 1, {"group:water"})
|
if minetest.find_node_near(pos, 1, {"group:water"})
|
||||||
or minetest.is_protected(pos, "") then
|
or minetest.is_protected(pos, "") then
|
||||||
|
|
||||||
node_break_radius = 1
|
node_break_radius = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -3521,7 +3463,6 @@ function mob_class:on_step(dtime, moveresult)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- attack timer
|
|
||||||
self.timer = self.timer + dtime
|
self.timer = self.timer + dtime
|
||||||
|
|
||||||
-- never go over 100
|
-- never go over 100
|
||||||
@ -4156,7 +4097,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- compatibility with older mob registration
|
-- compatibility with older mob registration [DEPRECATED]
|
||||||
function mobs:register_spawn(name, nodes, max_light, min_light, chance,
|
function mobs:register_spawn(name, nodes, max_light, min_light, chance,
|
||||||
active_object_count, max_height, day_toggle)
|
active_object_count, max_height, day_toggle)
|
||||||
|
|
||||||
@ -4202,7 +4143,8 @@ function mobs:register_arrow(name, def)
|
|||||||
textures = def.textures,
|
textures = def.textures,
|
||||||
collisionbox = def.collisionbox or {-.1, -.1, -.1, .1, .1, .1},
|
collisionbox = def.collisionbox or {-.1, -.1, -.1, .1, .1, .1},
|
||||||
glow = def.glow,
|
glow = def.glow,
|
||||||
automatic_face_movement_dir = def.rotate and (def.rotate - (pi / 180)) or false,
|
automatic_face_movement_dir = def.rotate
|
||||||
|
and (def.rotate - (pi / 180)) or false,
|
||||||
},
|
},
|
||||||
|
|
||||||
velocity = def.velocity,
|
velocity = def.velocity,
|
||||||
@ -4364,7 +4306,6 @@ end
|
|||||||
|
|
||||||
|
|
||||||
-- Register spawn eggs
|
-- Register spawn eggs
|
||||||
|
|
||||||
-- Note: This also introduces the “spawn_egg” group:
|
-- Note: This also introduces the “spawn_egg” group:
|
||||||
-- * spawn_egg=1: Spawn egg (generic mob, no metadata)
|
-- * spawn_egg=1: Spawn egg (generic mob, no metadata)
|
||||||
-- * spawn_egg=2: Spawn egg (captured/tamed mob, metadata)
|
-- * spawn_egg=2: Spawn egg (captured/tamed mob, metadata)
|
||||||
|
3
api.txt
3
api.txt
@ -395,13 +395,14 @@ another mod entirely, replace mob_class with the mob entity variable:
|
|||||||
|
|
||||||
mob_class:mob_sound(sound) -- play sound at mob position
|
mob_class:mob_sound(sound) -- play sound at mob position
|
||||||
mob_class:do_attack(player) -- if not already attacking, attack object given
|
mob_class:do_attack(player) -- if not already attacking, attack object given
|
||||||
|
mob_class:stop_attack() -- stops mob attacking
|
||||||
mob_class:collision() -- checks for player collision with mob and returns {x, z} vector
|
mob_class:collision() -- checks for player collision with mob and returns {x, z} vector
|
||||||
mob_class:set_velocity(velocity) -- move at velocity in the facing direction
|
mob_class:set_velocity(velocity) -- move at velocity in the facing direction
|
||||||
mob_class:get_velocity() -- returns mob speed value
|
mob_class:get_velocity() -- returns mob speed value
|
||||||
mob_class:set_yaw(yaw, delay) -- change mob yaw, delay is for smooth rotation (default:0)
|
mob_class:set_yaw(yaw, delay) -- change mob yaw, delay is for smooth rotation (default:0)
|
||||||
mob_class:yaw_to_pos(pos, delay) -- rotates mod to look at position and returns new yaw
|
mob_class:yaw_to_pos(pos, delay) -- rotates mod to look at position and returns new yaw
|
||||||
mob_class:set_animation(animation, force) -- set mob animation
|
mob_class:set_animation(animation, force) -- set mob animation
|
||||||
mob_class:line_of_sight(pos1, pos2, stepsize) -- internal line of sight function
|
mob_class:line_of_sight(pos1, pos2) -- internal line of sight function
|
||||||
mob_class:attempt_flight_correction(override) -- check for stuck flying mobs and fix
|
mob_class:attempt_flight_correction(override) -- check for stuck flying mobs and fix
|
||||||
mob_class:update_tag(newname) -- update nametag or give new name
|
mob_class:update_tag(newname) -- update nametag or give new name
|
||||||
mob_class:do_jump() -- check if mob can jump then jump
|
mob_class:do_jump() -- check if mob can jump then jump
|
||||||
|
Loading…
Reference in New Issue
Block a user