From 4ff00f8ab5c20ddbbcfc089fc90117140b281684 Mon Sep 17 00:00:00 2001 From: SatinIsle <98125273+SatinIsle@users.noreply.github.com> Date: Thu, 31 Oct 2024 09:53:31 +0000 Subject: [PATCH] Metal Vore Solid (#16542) * Metal Vore Solid Added a new AI function called guard_limit. This limits the "find target" portion of the AI to only acquire targets that are in front of them, allowing people to potentially sneak behind them. Added a few guard_limit variants of existing AI holder types, particularly for mercs. Tested and it seems to work exactly as intended. If their friends are engaged in combat, they will still rush in to help them even if they were looking the other way. * Update code/modules/ai/ai_holder_targeting.dm Co-authored-by: ShadowLarkens --------- Co-authored-by: ShadowLarkens --- .../ai/ai_holder_subtypes/simple_mob_ai.dm | 29 +++++++++++ code/modules/ai/ai_holder_targeting.dm | 6 ++- .../subtypes/humanoid/mercs/mercs.dm | 48 +++++++++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) diff --git a/code/modules/ai/ai_holder_subtypes/simple_mob_ai.dm b/code/modules/ai/ai_holder_subtypes/simple_mob_ai.dm index 4455b47072b..b2d4a896589 100644 --- a/code/modules/ai/ai_holder_subtypes/simple_mob_ai.dm +++ b/code/modules/ai/ai_holder_subtypes/simple_mob_ai.dm @@ -98,6 +98,23 @@ step_rand(holder) holder.face_atom(AM) +// Only attacks you if you're in front of it. +/datum/ai_holder/simple_mob/ranged/guard_limit + guard_limit = TRUE + returns_home = TRUE + +/datum/ai_holder/simple_mob/ranged/guard_limit/pointblank + pointblank = TRUE + +/datum/ai_holder/simple_mob/ranged/guard_limit/aggressive + pointblank = TRUE + var/closest_distance = 1 + +/datum/ai_holder/simple_mob/ranged/guard_limit/kiting + pointblank = TRUE // So we don't need to copypaste post_melee_attack(). + var/run_if_this_close = 4 // If anything gets within this range, it'll try to move away. + var/moonwalk = TRUE // If true, mob turns to face the target while kiting, otherwise they turn in the direction they moved towards. + // Switches intents based on specific criteria. // Used for special mobs who do different things based on intents (and aren't slimes). // Intent switching is generally done in pre_[ranged/special]_attack(), so that the mob can use the right attack for the right time. @@ -142,6 +159,14 @@ return TRUE // We're out in the open, uncloaked, and our target isn't stunned, so lets flee. return FALSE +// Can only target people in view range, will return home +/datum/ai_holder/simple_mob/melee/guard_limit + guard_limit = TRUE + returns_home = TRUE + +/datum/ai_holder/simple_mob/melee/evasive/guard_limit + guard_limit = TRUE + returns_home = TRUE // Simple mobs that aren't hostile, but will fight back. /datum/ai_holder/simple_mob/retaliate @@ -197,3 +222,7 @@ /datum/ai_holder/simple_mob/passive/speedy base_wander_delay = 1 + +// For setting up possible stealth missions +/datum/ai_holder/simple_mob/humanoid/hostile/guard_limit + guard_limit = TRUE diff --git a/code/modules/ai/ai_holder_targeting.dm b/code/modules/ai/ai_holder_targeting.dm index b918321f8b3..0525ee59515 100644 --- a/code/modules/ai/ai_holder_targeting.dm +++ b/code/modules/ai/ai_holder_targeting.dm @@ -10,6 +10,7 @@ var/micro_hunt = FALSE // Will target mobs at or under the micro_hunt_size size, requires vore_hostile to be true var/micro_hunt_size = 0.25 var/belly_attack = TRUE //Mobs attack if they are in a belly! + var/guard_limit = FALSE //Mobs will not acquire targets unless they are in front of them. var/atom/movable/target = null // The thing (mob or object) we're trying to kill. var/atom/movable/preferred_target = null// If set, and if given the chance, we will always prefer to target this over other options. @@ -49,7 +50,10 @@ . = list() if(!has_targets_list) possible_targets = list_targets() - for(var/possible_target in possible_targets) + for(var/atom/possible_target as anything in possible_targets) + if(guard_limit) + if((holder.dir == 1 && holder.y >= possible_target.y) || (holder.dir == 2 && holder.y <= possible_target.y) || (holder.dir == 4 && holder.x >= possible_target.x) || (holder.dir == 8 && holder.x <= possible_target.x)) //Ignore targets that are behind you + continue if(can_attack(possible_target)) // Can we attack it? . += possible_target diff --git a/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm b/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm index 115e0cb4101..eabe9b296ca 100644 --- a/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm +++ b/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm @@ -87,14 +87,23 @@ intelligence_level = AI_SMART // Also knows not to walk while confused if it risks death. threaten_delay = 30 SECONDS // Mercs will give you 30 seconds to leave or get shot. +/datum/ai_holder/simple_mob/merc/guard_limit + guard_limit = TRUE + /datum/ai_holder/simple_mob/merc/ranged pointblank = TRUE // They get close? Just shoot 'em! firing_lanes = TRUE // But not your buddies! conserve_ammo = TRUE // And don't go wasting bullets! +/datum/ai_holder/simple_mob/merc/ranged/guard_limit + guard_limit = TRUE + /datum/ai_holder/simple_mob/merc/ranged/sniper vision_range = 14 // We're a person with a long-ranged gun. +/datum/ai_holder/simple_mob/merc/ranged/sniper/guard_limit + guard_limit = TRUE + /datum/ai_holder/simple_mob/merc/ranged/sniper/max_range(atom/movable/AM) return holder.ICheckRangedAttack(AM) ? 14 : 1 @@ -426,3 +435,42 @@ /obj/item/grenade/spawnergrenade/manhacks/mercenary = 50, /obj/item/grenade/spawnergrenade/manhacks/mercenary = 30 ) + + +//////////////////////////////// +// Stealth Mission Mercs +//////////////////////////////// + +// Most likely to drop a broken weapon matching them, if it's a gun. +/mob/living/simple_mob/humanoid/merc/melee/poi/guard_limit + ai_holder_type = /datum/ai_holder/simple_mob/merc/guard_limit + +/mob/living/simple_mob/humanoid/merc/melee/sword/poi/guard_limit + ai_holder_type = /datum/ai_holder/simple_mob/merc/guard_limit + +/mob/living/simple_mob/humanoid/merc/ranged/poi/guard_limit + ai_holder_type = /datum/ai_holder/simple_mob/merc/ranged/guard_limit + +/mob/living/simple_mob/humanoid/merc/ranged/smg/poi/guard_limit + ai_holder_type = /datum/ai_holder/simple_mob/merc/ranged/guard_limit + +/mob/living/simple_mob/humanoid/merc/ranged/laser/poi/guard_limit + ai_holder_type = /datum/ai_holder/simple_mob/merc/ranged/guard_limit + +/mob/living/simple_mob/humanoid/merc/ranged/ionrifle/poi/guard_limit + ai_holder_type = /datum/ai_holder/simple_mob/merc/ranged/guard_limit + +/mob/living/simple_mob/humanoid/merc/ranged/grenadier/poi/guard_limit + ai_holder_type = /datum/ai_holder/simple_mob/merc/ranged/guard_limit + +/mob/living/simple_mob/humanoid/merc/ranged/rifle/poi/guard_limit + ai_holder_type = /datum/ai_holder/simple_mob/merc/ranged/guard_limit + +/mob/living/simple_mob/humanoid/merc/ranged/rifle/mag/poi/guard_limit + ai_holder_type = /datum/ai_holder/simple_mob/merc/ranged/guard_limit + +/mob/living/simple_mob/humanoid/merc/ranged/technician/poi/guard_limit + ai_holder_type = /datum/ai_holder/simple_mob/merc/ranged/guard_limit + +/mob/living/simple_mob/humanoid/merc/ranged/sniper/guard_limit + ai_holder_type = /datum/ai_holder/simple_mob/merc/ranged/sniper/guard_limit