mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-01-14 19:41:53 +00:00
94 lines
3.8 KiB
Plaintext
94 lines
3.8 KiB
Plaintext
/// Fire a ranged attack without interrupting movement.
|
|
/datum/ai_planning_subtree/ranged_skirmish
|
|
operational_datums = list(/datum/component/ranged_attacks)
|
|
/// Blackboard key holding target atom
|
|
var/target_key = BB_BASIC_MOB_CURRENT_TARGET
|
|
/// What AI behaviour do we actually run?
|
|
var/attack_behavior = /datum/ai_behavior/ranged_skirmish
|
|
/// If target is further away than this we don't fire
|
|
var/max_range = 9
|
|
/// If target is closer than this we don't fire
|
|
var/min_range = 2
|
|
|
|
/datum/ai_planning_subtree/ranged_skirmish/select_behaviors(datum/ai_controller/controller, seconds_per_tick)
|
|
. = ..()
|
|
if(!controller.blackboard_key_exists(target_key))
|
|
return
|
|
controller.queue_behavior(attack_behavior, target_key, BB_TARGETING_STRATEGY, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION, max_range, min_range)
|
|
|
|
/// How often will we try to perform our ranged attack?
|
|
/datum/ai_behavior/ranged_skirmish
|
|
action_cooldown = 0.5 SECONDS
|
|
/// Do we care about shooting friends?
|
|
var/avoid_friendly_fire = FALSE
|
|
|
|
/datum/ai_behavior/ranged_skirmish/setup(datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key, max_range, min_range)
|
|
. = ..()
|
|
var/atom/target = controller.blackboard[hiding_location_key] || controller.blackboard[target_key]
|
|
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))
|
|
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))
|
|
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)
|
|
|
|
target = hiding_target || target
|
|
|
|
var/distance = get_dist(controller.pawn, target)
|
|
if(distance > max_range || distance < min_range)
|
|
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
|
if(avoid_friendly_fire && check_friendly_in_path(controller.pawn, target, targeting_strategy))
|
|
return AI_BEHAVIOR_DELAY
|
|
|
|
if(avoid_friendly_fire && check_friendly_in_path(controller.pawn, target, targeting_strategy))
|
|
return AI_BEHAVIOR_DELAY
|
|
|
|
controller.ai_interact(target = target, intent = INTENT_HARM)
|
|
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
|
|
|
|
/datum/ai_behavior/ranged_skirmish/proc/check_friendly_in_path(mob/living/source, atom/target, datum/targeting_strategy/targeting_strategy)
|
|
var/list/turfs_list = calculate_trajectory(source, target)
|
|
for(var/turf/possible_turf as anything in turfs_list)
|
|
|
|
for(var/mob/living/potential_friend in possible_turf)
|
|
if(!targeting_strategy.can_attack(source, potential_friend))
|
|
return TRUE
|
|
|
|
return FALSE
|
|
|
|
/datum/ai_behavior/ranged_skirmish/proc/calculate_trajectory(mob/living/source, atom/target)
|
|
var/list/turf_list = get_line(source, target)
|
|
var/list_length = length(turf_list) - 1
|
|
for(var/i in 1 to list_length)
|
|
var/turf/current_turf = turf_list[i]
|
|
var/turf/next_turf = turf_list[i + 1]
|
|
var/direction_to_turf = get_dir(current_turf, next_turf)
|
|
if(!IS_DIR_DIAGONAL(direction_to_turf))
|
|
continue
|
|
|
|
for(var/cardinal_direction in GLOB.cardinal)
|
|
if(cardinal_direction & direction_to_turf)
|
|
turf_list += get_step(current_turf, cardinal_direction)
|
|
|
|
turf_list -= get_turf(source)
|
|
turf_list -= get_turf(target)
|
|
|
|
return turf_list
|
|
|
|
/datum/ai_planning_subtree/ranged_skirmish/no_minimum
|
|
min_range = 0
|
|
|
|
/datum/ai_planning_subtree/ranged_skirmish/avoid_friendly
|
|
attack_behavior = /datum/ai_behavior/ranged_skirmish/avoid_friendly
|
|
|
|
/datum/ai_behavior/ranged_skirmish/avoid_friendly
|
|
avoid_friendly_fire = TRUE
|