Files
cb3468a5ce Handrails, visual shuttle buckles, and buckling feedback changes (#91504)
## About The Pull Request

1. Adds Handrails, currently mapper only. [Sprite ported from
Baystation](https://github.com/Baystation12/Baystation12/blob/dev/icons/obj/structures/handrail.dmi).
This is just a small fluff object designed to be put onto shuttles.
Players can click on it (or mouse drop) to buckle to it (grab it),
keeping them from being thrown around on shuttle launch.


![image](https://github.com/user-attachments/assets/b5bba651-d6ad-4e12-bb13-988ad5bc64ca)

2. Adds Shuttle chair restraints. [Sprite ported from
Aurora](https://github.com/Aurorastation/Aurora.3/blob/master/icons/obj/structure/chairs.dmi),
though altered a decent amount. They flip up with no one seated and flip
down when someone buckles, but they have no gameplay effects (ie, they
don't require a do-after, they don't block hands, etc etc)


![image](https://github.com/user-attachments/assets/4118a174-2443-4da2-8126-649dccfdcb65)


![image](https://github.com/user-attachments/assets/d40fb7b4-f7d2-4052-8f6c-41dfda62cf95)

3. Some objects now have unique feedback messages for buckling - you sit
on chairs, or lay down on beds. This message will change depending on if
the mob is restrained, so it's a bit more obvious when someone is tied
to a chair vs just sitting down.


![image](https://github.com/user-attachments/assets/9ea1da9f-ae25-4008-8ca4-8202f7508290)

4. If you're buckled on a shuttle which has "knockdown" force, you won't
be paralyzed - instead, just knocked down and immobilized for a short
period (so you can still use your hands / act).

## Why It's Good For The Game

1. Gives mappers some additional fluff for shuttles, especially if their
shuttle has knockdown force.

2. Adds muh immersion to shuttle rides. Just a flavor thing.

3. Adds muh immersion to sitting down at the bar. Again just a flavor
thing.

4. I did this to make handrails work, but I can find an alternate
workaround if so desired.

## Changelog

🆑 Melbert, sprites from Baystation / Aurorastation
add: Adds grabbable handrails (mapper only for now)
image: Adds a visual effect to buckling to shuttle seats
qol: Different objects have different chat messages for buckling. 
qol: If you're buckled in on a violent shuttle ride, you will be knocked
down and immobilized, but not fully stunned (ie: can still use hands).
/🆑

---------

Co-authored-by: san7890 <the@san7890.com>
2025-06-15 15:53:27 -04:00

132 lines
5.1 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/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 ..()