|
| 1 | +/// Abstract class for an action an AI can take. Can range from movement to grabbing a nearby weapon. |
| 2 | +/datum/ai_behavior |
| 3 | + /// What distance you need to be from the target to perform the action. |
| 4 | + var/required_distance = 1 |
| 5 | + /// Flags for extra behavior |
| 6 | + var/behavior_flags = NONE |
| 7 | + /// Cooldown between actions performances, defaults to the value of |
| 8 | + /// CLICK_CD_MELEE because that seemed like a nice standard for the speed of |
| 9 | + /// AI behavior |
| 10 | + var/action_cooldown = CLICK_CD_MELEE |
| 11 | + |
| 12 | +/// Called by the AI controller when first being added. Additional arguments |
| 13 | +/// depend on the behavior type. For example, if the behavior involves attacking |
| 14 | +/// a mob, you may require an argument naming the blackboard key which points to |
| 15 | +/// the target. Return FALSE to cancel. |
| 16 | +/datum/ai_behavior/proc/setup(datum/ai_controller/controller, ...) |
| 17 | + return TRUE |
| 18 | + |
| 19 | +/// Returns the delay to use for this behavior in the moment. The default |
| 20 | +/// behavior cooldown is `CLICK_CD_MELEE`, but can be customized; for example, |
| 21 | +/// you may want a mob crawling through vents to move slowly and at a random |
| 22 | +/// pace between pipes. |
| 23 | +/datum/ai_behavior/proc/get_cooldown(datum/ai_controller/cooldown_for) |
| 24 | + return action_cooldown |
| 25 | + |
| 26 | +/// Called by the AI controller when this action is performed. This will |
| 27 | +/// typically require consulting the blackboard for information on the specific |
| 28 | +/// actions desired from this behavior, by passing the relevant blackboard data |
| 29 | +/// keys to this proc. Returns a combination of [AI_BEHAVIOR_DELAY] or |
| 30 | +/// [AI_BEHAVIOR_INSTANT], determining whether or not a cooldown occurs, and |
| 31 | +/// [AI_BEHAVIOR_SUCCEEDED] or [AI_BEHAVIOR_FAILED]. The behavior's |
| 32 | +/// `finish_action` proc is given TRUE or FALSE depending on whether or not the |
| 33 | +/// return value of `perform` is marked as successful or unsuccessful. |
| 34 | +/datum/ai_behavior/proc/perform(seconds_per_tick, datum/ai_controller/controller, ...) |
| 35 | + controller.behavior_cooldowns[src] = world.time + action_cooldown |
| 36 | + |
| 37 | +/// Called when the action is finished. This needs the same args as `perform` |
| 38 | +/// besides the default ones. This should be used to clear up the blackboard of |
| 39 | +/// any unnecessary or obsolete data, and update the state of the pawn if |
| 40 | +/// necessary once we know whether or not the AI action was successful. |
| 41 | +/// `succeeded` is `TRUE` or `FALSE` depending on whether |
| 42 | +/// [/datum/ai_behavior/proc/perform] returns [AI_BEHAVIOR_SUCCEEDED] or |
| 43 | +/// [AI_BEHAVIOR_FAILED]. |
| 44 | +/datum/ai_behavior/proc/finish_action(datum/ai_controller/controller, succeeded, ...) |
| 45 | + LAZYREMOVE(controller.current_behaviors, src) |
| 46 | + controller.behavior_args -= type |
| 47 | + // If this was a movement task, reset our movement target if necessary |
| 48 | + if(!(behavior_flags & AI_BEHAVIOR_REQUIRE_MOVEMENT)) |
| 49 | + return |
| 50 | + if(behavior_flags & AI_BEHAVIOR_KEEP_MOVE_TARGET_ON_FINISH) |
| 51 | + return |
| 52 | + clear_movement_target(controller) |
| 53 | + controller.ai_movement.stop_moving_towards(controller) |
| 54 | + |
| 55 | +/// Helper proc to ensure consistency in setting the source of the movement target |
| 56 | +/datum/ai_behavior/proc/set_movement_target(datum/ai_controller/controller, atom/target, datum/ai_movement/new_movement) |
| 57 | + controller.set_movement_target(type, target, new_movement) |
| 58 | + |
| 59 | +/// Clear the controller's movement target only if it was us who last set it |
| 60 | +/datum/ai_behavior/proc/clear_movement_target(datum/ai_controller/controller) |
| 61 | + if(controller.movement_target_source != type) |
| 62 | + return |
| 63 | + controller.set_movement_target(type, null) |
0 commit comments