Skip to content

Commit

Permalink
Retreating and pursuing
Browse files Browse the repository at this point in the history
  • Loading branch information
xDanilcusx committed Sep 19, 2024
1 parent 1fe7616 commit 473c512
Show file tree
Hide file tree
Showing 12 changed files with 115 additions and 35 deletions.
9 changes: 9 additions & 0 deletions code/__DEFINES/human_ai.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
#define HUMAN_AI_HEALTHITEMS "health"
#define HUMAN_AI_AMMUNITION "ammo"

#define AI_ACTION_APPROACH /datum/ongoing_action/approach_target
#define AI_ACTION_APPROACH_C /datum/ongoing_action/approach_target/carefully
#define AI_ACTION_RETREAT /datum/ongoing_action/retreat_from_target
#define AI_ACTION_PICKUP /datum/ongoing_action/item_pickup
#define AI_ACTION_PICKUP_GUN /datum/ongoing_action/item_pickup/pickup_primary
#define AI_ACTION_COVER /datum/ongoing_action/take_cover
#define AI_ACTION_COVER_I /datum/ongoing_action/take_inside_cover
#define AI_ACTION_TROWBACK /datum/ongoing_action/throw_back_nade

/// Action is completed, delete this and move onto the next ongoing action
#define ONGOING_ACTION_COMPLETED "completed"
/// Action isn't finished, move onto the next ongoing action
Expand Down
2 changes: 1 addition & 1 deletion code/_compile_options.dm
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@

//#define UNIT_TESTS //If this is uncommented, we do a single run though of the game setup and tear down process with unit tests in between

#define TESTING
// #define TESTING
// #define REFERENCE_TRACKING
// #define GC_FAILURE_HARD_LOOKUP
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,27 @@
name = "Approach Target"
var/atom/movable/target
var/acceptable_distance
var/do_target_dead

/datum/ongoing_action/approach_target/New(datum/human_ai_brain/brain, list/arguments)
. = ..()
target = arguments[2]
acceptable_distance = arguments[3]
do_target_dead = length(arguments) < 4 ? TRUE : arguments[4]

/datum/ongoing_action/approach_target/Destroy(force, ...)
target = null
return ..()

/datum/ongoing_action/approach_target/trigger_action()
if(QDELETED(target) || !isturf(target.loc))
if(QDELETED(target))
return ONGOING_ACTION_COMPLETED

if(ismob(target) && do_target_dead)
var/mob/M = target
if(M.is_dead())
return ONGOING_ACTION_COMPLETED

if(get_dist(target, brain.tied_human) > acceptable_distance)
if(!brain.move_to_next_turf(get_turf(target)))
return ONGOING_ACTION_COMPLETED
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/datum/ongoing_action/approach_target/carefully
name = "Approach Target Carefully"

/datum/ongoing_action/approach_target/carefully/trigger_action()
if(brain.current_target)
return ONGOING_ACTION_COMPLETED
. = ..()
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/datum/ongoing_action/retreat_from_target
name = "Retreat From Target"
var/atom/movable/target
var/acceptable_distance
var/do_target_dead

/datum/ongoing_action/retreat_from_target/New(datum/human_ai_brain/brain, list/arguments)
. = ..()
target = arguments[2]
acceptable_distance = arguments[3]
do_target_dead = length(arguments) < 4 ? TRUE : arguments[4]

/datum/ongoing_action/retreat_from_target/Destroy(force, ...)
target = null
return ..()

/datum/ongoing_action/retreat_from_target/trigger_action()
if(QDELETED(target))
return ONGOING_ACTION_COMPLETED

if(ismob(target) && do_target_dead)
var/mob/M = target
if(M.is_dead())
return ONGOING_ACTION_COMPLETED

if(get_dist(target, brain.tied_human) < acceptable_distance)
var/relative_dir = Get_Compass_Dir(target, brain.tied_human)
var/moved = FALSE
for(var/D in list(relative_dir, turn(relative_dir, 90), turn(relative_dir, -90)))
if(brain.move_to_next_turf(get_step(get_turf(brain.tied_human), D)))
moved = TRUE
break

if(!moved)
return ONGOING_ACTION_COMPLETED

if(get_dist(target, brain.tied_human) < acceptable_distance)
return ONGOING_ACTION_UNFINISHED

return ONGOING_ACTION_COMPLETED
28 changes: 18 additions & 10 deletions code/modules/mob/living/carbon/human/ai/brain/ai_brain.dm
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,22 @@ GLOBAL_LIST_EMPTY(human_ai_brains)
item_search(things_around)
//bullet_detect(things_around)

if(!currently_busy && primary_weapon && current_target && !currently_firing && COOLDOWN_FINISHED(src, fire_overload_cooldown) && primary_weapon.has_ammunition())
currently_busy = TRUE
var/target_futile = current_target.is_mob_incapacitated()
if(get_dist(tied_human, current_target) > gun_data.optimal_range || target_futile)
if(!has_ongoing_action(/datum/ongoing_action/approach_target) && !in_cover)
var/walk_distance = target_futile ? gun_data.minimum_range : gun_data.optimal_range
ADD_ONGOING_ACTION(src, /datum/ongoing_action/approach_target, current_target, walk_distance)
attack_target()
if(primary_weapon && current_target)
if(!has_ongoing_action(AI_ACTION_APPROACH) && !has_ongoing_action(AI_ACTION_RETREAT))
var/target_futile = current_target.is_mob_incapacitated()
var/distance = get_dist(tied_human, current_target)
if(distance > gun_data.optimal_range || target_futile)
if(!in_cover)
var/walk_distance = target_futile ? gun_data.minimum_range : gun_data.optimal_range
ADD_ONGOING_ACTION(src, AI_ACTION_APPROACH, current_target, walk_distance)

else if(distance < gun_data.optimal_range)
var/walk_distance = in_cover ? gun_data.minimum_range : gun_data.optimal_range
ADD_ONGOING_ACTION(src, AI_ACTION_RETREAT, current_target, walk_distance)

if(!currently_busy && !currently_firing && COOLDOWN_FINISHED(src, fire_overload_cooldown))
currently_busy = TRUE
attack_target()

if(!currently_busy && healing_start_check())
currently_busy = TRUE
Expand All @@ -124,7 +132,7 @@ GLOBAL_LIST_EMPTY(human_ai_brains)
tied_human.swap_hand()

/datum/human_ai_brain/proc/nade_throwback(list/things_around)
if(has_ongoing_action(/datum/ongoing_action/throw_back_nade))
if(has_ongoing_action(AI_ACTION_TROWBACK))
return

var/turf/place_to_throw
Expand Down Expand Up @@ -183,7 +191,7 @@ GLOBAL_LIST_EMPTY(human_ai_brains)
return

throw_back_nade:
ADD_ONGOING_ACTION(src, /datum/ongoing_action/throw_back_nade, throw_nade, place_to_throw)
ADD_ONGOING_ACTION(src, AI_ACTION_TROWBACK, throw_nade, place_to_throw)

/// Use ADD_ONGOING_ACTION() macro instead of calling this directly
/datum/human_ai_brain/proc/_add_ongoing_action(datum/ongoing_action/path, ...)
Expand Down
10 changes: 5 additions & 5 deletions code/modules/mob/living/carbon/human/ai/brain/ai_brain_cover.dm
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
shortest_cover_turf = get_turf(cade)
cover_atom = cade
if(shortest_cover_turf)
ADD_ONGOING_ACTION(src, /datum/ongoing_action/take_cover, shortest_cover_turf, cover_atom, FALSE)
ADD_ONGOING_ACTION(src, AI_ACTION_COVER, shortest_cover_turf, cover_atom, FALSE)
if(!from_squad)
squad_cover_processing(FALSE, view_contents - shortest_cover_turf)
else
Expand All @@ -140,7 +140,7 @@
shortest_cover_turf = maybe_cover
cover_atom = wall
if(shortest_cover_turf)
ADD_ONGOING_ACTION(src, /datum/ongoing_action/take_cover, shortest_cover_turf, cover_atom, TRUE)
ADD_ONGOING_ACTION(src, AI_ACTION_COVER, shortest_cover_turf, cover_atom, TRUE)
if(!from_squad)
squad_cover_processing(FALSE, view_contents - shortest_cover_turf)

Expand All @@ -164,7 +164,7 @@
#ifdef TESTING
to_chat(world, "highest_cover_value: [highest_cover_value], turf coords: [highest_cover_turf.x], [highest_cover_turf.y], [highest_cover_turf.z]")
addtimer(CALLBACK(src, PROC_REF(clear_cover_value_debug), turf_dict), 60 SECONDS)
ADD_ONGOING_ACTION(src, /datum/ongoing_action/take_inside_cover, highest_cover_turf)
ADD_ONGOING_ACTION(src, AI_ACTION_COVER_I, highest_cover_turf)
if(!from_squad)
squad_cover_processing(TRUE, turf_dict - highest_cover_turf)
else
Expand All @@ -175,9 +175,9 @@
T.maptext = null

#else
ADD_ONGOING_ACTION(src, /datum/ongoing_action/take_inside_cover, highest_cover_turf)
ADD_ONGOING_ACTION(src, AI_ACTION_COVER_I, highest_cover_turf)
if(!from_squad)
squad_cover_processing(TRUE, view_contents - highest_cover_turf)
squad_cover_processing(TRUE, turf_dict - highest_cover_turf)
else
squad_covering = FALSE
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,4 @@
return mag

/datum/human_ai_brain/proc/should_reload_primary()
return (primary_weapon?.current_mag?.current_rounds <= 0)
return (primary_weapon?.current_mag?.current_rounds <= 0 && !primary_weapon?.in_chamber)
18 changes: 11 additions & 7 deletions code/modules/mob/living/carbon/human/ai/brain/ai_brain_items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@
var/obj/item/storage/storage_item = container_refs[object_loc]
storage_item.attempt_item_insertion(object_ref, FALSE, tied_human)

appraise_inventory()


/// Whenever an item is deleted, purge it from anywhere it may be stored in here
/datum/human_ai_brain/proc/on_item_delete(obj/item/source, force)
Expand Down Expand Up @@ -235,7 +237,7 @@

if(dropped == primary_weapon)
set_primary_weapon(null)
ADD_ONGOING_ACTION(src, /datum/ongoing_action/item_pickup/pickup_primary, dropped)
ADD_ONGOING_ACTION(src, AI_ACTION_PICKUP_GUN, dropped)
for(var/slot in container_refs)
if(container_refs[slot] == dropped)
appraise_inventory(slot == "belt", slot == "backpack", slot == "left_pocket", slot == "right_pocket")
Expand Down Expand Up @@ -272,32 +274,34 @@
continue

if(!primary_weapon && isgun(thing))
ADD_ONGOING_ACTION(src, /datum/ongoing_action/item_pickup, thing)
ADD_ONGOING_ACTION(src, AI_ACTION_PICKUP, thing)
break

if(istype(thing, /obj/item/storage/belt) && !container_refs["belt"])
ADD_ONGOING_ACTION(src, /datum/ongoing_action/item_pickup, thing)
ADD_ONGOING_ACTION(src, AI_ACTION_PICKUP, thing)
break

if(istype(thing, /obj/item/storage/backpack) && !container_refs["backpack"])
ADD_ONGOING_ACTION(src, /datum/ongoing_action/item_pickup, thing)
ADD_ONGOING_ACTION(src, AI_ACTION_PICKUP, thing)
break

if(istype(thing, /obj/item/storage/pouch) && (!container_refs["left_pocket"] || !container_refs["right_pocket"]))
ADD_ONGOING_ACTION(src, /datum/ongoing_action/item_pickup, thing)
ADD_ONGOING_ACTION(src, AI_ACTION_PICKUP, thing)
break

var/storage_spot = storage_has_room(thing)
if(!storage_spot || !thing.ai_can_use(tied_human))
continue

if(is_type_in_list(thing, all_medical_items))
ADD_ONGOING_ACTION(src, /datum/ongoing_action/item_pickup, thing)
ADD_ONGOING_ACTION(src, AI_ACTION_PICKUP, thing)
break

else if(primary_weapon && istype(thing, /obj/item/ammo_magazine))
var/obj/item/ammo_magazine/mag = thing
if(istype(mag, /obj/item/ammo_magazine/handful))
continue
if(istype(primary_weapon, mag.gun_type))
ADD_ONGOING_ACTION(src, /datum/ongoing_action/item_pickup, thing)
ADD_ONGOING_ACTION(src, AI_ACTION_PICKUP, thing)
break

Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@

primary_weapon.set_target(current_target)
gun_data.before_fire(primary_weapon, tied_human, src)
if(!primary_weapon.current_mag || !primary_weapon.current_mag.current_rounds || !friendly_check())
if((!primary_weapon?.current_mag.current_rounds && !primary_weapon.in_chamber) || !friendly_check())
end_gun_fire()
return

Expand Down Expand Up @@ -197,22 +197,24 @@
end_gun_fire()
return

if(get_dist(tied_human, current_target) > gun_data.maximum_range)
if(QDELETED(current_target) || !friendly_check())
end_gun_fire()
return

if(QDELETED(current_target) || !friendly_check())
if(primary_weapon.current_mag?.current_rounds <= 1 && !primary_weapon.in_chamber) // bullet removal comes after comsig is triggered
end_gun_fire()
return

if(primary_weapon.current_mag?.current_rounds <= 1) // bullet removal comes after comsig is triggered
if(!(current_target in viewers(world.view, tied_human)))
if(!in_cover)
ADD_ONGOING_ACTION(src, AI_ACTION_APPROACH_C, current_target, 0)
else if(overwatch_allowed)
establish_overwatch()
end_gun_fire()
return

if(!(current_target in viewers(world.view, tied_human)))
if(get_dist(tied_human, current_target) > gun_data.maximum_range)
end_gun_fire()
if(overwatch_allowed)
establish_overwatch()
return

if(istype(primary_weapon, /obj/item/weapon/gun/shotgun/pump))
Expand Down
7 changes: 4 additions & 3 deletions code/modules/mob/living/carbon/human/ai/firearm_appraisal.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ GLOBAL_LIST_INIT_TYPED(firearm_appraisals, /datum/firearm_appraisal, build_firea

/datum/firearm_appraisal
/// Minimum engagement range with weapon type
var/minimum_range = 1
/// Optimal engagement range, try to approach if further than this
var/minimum_range = 2
/// Optimal engagement range, try to stay at this distance
var/optimal_range = 6
/// Maximum engagement range, stop firing at this distance
var/maximum_range = 9
Expand All @@ -34,14 +34,15 @@ GLOBAL_LIST_INIT_TYPED(firearm_appraisals, /datum/firearm_appraisal, build_firea

/datum/firearm_appraisal/smg
burst_amount_max = 10
minimum_range = 1
optimal_range = 5
maximum_range = 7
gun_types = list(
/obj/item/weapon/gun/smg,
)

/datum/firearm_appraisal/shotgun
burst_amount_max = 2
minimum_range = 1
optimal_range = 1 // point-blank our beloved
maximum_range = 3
gun_types = list(
Expand Down
2 changes: 2 additions & 0 deletions colonialmarines.dme
Original file line number Diff line number Diff line change
Expand Up @@ -1982,6 +1982,8 @@
#include "code\modules\mob\living\carbon\human\ai\ai_management_menu.dm"
#include "code\modules\mob\living\carbon\human\ai\faction_management_panel.dm"
#include "code\modules\mob\living\carbon\human\ai\action_datums\pickup_primary.dm"
#include "code\modules\mob\living\carbon\human\ai\action_datums\approach_target_carefully.dm"
#include "code\modules\mob\living\carbon\human\ai\action_datums\retreat_from_target.dm"
#include "code\modules\mob\living\carbon\human\ai\action_datums\orders\order_action.dm"
#include "code\modules\mob\living\carbon\human\ai\action_datums\orders\patrol_waypoints.dm"
#include "code\modules\mob\living\carbon\human\ai\brain\ai_brain_communication.dm"
Expand Down

0 comments on commit 473c512

Please sign in to comment.