port minebots to basic mobs and add some behavior (#29319)

* port minebots to basic mobs and add some behavior

* remove unused define

* update is_blocked_turf usage

* fix radio, goldgrub, and armor upgrade

* standardize blackboard names

* Apply suggestions from code review

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: warriorstar-orion <orion@snowfrost.garden>

* lewc review

* whoops

* Apply suggestions from code review

Co-authored-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com>
Signed-off-by: warriorstar-orion <orion@snowfrost.garden>

---------

Signed-off-by: warriorstar-orion <orion@snowfrost.garden>
Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Co-authored-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com>
This commit is contained in:
warriorstar-orion
2025-06-13 15:48:40 -04:00
committed by GitHub
parent 586e2e6c4d
commit e63415a483
50 changed files with 1892 additions and 529 deletions
@@ -0,0 +1,31 @@
/datum/ai_behavior/find_mineral_wall
/datum/ai_behavior/find_mineral_wall/perform(seconds_per_tick, datum/ai_controller/controller, found_wall_key)
var/mob/living_pawn = controller.pawn
for(var/turf/simulated/mineral/potential_wall in oview(9, living_pawn))
if(!check_if_mineable(controller, potential_wall)) // check if its surrounded by walls
continue
controller.set_blackboard_key(found_wall_key, potential_wall) // closest wall first!
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
/// Check to see if we can get to and mine the turf the mineral is in
/datum/ai_behavior/find_mineral_wall/proc/check_if_mineable(datum/ai_controller/controller, turf/target_wall)
var/mob/living/source = controller.pawn
var/direction_to_turf = get_dir(target_wall, source)
if(!IS_DIR_DIAGONAL(direction_to_turf))
return TRUE
var/list/directions_to_check = list()
for(var/direction_check in GLOB.cardinal)
if(direction_check & direction_to_turf)
directions_to_check += direction_check
for(var/direction in directions_to_check)
var/turf/test_turf = get_step(target_wall, direction)
if(isnull(test_turf))
continue
if(!test_turf.is_blocked_turf(source_atom = source))
return TRUE
return FALSE
@@ -11,3 +11,14 @@
controller.queue_behavior(melee_attack_behavior, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETING_STRATEGY, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
if(end_planning)
return SUBTREE_RETURN_FINISH_PLANNING // we are going into battle...no distractions.
/datum/ai_planning_subtree/basic_ranged_attack_subtree
operational_datums = list(/datum/component/ranged_attacks)
var/datum/ai_behavior/basic_ranged_attack/ranged_attack_behavior = /datum/ai_behavior/basic_ranged_attack
/datum/ai_planning_subtree/basic_ranged_attack_subtree/select_behaviors(datum/ai_controller/controller, seconds_per_tick)
. = ..()
if(!controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET))
return
controller.queue_behavior(ranged_attack_behavior, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETING_STRATEGY, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
return SUBTREE_RETURN_FINISH_PLANNING //we are going into battle...no distractions.
@@ -0,0 +1,19 @@
/datum/ai_planning_subtree/simple_find_target
/// Variable to store target in
var/target_key = BB_BASIC_MOB_CURRENT_TARGET
/datum/ai_planning_subtree/simple_find_target/select_behaviors(datum/ai_controller/controller, seconds_per_tick)
. = ..()
controller.queue_behavior(/datum/ai_behavior/find_potential_targets, target_key, BB_TARGETING_STRATEGY, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
// Prevents finding a target if a human is nearby
/datum/ai_planning_subtree/simple_find_target/not_while_observed
/datum/ai_planning_subtree/simple_find_target/not_while_observed/select_behaviors(datum/ai_controller/controller, seconds_per_tick)
for(var/mob/living/carbon/human/watcher in hearers(11, controller.pawn))
if(watcher.stat != DEAD)
return
return ..()
/datum/ai_planning_subtree/simple_find_target/to_flee
target_key = BB_BASIC_MOB_FLEE_TARGET
@@ -0,0 +1,33 @@
/**
* Simple behaviours which simply try to use an ability whenever it is available.
* For something which wants a target try `targeted_mob_ability`.
*/
/datum/ai_planning_subtree/use_mob_ability
/// Blackboard key for the ability
var/ability_key = BB_GENERIC_ACTION
/// Behaviour to perform using ability
var/use_ability_behavior = /datum/ai_behavior/use_mob_ability
/// If true we terminate planning after trying to use the ability.
var/finish_planning = FALSE
/datum/ai_planning_subtree/use_mob_ability/select_behaviors(datum/ai_controller/controller, seconds_per_tick)
if(!ability_key)
CRASH("You forgot to tell this mob where to find its ability")
var/datum/action/using_action = controller.blackboard[ability_key]
if(!using_action?.IsAvailable())
return
controller.queue_behavior(use_ability_behavior, ability_key)
if(finish_planning)
return SUBTREE_RETURN_FINISH_PLANNING
/datum/ai_behavior/use_mob_ability
/datum/ai_behavior/use_mob_ability/perform(seconds_per_tick, datum/ai_controller/controller, ability_key)
var/datum/action/using_action = controller.blackboard[ability_key]
if(QDELETED(using_action))
return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
if(using_action.Trigger())
return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED