Hardsuit fixes (#22519)

Various fixes and cleanups for hardsuits following the rework.

changes:
- bugfix: "Adds additional safety checks to hardsuit deployment logic to
better handle boot checks."
  - bugfix: "Hardsuit Health Analyzer module works again."
  - rscadd: "Adds 'Retract All Parts' verb for hardsuits."
- rscdel: "Removes Vitals Scanner module; hardsuits which had this
module by default have had it replaced with the Health Analzyer module."
  - rscdel: "Removes hardsuit Maneuvering Jets onmob sprites."
This commit is contained in:
Batrachophreno
2026-06-01 10:46:56 +00:00
committed by GitHub
parent 8e53577ee7
commit 1b54762d36
8 changed files with 110 additions and 38 deletions
@@ -42,6 +42,15 @@
. = ..()
/obj/item/rig_module/device/proc/handle_device_engage(atom/target, mob/user)
var/resolved = target.attackby(device, user)
if(!resolved && device && target)
if(device.afterattack(target, user, TRUE))
return TRUE
else
return FALSE
return TRUE
/obj/item/rig_module/device/healthscanner
name = "health scanner module"
desc = "A hardsuit-mounted health scanner."
@@ -51,19 +60,25 @@
construction_cost = list("$glass" = 5250, DEFAULT_WALL_MATERIAL = 2500)
construction_time = 300
engage_string = "Run Self-Diagnostic"
engage_string = "Run Diagnostic"
device_type = /obj/item/healthanalyzer
category = MODULE_MEDICAL
/obj/item/rig_module/device/healthscanner/vitalscanner
name = "integrated vitals tracker"
desc = "A hardsuit-mounted vitals tracker."
interface_name = "vitals tracker"
interface_desc = "Shows an informative health readout of the user."
/obj/item/rig_module/device/healthscanner/engage(atom/target, mob/user)
if(!..() || !device)
return FALSE
category = MODULE_GENERAL
if(!target.Adjacent(user))
return FALSE
var/obj/item/healthanalyzer/our_device = device
if(!target || user == target)
our_device.attack_self(user)
return TRUE
return handle_device_engage(target, user)
/obj/item/rig_module/device/drill
name = "hardsuit diamond drill mount"
@@ -158,15 +173,6 @@
if("rfd_settings")
our_device.attack_self(user)
/obj/item/rig_module/device/rfd_c/handle_device_engage(atom/target, mob/user)
var/resolved = target.attackby(device, user)
if(!resolved && device && target)
if(device.afterattack(target, user, TRUE))
return TRUE
else
return FALSE
return TRUE
/obj/item/rig_module/device/rfd_c/engage(atom/target, mob/user)
if(!..() || !device)
return FALSE
@@ -186,12 +192,6 @@
return handle_device_engage(target, user)
/obj/item/rig_module/device/proc/handle_device_engage(atom/target, mob/user)
var/resolved = target.attackby(device, user)
if(!resolved && device && target)
device.afterattack(target, user, TRUE)
return TRUE
/obj/item/rig_module/chem_dispenser
name = "mounted chemical dispenser"
desc = "A complex web of tubing and needles suitable for hardsuit use."
@@ -477,9 +477,6 @@
construction_cost = list(DEFAULT_WALL_MATERIAL = 15000, MATERIAL_GLASS = 4250, MATERIAL_SILVER = 4250, MATERIAL_URANIUM = 5250)
construction_time = 300
suit_overlay_active = "maneuvering_active"
suit_overlay_inactive = "maneuvering_inactive"
interface_name = "maneuvering jets"
interface_desc = "An inbuilt EVA maneuvering system that runs off the hardsuit air supply."
+46 -2
View File
@@ -100,6 +100,8 @@
var/malfunctioning = 0
var/malfunction_delay = 0
var/electrified = 0
/// Ensures that you can't queue up multiple piece toggle commands at once and bug anything out.
var/piece_being_deployed = FALSE
/// Rate at which the suit cell will passively use power when online.
var/cell_draw_rate = CHARGE_DRAIN_DEFAULT
@@ -842,6 +844,8 @@
return TRUE
/obj/item/rig/proc/toggle_piece(var/piece, var/mob/initiator, var/deploy_mode)
if(piece_being_deployed)
return
if(!usr || sealing || !cell || !cell.charge)
return
@@ -877,6 +881,7 @@
use_obj = chest
check_slot = wearer.wear_suit
piece_being_deployed = TRUE
if(use_obj)
// Handle retracting the piece, if possible.
if(check_slot == use_obj && deploy_mode != ONLY_DEPLOY)
@@ -890,6 +895,7 @@
if(use_obj == boots && chest_slot == chest_obj)
to_chat(wearer, SPAN_WARNING("The chest piece of the hardsuit must be retracted before you can retract your boots!"))
sound_to(wearer, 'sound/machines/terminal/terminal_error.ogg')
piece_being_deployed = FALSE
return
if(check_slot == use_obj)
@@ -904,16 +910,21 @@
// Handle deploying the piece, if possible.
else if (deploy_mode != ONLY_RETRACT)
if(check_slot && check_slot == use_obj)
piece_being_deployed = FALSE
return TRUE
if(!do_after(wearer, 8))
if(wearer)
to_chat(wearer, SPAN_WARNING("You must remain still while the suit deploys its parts."))
piece_being_deployed = FALSE
return FALSE
// If we're deploying the chest, we also try to deploy boots. If we can't also deploy boots, the entire thing fails.
if(use_obj == chest)
if(!toggle_piece("boots", initiator, ONLY_DEPLOY))
var/obj/item/boots_slot = wearer.shoes
var/obj/item/boots_obj = boots
if(boots_slot != boots_obj)
to_chat(initiator, SPAN_DANGER("You are unable to deploy \the [piece] as the boots were unable to also deploy!"))
playsound(src, 'sound/items/rfd_empty.ogg', 20, FALSE)
piece_being_deployed = FALSE
return FALSE
use_obj.forceMove(wearer)
if(src.color)
@@ -923,6 +934,7 @@
if(check_slot)
to_chat(initiator, SPAN_DANGER("You are unable to deploy \the [piece] as \the [check_slot] [check_slot.gender == PLURAL ? "are" : "is"] in the way."))
playsound(src, 'sound/items/rfd_empty.ogg', 20, FALSE)
piece_being_deployed = FALSE
return FALSE
else
to_chat(wearer, SPAN_NOTICE("Your [use_obj.name] [use_obj.gender == PLURAL ? "deploy" : "deploys"] swiftly."))
@@ -933,10 +945,42 @@
update_icon(TRUE)
piece_being_deployed = FALSE
return TRUE
/obj/item/rig/proc/deploy(mob/M,var/sealed)
var/mob/living/carbon/human/H = M
if(!H || !istype(H)) return
if(H.back != src)
return
if(sealed)
if(H.head)
var/obj/item/garbage = H.head
H.head = null
qdel(garbage)
if(H.gloves)
var/obj/item/garbage = H.gloves
H.gloves = null
qdel(garbage)
if(H.shoes)
var/obj/item/garbage = H.shoes
H.shoes = null
qdel(garbage)
if(H.wear_suit)
var/obj/item/garbage = H.wear_suit
H.wear_suit = null
qdel(garbage)
for(var/piece in list("helmet","gauntlets","boots",BP_CHEST))
toggle_piece(piece, H, ONLY_DEPLOY)
/obj/item/rig/proc/retract(mob/M,var/sealed)
var/mob/living/carbon/human/H = M
if(!H || !istype(H)) return
@@ -966,7 +1010,7 @@
qdel(garbage)
for(var/piece in list("helmet","gauntlets",BP_CHEST,"boots"))
toggle_piece(piece, H, ONLY_DEPLOY)
toggle_piece(piece, H, ONLY_RETRACT)
/obj/item/rig/proc/null_wearer(var/mob/user)
for(var/piece in list("helmet","gauntlets",BP_CHEST,"boots"))
@@ -130,6 +130,27 @@
deploy(wearer)
/obj/item/rig/verb/retract_suit()
set name = "Retract All Hardsuit Parts"
set desc = "Retracts helmet, gloves and boots."
set category = "Hardsuit.Core Functions"
set src = usr.contents
if(!istype(wearer) || !wearer.back == src)
to_chat(usr, SPAN_WARNING("The hardsuit is not being worn."))
return
if(use_check_and_message(usr))
return
if(!check_suit_access(usr))
return
if(!check_power_cost(usr))
return
deploy(wearer)
/obj/item/rig/verb/toggle_seals_verb()
set name = "Engage/Disengage Hardsuit"
set desc = "Activates or deactivates your hardsuit."
@@ -223,7 +223,7 @@
boot_type = null
initial_modules = list(
/obj/item/rig_module/device/healthscanner/vitalscanner,
/obj/item/rig_module/device/healthscanner,
/obj/item/rig_module/chem_dispenser/offworlder,
/obj/item/rig_module/storage
)
@@ -278,7 +278,7 @@
)
initial_modules = list(
/obj/item/rig_module/device/healthscanner/vitalscanner,
/obj/item/rig_module/device/healthscanner,
/obj/item/rig_module/chem_dispenser/offworlder,
/obj/item/rig_module/actuators/combat,
/obj/item/rig_module/chem_dispenser/combat
@@ -293,7 +293,7 @@
/obj/item/rig/light/offworlder/frontier/equipped
initial_modules = list(
/obj/item/rig_module/device/healthscanner/vitalscanner,
/obj/item/rig_module/device/healthscanner,
/obj/item/rig_module/chem_dispenser/offworlder,
/obj/item/rig_module/actuators/combat,
/obj/item/rig_module/fabricator/energy_net,
@@ -302,7 +302,7 @@
)
/obj/item/rig/light/offworlder/frontier/ninja
initial_modules = list(
/obj/item/rig_module/device/healthscanner/vitalscanner,
/obj/item/rig_module/device/healthscanner,
/obj/item/rig_module/chem_dispenser/offworlder,
/obj/item/rig_module/actuators/combat,
/obj/item/rig_module/fabricator/energy_net,