basic mobs ranged attacks can check for friendly fire (#78451)

## About The Pull Request
basic mobs can check for friends in the way before firing a attack. if
they find someone in the way they will try to adjust their position so
their friends dont get hit by the projectiles


## Why It's Good For The Game
nice optional feature people can put on the monsters they create

## Changelog
🆑
add: added ranged attack friendly fire checks for basic mobs. minebots
and hivebots will now try to avoid shooting their friends
/🆑
This commit is contained in:
Ben10Omintrix
2023-09-25 16:19:58 -06:00
committed by GitHub
parent 4ba9d94113
commit a65d88dd03
4 changed files with 59 additions and 1 deletions
@@ -51,6 +51,8 @@
required_distance = 3
/// range we will try chasing the target before giving up
var/chase_range = 9
///do we care about avoiding friendly fire?
var/avoid_friendly_fire = FALSE
/datum/ai_behavior/basic_ranged_attack/setup(datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
. = ..()
@@ -75,6 +77,10 @@
if(!can_see(basic_mob, final_target, required_distance))
return
if(avoid_friendly_fire && check_friendly_in_path(basic_mob, target, targetting_datum))
adjust_position(basic_mob, target)
return ..()
controller.set_blackboard_key(hiding_location_key, hiding_target)
basic_mob.RangedAttack(final_target)
return ..() //only start the cooldown when the shot is shot
@@ -83,3 +89,52 @@
. = ..()
if(!succeeded)
controller.clear_blackboard_key(target_key)
/datum/ai_behavior/basic_ranged_attack/proc/check_friendly_in_path(mob/living/source, atom/target, datum/targetting_datum/targetting_datum)
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(!targetting_datum.can_attack(source, potential_friend))
return TRUE
return FALSE
/datum/ai_behavior/basic_ranged_attack/proc/adjust_position(mob/living/living_pawn, atom/target)
var/turf/our_turf = get_turf(living_pawn)
var/list/possible_turfs = list()
for(var/direction in GLOB.alldirs)
var/turf/target_turf = get_step(our_turf, direction)
if(isnull(target_turf))
continue
if(target_turf.is_blocked_turf() || get_dist(target_turf, target) > get_dist(living_pawn, target))
continue
possible_turfs += target_turf
if(!length(possible_turfs))
return
var/turf/picked_turf = get_closest_atom(/turf, possible_turfs, target)
step(living_pawn, get_dir(living_pawn, picked_turf))
/datum/ai_behavior/basic_ranged_attack/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(!ISDIAGONALDIR(direction_to_turf))
continue
for(var/cardinal_direction in GLOB.cardinals)
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_behavior/basic_ranged_attack/avoid_friendly_fire
avoid_friendly_fire = TRUE