diff --git a/code/controllers/subsystem/xeno_ai.dm b/code/controllers/subsystem/xeno_ai.dm index 9cd608f211..6f22d17e42 100644 --- a/code/controllers/subsystem/xeno_ai.dm +++ b/code/controllers/subsystem/xeno_ai.dm @@ -11,6 +11,43 @@ SUBSYSTEM_DEF(xeno_ai) var/ai_kill = FALSE + //currently the only caste that has an actual targeting difference is facehugger + /// Assoc list of valid targets by hive & caste, in the form of: hive = (/caste = targets) + var/list/target_cache = list() + +/datum/controller/subsystem/xeno_ai/proc/get_valid_targets(mob/living/carbon/xenomorph/xeno) + var/datum/hive_status/hive = xeno.hive + LAZYINITLIST(target_cache[hive]) + + var/caste = xeno.type + if(target_cache[hive][caste]) + return target_cache[hive][caste] + + var/list/valid_targets = list() + target_cache[hive][caste] = valid_targets + + for(var/mob/living/carbon/potential_target in GLOB.alive_mob_list) + if(!potential_target.ai_can_target(xeno)) + continue + + valid_targets += potential_target + + for(var/obj/vehicle/multitile/potential_vehicle_target as anything in GLOB.all_multi_vehicles) + if(potential_vehicle_target.health <= 0) + continue + + if(hive.faction_is_ally(potential_vehicle_target.vehicle_faction)) + continue + + if(!length(valid_targets & potential_vehicle_target.interior.get_passengers())) + continue + + valid_targets += potential_vehicle_target + + valid_targets += GLOB.all_active_defenses + + return valid_targets + /datum/controller/subsystem/xeno_ai/stat_entry(msg) msg = "P:[length(ai_mobs)]" return ..() @@ -26,6 +63,10 @@ SUBSYSTEM_DEF(xeno_ai) message_admins("[key_name_admin(usr)] [SSxeno_ai.ai_kill? "killed" : "revived"] all xeno AI.") /datum/controller/subsystem/xeno_ai/fire(resumed = FALSE) + for(var/datum/hive_status/hive as anything in target_cache) + for(var/caste as anything in target_cache[hive]) + target_cache[hive][caste] = null + if(ai_kill) return diff --git a/code/modules/mob/living/carbon/xenomorph/ai/xeno_ai.dm b/code/modules/mob/living/carbon/xenomorph/ai/xeno_ai.dm index 6e5ca5f2c1..7ccd4cde55 100644 --- a/code/modules/mob/living/carbon/xenomorph/ai/xeno_ai.dm +++ b/code/modules/mob/living/carbon/xenomorph/ai/xeno_ai.dm @@ -235,16 +235,12 @@ var/atom/movable/closest_target var/smallest_distance = INFINITY - for(var/mob/living/carbon/potential_target as anything in GLOB.alive_mob_list) - if(!istype(potential_target)) - continue + var/list/valid_targets = SSxeno_ai.get_valid_targets(src) + for(var/atom/movable/potential_target as anything in valid_targets) if(z != potential_target.z) continue - if(!potential_target.ai_can_target(src)) - continue - var/distance = get_dist(src, potential_target) if(distance > ai_range) @@ -258,59 +254,6 @@ closest_target = potential_target smallest_distance = distance - for(var/obj/vehicle/multitile/potential_vehicle_target as anything in GLOB.all_multi_vehicles) - if(z != potential_vehicle_target.z) - continue - - var/distance = get_dist(src, potential_vehicle_target) - - if(distance > ai_range) - continue - - if(potential_vehicle_target.health <= 0) - continue - - var/multitile_faction = potential_vehicle_target.vehicle_faction - if(hive.faction_is_ally(multitile_faction)) - continue - - var/skip_vehicle - var/list/interior_living_mobs = potential_vehicle_target.interior.get_passengers() - for(var/mob/living/carbon/human/human_mob in interior_living_mobs) - if(!human_mob.ai_can_target(src)) - continue - - skip_vehicle = FALSE - break - - if(skip_vehicle) - continue - - viable_targets += potential_vehicle_target - - if(smallest_distance <= distance) - continue - - closest_target = potential_vehicle_target - smallest_distance = distance - - for(var/obj/structure/machinery/defenses/potential_defense_target as anything in GLOB.all_active_defenses) - if(z != potential_defense_target.z) - continue - - var/distance = get_dist(src, potential_defense_target) - - if(distance > ai_range) - continue - - viable_targets += potential_defense_target - - if(smallest_distance <= distance) - continue - - closest_target = potential_defense_target - smallest_distance = distance - var/extra_check_distance = round(smallest_distance * EXTRA_CHECK_DISTANCE_MULTIPLIER) if(extra_check_distance < 1)