Clean up hostile mob following behavior

This commit is contained in:
Wuzzy 2024-03-21 14:54:14 +01:00
parent 26a6ae911d
commit b05944e4b6
3 changed files with 51 additions and 29 deletions

View File

@ -51,35 +51,48 @@ Parameters:
Finish condition: If the time runs out (if set with `max_timer`), otherwise does not finish
on its own.
### `rp_mobs.microtasks.walk_straight(walk_speed, yaw, jump, max_timer)`
### `rp_mobs.microtasks.walk_straight(walk_speed, yaw, jump, jump_clear_height, stop_at_object_collision, max_timer)`
Walk in a straight line, jumping if hitting obstacle and `jump~=nil`.
Walk in a straight horizontal line (on the XZ plane), will jump if hitting a node obstacle and `jump~=nil`.
It's recommended the mob is subject to gravity.
Parameters:
* `walk_speed`: How fast to walk
* `yaw`: walk direction in radians
* `jump`: jump strength if mob needs to jump or nil if no jumping
* `jump_clear_height`: how many nodes to jump up at most
* `stop_at_object_collision`: stop walking if colliding with object
* `max_timer`: automatically finish microtask after this many seconds (nil = infinite)
Finish condition: If the time runs out (if set with `max_timer`), otherwise does not finish
on its own.
Finish condition: If the time runs out (if set with `max_timer`) or collides with
and object if `stop_at_object_collision` is true.
### `rp_mobs.microtasks.walk_straight_towards(walk_speed, target_type, target, set_yaw, reach_distance, jump, max_timer)`
### `rp_mobs.microtasks.walk_straight_towards(walk_speed, target_type, target, set_yaw, reach_distance, jump, jump_clear_height, stop_at_reached, stop_at_object_collision, max_timer)`
Walk in a straight line towards a position or object.
Walk in a straight horizontal line (on the XZ plane) towards a position or object,
will jump if hitting node obstacle and `jump~=nil`.
It's recommended the mob is subject to gravity.
Parameters:
* `walk_speed`: walk speed
* `walk_speed`: How fast to walk
* `target_type`: "pos" (position) or "object"
* `target`: target, depending on `target_type`: position or object handle
* `set_yaw`: If true, will set mob's yaw to face target
* `reach_distance`: If mob is within this distance towards target, finish task
* `reach_distance`: If mob is within this distance towards target, stop walking. If `nil`, has no effect
* `jump`: jump strength if mob needs to jump or nil if no jumping
* `jump_clear_height`: how many nodes to jump up at most
* `stop_at_reached`: stop walking and finish if within `reach_distance` of target
* `stop_at_object_collision`: stop walking and finish if colliding with object
* `max_timer`: automatically finish microtask after this many seconds (nil = infinite)
Finish condition: If the target is within `reach_distance` of the mob. Otherwise, when
the time runs out (if `max_timer` was set)
Finish condition: If any of the following is true:
* When the time runs out (if `max_timer` was set)
* Target is within `reach_distance` of the mob and `stop_at_reached` is true
* When colliding with object if `stop_at_object_collision` is true
### `rp_mobs.microtasks.set_yaw(yaw)`

View File

@ -222,7 +222,7 @@ local can_clear_jump = function(mob, jump_clear_height)
return false
end
rp_mobs.microtasks.walk_straight = function(walk_speed, yaw, jump, jump_clear_height, max_timer)
rp_mobs.microtasks.walk_straight = function(walk_speed, yaw, jump, jump_clear_height, stop_at_object_collision, max_timer)
local label
if max_timer then
label = "walk straight for "..string.format("%.1f", max_timer).."s"
@ -256,7 +256,7 @@ rp_mobs.microtasks.walk_straight = function(walk_speed, yaw, jump, jump_clear_he
end
end
local wall_collision, wall_collision_data = collides_with_wall(moveresult, true)
if wall_collision and wall_collision_data.type == "object" then
if stop_at_object_collision and wall_collision and wall_collision_data.type == "object" then
self.statedata.stop = true
vel.x = 0
vel.z = 0
@ -319,7 +319,7 @@ rp_mobs.microtasks.walk_straight = function(walk_speed, yaw, jump, jump_clear_he
})
end
rp_mobs.microtasks.walk_straight_towards = function(walk_speed, target_type, target, set_yaw, reach_distance, jump, jump_clear_height, max_timer)
rp_mobs.microtasks.walk_straight_towards = function(walk_speed, target_type, target, set_yaw, reach_distance, jump, jump_clear_height, stop_at_reached, stop_at_object_collision, max_timer)
local label
if max_timer then
label = "walk towards something for "..string.format("%.1f", max_timer).."s"
@ -353,7 +353,7 @@ rp_mobs.microtasks.walk_straight_towards = function(walk_speed, target_type, tar
end
end
local wall_collision, wall_collision_data = collides_with_wall(moveresult, true)
if wall_collision and wall_collision_data.type == "object" then
if stop_at_object_collision and wall_collision and wall_collision_data.type == "object" then
self.statedata.stop = true
vel.x = 0
vel.z = 0
@ -363,11 +363,12 @@ rp_mobs.microtasks.walk_straight_towards = function(walk_speed, target_type, tar
-- Get target position
local mypos = mob.object:get_pos()
local dir
local dir, tpos
if target_type == "pos" then
tpos = target
dir = vector.direction(mypos, target)
elseif target_type == "object" then
local tpos = target:get_pos()
tpos = target:get_pos()
dir = vector.direction(mypos, tpos)
else
self.statedata.stop = true
@ -380,8 +381,19 @@ rp_mobs.microtasks.walk_straight_towards = function(walk_speed, target_type, tar
mob.object:set_yaw(yaw)
end
-- Jump
if jump and not self.statedata.jumping and moveresult.touching_ground and wall_collision then
-- Stop walking if within reach_distance
if reach_distance and vector.distance(mypos, tpos) <= reach_distance then
vel.x = 0
vel.z = 0
mob.object:set_velocity(vel)
if stop_at_reached then
self.statedata.stop = true
end
return
end
-- Jump over nodes (but not objects)
if jump and not self.statedata.jumping and moveresult.touching_ground and wall_collision and wall_collision_data.type == "node" then
local can_jump = true
-- Can't jump if standing on a disable_jump node
if mob._env_node_floor then
@ -449,11 +461,7 @@ rp_mobs.microtasks.walk_straight_towards = function(walk_speed, target_type, tar
end
mypos.y = 0
tpos.y = 0
if vector.distance(mypos, tpos) <= reach_distance then
return true
else
return false
end
return false
end,
on_end = function(self, mob)
mob.object:set_velocity(vector.zero())

View File

@ -27,7 +27,7 @@ return function(task_queue, mob)
yaw = math.random(0, 360) / 360 * (math.pi*2)
walk_duration = math.random(settings.walk_duration_min, settings.walk_duration_max)/1000
end
local mt_walk = rp_mobs.microtasks.walk_straight(settings.walk_speed, yaw, nil, nil, walk_duration)
local mt_walk = rp_mobs.microtasks.walk_straight(settings.walk_speed, yaw, nil, nil, false, walk_duration)
local mt_acceleration = rp_mobs.microtasks.set_acceleration(rp_mobs.GRAVITY_VECTOR)
local mt_yaw = rp_mobs.microtasks.set_yaw(yaw)
mt_walk.start_animation = "walk"
@ -63,7 +63,7 @@ return function(task_queue, mob)
yaw = math.random(0, 360) / 360 * (math.pi*2)
walk_duration = math.random(settings.walk_duration_min, settings.walk_duration_max)/1000
end
local mt_walk = rp_mobs.microtasks.walk_straight(settings.walk_speed, yaw, settings.jump_strength, settings.jump_clear_height, walk_duration)
local mt_walk = rp_mobs.microtasks.walk_straight(settings.walk_speed, yaw, settings.jump_strength, settings.jump_clear_height, true, walk_duration)
local mt_yaw = rp_mobs.microtasks.set_yaw(yaw)
local mt_acceleration = rp_mobs.microtasks.set_acceleration(vector.zero())
mt_walk.start_animation = "walk"
@ -76,7 +76,7 @@ return function(task_queue, mob)
local yaw = math.random(0, 360) / 360 * (math.pi*2)
local walk_duration = math.random(settings.walk_duration_min, settings.walk_duration_max)/1000
local mt_walk = rp_mobs.microtasks.walk_straight(settings.walk_speed, yaw, settings.jump_strength, settings.jump_clear_height, walk_duration)
local mt_walk = rp_mobs.microtasks.walk_straight(settings.walk_speed, yaw, settings.jump_strength, settings.jump_clear_height, true, walk_duration)
local mt_yaw = rp_mobs.microtasks.set_yaw(yaw)
local mt_acceleration = rp_mobs.microtasks.set_acceleration(rp_mobs.GRAVITY_VECTOR)
mt_walk.start_animation = "walk"
@ -179,20 +179,21 @@ return function(task_queue, mob, dtime)
local task = rp_mobs.create_task({label=task_label})
local mt_acceleration = rp_mobs.microtasks.set_acceleration(rp_mobs.GRAVITY_VECTOR)
rp_mobs.add_microtask_to_task(mob, mt_acceleration, task)
local speed
local speed, stop_at_reached
if task_label == "hunt player" then
speed = settings.hunt_speed or settings.walk_speed
stop_at_reached = settings.dogfight == true
else
speed = settings.walk_speed
stop_at_reached = true
end
local mt_follow = rp_mobs.microtasks.walk_straight_towards(speed, "object", target, true, settings.follow_reach_distance, settings.jump_strength, settings.jump_clear_height, settings.follow_give_up_time)
local mt_follow = rp_mobs.microtasks.walk_straight_towards(speed, "object", target, true, settings.follow_reach_distance, settings.jump_strength, settings.jump_clear_height, stop_at_reached, false, settings.follow_give_up_time)
if task_label == "hunt player" then
mt_follow.start_animation = "run"
else
mt_follow.start_animation = "walk"
end
rp_mobs.add_microtask_to_task(mob, mt_follow, task)
local dogfight = false
-- Dogfight, if enabled in settings
if settings.dogfight and task_label == "hunt player" then
local mt_attack = rp_mobs_mobs.create_dogfight_microtask(settings.dogfight_range, settings.dogfight_toolcaps, settings.dogfight_interval)