mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
Merge pull request #10348 from VOREStation/upstream-merge-8052
[MIRROR] Simplemobs seek lost targets
This commit is contained in:
committed by
Chompstation Bot
parent
129eaeade4
commit
33f92d51ac
@@ -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
|
||||
|
||||
|
||||
@@ -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))
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user