Springlock MODule now only activates when you have at least a single sealed piece (#89222)

## About The Pull Request

Springlocks no longer trigger when you only have a back piece deployed,
only damages bodyparts covered by deployed pieces, and prevents you from
retracting them when it's been set off

Closes #89218

## Changelog
🆑
fix: Springlock MODule now only activates when you have at least a
single sealed piece
fix: Springlock MODule no longer damages bodyparts not covered by your
MODsuit
/🆑
This commit is contained in:
SmArtKar
2025-01-29 17:56:55 +01:00
committed by GitHub
parent c35737fa29
commit cb1bf1431e
3 changed files with 28 additions and 6 deletions
+2 -1
View File
@@ -8,7 +8,8 @@
/// Called when a MOD deploys a part. (mob/user, datum/mod_part/part)
#define COMSIG_MOD_PART_DEPLOYED "mod_part_deployed"
/// Called when a MOD retracts a part. (mob/user, datum/mod_part/part)
#define COMSIG_MOD_PART_RETRACTED "mod_part_retracted"
#define COMSIG_MOD_PART_RETRACTING "mod_part_retracting"
#define MOD_CANCEL_RETRACTION (1 << 0)
/// Called when a MOD seals/unseals a part. (datum/mod_part/part)
#define COMSIG_MOD_PART_SEALED "mod_part_sealed"
/// Called when a MOD is finished toggling itself.
+2 -1
View File
@@ -127,6 +127,8 @@
balloon_alert(user, "already retracted!")
playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
return FALSE
if(SEND_SIGNAL(src, COMSIG_MOD_PART_RETRACTING, user, part_datum) & MOD_CANCEL_RETRACTION)
return FALSE
if(active && part_datum.sealed)
if(instant)
seal_part(part, is_sealed = FALSE)
@@ -141,7 +143,6 @@
if(!QDELING(wearer) && !wearer.equip_to_slot_if_possible(overslot, overslot.slot_flags, qdel_on_fail = FALSE, disable_warning = TRUE))
wearer.dropItemToGround(overslot, force = TRUE, silent = TRUE)
wearer.update_clothing(slot_flags)
SEND_SIGNAL(src, COMSIG_MOD_PART_RETRACTED, user, part_datum)
if(!user)
return TRUE
wearer.visible_message(span_notice("[wearer]'s [part.name] retract[part.p_s()] back into [src] with a mechanical hiss."),
+24 -4
View File
@@ -32,12 +32,23 @@
///Registers the signal COMSIG_MOD_ACTIVATE and calls the proc snap_shut() after a timer
/obj/item/mod/module/springlock/proc/snap_signal()
if(set_off || mod.wearer.stat == DEAD)
if (set_off || mod.wearer.stat == DEAD)
return
var/found_part = FALSE
for (var/obj/item/part as anything in mod.get_parts())
// Don't snap if no parts besides the MOD itself are active
if (part.loc != mod && mod.get_part_datum(part)?.sealed)
found_part = TRUE
break
if (!found_part)
return
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_REF(snap_shut)), rand(3 SECONDS, 5 SECONDS))
RegisterSignal(mod, COMSIG_MOD_ACTIVATE, PROC_REF(on_activate_spring_block))
RegisterSignals(mod, list(COMSIG_MOD_ACTIVATE, COMSIG_MOD_PART_RETRACTING), PROC_REF(on_activate_spring_block))
set_off = TRUE
///Calls snap_signal() when exposed to a reagent via VAPOR, PATCH or TOUCH
@@ -66,7 +77,7 @@
///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)
UnregisterSignal(mod, list(COMSIG_MOD_ACTIVATE, COMSIG_MOD_PART_RETRACTING))
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*"))
@@ -74,7 +85,16 @@
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
mod.wearer.get_bodypart(BODY_ZONE_CHEST)?.receive_damage(200, forced = TRUE, sharpness = SHARP_POINTY) // Chest always gets hit, from the back piece you're wearing
for (var/obj/item/part as anything in mod.get_parts())
if (part.loc == mod || !mod.get_part_datum(part)?.sealed)
continue
for (var/obj/item/bodypart/bodypart as anything in mod.wearer.get_damageable_bodyparts())
if (part.body_parts_covered & bodypart.body_part) // can hit chest again
bodypart.receive_damage(100, forced = TRUE, sharpness = SHARP_POINTY) //boggers, bogchamp, etc
if(!HAS_TRAIT(mod.wearer, TRAIT_NODEATH))
mod.wearer.investigate_log("has been killed by [src].", INVESTIGATE_DEATHS)
mod.wearer.death() //just in case, for some reason, they're still alive