diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/targeting.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/targeting.dm index e5de231aff5..9305c398611 100644 --- a/code/datums/ai/basic_mobs/basic_ai_behaviors/targeting.dm +++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/targeting.dm @@ -1,5 +1,5 @@ /// List of objects that AIs will treat as targets -GLOBAL_LIST_EMPTY_TYPED(hostile_machines, /atom) +GLOBAL_ALIST_EMPTY(hostile_machines_by_z) /// Static typecache list of things we are interested in /// Consider this a union of the for loop and the hearers call from below /// Must be kept up to date with the contents of hostile_machines @@ -39,9 +39,11 @@ GLOBAL_LIST_INIT(target_interested_atoms, typecacheof(list(/mob, /obj/machinery/ var/list/potential_targets = hearers(aggro_range, get_turf(controller.pawn)) - living_mob //Remove self, so we don't suicide - for (var/atom/hostile_machine as anything in GLOB.hostile_machines) - if (can_see(living_mob, hostile_machine, aggro_range)) - potential_targets += hostile_machine + var/turf/mob_turf = get_turf(living_mob) + if(mob_turf?.z) + for (var/atom/hostile_machine as anything in GLOB.hostile_machines_by_z[mob_turf.z]) + if (can_see(living_mob, hostile_machine, aggro_range)) + potential_targets += hostile_machine if(!potential_targets.len) failed_to_find_anyone(controller, target_key, targeting_strategy_key, hiding_location_key) diff --git a/code/datums/elements/hostile_machine.dm b/code/datums/elements/hostile_machine.dm index cb846d830e8..0b67775ecfe 100644 --- a/code/datums/elements/hostile_machine.dm +++ b/code/datums/elements/hostile_machine.dm @@ -12,8 +12,41 @@ if(!GLOB.target_interested_atoms[target.type]) stack_trace("Tried to make a hostile machine without updating ai targeting to include it, they must be synced") #endif - GLOB.hostile_machines += target + + if(ismovable(target)) + RegisterSignal(target, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(on_z_change)) + + add_to_z(target) /datum/element/hostile_machine/Detach(datum/source) - GLOB.hostile_machines -= source + UnregisterSignal(source, COMSIG_MOVABLE_Z_CHANGED) + remove_from_z(source) return ..() + +/datum/element/hostile_machine/proc/on_z_change(atom/movable/source, turf/old_turf, turf/new_turf, same_z_layer) + SIGNAL_HANDLER + + if(same_z_layer) + return + remove_from_z(source, old_turf.z) + add_to_z(source, new_turf.z) + +/datum/element/hostile_machine/proc/add_to_z(atom/target, z) + if(isnull(z)) + var/turf/target_turf = get_turf(target) + z = target_turf?.z + if(!z) + return + if(!GLOB.hostile_machines_by_z[z]) + GLOB.hostile_machines_by_z[z] = list() + GLOB.hostile_machines_by_z[z] |= target + +/datum/element/hostile_machine/proc/remove_from_z(atom/target, z) + if(isnull(z)) + var/turf/target_turf = get_turf(target) + z = target_turf?.z + if(!z) + return + GLOB.hostile_machines_by_z[z] -= target + if(!length(GLOB.hostile_machines_by_z[z])) + GLOB.hostile_machines_by_z -= z