diff --git a/mods/rp_mobs/API_templates.md b/mods/rp_mobs/API_templates.md index 3b224ef3..c1e06370 100644 --- a/mods/rp_mobs/API_templates.md +++ b/mods/rp_mobs/API_templates.md @@ -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)` diff --git a/mods/rp_mobs/task_templates.lua b/mods/rp_mobs/task_templates.lua index ebdd38b1..cc80a425 100644 --- a/mods/rp_mobs/task_templates.lua +++ b/mods/rp_mobs/task_templates.lua @@ -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()) diff --git a/mods/rp_mobs_mobs/land_animal.lua b/mods/rp_mobs_mobs/land_animal.lua index 347640a1..1a350967 100644 --- a/mods/rp_mobs_mobs/land_animal.lua +++ b/mods/rp_mobs_mobs/land_animal.lua @@ -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)