diff --git a/code/controllers/subsystem/xeno_ai.dm b/code/controllers/subsystem/xeno_ai.dm index 8ba29b5f7f..f323f90a6f 100644 --- a/code/controllers/subsystem/xeno_ai.dm +++ b/code/controllers/subsystem/xeno_ai.dm @@ -40,8 +40,8 @@ SUBSYSTEM_DEF(xeno_ai) current_run.len-- if(!QDELETED(M) && !M.client && M.stat != DEAD) M.process_ai(wait * 0.1, game_evaluation) -// else -// remove_ai(M) + else + remove_ai(M) if(MC_TICK_CHECK) return diff --git a/code/modules/mob/living/carbon/xenomorph/ai/movement/drone.dm b/code/modules/mob/living/carbon/xenomorph/ai/movement/drone.dm index aac9d1f66b..7f8349177e 100644 --- a/code/modules/mob/living/carbon/xenomorph/ai/movement/drone.dm +++ b/code/modules/mob/living/carbon/xenomorph/ai/movement/drone.dm @@ -1,58 +1,105 @@ +#define BLACKLIST_TURF_TIMEOUT (180 SECONDS) + /datum/xeno_ai_movement/drone + var/last_home_turf + var/list/blacklisted_turfs = list() + +/datum/xeno_ai_movement/drone/Destroy(force, ...) + . = ..() + blacklisted_turfs = null //drones expand the hive /datum/xeno_ai_movement/drone/ai_move_idle(delta_time, game_evaluation) - var/mob/living/carbon/xenomorph/X = parent - if(X.throwing) + var/mob/living/carbon/xenomorph/idle_xeno = parent + + if(idle_xeno.throwing) return - if(next_home_search < world.time && (!home_turf || home_turf.weeds || get_dist(home_turf, X) > max_distance_from_home)) - var/turf/T = get_turf(X.loc) - next_home_search = world.time + home_search_delay - if(!T.weeds) - home_turf = T - else - var/shortest_distance - for(var/i in RANGE_TURFS(home_locate_range, T)) - var/turf/potential_home = i - - var/area/found_area = get_area(potential_home) - if(found_area.flags_area & AREA_NOTUNNEL) - continue + if(idle_xeno.resting) + return - if(!found_area.can_build_special) - continue + if(home_turf) + if(get_dist(home_turf, idle_xeno) > max_distance_from_home) + home_turf = null + return - if(potential_home.weeds) - continue + if(get_dist(home_turf, idle_xeno) <= 0) + var/datum/action/xeno_action/onclick/plant_weeds/plant_weed_action = get_xeno_action_by_type(parent, /datum/action/xeno_action/onclick/plant_weeds) + INVOKE_ASYNC(plant_weed_action, TYPE_PROC_REF(/datum/action/xeno_action/onclick/plant_weeds, use_ability_wrapper)) + home_turf = null + return - if(!potential_home.is_weedable()) - continue + if(!idle_xeno.move_to_next_turf(home_turf, home_locate_range)) + home_turf = null + return - if(locate(/obj/effect/alien/weeds/node) in range(3, potential_home)) - continue + return - if(potential_home.density) - continue + if(next_home_search > world.time) + return - if(shortest_distance && get_dist(X, potential_home) > shortest_distance) + var/turf/current_turf = get_turf(idle_xeno.loc) + next_home_search = world.time + home_search_delay + if(!current_turf.weeds && current_turf.is_weedable() >= FULLY_WEEDABLE) + home_turf = current_turf + else + var/shortest_distance + for(var/turf/potential_home as anything in RANGE_TURFS(home_locate_range, current_turf)) + + var/area/found_area = get_area(potential_home) + if(found_area.flags_area & AREA_NOTUNNEL) + continue + + if(found_area.flags_area & AREA_UNWEEDABLE) + continue + + if(!found_area.can_build_special) + continue + + if(potential_home in blacklisted_turfs) + continue + + if(potential_home.weeds) + continue + + if(potential_home.is_weedable() < FULLY_WEEDABLE) + continue + + if(locate(/obj/effect/alien/weeds/node) in range(3, potential_home)) + continue + + if(potential_home.density) + continue + + var/blocked = FALSE + for(var/atom/potential_blocker as anything in potential_home) + if(potential_blocker.can_block_movement) + blocked = TRUE + break + + if(blocked) + continue + + for(var/obj/structure/struct in potential_home) + if(struct.density && !(struct.flags_atom & ON_BORDER)) continue - shortest_distance = get_dist(X, potential_home) - home_turf = potential_home + if(shortest_distance && get_dist(idle_xeno, potential_home) > shortest_distance) + continue + + shortest_distance = get_dist(idle_xeno, potential_home) + home_turf = potential_home if(!home_turf) - if(!X.resting) - X.lay_down() + if(!idle_xeno.resting) + idle_xeno.lay_down() return - if(X.resting) - X.lay_down() + if(home_turf == last_home_turf) + blacklisted_turfs += home_turf + addtimer(CALLBACK(src, PROC_REF(unblacklist_turf), home_turf), BLACKLIST_TURF_TIMEOUT) - if(!X.move_to_next_turf(home_turf, home_locate_range)) - home_turf = null + last_home_turf = home_turf - if(get_dist(home_turf, X) <= 0) - var/datum/action/xeno_action/onclick/plant_weeds/plant_weed_action = get_xeno_action_by_type(parent, /datum/action/xeno_action/onclick/plant_weeds) - INVOKE_ASYNC(plant_weed_action, TYPE_PROC_REF(/datum/action/xeno_action/onclick/plant_weeds, use_ability_wrapper)) - home_turf = null +/datum/xeno_ai_movement/drone/proc/unblacklist_turf(turf/unblacklisting_turf) + blacklisted_turfs -= unblacklisting_turf 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 4ae5d3e425..9b7d230b55 100644 --- a/code/modules/mob/living/carbon/xenomorph/ai/xeno_ai.dm +++ b/code/modules/mob/living/carbon/xenomorph/ai/xeno_ai.dm @@ -69,12 +69,12 @@ GLOBAL_LIST_INIT(ai_target_limbs, list( resting = FALSE return TRUE + a_intent = INTENT_HARM + if(!current_target) ai_move_idle(delta_time, game_evaluation) return TRUE - a_intent = INTENT_HARM - if(ai_move_target(delta_time, game_evaluation)) return TRUE