From 42f4df09a7ca6a7dbe01cf6b3e14c8cd11378c96 Mon Sep 17 00:00:00 2001 From: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Date: Sun, 30 Nov 2025 18:26:11 -0600 Subject: [PATCH] Tweaks ai `escape_captivity` behavior (#94224) ## About The Pull Request Now: AI will break chairs they're buckled in After PR: Ai will prefer to resist out of chairs if possible Fixes #94222 , partially Really I think this shouldn't be a subtree, orrrrr if it is it should be enabled by combat. It's weird that buckling a pet into a pet bed encourages them to get up ASAP. If a mob is completely docile or otherwise not trying to act, they shouldn't freak out and break whatever they're sat in. Alternatively pets need a behavior for seeking out a bed (but that's more effort) ## Changelog :cl: Melbert fix: AI mobs will prefer to resist out of simple buckles (like being sat in a chair or bed) rather than try to break the chair. /:cl: --- code/__DEFINES/traits/declarations.dm | 3 +++ code/_globalvars/traits/_traits.dm | 1 + .../ai/basic_mobs/basic_subtrees/escape_captivity.dm | 12 +++++++----- .../objects/structures/beds_chairs/alien_nest.dm | 4 ++++ code/game/objects/structures/kitchen_spike.dm | 1 + code/modules/antagonists/ninja/energy_net_nets.dm | 1 + 6 files changed, 17 insertions(+), 5 deletions(-) diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index d21b53334a0..b48d5301670 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -1608,4 +1608,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Doesn't need to be applied to any turfs that override can_cross_safely #define TRAIT_AI_AVOID_TURF "warning_turf" +/// Object is dangerous to mobs buckled to it +#define TRAIT_DANGEROUS_BUCKLE "dangerous_buckle" + // END TRAIT DEFINES diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index fdb59ad3c00..27d80d6e540 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -49,6 +49,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_CASTABLE_LOC" = TRAIT_CASTABLE_LOC, "TRAIT_CHASM_STOPPER" = TRAIT_CHASM_STOPPER, "TRAIT_COMBAT_MODE_SKIP_INTERACTION" = TRAIT_COMBAT_MODE_SKIP_INTERACTION, + "TRAIT_DANGEROUS_BUCKLE" = TRAIT_DANGEROUS_BUCKLE, "TRAIT_DEL_ON_SPACE_DUMP" = TRAIT_DEL_ON_SPACE_DUMP, "TRAIT_FOOD_DONT_INHERIT_NAME_FROM_PROCESSED" = TRAIT_FOOD_DONT_INHERIT_NAME_FROM_PROCESSED, "TRAIT_FROZEN" = TRAIT_FROZEN, diff --git a/code/datums/ai/basic_mobs/basic_subtrees/escape_captivity.dm b/code/datums/ai/basic_mobs/basic_subtrees/escape_captivity.dm index 2c0a198c768..759a5c69eb8 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/escape_captivity.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/escape_captivity.dm @@ -8,11 +8,13 @@ /datum/ai_planning_subtree/escape_captivity/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) var/mob/living/living_pawn = controller.pawn - if (living_pawn.buckled && !ismob(living_pawn.buckled)) - if (!pacifist && !living_pawn.can_hold_items() || living_pawn.usable_hands < 1) // If we don't have hands then prioritise slapping the shit out of whatever we are attached to - controller.queue_behavior(/datum/ai_behavior/break_out_of_object, living_pawn.buckled) - else + if (isobj(living_pawn.buckled)) + // we can just stand up we don't need to freak out + if (pacifist || !HAS_TRAIT(living_pawn.buckled, TRAIT_DANGEROUS_BUCKLE)) controller.queue_behavior(/datum/ai_behavior/resist) + // otherwise beat the shit out of we we gotta get out NOW + else + controller.queue_behavior(/datum/ai_behavior/break_out_of_object, living_pawn.buckled) return SUBTREE_RETURN_FINISH_PLANNING if (!isturf(living_pawn.loc) && !ismob(living_pawn.loc) && !istype(living_pawn.loc, /obj/item/mob_holder)) @@ -26,7 +28,7 @@ controller.queue_behavior(/datum/ai_behavior/break_out_of_object, contained_in) else controller.queue_behavior(/datum/ai_behavior/resist) - return SUBTREE_RETURN_FINISH_PLANNING + return SUBTREE_RETURN_FINISH_PLANNING var/mob/puller = living_pawn.pulledby if (puller && puller.grab_state > GRAB_PASSIVE) diff --git a/code/game/objects/structures/beds_chairs/alien_nest.dm b/code/game/objects/structures/beds_chairs/alien_nest.dm index 1f77227a8be..2c0b620dce9 100644 --- a/code/game/objects/structures/beds_chairs/alien_nest.dm +++ b/code/game/objects/structures/beds_chairs/alien_nest.dm @@ -15,6 +15,10 @@ can_deconstruct = FALSE var/static/mutable_appearance/nest_overlay = mutable_appearance('icons/mob/nonhuman-player/alien.dmi', "nestoverlay", LYING_MOB_LAYER) +/obj/structure/bed/nest/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_DANGEROUS_BUCKLE, INNATE_TRAIT) + /obj/structure/bed/nest/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) if(held_item?.tool_behaviour == TOOL_WRENCH) return NONE diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm index 2d5a67ffe42..d70315a43e9 100644 --- a/code/game/objects/structures/kitchen_spike.dm +++ b/code/game/objects/structures/kitchen_spike.dm @@ -78,6 +78,7 @@ /obj/structure/kitchenspike/Initialize(mapload) . = ..() register_context() + ADD_TRAIT(src, TRAIT_DANGEROUS_BUCKLE, INNATE_TRAIT) /obj/structure/kitchenspike/examine(mob/user) . = ..() diff --git a/code/modules/antagonists/ninja/energy_net_nets.dm b/code/modules/antagonists/ninja/energy_net_nets.dm index 5f08762b341..8d4b37cc0ad 100644 --- a/code/modules/antagonists/ninja/energy_net_nets.dm +++ b/code/modules/antagonists/ninja/energy_net_nets.dm @@ -27,6 +27,7 @@ underlay.layer = BELOW_MOB_LAYER SET_PLANE_EXPLICIT(underlay, GAME_PLANE, src) add_overlay(underlay) + ADD_TRAIT(src, TRAIT_DANGEROUS_BUCKLE, INNATE_TRAIT) /obj/structure/energy_net/play_attack_sound(damage, damage_type = BRUTE, damage_flag = 0) if(damage_type == BRUTE || damage_type == BURN)