diff --git a/code/datums/elements/skittish.dm b/code/datums/elements/skittish.dm new file mode 100644 index 00000000000..f3706c0e286 --- /dev/null +++ b/code/datums/elements/skittish.dm @@ -0,0 +1,61 @@ +/* + * An element that makes mobs run into lockers when they bump into them. + */ + +/datum/element/skittish + element_flags = ELEMENT_DETACH + +/datum/element/skittish/Attach(datum/target) + . = ..() + if(!isliving(target)) + return ELEMENT_INCOMPATIBLE + + RegisterSignal(target, COMSIG_MOVABLE_BUMP, .proc/Bump) + +/datum/element/skittish/Detach(datum/target) + UnregisterSignal(target, COMSIG_MOVABLE_BUMP) + . = ..() + +/datum/element/skittish/proc/Bump(mob/living/scooby, atom/target) + if(scooby.stat != CONSCIOUS || scooby.m_intent != MOVE_INTENT_RUN) + return + + if(!istype(target, /obj/structure/closet)) + return + + var/obj/structure/closet/closet = target + + if(!closet.divable) + // Things like secure crates can blow up under certain circumstances + return + + var/turf/closet_turf = get_turf(closet) + + if(!closet.opened) + if(closet.locked) + closet.togglelock(scooby, silent = TRUE) + if(!closet.open(scooby)) + // No message if unable to open, since this is on Bump, spammy potential + return + + // If it's a crate, "dive for cover" and start resting so people can jump into crates without slamming the lid on their head + if(closet.horizontal) + // need to rest before moving, otherwise "can't get crate to close" message will be printed erroneously + scooby.set_resting(TRUE, silent = TRUE) + + scooby.forceMove(closet_turf) + + if(!closet.close(scooby)) + to_chat(scooby, "You can't get [closet] to close!") + if(closet.horizontal) + scooby.set_resting(FALSE, silent = TRUE) + return + + closet.togglelock(scooby, silent = TRUE) + + if(closet.horizontal) + scooby.set_resting(FALSE, silent = TRUE) + + closet_turf.visible_message("[scooby] dives into [closet]!") + // If you run into a locker, you don't want to run out immediately + scooby.Immobilize(0.5 SECONDS) diff --git a/code/datums/traits/good.dm b/code/datums/traits/good.dm index 8bd59861af0..c0762bac662 100644 --- a/code/datums/traits/good.dm +++ b/code/datums/traits/good.dm @@ -188,7 +188,7 @@ /datum/quirk/skittish name = "Skittish" - desc = "You can conceal yourself in danger. Ctrl-shift-click a closed locker to jump into it, as long as you have access." + desc = "You're easy to startle, and hide frequently. Run into a closed locker to jump into it, as long as you have access. You can walk to avoid this." value = 8 mob_trait = TRAIT_SKITTISH medical_record_text = "Patient demonstrates a high aversion to danger and has described hiding in containers out of fear." diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index fcbb7a135a5..e4d60c849a4 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -37,6 +37,8 @@ var/delivery_icon = "deliverycloset" //which icon to use when packagewrapped. null to be unwrappable. var/anchorable = TRUE var/icon_welded = "welded" + /// Whether a skittish person can dive inside this closet. Disable if opening the closet causes "bad things" to happen or that it leads to a logical inconsistency. + var/divable = TRUE /obj/structure/closet/Initialize(mapload) @@ -102,10 +104,9 @@ . += "The parts are welded together." else if(secure && !opened) . += "Alt-click to [locked ? "unlock" : "lock"]." - if(isliving(user)) - var/mob/living/L = user - if(HAS_TRAIT(L, TRAIT_SKITTISH)) - . += "Ctrl-Shift-click [src] to jump inside." + + if(HAS_TRAIT(user, TRAIT_SKITTISH) && divable) + . += "If you bump into [p_them()] while running, you will jump inside." /obj/structure/closet/CanAllowThrough(atom/movable/mover, turf/target) . = ..() @@ -448,13 +449,6 @@ else togglelock(user) -/obj/structure/closet/CtrlShiftClick(mob/living/user) - if(!HAS_TRAIT(user, TRAIT_SKITTISH)) - return ..() - if(!user.canUseTopic(src, BE_CLOSE) || !isturf(user.loc)) - return - dive_into(user) - /obj/structure/closet/proc/togglelock(mob/living/user, silent) if(secure && !broken) if(allowed(user)) @@ -522,24 +516,3 @@ /obj/structure/closet/return_temperature() return - -/obj/structure/closet/proc/dive_into(mob/living/user) - var/turf/T1 = get_turf(user) - var/turf/T2 = get_turf(src) - if(!opened) - if(locked) - togglelock(user, TRUE) - if(!open(user)) - to_chat(user, "It won't budge!") - return - step_towards(user, T2) - T1 = get_turf(user) - if(T1 == T2) - user.set_resting(TRUE) //so people can jump into crates without slamming the lid on their head - if(!close(user)) - to_chat(user, "You can't get [src] to close!") - user.set_resting(FALSE) - return - user.set_resting(FALSE) - togglelock(user) - T1.visible_message("[user] dives into [src]!") diff --git a/code/game/objects/structures/crates_lockers/crates/large.dm b/code/game/objects/structures/crates_lockers/crates/large.dm index 4861cc3c5bb..655c42a0826 100644 --- a/code/game/objects/structures/crates_lockers/crates/large.dm +++ b/code/game/objects/structures/crates_lockers/crates/large.dm @@ -12,6 +12,9 @@ open_sound_volume = 25 close_sound_volume = 50 + // Stops people from "diving into" a crate you can't open normally + divable = FALSE + /obj/structure/closet/crate/large/attack_hand(mob/user) add_fingerprint(user) if(manifest) diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm index 17af647cc64..f86bce4268c 100644 --- a/code/modules/mining/abandoned_crates.dm +++ b/code/modules/mining/abandoned_crates.dm @@ -13,6 +13,9 @@ var/spawned_loot = FALSE tamperproof = 90 + // Stop people from "diving into" the crate accidentally, and then detonating it. + divable = FALSE + /obj/structure/closet/crate/secure/loot/Initialize() . = ..() var/list/digits = list("1", "2", "3", "4", "5", "6", "7", "8", "9", "0") @@ -98,17 +101,11 @@ return return ..() -/obj/structure/closet/secure/loot/dive_into(mob/living/user) - if(!locked) - return ..() - to_chat(user, "That seems like a stupid idea.") - return FALSE - /obj/structure/closet/crate/secure/loot/emag_act(mob/user) if(locked) boom(user) -/obj/structure/closet/crate/secure/loot/togglelock(mob/user) +/obj/structure/closet/crate/secure/loot/togglelock(mob/user, silent = FALSE) if(locked) boom(user) else diff --git a/code/modules/mob/living/init_signals.dm b/code/modules/mob/living/init_signals.dm index 6eba736084f..08ddbf7a5f7 100644 --- a/code/modules/mob/living/init_signals.dm +++ b/code/modules/mob/living/init_signals.dm @@ -41,6 +41,9 @@ RegisterSignal(src, COMSIG_MOVETYPE_FLAG_ENABLED, .proc/on_movement_type_flag_enabled) RegisterSignal(src, COMSIG_MOVETYPE_FLAG_DISABLED, .proc/on_movement_type_flag_disabled) + RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_SKITTISH), .proc/on_skittish_trait_gain) + RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_SKITTISH), .proc/on_skittish_trait_loss) + /// Called when [TRAIT_KNOCKEDOUT] is added to the mob. /mob/living/proc/on_knockedout_trait_gain(datum/source) SIGNAL_HANDLER @@ -192,3 +195,14 @@ /mob/living/proc/on_movement_type_flag_disabled(datum/source, trait) SIGNAL_HANDLER update_movespeed(FALSE) + + +/// Called when [TRAIT_SKITTISH] is added to the mob. +/mob/living/proc/on_skittish_trait_gain(datum/source) + SIGNAL_HANDLER + AddElement(/datum/element/skittish) + +/// Called when [TRAIT_SKITTISH] is removed from the mob. +/mob/living/proc/on_skittish_trait_loss(datum/source) + SIGNAL_HANDLER + RemoveElement(/datum/element/skittish) diff --git a/tgstation.dme b/tgstation.dme index 811ae45340d..3aa28148237 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -610,6 +610,7 @@ #include "code\datums\elements\rad_insulation.dm" #include "code\datums\elements\ridable.dm" #include "code\datums\elements\selfknockback.dm" +#include "code\datums\elements\skittish.dm" #include "code\datums\elements\snail_crawl.dm" #include "code\datums\elements\squashable.dm" #include "code\datums\elements\squish.dm"