Fix animal movement

This commit is contained in:
ElCeejo 2022-07-13 22:01:53 -07:00 committed by GitHub
parent db1c6c84ca
commit 50c56f9d79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 55 additions and 26 deletions

View File

@ -8,16 +8,10 @@ local abs = math.abs
local random = math.random
local ceil = math.ceil
local floor = math.floor
local sin = math.sin
local cos = math.cos
local rad = math.rad
local function average(t)
local sum = 0
for _,v in pairs(t) do -- Get the sum of all numbers in t
sum = sum + v
end
return sum / #t
end
local function clamp(val, min, max)
if val < min then
val = min
@ -36,6 +30,10 @@ local vec_add = vector.add
local vec_multi = vector.multiply
local vec_normal = vector.normalize
local function vec_center(v)
return {x = floor(v.x + 0.5), y = floor(v.y + 0.5), z = floor(v.z + 0.5)}
end
local function vec_raise(v, n)
return {x = v.x, y = v.y + n, z = v.z}
end
@ -51,8 +49,6 @@ local dir2yaw = minetest.dir_to_yaw
-- Tables --
------------
local is_flyable = {}
local is_liquid = {}
local is_solid = {}
minetest.register_on_mods_loaded(function()
@ -97,7 +93,7 @@ local function get_ceiling_positions(pos, range)
z = i_pos.z
}
if minetest.get_node(under).name == "air"
and is_solid[minetest.get_node(i_pos).name] then
and creatura.get_node_def(i_pos).walkable then
table.insert(output, i_pos)
end
end
@ -378,7 +374,7 @@ function animalia.action_latch_to_ceil(self, time, anim)
self:set_action(func)
end
function animalia.action_boid_move(self, pos2, timeout, method)
function animalia.action_boid_move(self, pos2, timeout, method, speed_factor, anim)
local boids = get_boid_members(self.object:get_pos(), 6, self.name, self.texture_no)
local timer = timeout
local goal = pos2
@ -402,10 +398,11 @@ function animalia.action_boid_move(self, pos2, timeout, method)
end
end
if timer <= 0
or self:move_to(goal, method or "animalia:fly_obstacle_avoidance", 1)then
or self:move_to(goal, method or "animalia:fly_obstacle_avoidance", speed_factor or 1) then
self:halt()
return true
end
self:animate(anim or "fly")
end
self:set_action(func)
end
@ -428,10 +425,13 @@ function animalia.action_boid_walk(self, pos2, timeout, method, speed_factor, an
end
end
if timer <= 0
or self:move_to(pos2, method or "creatura:obstacle_avoidance", speed_factor or 1, anim or "walk") then
or not self:is_pos_safe(pos2)
or self:move_to(pos2, method or "creatura:obstacle_avoidance", speed_factor or 1) then
self:halt()
return true
end
self:animate(anim or "walk")
end
self:set_action(func)
end
@ -466,6 +466,35 @@ function animalia.action_horse_spin(self, speed, anim)
self:set_action(func)
end
function animalia.action_pursue(self, target, timeout, method, speed_factor, anim)
local timer = timeout or 4
local goal
local function func(self)
local target_alive, line_of_sight, tgt_pos = self:get_target(target)
if not target_alive then
return true
end
local pos = self.object:get_pos()
if not pos then return end
timer = timer - self.dtime
if timer <= 0 then return true end
if not goal
or (line_of_sight
and vec_dist(goal, tgt_pos) > 3) then
goal = tgt_pos
end
goal.y = creatura.get_ground_level(pos, 3).y
if timer <= 0
or self:move_to(goal, method or "creatura:obstacle_avoidance", speed_factor or 0.5) then
self:halt()
return true
end
self:animate(anim or "walk")
end
self:set_action(func)
end
------------------------
-- Register Utilities --
------------------------
@ -512,7 +541,7 @@ creatura.register_utility("animalia:wander", function(self, group)
if (move
and goal)
or far_from_group then
creatura.action_walk(self, goal, 2, "creatura:neighbors")
creatura.action_walk(self, goal, 2, "creatura:obstacle_avoidance")
else
creatura.action_idle(self, idle_time)
end
@ -561,7 +590,7 @@ creatura.register_utility("animalia:skittish_wander", function(self)
end
if move
and goal then
creatura.action_walk(self, goal, 3, "creatura:neighbors", 0.35)
creatura.action_walk(self, goal, 3, "creatura:obstacle_avoidance", 0.35)
else
creatura.action_idle(self, idle_time)
end
@ -620,7 +649,7 @@ creatura.register_utility("animalia:skittish_boid_wander", function(self)
end
if move
and goal then
animalia.action_boid_walk(self, goal, 6, "creatura:neighbors", 0.35)
animalia.action_boid_walk(self, goal, 6, "creatura:obstacle_avoidance", 0.35)
else
creatura.action_idle(self, idle_time)
end
@ -668,7 +697,7 @@ creatura.register_utility("animalia:boid_wander", function(self, group)
if (move
or far_from_group)
and goal then
animalia.action_boid_walk(self, goal, 6, "creatura:neighbors", 0.35)
animalia.action_boid_walk(self, goal, 2, "creatura:obstacle_avoidance", 0.35)
else
creatura.action_idle(self, idle_time)
end
@ -907,7 +936,7 @@ creatura.register_utility("animalia:boid_flee_from_player", function(self, playe
escape_pos = self.lasso_pos
end
if escape_pos then
animalia.action_boid_walk(self, escape_pos, 6, "creatura:obstacle_avoidance", 1, "run")
animalia.action_boid_walk(self, escape_pos, 6, "creatura:obstacle_avoidance", 1)
end
end
if vec_dist(pos, tpos) > self.tracking_range + (#mobs_in_group or 0) then
@ -953,7 +982,7 @@ creatura.register_utility("animalia:follow_player", function(self, player, force
end
if not self:get_action() then
if dist > self:get_hitbox(self)[4] + 1.5 then
creatura.action_walk(self, tpos, 6, "creatura:pathfind")
animalia.action_pursue(self, player, 6, "creatura:pathfind", 1, "walk")
else
creatura.action_idle(self, 0.1, "stand")
end
@ -1231,7 +1260,7 @@ creatura.register_utility("animalia:aerial_flock", function(self, scale)
if self.in_liquid then
pos2.y = pos.y + 2
end
animalia.action_boid_move(self, pos2, 2)
animalia.action_boid_move(self, pos2, 2, "animalia:fly_obstacle_avoidance", 1)
end
end
self:set_utility(func)
@ -1269,7 +1298,7 @@ creatura.register_utility("animalia:aerial_swarm", function(self, scale)
if dist2ceil < 2 then
pos2.y = pos.y - 1
end
animalia.action_boid_move(self, pos2, 2)
animalia.action_boid_move(self, pos2, 2, "animalia:fly_obstacle_avoidance", 1)
end
end
self:set_utility(func)
@ -1295,7 +1324,7 @@ creatura.register_utility("animalia:land", function(self, scale)
}
pos2.y = pos2.y - (3 * scale)
self:animate("fly")
animalia.action_boid_move(self, pos2, 2, "animalia:fly_path", 1)
animalia.action_boid_move(self, pos2, 2, "creatura:fly_path", 1)
end
end
self:set_utility(func)
@ -1333,7 +1362,7 @@ creatura.register_utility("animalia:schooling", function(self)
local iter = random(#water)
local pos2 = water[iter]
table.remove(water, iter)
animalia.action_boid_move(self, pos2, 2, "animalia:swim_obstacle_avoidance")
animalia.action_boid_move(self, pos2, 2, "animalia:swim_obstacle_avoidance", 1, "swim")
end
end
self:set_utility(func)
@ -1481,7 +1510,7 @@ creatura.register_utility("animalia:return_to_home", function(self)
local pos2 = self.home_position
local dist = vec_dist(pos, pos2)
if dist < 2 then
if is_solid[minetest.get_node(vec_raise(pos, 1)).name] then
if creatura.get_node_def(vec_raise(pos, 1)).walkable then
creatura.action_idle(self, 1, "latch")
self:set_gravity(9.8)
self.object:set_velocity({x = 0, y = 0, z = 0})
@ -1518,7 +1547,7 @@ creatura.register_utility("animalia:find_home", function(self)
elseif dist2ceil < 4 then
pos2.y = pos.y - 1
end
animalia.action_boid_move(self, pos2, 2)
animalia.action_boid_move(self, pos2, 2, "animalia:fly_obstacle_avoidance", 1)
end
if ceiling[iter] then
local pos2 = {