Merge pull request #10348 from VOREStation/upstream-merge-8052

[MIRROR] Simplemobs seek lost targets
This commit is contained in:
Novacat
2021-05-18 08:30:24 -04:00
committed by Chompstation Bot
parent 129eaeade4
commit 33f92d51ac
3 changed files with 96 additions and 23 deletions

View File

@@ -7,27 +7,30 @@
if(conserve_ammo || !holder.ICheckRangedAttack(target_last_seen_turf))
if(get_dist(holder, target_last_seen_turf) > 1) // We last saw them over there.
// Go to where you last saw the enemy.
give_destination(target_last_seen_turf, 1, TRUE) // Sets stance as well
else if(lose_target_time == world.time) // We last saw them next to us, so do a blind attack on that tile.
melee_on_tile(target_last_seen_turf)
return give_destination(target_last_seen_turf, 1, TRUE) // Sets stance as well
else if(lose_target_time < world.time) // We last saw them next to us, so do a blind attack on that tile.
if(melee_on_tile(target_last_seen_turf) != ATTACK_SUCCESSFUL && intelligence_level >= AI_NORMAL)
var/obj/O = find_escape_route()
if(istype(O))
return give_destination(get_turf(O), 0, TRUE)
else
find_target()
return find_target()
else
shoot_near_turf(target_last_seen_turf)
return shoot_near_turf(target_last_seen_turf)
// This shoots semi-randomly near a specific turf.
/datum/ai_holder/proc/shoot_near_turf(turf/targeted_turf)
if(get_dist(holder, targeted_turf) > max_range(targeted_turf))
return // Too far to shoot.
return ATTACK_FAILED// Too far to shoot.
var/turf/T = pick(RANGE_TURFS(2, targeted_turf)) // The turf we're actually gonna shoot at.
on_engagement(T)
if(firing_lanes && !test_projectile_safety(T))
step_rand(holder)
holder.face_atom(T)
return
return ATTACK_FAILED
ranged_attack(T)
return ranged_attack(T)
// Attempts to attack something on a specific tile.
// TODO: Put on mob/living?
@@ -36,9 +39,53 @@
var/mob/living/L = locate() in T
if(!L)
T.visible_message("\The [holder] attacks nothing around \the [T].")
return
return ATTACK_FAILED
if(holder.IIsAlly(L)) // Don't hurt our ally.
return
return ATTACK_FAILED
melee_attack(L)
return melee_attack(L)
// Attempts to locate any possible avenues that the target might have escaped via
// Could be an open door, could be a stairwell or a ladder
// Returns object to path to. If multiple targets are equidistant, picks randomly
/datum/ai_holder/proc/find_escape_route()
ai_log("find_escape_route() : Entering.", AI_LOG_DEBUG)
var/list/closest_escape = list()
var/closest_dist = world.view // We can't see any further than this
var/list/possible_escape_types = list(
/obj/machinery/door,
/obj/structure/stairs/top,
/obj/structure/stairs/bottom
)
if(intelligence_level >= AI_SMART)
possible_escape_types += /obj/structure/ladder
for(var/atom/A in view(world.view, holder))
if(!is_type_in_list(A, possible_escape_types))
continue // Not something they could have escaped through
if(turn(holder.dir, 180) & get_dir(get_turf(holder), get_turf(A)))
continue // Surely, they couldn't have escaped *behind* us!
if(istype(A, /obj/machinery/door))
var/obj/machinery/door/D = A
if(D.glass) // Surely, they couldn't hide behind a transparent door!
continue
if(D.density && intelligence_level < AI_SMART) // Surely, they couldn't have escaped through a *closed* door
continue
var/dist = get_dist(holder, A)
if(dist == closest_dist)
closest_escape += A
else if(dist < closest_dist)
closest_escape.Cut()
closest_escape += A
closest_dist = dist
ai_log("find_escape_route() : Found [closest_escape.len] candidates [closest_dist] tiles away.", AI_LOG_DEBUG)
if(closest_escape.len)
return pick(closest_escape)
return null

View File

@@ -27,19 +27,19 @@
ai_log("walk_to_destination() : Exiting.", AI_LOG_TRACE)
return
var/get_to = min_distance_to_destination
var/distance = get_dist(holder, destination)
ai_log("walk_to_destination() : get_to is [get_to].", AI_LOG_TRACE)
ai_log("walk_to_destination() : get_to is [min_distance_to_destination].", AI_LOG_TRACE)
// We're here!
if(distance <= get_to)
// We're here! Or we're horribly lost
if(distance <= min_distance_to_destination || holder.z != destination.z)
check_use_ladder()
give_up_movement()
set_stance(stance == STANCE_REPOSITION ? STANCE_APPROACH : STANCE_IDLE)
ai_log("walk_to_destination() : Destination reached. Exiting.", AI_LOG_INFO)
return
ai_log("walk_to_destination() : Walking.", AI_LOG_TRACE)
walk_path(destination, get_to)
walk_path(destination, min_distance_to_destination)
ai_log("walk_to_destination() : Exiting.",AI_LOG_TRACE)
/datum/ai_holder/proc/should_go_home()
@@ -159,3 +159,34 @@
holder.IMove(get_step(holder,moving_to))
wander_delay = base_wander_delay
ai_log("handle_wander_movement() : Exited.", AI_LOG_TRACE)
/datum/ai_holder/proc/check_use_ladder()
// No target, don't use the ladder
// Target is visible, don't use the ladder
if(!target || can_see_target(target))
return
var/has_hands = TRUE
if(istype(holder, /mob/living/simple_mob))
var/mob/living/simple_mob/S = holder
has_hands = S.has_hands
// Don't have means to use a ladder or the space around it, don't use the ladder
if(!has_hands && !holder.hovering)
return
var/obj/structure/ladder/L = locate() in get_turf(holder)
if(!istype(L))
return // No ladder, can't use it
if(!holder.may_climb_ladders(L))
return // Can't climb the ladder for other reasons (Probably inconsequential?)
var/list/directions = list()
if(L.allowed_directions & DOWN)
directions += L.target_down
if(L.allowed_directions & UP)
directions += L.target_up
if(directions.len)
L.climbLadder(holder, pick(directions))

View File

@@ -165,19 +165,14 @@
target = null
lose_target_time = world.time
give_up_movement()
if(target_last_seen_turf && intelligence_level >= AI_SMART)
if(target_last_seen_turf && intelligence_level >= AI_NORMAL)
ai_log("lose_target() : Going into 'engage unseen enemy' mode.", AI_LOG_INFO)
engage_unseen_enemy()
return TRUE //We're still working on it
return engage_unseen_enemy() //We're still working on it
else
ai_log("lose_target() : Can't chase target, so giving up.", AI_LOG_INFO)
remove_target()
return find_target() //Returns if we found anything else to do
return FALSE //Nothing new to do
// 'Hard' loss of target. Clean things up and return to idle.
/datum/ai_holder/proc/remove_target()
ai_log("remove_target() : Entering.", AI_LOG_TRACE)