Files
MrMelbert 42f4df09a7 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

🆑 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.
/🆑
2025-11-30 17:26:11 -07:00

136 lines
5.2 KiB
Plaintext

//Alium nests. Essentially beds with an unbuckle delay that only aliums can buckle mobs to.
/obj/structure/bed/nest
name = "alien nest"
desc = "It's a gruesome pile of thick, sticky resin shaped like a nest."
icon = 'icons/obj/smooth_structures/alien/nest.dmi'
icon_state = "nest-0"
base_icon_state = "nest"
max_integrity = 120
smoothing_flags = SMOOTH_BITMASK
smoothing_groups = SMOOTH_GROUP_ALIEN_NEST
canSmoothWith = SMOOTH_GROUP_ALIEN_NEST
build_stack_type = null
elevation = 0
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
return ..()
/obj/structure/bed/nest/buckle_feedback(mob/living/being_buckled, mob/buckler)
if(being_buckled == buckler)
being_buckled.visible_message(
span_notice("[buckler] lays down on [src], wrapping [buckler.p_them()]self in a thick, sticky resin."),
span_notice("You lay down on [src], wrapping yourself in a thick, sticky resin."),
visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE,
)
else
being_buckled.visible_message(
span_notice("[buckler] lays [being_buckled] down on [src], wrapping [being_buckled.p_them()] in a thick, sticky resin."),
span_notice("[buckler] lays you down on [src], wrapping you in a thick, sticky resin."),
visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE,
)
/obj/structure/bed/nest/unbuckle_feedback(mob/living/being_unbuckled, mob/unbuckler)
if(being_unbuckled == unbuckler)
being_unbuckled.visible_message(
span_notice("[unbuckler] pulls [unbuckler.p_them()]self free from the sticky nest!"),
span_notice("You pull yourself free from the sticky nest!"),
visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE,
)
else
being_unbuckled.visible_message(
span_notice("[unbuckler] pulls [being_unbuckled] free from the sticky nest!"),
span_notice("[unbuckler] pulls you free from the sticky nest!"),
visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE,
)
/obj/structure/bed/nest/user_unbuckle_mob(mob/living/captive, mob/living/hero)
if(!length(buckled_mobs))
return
if(hero.get_organ_by_type(/obj/item/organ/alien/plasmavessel))
unbuckle_mob(captive)
add_fingerprint(hero)
return
if(captive != hero)
captive.visible_message(span_notice("[hero.name] pulls [captive.name] free from the sticky nest!"),
span_notice("[hero.name] pulls you free from the gelatinous resin."),
span_hear("You hear squelching..."))
unbuckle_mob(captive)
add_fingerprint(hero)
return
captive.visible_message(span_warning("[captive.name] struggles to break free from the gelatinous resin!"),
span_notice("You struggle to break free from the gelatinous resin... (Stay still for about a minute and a half.)"),
span_hear("You hear squelching..."))
if(!do_after(captive, 100 SECONDS, target = src, hidden = TRUE))
if(captive.buckled)
to_chat(captive, span_warning("You fail to unbuckle yourself!"))
return
captive.visible_message(span_warning("[captive.name] breaks free from the gelatinous resin!"),
span_notice("You break free from the gelatinous resin!"),
span_hear("You hear squelching..."))
unbuckle_mob(captive)
add_fingerprint(hero)
/obj/structure/bed/nest/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE)
if ( !ismob(M) || (get_dist(src, user) > 1) || (M.loc != src.loc) || user.incapacitated || M.buckled )
return
if(M.get_organ_by_type(/obj/item/organ/alien/plasmavessel))
return
if(!user.get_organ_by_type(/obj/item/organ/alien/plasmavessel))
return
if(has_buckled_mobs())
unbuckle_all_mobs()
if(buckle_mob(M))
M.visible_message(span_notice("[user.name] secretes a thick vile goo, securing [M.name] into [src]!"),\
span_danger("[user.name] drenches you in a foul-smelling resin, trapping you in [src]!"),\
span_hear("You hear squelching..."))
/obj/structure/bed/nest/post_buckle_mob(mob/living/M)
ADD_TRAIT(M, TRAIT_HANDS_BLOCKED, type)
M.add_offsets(type, x_add = 2)
M.layer = BELOW_MOB_LAYER
add_overlay(nest_overlay)
if(ishuman(M))
var/mob/living/carbon/human/victim = M
if(((victim.wear_mask && istype(victim.wear_mask, /obj/item/clothing/mask/facehugger)) || HAS_TRAIT(victim, TRAIT_XENO_HOST)) && victim.stat != DEAD) //If they're a host or have a facehugger currently infecting them. Must be alive.
victim.apply_status_effect(/datum/status_effect/nest_sustenance)
/obj/structure/bed/nest/post_unbuckle_mob(mob/living/M)
REMOVE_TRAIT(M, TRAIT_HANDS_BLOCKED, type)
M.remove_offsets(type)
M.layer = initial(M.layer)
cut_overlay(nest_overlay)
M.remove_status_effect(/datum/status_effect/nest_sustenance)
/obj/structure/bed/nest/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
playsound(loc, 'sound/effects/blob/attackblob.ogg', 100, TRUE)
if(BURN)
playsound(loc, 'sound/items/tools/welder.ogg', 100, TRUE)
/obj/structure/bed/nest/attack_alien(mob/living/carbon/alien/user, list/modifiers)
if(!user.combat_mode)
return attack_hand(user, modifiers)
else
return ..()