Mobs REDO with pathfinding by rnd
parent
08fb90348d
commit
d8e120eb10
71
api.lua
71
api.lua
|
@ -9,6 +9,9 @@ local disable_blood = minetest.setting_getbool("mobs_disable_blood")
|
|||
local creative = minetest.setting_getbool("creative_mode")
|
||||
local spawn_protected = tonumber(minetest.setting_get("mobs_spawn_protected")) or 1
|
||||
local remove_far = minetest.setting_getbool("remove_far_mobs")
|
||||
-- PATHFINDING settings
|
||||
local stuck_timeout = 5 -- how long before mob gets stuck in place and starts searching
|
||||
local stuck_path_timeout = 15 -- how long will mob follow path before giving up
|
||||
|
||||
-- internal functions
|
||||
|
||||
|
@ -891,6 +894,7 @@ minetest.register_entity(name, {
|
|||
and self.state ~= "attack"
|
||||
and not day_docile(self) then
|
||||
|
||||
-- rnd to do: if stuck then find better way
|
||||
local s = self.object:getpos()
|
||||
local p, sp, dist
|
||||
local player = nil
|
||||
|
@ -1257,7 +1261,7 @@ minetest.register_entity(name, {
|
|||
end
|
||||
|
||||
-- attack routines (explode, dogfight, shoot, dogshoot)
|
||||
elseif self.state == "attack" then
|
||||
elseif self.state == "attack" then -- rnd : to do if cant attack search better way
|
||||
|
||||
-- calculate distance from mob and enemy
|
||||
local s = self.object:getpos()
|
||||
|
@ -1302,7 +1306,7 @@ minetest.register_entity(name, {
|
|||
self.object:setyaw(yaw)
|
||||
end
|
||||
|
||||
if dist > self.reach then
|
||||
if dist > self.reach then
|
||||
|
||||
if not self.v_start then
|
||||
|
||||
|
@ -1385,12 +1389,12 @@ minetest.register_entity(name, {
|
|||
or (self.attack_type == "dogshoot" and dist <= self.reach) then
|
||||
|
||||
if self.fly
|
||||
and dist > self.reach then
|
||||
and dist > self.reach then
|
||||
|
||||
local nod = node_ok(s)
|
||||
local p1 = s
|
||||
local p1 = s
|
||||
local me_y = math.floor(p1.y)
|
||||
local p2 = p
|
||||
local p2 = p
|
||||
local p_y = math.floor(p2.y + 1)
|
||||
local v = self.object:getvelocity()
|
||||
|
||||
|
@ -1433,6 +1437,17 @@ minetest.register_entity(name, {
|
|||
|
||||
end
|
||||
|
||||
-- rnd: new movement direction
|
||||
|
||||
if self.path.stuck and self.path.way then
|
||||
if #self.path.way>50 then self.path.stuck = false return end -- no paths longer than 50
|
||||
local p1 = self.path.way[1]; if not p1 then self.path.stuck = false return end
|
||||
if math.abs(p1.x-s.x)+math.abs(p1.z-s.z)<0.75 then -- reached waypoint, remove it from queue
|
||||
table.remove(self.path.way,1);
|
||||
end
|
||||
p = {x=p1.x,y=p1.y,z=p1.z}; -- set new temporary target
|
||||
end
|
||||
|
||||
local vec = {
|
||||
x = p.x - s.x,
|
||||
y = p.y - s.y,
|
||||
|
@ -1447,22 +1462,51 @@ minetest.register_entity(name, {
|
|||
if p.x > s.x then
|
||||
yaw = yaw + pi
|
||||
end
|
||||
|
||||
self.object:setyaw(yaw)
|
||||
|
||||
self.object:setyaw(yaw) -- rnd: look toward target
|
||||
end
|
||||
|
||||
-- move towards enemy if beyond mob reach
|
||||
if dist > self.reach then
|
||||
|
||||
-- PATH FINDING by rnd
|
||||
local s1 = self.path.lastpos;
|
||||
if math.abs(s1.x-s.x)+math.abs(s1.z-s.z)<2 then -- rnd: almost standing still, to do: insert path finding here
|
||||
self.path.stuck_timer = self.path.stuck_timer+dtime
|
||||
else self.path.stuck_timer = 0;
|
||||
end
|
||||
self.path.lastpos = {x=s.x,y=s.y,z=s.z};
|
||||
if (self.path.stuck_timer>stuck_timeout and not self.path.stuck) or (self.path.stuck_timer>stuck_path_timeout and self.path.stuck) then -- im stuck, search for path
|
||||
self.path.stuck = true;
|
||||
local sheight=self.collisionbox[5]-self.collisionbox[2];
|
||||
s.x=math.floor(s.x+0.5);s.y=math.floor(s.y+0.5)-sheight;s.z=math.floor(s.z+0.5); -- round position to center of node to avoid stuck in walls, also adjust height for player models!
|
||||
--minetest.chat_send_all("stuck at " .. s.x .." " .. s.y .. " " .. s.z .. ", calculating path")
|
||||
local p1 = self.attack:getpos();p1.x=math.floor(p1.x+0.5);p1.y=math.floor(p1.y+0.5);p1.z=math.floor(p1.z+0.5);
|
||||
--minetest.find_path(pos1, pos2, searchdistance, max_jump, max_drop, algorithm)
|
||||
self.path.way = minetest.find_path(s, p1, 16, 2, 6,"A*_noprefetch"); --"A*_noprefetch");
|
||||
if not self.path.way then
|
||||
self.path.stuck=false
|
||||
minetest.sound_play(self.sounds.attack, { -- play sound to acknowledge found way
|
||||
object = self.object,
|
||||
max_hear_distance = self.sounds.distance
|
||||
})
|
||||
--else minetest.chat_send_all("found path with length " .. #self.path.way);
|
||||
end
|
||||
self.path.stuck_timer=0;
|
||||
end
|
||||
-- END PATH FINDING
|
||||
|
||||
-- jump attack
|
||||
if (self.jump
|
||||
and get_velocity(self) <= 0.5
|
||||
and get_velocity(self) <= 0.5
|
||||
and self.object:getvelocity().y == 0)
|
||||
or (self.object:getvelocity().y == 0
|
||||
and self.jump_chance > 0) then
|
||||
|
||||
do_jump(self)
|
||||
end
|
||||
|
||||
|
||||
|
||||
if is_at_cliff(self) then
|
||||
|
||||
|
@ -1498,6 +1542,8 @@ minetest.register_entity(name, {
|
|||
max_hear_distance = self.sounds.distance
|
||||
})
|
||||
end
|
||||
|
||||
self.path.stuck = false; -- rnd: no more stuck
|
||||
|
||||
-- punch player
|
||||
self.attack:punch(self.object, 1.0, {
|
||||
|
@ -1769,6 +1815,15 @@ minetest.register_entity(name, {
|
|||
if self.health == 0 then
|
||||
self.health = math.random (self.hp_min, self.hp_max)
|
||||
end
|
||||
|
||||
-- rnd: pathfinding init
|
||||
|
||||
self.path = {};
|
||||
self.path.way = {};-- path to follow, table of positions
|
||||
self.path.lastpos = {x=0,y=0,z=0};
|
||||
self.path.stuck = false;
|
||||
self.path.stuck_timer = 0; -- if stuck for too long search for path, stuck if v.x, v.z has magnitude smaller than 0.25 for too long
|
||||
|
||||
|
||||
self.object:set_hp(self.health)
|
||||
self.object:set_armor_groups({fleshy = self.armor})
|
||||
|
|
|
@ -32,7 +32,7 @@ mobs:register_mob("mobs:oerkki", {
|
|||
water_damage = 2,
|
||||
lava_damage = 4,
|
||||
light_damage = 1,
|
||||
fear_height = 3,
|
||||
fear_height = 6,
|
||||
animation = {
|
||||
stand_start = 0,
|
||||
stand_end = 23,
|
||||
|
|
|
@ -34,7 +34,7 @@ mobs:register_mob("mobs:pumba", {
|
|||
water_damage = 1,
|
||||
lava_damage = 5,
|
||||
light_damage = 0,
|
||||
fear_height = 2,
|
||||
fear_height = 6,
|
||||
animation = {
|
||||
speed_normal = 15,
|
||||
stand_start = 25,
|
||||
|
|
Loading…
Reference in New Issue