diff --git a/code/__DEFINES/achievements.dm b/code/__DEFINES/achievements.dm index 20c68c015b..0cbba32b96 100644 --- a/code/__DEFINES/achievements.dm +++ b/code/__DEFINES/achievements.dm @@ -35,6 +35,7 @@ #define MEDAL_HOT_DAMN "Hot Damn!" #define MEDAL_CAYENNE_DISK "Very Important Piscis" #define MEDAL_TRAM_SURFER "Tram Surfer" +#define MEDAL_SPRINGLOCK "The Man Inside the Modsuit" //Skill medal hub IDs #define MEDAL_LEGENDARY_MINER "Legendary Miner" diff --git a/code/__DEFINES/dcs/signals/signals_reagent.dm b/code/__DEFINES/dcs/signals/signals_reagent.dm new file mode 100644 index 0000000000..848458f91c --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_reagent.dm @@ -0,0 +1,2 @@ +///Sent by /datum/reagents/proc/reaction, used for /obj/item/mod/module/springlock +#define COMSIG_ATOM_EXPOSE_REAGENTS "atom_expose_reagents" diff --git a/code/_globalvars/lists/maintenance_loot.dm b/code/_globalvars/lists/maintenance_loot.dm index 9aa0f8be0a..53366d23a6 100644 --- a/code/_globalvars/lists/maintenance_loot.dm +++ b/code/_globalvars/lists/maintenance_loot.dm @@ -52,6 +52,7 @@ GLOBAL_LIST_INIT(maintenance_loot, list( /obj/item/stack/cable_coil/random = 4, /obj/item/stack/cable_coil/random/five = 6, /obj/item/mod/construction/broken_core = 5, + /obj/item/mod/module/springlock = 1, /obj/item/stack/medical/suture = 1, /obj/item/stack/rods/ten = 9, /obj/item/stack/rods/twentyfive = 1, diff --git a/code/datums/achievements/misc_achievements.dm b/code/datums/achievements/misc_achievements.dm index 5ad337445b..ace74c13a8 100644 --- a/code/datums/achievements/misc_achievements.dm +++ b/code/datums/achievements/misc_achievements.dm @@ -171,3 +171,9 @@ desc = "Lights out, guerilla radio!" database_id = MEDAL_TRAM_SURFER icon = "tram_surfer" + +/datum/award/achievement/misc/springlock + name = "The Man Inside the MODsuit" + desc = "Ignore the warning label on a springlock MODsuit." + database_id = MEDAL_SPRINGLOCK + icon = "springlock" diff --git a/code/modules/mod/mod_activation.dm b/code/modules/mod/mod_activation.dm index 886ba0fec4..b3705889f1 100644 --- a/code/modules/mod/mod_activation.dm +++ b/code/modules/mod/mod_activation.dm @@ -138,31 +138,31 @@ playsound(src, 'sound/machines/synth_no.ogg', 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, frequency = 6000) return TRUE - if(do_after(wearer, MOD_ACTIVATION_STEP_TIME, target = wearer, required_mobility_flags = NONE)) + if(do_after(wearer, activation_step_time, target = wearer, required_mobility_flags = NONE)) to_chat(wearer, span_notice("[boots] [active ? "relax their grip on your legs" : "seal around your feet"].")) playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) seal_part(boots, seal = !active) else return toggle_activate_fail() - if(do_after(wearer, MOD_ACTIVATION_STEP_TIME, target = wearer, required_mobility_flags = NONE)) + if(do_after(wearer, activation_step_time, target = wearer, required_mobility_flags = NONE)) to_chat(wearer, span_notice("[gauntlets] [active ? "become loose around your fingers" : "tighten around your fingers and wrists"].")) playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) seal_part(gauntlets, seal = !active) else return toggle_activate_fail() - if(do_after(wearer, MOD_ACTIVATION_STEP_TIME, target = wearer, required_mobility_flags = NONE)) + if(do_after(wearer, activation_step_time, target = wearer, required_mobility_flags = NONE)) to_chat(wearer, span_notice("[chestplate] [active ? "releases your chest" : "cinches tightly against your chest"].")) playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) seal_part(chestplate,seal = !active) else return toggle_activate_fail() - if(do_after(wearer, MOD_ACTIVATION_STEP_TIME, target = wearer, required_mobility_flags = NONE)) + if(do_after(wearer, activation_step_time, target = wearer, required_mobility_flags = NONE)) to_chat(wearer, span_notice("[helmet] hisses [active ? "open" : "closed"].")) playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) seal_part(helmet, seal = !active) else return toggle_activate_fail() - if(do_after(wearer, MOD_ACTIVATION_STEP_TIME, target = wearer, required_mobility_flags = NONE)) + if(do_after(wearer, activation_step_time, target = wearer, required_mobility_flags = NONE)) to_chat(wearer, span_notice("Systems [active ? "shut down. Parts unsealed. Goodbye" : "started up. Parts sealed. Welcome"], [wearer].")) if(ai) to_chat(ai, span_notice("SYSTEMS [active ? "DEACTIVATED. GOODBYE" : "ACTIVATED. WELCOME"]: \"[ai]\"")) @@ -247,5 +247,4 @@ seal_part(part, seal = TRUE) finish_activation(on = TRUE) -#undef MOD_ACTIVATION_STEP_TIME #undef MOD_ACTIVATION_STEP_FLAGS diff --git a/code/modules/mod/mod_control.dm b/code/modules/mod/mod_control.dm index 2e650b8045..6dea981443 100644 --- a/code/modules/mod/mod_control.dm +++ b/code/modules/mod/mod_control.dm @@ -65,6 +65,8 @@ var/slowdown_inactive = 2 /// Slowdown of the MOD when active. var/slowdown_active = 1 + /// How long this MOD takes each part to seal. + var/activation_step_time = MOD_ACTIVATION_STEP_TIME /// MOD cell. var/obj/item/stock_parts/cell/cell /// MOD helmet. diff --git a/code/modules/mod/modules/modules_maint.dm b/code/modules/mod/modules/modules_maint.dm index 9252ed7ce8..f73969d625 100644 --- a/code/modules/mod/modules/modules_maint.dm +++ b/code/modules/mod/modules/modules_maint.dm @@ -1,6 +1,62 @@ //Maint modules for MODsuits -///Springlock Mechanism - Nope +///Springlock Mechanism - allows your modsuit to activate faster, but reagents are very dangerous. +/obj/item/mod/module/springlock + name = "MOD springlock module" + desc = "A module that spans the entire size of the MOD unit, sitting under the outer shell. \ + This mechanical exoskeleton pushes out of the way when the user enters and it helps in booting \ + up, but was taken out of modern suits because of the springlock's tendency to \"snap\" back \ + into place when exposed to humidity. You know what it's like to have an entire exoskeleton enter you?" + icon_state = "springlock" + complexity = 3 // it is inside every part of your suit, so + incompatible_modules = list(/obj/item/mod/module/springlock) + +/obj/item/mod/module/springlock/on_install() + mod.activation_step_time *= 0.5 + +/obj/item/mod/module/springlock/on_uninstall(deleting = FALSE) + mod.activation_step_time *= 2 + +/obj/item/mod/module/springlock/on_suit_activation() + RegisterSignal(mod.wearer, COMSIG_ATOM_EXPOSE_REAGENTS, .proc/on_wearer_exposed) + +/obj/item/mod/module/springlock/on_suit_deactivation(deleting = FALSE) + UnregisterSignal(mod.wearer, COMSIG_ATOM_EXPOSE_REAGENTS) + +///Signal fired when wearer is exposed to reagents +/obj/item/mod/module/springlock/proc/on_wearer_exposed(atom/source, list/reagents, datum/reagents/source_reagents, methods, volume_modifier, show_message, from_gas) + SIGNAL_HANDLER + + if(!reagents.len) + return + if(!(methods & (VAPOR|PATCH|TOUCH))) + return //remove non-touch reagent exposure + to_chat(mod.wearer, span_danger("[src] makes an ominous click sound...")) + playsound(src, 'sound/items/modsuit/springlock.ogg', 75, TRUE) + addtimer(CALLBACK(src, .proc/snap_shut), rand(3 SECONDS, 5 SECONDS)) + RegisterSignal(mod, COMSIG_MOD_ACTIVATE, .proc/on_activate_spring_block) + +///Signal fired when wearer attempts to activate/deactivate suits +/obj/item/mod/module/springlock/proc/on_activate_spring_block(datum/source, user) + SIGNAL_HANDLER + + balloon_alert(user, "springlocks aren't responding...?") + return MOD_CANCEL_ACTIVATE + +///Delayed death proc of the suit after the wearer is exposed to reagents +/obj/item/mod/module/springlock/proc/snap_shut() + UnregisterSignal(mod, COMSIG_MOD_ACTIVATE) + if(!mod.wearer) //while there is a guaranteed user when on_wearer_exposed() fires, that isn't the same case for this proc + return + mod.wearer.visible_message("[src] inside [mod.wearer]'s [mod.name] snaps shut, mutilating the user inside!", span_userdanger("*SNAP*")) + mod.wearer.emote("scream") + playsound(mod.wearer, 'sound/effects/snap.ogg', 75, TRUE, frequency = 0.5) + playsound(mod.wearer, 'sound/effects/splat.ogg', 50, TRUE, frequency = 0.5) + mod.wearer.client?.give_award(/datum/award/achievement/misc/springlock, mod.wearer) + mod.wearer.apply_damage(500, BRUTE, forced = TRUE, spread_damage = TRUE, sharpness = SHARP_POINTY) //boggers, bogchamp, etc + if(!HAS_TRAIT(mod.wearer, TRAIT_NODEATH)) + mod.wearer.death() //just in case, for some reason, they're still alive + flash_color(mod.wearer, flash_color = "#FF0000", flash_time = 10 SECONDS) ///Rave Visor - Pointless diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index d233866f80..77d713047a 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -890,6 +890,7 @@ R.reaction_turf(A, R.volume * volume_modifier, show_message, from_gas) if("OBJ") R.reaction_obj(A, R.volume * volume_modifier, show_message) + SEND_SIGNAL(A, COMSIG_ATOM_EXPOSE_REAGENTS, cached_reagents, src, method, volume_modifier, show_message, from_gas) /datum/reagents/proc/holder_full() if(total_volume >= maximum_volume) diff --git a/tgstation.dme b/tgstation.dme index 13fa372d59..df50f2c197 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -160,6 +160,7 @@ #include "code\__DEFINES\dcs\signals.dm" #include "code\__DEFINES\dcs\signals\signals_medical.dm" #include "code\__DEFINES\dcs\signals\signals_mod.dm" +#include "code\__DEFINES\dcs\signals\signals_reagent.dm" #include "code\__DEFINES\dcs\signals\signals_subsystem.dm" #include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_movable.dm" #include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_movement.dm"