110 lines
2.8 KiB
Lua
110 lines
2.8 KiB
Lua
-- local PATH_FIND_ALGORITHM = "Dijkstra"
|
|
local PATH_FIND_ALGORITHM = "A*_noprefetch"
|
|
|
|
PyuTest.ENTITY_BLOOD_AMOUNT = 6
|
|
PyuTest.HUMAN_LIKE_CBOX = {-0.25, -1, -0.25, 0.25, 1, 0.25}
|
|
|
|
PyuTest.get_nearest_entity = function (self, pos, range, only_player)
|
|
local closet_distance = math.huge
|
|
local nearest
|
|
|
|
for obj in minetest.objects_inside_radius(pos, range) do
|
|
local dist = vector.distance(pos, obj:get_pos())
|
|
|
|
if dist < closet_distance and obj ~= self then
|
|
if only_player then
|
|
if obj:is_player() then
|
|
closet_distance = dist
|
|
nearest = obj
|
|
end
|
|
else
|
|
closet_distance = dist
|
|
nearest = obj
|
|
end
|
|
end
|
|
end
|
|
|
|
return nearest
|
|
end
|
|
|
|
PyuTest.make_mob = function (name, properties, options)
|
|
local default_options = {
|
|
ai = "dummy",
|
|
max_jump = 1,
|
|
max_drop = 8,
|
|
speed = 3,
|
|
view_range = 3,
|
|
sight_range = 10,
|
|
}
|
|
local cfg = {}
|
|
|
|
for k, v in pairs(options) do
|
|
cfg[k] = v
|
|
end
|
|
|
|
for k, v in pairs(default_options) do
|
|
if cfg[k] == nil then
|
|
cfg[k] = v
|
|
end
|
|
end
|
|
|
|
local collisionbox = properties.collisionbox or PyuTest.HUMAN_LIKE_CBOX
|
|
|
|
minetest.register_entity(name, {
|
|
initial_properties = PyuTest.util.tableconcat(properties, {
|
|
physical = true,
|
|
collide_with_objects = true,
|
|
stepheight = properties.stepheight or 1.1,
|
|
collisionbox = collisionbox,
|
|
selectionbox = properties.selectionbox or collisionbox
|
|
}),
|
|
options = cfg,
|
|
data = {
|
|
target = {
|
|
object = nil,
|
|
position = nil,
|
|
path = nil,
|
|
pathindex = nil
|
|
}
|
|
},
|
|
|
|
on_step = function (self, dtime, moveresult)
|
|
local obj = self.object
|
|
local pos = obj:get_pos()
|
|
local ai = self.options.ai
|
|
local data = self.data
|
|
|
|
if ai == nil or ai == "dummy" then
|
|
return
|
|
end
|
|
|
|
if ai == "follownearest" then
|
|
if data.target.path == nil then
|
|
data.target.object = PyuTest.get_nearest_entity(obj, pos, cfg.sight_range, true)
|
|
|
|
if data.target.object == nil then
|
|
return
|
|
end
|
|
|
|
data.target.position = data.target.object:get_pos()
|
|
data.target.path = minetest.find_path(pos, data.target.position, cfg.view_range, cfg.max_jump, cfg.max_drop, PATH_FIND_ALGORITHM)
|
|
data.target.pathindex = 1
|
|
else
|
|
if data.target.pathindex == #data.target.path then
|
|
data.target.path = nil
|
|
data.target.object = nil
|
|
data.target.position = nil
|
|
data.target.pathindex = nil
|
|
else
|
|
local p = data.target.path[data.target.pathindex]
|
|
-- obj:move_to(p, true)
|
|
obj:move_to(p, true)
|
|
obj:set_yaw(vector.angle(data.target.object:get_pos(), obj:get_pos()))
|
|
data.target.pathindex = data.target.pathindex + 1
|
|
end
|
|
end
|
|
end
|
|
end
|
|
})
|
|
end
|