Obstacle Avoidance Optimization

This commit is contained in:
ElCeejo 2022-08-08 15:52:48 -07:00
parent 217ad7615e
commit 3b1085f309
3 changed files with 51 additions and 23 deletions

27
api.lua
View file

@ -35,11 +35,9 @@ end
-- Local API -- -- Local API --
--------------- ---------------
local function is_value_in_table(tbl, val) local function contains_val(tbl, val)
for _, v in pairs(tbl) do for _, v in pairs(tbl) do
if v == val then if v == val then return true end
return true
end
end end
return false return false
end end
@ -382,26 +380,27 @@ end
function creatura.get_nearby_object(self, name, range) function creatura.get_nearby_object(self, name, range)
local objects = minetest.get_objects_inside_radius(self:get_center_pos(), range or self.tracking_range) local objects = minetest.get_objects_inside_radius(self:get_center_pos(), range or self.tracking_range)
for _, object in ipairs(objects) do for _, object in ipairs(objects) do
if creatura.is_alive(object) local ent = creatura.is_alive(ent) and object:get_luaentity()
and not object:is_player() if ent
and object ~= self.object and object ~= self.object
and not object:get_luaentity()._ignore and not ent._ignore
and object:get_luaentity().name == name then and ((type(name) == "table" and contains_val(name, ent.name))
or ent.name == name) then
return object return object
end end
end end
return
end end
function creatura.get_nearby_objects(self, name, range) function creatura.get_nearby_objects(self, name, range)
local objects = minetest.get_objects_inside_radius(self:get_center_pos(), range or self.tracking_range) local objects = minetest.get_objects_inside_radius(self:get_center_pos(), range or self.tracking_range)
local nearby = {} local nearby = {}
for _, object in ipairs(objects) do for _, object in ipairs(objects) do
if creatura.is_alive(object) local ent = creatura.is_alive(ent) and object:get_luaentity()
and not object:is_player() if ent
and object ~= self.object and object ~= self.object
and not object:get_luaentity()._ignore and not ent._ignore
and object:get_luaentity().name == name then and ((type(name) == "table" and contains_val(name, ent.name))
or ent.name == name) then
table.insert(nearby, object) table.insert(nearby, object)
end end
end end
@ -450,7 +449,7 @@ function creatura.basic_punch_func(self, puncher, tflp, tool_caps, dir)
add_wear = not minetest.is_creative_enabled(puncher) add_wear = not minetest.is_creative_enabled(puncher)
end end
if (self.immune_to if (self.immune_to
and is_value_in_table(self.immune_to, tool_name)) then and contains_val(self.immune_to, tool_name)) then
return return
end end
self:apply_knockback(dir, 12) self:apply_knockback(dir, 12)

View file

@ -58,7 +58,7 @@ local function raycast(pos1, pos2, liquid)
end end
end end
local function get_collision(self, yaw) --[[local function get_collision(self, yaw)
local width = self.width local width = self.width
local height = self.height local height = self.height
local total_height = height + self.stepheight local total_height = height + self.stepheight
@ -98,22 +98,50 @@ local function get_collision(self, yaw)
end end
end end
end end
--[[if width > 0.5 return false
and height > 0.5 then end]]
else
local ray = raycast(pos, pos2, true) local function get_collision(self)
local yaw = self.object:get_yaw()
local pos = self.object:get_pos()
if not pos then return end
local width = self.width
local height = self.height
pos.y = pos.y + 0.01
local m_dir = vec_normal(yaw2dir(yaw))
local ahead = vec_add(pos, vec_multi(m_dir, width + 1)) -- 1 node out from edge of box
-- Loop
local pos_x, pos_z = ahead.x, ahead.z
for x = -width, width, width / ceil(width) do
local vec1 = {
x = cos(yaw) * ((pos_x + x) - pos_x) + pos_x,
y = pos.y + height,
z = sin(yaw) * ((pos_x + x) - pos_x) + pos_z
}
local vec2 = {
x = cos(yaw) * ((pos_x + x) - pos_x) + pos_x,
y = pos.y,
z = sin(yaw) * ((pos_x + x) - pos_x) + pos_z
}
local ray = raycast(vec1, vec2, false)
if ray then if ray then
return true, ray.intersection_point local collision = ray.intersection_point
if collision.y - pos.y <= (self.stepheight or 1.1) then
local step = creatura.get_node_def({x = vec1.x, y = vec1.y + 0.5, z = vec1.z})
if step.walkable then
return true, collision
end
end
end end
end]] end
return false return false
end end
local function get_avoidance_dir(self) local function get_avoidance_dir(self)
local pos = self.object:get_pos() local pos = self.object:get_pos()
if not pos then return end if not pos then return end
local collide, col_pos = get_collision(self, self.object:get_yaw()) local _, col_pos = get_collision(self)
if collide then if col_pos then
local vel = self.object:get_velocity() local vel = self.object:get_velocity()
local ahead = vec_add(pos, vec_normal(self.object:get_velocity())) local ahead = vec_add(pos, vec_normal(self.object:get_velocity()))
local avoidance_force = vector.subtract(ahead, col_pos) local avoidance_force = vector.subtract(ahead, col_pos)

View file

@ -154,6 +154,7 @@ function mob:halt()
} }
--self.object:set_velocity({x = 0, y = 0, z = 0}) --self.object:set_velocity({x = 0, y = 0, z = 0})
self._path_data = {} self._path_data = {}
self._tyaw = self.object:get_yaw() or 0
end end
-- Turn to specified yaw -- Turn to specified yaw