mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-27 15:17:01 +01:00
Refactors how basic ais do their success/failures (#82643)
This commit is contained in:
@@ -27,7 +27,6 @@
|
||||
/datum/ai_behavior/basic_melee_attack/opportunistic/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key)
|
||||
var/atom/movable/atom_pawn = controller.pawn
|
||||
if(!atom_pawn.CanReach(controller.blackboard[target_key]))
|
||||
finish_action(controller, TRUE, target_key) // Don't clear target
|
||||
return FALSE
|
||||
return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
|
||||
. = ..()
|
||||
finish_action(controller, TRUE, target_key) // Try doing something else
|
||||
return . | AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
|
||||
|
||||
@@ -27,13 +27,11 @@
|
||||
var/can_attack_dense_objects = FALSE
|
||||
|
||||
/datum/ai_behavior/attack_obstructions/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
|
||||
. = ..()
|
||||
var/mob/living/basic/basic_mob = controller.pawn
|
||||
var/atom/target = controller.blackboard[target_key]
|
||||
|
||||
if (QDELETED(target))
|
||||
finish_action(controller, succeeded = FALSE)
|
||||
return
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
||||
|
||||
var/turf/next_step = get_step_towards(basic_mob, target)
|
||||
var/dir_to_next_step = get_dir(basic_mob, next_step)
|
||||
@@ -48,8 +46,8 @@
|
||||
|
||||
for (var/direction in dirs_to_move)
|
||||
if (attack_in_direction(controller, basic_mob, direction))
|
||||
return
|
||||
finish_action(controller, succeeded = TRUE)
|
||||
return AI_BEHAVIOR_DELAY
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
|
||||
|
||||
/datum/ai_behavior/attack_obstructions/proc/attack_in_direction(datum/ai_controller/controller, mob/living/basic/basic_mob, direction)
|
||||
var/turf/next_step = get_step(basic_mob, direction)
|
||||
|
||||
@@ -36,8 +36,6 @@
|
||||
var/reinforcements_range = 15
|
||||
|
||||
/datum/ai_behavior/call_reinforcements/perform(seconds_per_tick, datum/ai_controller/controller)
|
||||
. = ..()
|
||||
|
||||
var/mob/pawn_mob = controller.pawn
|
||||
for(var/mob/other_mob in oview(reinforcements_range, pawn_mob))
|
||||
if(pawn_mob.faction_check_atom(other_mob) && !isnull(other_mob.ai_controller))
|
||||
@@ -46,5 +44,6 @@
|
||||
other_mob.ai_controller.set_blackboard_key(BB_BASIC_MOB_REINFORCEMENT_TARGET, pawn_mob)
|
||||
|
||||
controller.set_blackboard_key(BB_BASIC_MOB_REINFORCEMENTS_COOLDOWN, world.time + REINFORCEMENTS_COOLDOWN)
|
||||
return AI_BEHAVIOR_DELAY
|
||||
|
||||
#undef REINFORCEMENTS_COOLDOWN
|
||||
|
||||
@@ -14,29 +14,25 @@
|
||||
action_cooldown = 1 SECONDS
|
||||
|
||||
/datum/ai_behavior/capricious_retaliate/perform(seconds_per_tick, datum/ai_controller/controller, targeting_strategy_key, ignore_faction)
|
||||
. = ..()
|
||||
var/atom/pawn = controller.pawn
|
||||
if (controller.blackboard_key_exists(BB_BASIC_MOB_RETALIATE_LIST))
|
||||
var/deaggro_chance = controller.blackboard[BB_RANDOM_DEAGGRO_CHANCE] || 10
|
||||
if (!SPT_PROB(deaggro_chance, seconds_per_tick))
|
||||
finish_action(controller, TRUE, ignore_faction) // "true" here means "don't clear our ignoring factions status"
|
||||
return
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
|
||||
pawn.visible_message(span_notice("[pawn] calms down.")) // We can blackboard key this if anyone else actually wants to customise it
|
||||
controller.clear_blackboard_key(BB_BASIC_MOB_RETALIATE_LIST)
|
||||
finish_action(controller, FALSE, ignore_faction)
|
||||
controller.CancelActions() // Otherwise they will try and get one last kick in
|
||||
return
|
||||
return AI_BEHAVIOR_DELAY
|
||||
|
||||
var/aggro_chance = controller.blackboard[BB_RANDOM_AGGRO_CHANCE] || 0.5
|
||||
if (!SPT_PROB(aggro_chance, seconds_per_tick))
|
||||
finish_action(controller, FALSE, ignore_faction)
|
||||
return
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
||||
|
||||
var/aggro_range = controller.blackboard[BB_AGGRO_RANGE] || 9
|
||||
var/list/potential_targets = hearers(aggro_range, get_turf(pawn)) - pawn
|
||||
if (!length(potential_targets))
|
||||
failed_targeting(controller, pawn, ignore_faction)
|
||||
return
|
||||
failed_targeting(pawn)
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
||||
|
||||
var/datum/targeting_strategy/target_helper = GET_TARGETING_STRATEGY(controller.blackboard[targeting_strategy_key])
|
||||
|
||||
@@ -49,16 +45,15 @@
|
||||
final_target = test_target
|
||||
|
||||
if (isnull(final_target))
|
||||
failed_targeting(controller, pawn, ignore_faction)
|
||||
return
|
||||
failed_targeting(pawn)
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
||||
|
||||
controller.insert_blackboard_key_lazylist(BB_BASIC_MOB_RETALIATE_LIST, final_target)
|
||||
pawn.visible_message(span_warning("[pawn] glares grumpily at [final_target]!"))
|
||||
finish_action(controller, TRUE, ignore_faction)
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
|
||||
|
||||
/// Called if we try but fail to target something
|
||||
/datum/ai_behavior/capricious_retaliate/proc/failed_targeting(datum/ai_controller/controller, atom/pawn, ignore_faction)
|
||||
finish_action(controller, FALSE, ignore_faction)
|
||||
/datum/ai_behavior/capricious_retaliate/proc/failed_targeting(atom/pawn)
|
||||
pawn.visible_message(span_notice("[pawn] grumbles.")) // We're pissed off but with no outlet to vent our frustration upon
|
||||
|
||||
/datum/ai_behavior/capricious_retaliate/finish_action(datum/ai_controller/controller, succeeded, ignore_faction)
|
||||
|
||||
@@ -60,8 +60,7 @@
|
||||
return FALSE
|
||||
|
||||
/datum/ai_behavior/step_away/perform(seconds_per_tick, datum/ai_controller/controller)
|
||||
. = ..()
|
||||
finish_action(controller, succeeded = TRUE)
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
|
||||
|
||||
/datum/ai_behavior/step_away/finish_action(datum/ai_controller/controller, succeeded)
|
||||
. = ..()
|
||||
@@ -83,8 +82,8 @@
|
||||
/datum/ai_behavior/pursue_to_range/perform(seconds_per_tick, datum/ai_controller/controller, target_key, range)
|
||||
var/atom/current_target = controller.blackboard[target_key]
|
||||
if (!QDELETED(current_target) && get_dist(controller.pawn, current_target) > range)
|
||||
return
|
||||
finish_action(controller, succeeded = TRUE)
|
||||
return AI_BEHAVIOR_INSTANT
|
||||
return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
|
||||
|
||||
///instead of taking a single step, we cover the entire distance
|
||||
/datum/ai_behavior/cover_minimum_distance
|
||||
@@ -112,5 +111,4 @@
|
||||
set_movement_target(controller, target = chosen_turf)
|
||||
|
||||
/datum/ai_behavior/cover_minimum_distance/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
|
||||
. = ..()
|
||||
finish_action(controller, succeeded = TRUE)
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
|
||||
|
||||
@@ -21,19 +21,16 @@
|
||||
set_movement_target(controller, target)
|
||||
|
||||
/datum/ai_behavior/mine_wall/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
|
||||
. = ..()
|
||||
var/mob/living/basic/living_pawn = controller.pawn
|
||||
var/turf/closed/mineral/target = controller.blackboard[target_key]
|
||||
var/is_gibtonite_turf = istype(target, /turf/closed/mineral/gibtonite)
|
||||
if(QDELETED(target))
|
||||
finish_action(controller, FALSE, target_key)
|
||||
return
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
||||
living_pawn.melee_attack(target)
|
||||
if(is_gibtonite_turf)
|
||||
living_pawn.manual_emote("sighs...") //accept whats about to happen to us
|
||||
|
||||
finish_action(controller, TRUE, target_key)
|
||||
return
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
|
||||
|
||||
/datum/ai_behavior/mine_wall/finish_action(datum/ai_controller/controller, success, target_key)
|
||||
. = ..()
|
||||
@@ -42,17 +39,15 @@
|
||||
/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/closed/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!
|
||||
finish_action(controller, TRUE)
|
||||
return
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
|
||||
|
||||
finish_action(controller, FALSE)
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
||||
|
||||
/datum/ai_behavior/find_mineral_wall/proc/check_if_mineable(datum/ai_controller/controller, turf/target_wall)
|
||||
var/mob/living/source = controller.pawn
|
||||
|
||||
@@ -51,19 +51,17 @@
|
||||
/datum/ai_behavior/move_to_cardinal/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
|
||||
var/atom/target = controller.blackboard[target_key]
|
||||
if (QDELETED(target))
|
||||
finish_action(controller = controller, succeeded = FALSE, target_key = target_key)
|
||||
return
|
||||
return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
|
||||
if (!(get_dir(controller.pawn, target) in GLOB.cardinals))
|
||||
target_nearest_cardinal(controller, target)
|
||||
return
|
||||
return AI_BEHAVIOR_INSTANT
|
||||
var/distance_to_target = get_dist(controller.pawn, target)
|
||||
if (distance_to_target < minimum_distance)
|
||||
target_nearest_cardinal(controller, target)
|
||||
return
|
||||
return AI_BEHAVIOR_INSTANT
|
||||
if (distance_to_target > maximum_distance)
|
||||
return
|
||||
finish_action(controller = controller, succeeded = TRUE, target_key = target_key)
|
||||
return
|
||||
return AI_BEHAVIOR_INSTANT
|
||||
return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
|
||||
|
||||
/datum/ai_behavior/move_to_cardinal/finish_action(datum/ai_controller/controller, succeeded, target_key)
|
||||
if (!succeeded)
|
||||
|
||||
@@ -26,16 +26,13 @@
|
||||
return !QDELETED(target)
|
||||
|
||||
/datum/ai_behavior/ranged_skirmish/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key, max_range, min_range)
|
||||
. = ..()
|
||||
var/atom/target = controller.blackboard[target_key]
|
||||
if (QDELETED(target))
|
||||
finish_action(controller, succeeded = FALSE)
|
||||
return
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
||||
|
||||
var/datum/targeting_strategy/targeting_strategy = GET_TARGETING_STRATEGY(controller.blackboard[targeting_strategy_key])
|
||||
if(!targeting_strategy.can_attack(controller.pawn, target))
|
||||
finish_action(controller, succeeded = FALSE)
|
||||
return
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
||||
|
||||
var/hiding_target = targeting_strategy.find_hidden_mobs(controller.pawn, target)
|
||||
controller.set_blackboard_key(hiding_location_key, hiding_target)
|
||||
@@ -44,9 +41,8 @@
|
||||
|
||||
var/distance = get_dist(controller.pawn, target)
|
||||
if (distance > max_range || distance < min_range)
|
||||
finish_action(controller, succeeded = FALSE)
|
||||
return
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
||||
|
||||
var/mob/living/basic/gunman = controller.pawn
|
||||
gunman.RangedAttack(target)
|
||||
finish_action(controller, succeeded = TRUE)
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
/datum/ai_behavior/run_emote/perform(seconds_per_tick, datum/ai_controller/controller, emote_key)
|
||||
var/mob/living/living_pawn = controller.pawn
|
||||
if (!isliving(living_pawn))
|
||||
finish_action(controller, FALSE)
|
||||
return
|
||||
return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
|
||||
|
||||
var/list/emote_list = controller.blackboard[emote_key]
|
||||
var/emote
|
||||
@@ -26,8 +25,7 @@
|
||||
emote = emote_list
|
||||
|
||||
if(isnull(emote))
|
||||
finish_action(controller, FALSE)
|
||||
return
|
||||
return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
|
||||
|
||||
living_pawn.emote(emote)
|
||||
finish_action(controller, TRUE)
|
||||
return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
/datum/ai_behavior/sleep_after_targetless_time/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
|
||||
var/atom/target = controller.blackboard[target_key]
|
||||
finish_action(controller, succeeded = QDELETED(target), seconds_per_tick = seconds_per_tick)
|
||||
if(QDELETED(target))
|
||||
return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
|
||||
return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
|
||||
|
||||
/datum/ai_behavior/sleep_after_targetless_time/finish_action(datum/ai_controller/controller, succeeded, seconds_per_tick)
|
||||
. = ..()
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
var/mob/living/living_mob = controller.pawn
|
||||
var/datum/targeting_strategy/targeting_strategy = GET_TARGETING_STRATEGY(controller.blackboard[targeting_strategy_key])
|
||||
if(!targeting_strategy)
|
||||
. = AI_BEHAVIOR_DELAY
|
||||
CRASH("No target datum was supplied in the blackboard for [controller.pawn]")
|
||||
|
||||
var/list/shitlist = controller.blackboard[shitlist_key]
|
||||
@@ -48,8 +49,7 @@
|
||||
controller.set_blackboard_key(BB_TEMPORARILY_IGNORE_FACTION, TRUE)
|
||||
|
||||
if (!QDELETED(existing_target) && (locate(existing_target) in shitlist) && targeting_strategy.can_attack(living_mob, existing_target, vision_range))
|
||||
finish_action(controller, succeeded = TRUE, check_faction = check_faction)
|
||||
return
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
|
||||
|
||||
var/list/enemies_list = list()
|
||||
for(var/mob/living/potential_target as anything in shitlist)
|
||||
@@ -59,8 +59,7 @@
|
||||
|
||||
if(!length(enemies_list))
|
||||
controller.clear_blackboard_key(target_key)
|
||||
finish_action(controller, succeeded = FALSE, check_faction = check_faction)
|
||||
return
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
||||
|
||||
var/atom/new_target = pick_final_target(controller, enemies_list)
|
||||
controller.set_blackboard_key(target_key, new_target)
|
||||
@@ -70,7 +69,7 @@
|
||||
if(potential_hiding_location) //If they're hiding inside of something, we need to know so we can go for that instead initially.
|
||||
controller.set_blackboard_key(hiding_location_key, potential_hiding_location)
|
||||
|
||||
finish_action(controller, succeeded = TRUE, check_faction = check_faction)
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
|
||||
|
||||
/// Returns the desired final target from the filtered list of enemies
|
||||
/datum/ai_behavior/target_from_retaliate_list/proc/pick_final_target(datum/ai_controller/controller, list/enemies_list)
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
/datum/ai_behavior/find_furthest_turf_from_target/perform(seconds_per_tick, datum/ai_controller/controller, target_key, set_key, range)
|
||||
var/mob/living/living_target = controller.blackboard[target_key]
|
||||
if(QDELETED(living_target))
|
||||
return
|
||||
return AI_BEHAVIOR_INSTANT
|
||||
|
||||
var/distance = 0
|
||||
var/turf/chosen_turf
|
||||
@@ -49,8 +49,7 @@
|
||||
break //we have already found the max distance
|
||||
|
||||
if(isnull(chosen_turf))
|
||||
finish_action(controller, FALSE)
|
||||
return
|
||||
return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
|
||||
|
||||
controller.set_blackboard_key(set_key, chosen_turf)
|
||||
finish_action(controller, TRUE)
|
||||
return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
/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))
|
||||
finish_action(controller, FALSE, ability_key)
|
||||
return
|
||||
var/result = using_action.Trigger()
|
||||
finish_action(controller, result, ability_key)
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user