diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index 3a1d1c98932..60491144721 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -42720,6 +42720,10 @@
/obj/structure/table,
/obj/item/stack/sheet/metal/fifty,
/obj/item/stack/sheet/glass/fifty,
+/obj/item/stock_parts/cell/emproof{
+ pixel_x = 6;
+ pixel_y = -2
+ },
/turf/open/floor/plasteel/dark,
/area/engine/engine_smes)
"ckF" = (
@@ -43454,6 +43458,10 @@
/obj/item/clothing/gloves/color/yellow,
/obj/item/clothing/gloves/color/yellow,
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/obj/item/stock_parts/cell/emproof{
+ pixel_x = -4;
+ pixel_y = -1
+ },
/turf/open/floor/plasteel/dark,
/area/engine/engine_smes)
"cnB" = (
@@ -52080,6 +52088,7 @@
/obj/item/storage/box/lights/mixed,
/obj/item/stack/cable_coil,
/obj/item/stack/cable_coil,
+/obj/item/stock_parts/cell/emproof,
/turf/open/floor/plasteel/dark,
/area/engine/engine_smes)
"sdX" = (
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index 4d4b92a4efd..d9d84ddf783 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -24701,6 +24701,10 @@
pixel_x = 32
},
/obj/effect/turf_decal/bot,
+/obj/item/stock_parts/cell/emproof{
+ pixel_x = 4;
+ pixel_y = 2
+ },
/turf/open/floor/plasteel,
/area/engine/atmos)
"aYk" = (
@@ -69601,6 +69605,10 @@
pixel_x = 26
},
/obj/effect/turf_decal/bot,
+/obj/item/stock_parts/cell/emproof{
+ pixel_x = -3;
+ pixel_y = 5
+ },
/turf/open/floor/plasteel,
/area/engine/storage)
"czA" = (
@@ -73268,6 +73276,10 @@
pixel_x = 32
},
/obj/effect/turf_decal/bot,
+/obj/item/stock_parts/cell/emproof{
+ pixel_x = 1;
+ pixel_y = 3
+ },
/turf/open/floor/plasteel,
/area/engine/storage)
"cFZ" = (
diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm
index c3b5dea38f4..54e40168596 100644
--- a/_maps/map_files/KiloStation/KiloStation.dmm
+++ b/_maps/map_files/KiloStation/KiloStation.dmm
@@ -14333,6 +14333,14 @@
/obj/machinery/light_switch{
pixel_x = 24
},
+/obj/item/stock_parts/cell/emproof{
+ pixel_x = 3;
+ pixel_y = 7
+ },
+/obj/item/stock_parts/cell/emproof{
+ pixel_x = -6;
+ pixel_y = 5
+ },
/turf/open/floor/plasteel/dark,
/area/engine/engineering)
"awD" = (
@@ -15093,6 +15101,10 @@
/obj/item/grenade/chem_grenade/smart_metal_foam{
pixel_x = -2
},
+/obj/item/stock_parts/cell/emproof{
+ pixel_x = 6;
+ pixel_y = -6
+ },
/turf/open/floor/plasteel/dark,
/area/engine/engineering)
"axQ" = (
@@ -33225,8 +33237,8 @@
dir = 8
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1,
-/mob/living/simple_animal/bot/secbot/pingsky,
/obj/structure/cable,
+/mob/living/simple_animal/bot/secbot/pingsky,
/turf/open/floor/engine,
/area/ai_monitored/turret_protected/aisat_interior)
"aZi" = (
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 9150d45a73a..26397ce2117 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -14845,6 +14845,14 @@
/obj/effect/turf_decal/bot{
dir = 1
},
+/obj/item/stock_parts/cell/emproof{
+ pixel_x = -6;
+ pixel_y = 2
+ },
+/obj/item/stock_parts/cell/emproof{
+ pixel_x = 4;
+ pixel_y = 6
+ },
/turf/open/floor/plasteel{
dir = 1
},
@@ -14869,6 +14877,10 @@
/obj/effect/turf_decal/bot{
dir = 1
},
+/obj/item/stock_parts/cell/emproof{
+ pixel_x = -4;
+ pixel_y = 6
+ },
/turf/open/floor/plasteel{
dir = 1
},
diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm
index dbe222442f5..3336c41997b 100644
--- a/_maps/map_files/PubbyStation/PubbyStation.dmm
+++ b/_maps/map_files/PubbyStation/PubbyStation.dmm
@@ -40857,6 +40857,14 @@
dir = 4
},
/obj/structure/cable,
+/obj/item/stock_parts/cell/emproof{
+ pixel_x = -4;
+ pixel_y = -2
+ },
+/obj/item/stock_parts/cell/emproof{
+ pixel_x = 4;
+ pixel_y = 6
+ },
/turf/open/floor/plasteel/dark,
/area/engine/engine_smes)
"bWA" = (
diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm
index 1a2ed41c69e..c922a86887e 100644
--- a/code/__DEFINES/atmospherics.dm
+++ b/code/__DEFINES/atmospherics.dm
@@ -146,6 +146,8 @@
#define SPACE_HELM_MAX_TEMP_PROTECT 1500
/// what min_cold_protection_temperature is set to for space-suit quality jumpsuits or suits. MUST NOT BE 0.
#define SPACE_SUIT_MIN_TEMP_PROTECT 2.0
+/// The min cold protection of a space suit without the heater active
+#define SPACE_SUIT_MIN_TEMP_PROTECT_OFF 72
#define SPACE_SUIT_MAX_TEMP_PROTECT 1500
/// Cold protection for firesuits
diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm
index 353769f24ea..4db5fbe9095 100644
--- a/code/_onclick/hud/_defines.dm
+++ b/code/_onclick/hud/_defines.dm
@@ -70,8 +70,9 @@
//Middle right (status indicators)
#define ui_healthdoll "EAST-1:28,CENTER-2:13"
#define ui_health "EAST-1:28,CENTER-1:15"
-#define ui_internal "EAST-1:28,CENTER:17"
-#define ui_mood "EAST-1:28,CENTER-3:10"
+#define ui_internal "EAST-1:28,CENTER-3:10"
+#define ui_mood "EAST-1:28,CENTER:17"
+#define ui_spacesuit "EAST-1:28,CENTER-4:10"
//Pop-up inventory
#define ui_shoes "WEST+1:8,SOUTH:5"
diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm
index abcf107d202..a833d1c6859 100644
--- a/code/_onclick/hud/hud.dm
+++ b/code/_onclick/hud/hud.dm
@@ -57,6 +57,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list(
var/obj/screen/healths
var/obj/screen/healthdoll
var/obj/screen/internals
+ var/obj/screen/spacesuit
// subtypes can override this to force a specific UI style
var/ui_style
@@ -101,6 +102,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list(
healths = null
healthdoll = null
internals = null
+ spacesuit = null
lingchemdisplay = null
devilsouldisplay = null
lingstingdisplay = null
diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm
index fcdc69d4c1c..c2d0b0526ee 100644
--- a/code/_onclick/hud/human.dm
+++ b/code/_onclick/hud/human.dm
@@ -315,6 +315,10 @@
internals.hud = src
infodisplay += internals
+ spacesuit = new /obj/screen/spacesuit
+ spacesuit.hud = src
+ infodisplay += spacesuit
+
healths = new /obj/screen/healths()
healths.hud = src
infodisplay += healths
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index 91ff649b165..84b91263dec 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -342,6 +342,11 @@
return
C.update_action_buttons_icon()
+/obj/screen/spacesuit
+ name = "Space suit cell status"
+ icon_state = "spacesuit_0"
+ screen_loc = ui_spacesuit
+
/obj/screen/mov_intent
name = "run/walk toggle"
icon = 'icons/mob/screen_midnight.dmi'
@@ -406,7 +411,6 @@
var/mob/living/user = hud?.mymob
if(!istype(user))
return
-
if(!user.resting)
icon_state = "act_rest"
else
diff --git a/code/datums/action.dm b/code/datums/action.dm
index ece6076ff56..32b7c643178 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -272,6 +272,19 @@
if(istype(H))
H.toggle_welding_screen(owner)
+/datum/action/item_action/toggle_spacesuit
+ name = "Toggle Suit Thermal Regulator"
+ icon_icon = 'icons/mob/actions/actions_spacesuit.dmi'
+ button_icon_state = "thermal_off"
+
+/datum/action/item_action/toggle_spacesuit/Trigger()
+ var/obj/item/clothing/suit/space/suit = target
+ if(!istype(suit))
+ return
+ suit.toggle_spacesuit()
+ button_icon_state = "thermal_[suit.thermal_on ? "on" : "off"]"
+ UpdateButtonIcon()
+
/datum/action/item_action/toggle_unfriendly_fire
name = "Toggle Friendly Fire \[ON\]"
desc = "Toggles if the club's blasts cause friendly fire."
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index 6cfb708cbd0..7507d89bf8b 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -4,6 +4,9 @@
desc = "An industrial unit made to hold and decontaminate irradiated equipment. It comes with a built-in UV cauterization mechanism. A small warning label advises that organic matter should not be placed into the unit."
icon = 'icons/obj/machines/suit_storage.dmi'
icon_state = "close"
+ use_power = ACTIVE_POWER_USE
+ active_power_usage = 60
+ power_channel = EQUIP
density = TRUE
max_integrity = 250
ui_x = 400
@@ -46,6 +49,8 @@
var/message_cooldown
/// How long it takes to break out of the SSU.
var/breakout_time = 300
+ /// How fast it charges cells in a suit
+ var/charge_rate = 500
/obj/machinery/suit_storage_unit/standard_unit
suit_type = /obj/item/clothing/suit/space/eva
@@ -302,6 +307,18 @@
if(occupant)
dump_contents()
+/obj/machinery/suit_storage_unit/process()
+ if(!suit)
+ return
+ if(!istype(suit, /obj/item/clothing/suit/space))
+ return
+ if(!suit.cell)
+ return
+
+ var/obj/item/stock_parts/cell/C = suit.cell
+ use_power(charge_rate)
+ C.give(charge_rate)
+
/obj/machinery/suit_storage_unit/proc/shock(mob/user, prb)
if(!prob(prb))
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
diff --git a/code/game/objects/items/inducer.dm b/code/game/objects/items/inducer.dm
index 7ba7217c1d6..fea94ced1c1 100644
--- a/code/game/objects/items/inducer.dm
+++ b/code/game/objects/items/inducer.dm
@@ -107,6 +107,9 @@
if(istype(A, /obj/item/gun/energy))
to_chat(user, "Error unable to interface with device.")
return FALSE
+ if(istype(A, /obj/item/clothing/suit/space))
+ to_chat(user, "Error unable to interface with device.")
+ return FALSE
if(istype(A, /obj))
O = A
if(C)
diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm
index e0ec4cfab7f..740f9d04e65 100644
--- a/code/modules/antagonists/changeling/powers/mutations.dm
+++ b/code/modules/antagonists/changeling/powers/mutations.dm
@@ -476,6 +476,8 @@
clothing_flags = STOPSPRESSUREDAMAGE //Not THICKMATERIAL because it's organic tissue, so if somebody tries to inject something into it, it still ends up in your blood. (also balance but muh fluff)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/oxygen)
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) //No armor at all.
+ actions_types = list()
+ cell = null
/obj/item/clothing/suit/space/changeling/Initialize()
. = ..()
@@ -484,10 +486,15 @@
loc.visible_message("[loc.name]\'s flesh rapidly inflates, forming a bloated mass around [loc.p_their()] body!", "We inflate our flesh, creating a spaceproof suit!", "You hear organic matter ripping and tearing!")
START_PROCESSING(SSobj, src)
+// seal the cell door
+/obj/item/clothing/suit/space/changeling/toggle_spacesuit_cell(mob/user)
+ return
+
/obj/item/clothing/suit/space/changeling/process()
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
H.reagents.add_reagent(/datum/reagent/medicine/salbutamol, REAGENTS_METABOLISM)
+ H.adjust_bodytemperature(temperature_setting - H.bodytemperature) // force changelings to normal temp step mode played badly
/obj/item/clothing/head/helmet/space/changeling
name = "flesh mass"
diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm
index 06aa84ec612..2738563313e 100644
--- a/code/modules/clothing/head/helmet.dm
+++ b/code/modules/clothing/head/helmet.dm
@@ -319,7 +319,7 @@
item_state = "rus_ushanka"
body_parts_covered = HEAD
cold_protection = HEAD
- min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
+ min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
armor = list("melee" = 25, "bullet" = 20, "laser" = 20, "energy" = 30, "bomb" = 20, "bio" = 50, "rad" = 20, "fire" = -10, "acid" = 50)
//LightToggle
diff --git a/code/modules/clothing/spacesuits/_spacesuits.dm b/code/modules/clothing/spacesuits/_spacesuits.dm
index 1cbc765a642..1dbb155a269 100644
--- a/code/modules/clothing/spacesuits/_spacesuits.dm
+++ b/code/modules/clothing/spacesuits/_spacesuits.dm
@@ -1,3 +1,5 @@
+#define THERMAL_REGULATOR_COST 18 // the cost per tick for the thermal regulator
+
//Note: Everything in modules/clothing/spacesuits should have the entire suit grouped together.
// Meaning the the suit is defined directly after the corrisponding helmet. Just like below!
/obj/item/clothing/head/helmet/space
@@ -37,9 +39,177 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 50, "fire" = 80, "acid" = 70)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
cold_protection = CHEST | GROIN | LEGS | FEET | ARMS | HANDS
- min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
+ min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT_OFF
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
strip_delay = 80
equip_delay_other = 80
resistance_flags = NONE
+ actions_types = list(/datum/action/item_action/toggle_spacesuit)
+ var/temperature_setting = BODYTEMP_NORMAL /// The default temperature setting
+ var/obj/item/stock_parts/cell/cell = /obj/item/stock_parts/cell/high /// If this is a path, this gets created as an object in Initialize.
+ var/cell_cover_open = FALSE /// Status of the cell cover on the suit
+ var/thermal_on = FALSE /// Status of the thermal regulator
+
+/obj/item/clothing/suit/space/Initialize(mapload)
+ . = ..()
+ if(ispath(cell))
+ cell = new cell(src)
+
+/// Start Processing on the space suit when it is worn to heat the wearer
+/obj/item/clothing/suit/space/equipped(mob/user, slot)
+ . = ..()
+ if(slot == ITEM_SLOT_OCLOTHING) // Check that the slot is valid
+ START_PROCESSING(SSobj, src)
+
+// On removal stop processing, save battery
+/obj/item/clothing/suit/space/dropped(mob/user)
+ . = ..()
+ STOP_PROCESSING(SSobj, src)
+ var/mob/living/carbon/human/human = user
+ if(istype(human))
+ human.update_spacesuit_hud_icon("0")
+
+// Space Suit temperature regulation and power usage
+/obj/item/clothing/suit/space/process()
+ var/mob/living/carbon/human/user = src.loc
+ if(!user || !ishuman(user) || !(user.wear_suit == src))
+ return
+ if(!cell)
+ user.update_spacesuit_hud_icon("missing")
+ else
+ var/cell_percent = cell.charge / cell.maxcharge
+ if(cell_percent > 0.6)
+ user.update_spacesuit_hud_icon("high")
+ else if(cell_percent > 0.20)
+ user.update_spacesuit_hud_icon("mid")
+ else if(cell_percent > 0.01 && cell.charge > THERMAL_REGULATOR_COST)
+ user.update_spacesuit_hud_icon("low")
+ else
+ user.update_spacesuit_hud_icon("empty")
+
+ if(thermal_on && cell.charge >= THERMAL_REGULATOR_COST)
+ user.adjust_bodytemperature((temperature_setting - user.bodytemperature), use_steps=TRUE, capped=FALSE)
+ cell.charge -= THERMAL_REGULATOR_COST
+
+// Clean up the cell on destroy
+/obj/item/clothing/suit/space/Destroy()
+ if(cell)
+ QDEL_NULL(cell)
+ var/mob/living/carbon/human/human = src.loc
+ if(istype(human))
+ human.update_spacesuit_hud_icon("0")
+ STOP_PROCESSING(SSobj, src)
+ return ..()
+
+// Clean up the cell on destroy
+/obj/item/clothing/suit/space/handle_atom_del(atom/A)
+ if(A == cell)
+ cell = null
+ thermal_on = FALSE
+ return ..()
+
+// support for items that interact with the cell
+/obj/item/clothing/suit/space/get_cell()
+ return cell
+
+// Show the status of the suit and the cell
+/obj/item/clothing/suit/space/examine(mob/user)
+ . = ..()
+ if(!in_range(src, user) && !isobserver(user))
+ return
+
+ . += "The thermal regulator is [thermal_on ? "on" : "off"] and the temperature is set to \
+ [round(temperature_setting-T0C,0.1)] °C ([round(temperature_setting*1.8-459.67,0.1)] °F)"
+ . += "The power meeter shows [cell ? "[round(cell.charge / cell.maxcharge * 100)]%" : "!invalid!"] charge remaining."
+ if(cell_cover_open)
+ . += "The cell cover is open exposing the cell and setting knobs."
+ if(!cell)
+ . += "The slot for a cell is empty."
+ else
+ . += "\The [cell] is firmly in place."
+
+// object handling for accessing features of the suit
+/obj/item/clothing/suit/space/attackby(obj/item/I, mob/user, params)
+ if(I.tool_behaviour == TOOL_CROWBAR)
+ toggle_spacesuit_cell(user)
+ return
+ else if(cell_cover_open && I.tool_behaviour == TOOL_SCREWDRIVER)
+ var/range_low = 20 // Default min temp c
+ var/range_high = 45 // default max temp c
+ if(obj_flags & EMAGGED)
+ range_low = -20 // emagged min temp c
+ range_high = 120 // emagged max temp c
+
+ var/deg_c = input(user, "What temperature would you like to set the thermal regulator to? \
+ ([range_low]-[range_high] degrees celcius)") as null|num
+ if(deg_c && deg_c >= range_low && deg_c <= range_high)
+ temperature_setting = round(T0C + deg_c, 0.1)
+ to_chat(user, "You see the readout change to [deg_c] c.")
+ return
+ else if(cell_cover_open && istype(I, /obj/item/stock_parts/cell))
+ if(cell)
+ to_chat(user, "[src] already has a cell installed.")
+ return
+ if(user.transferItemToLoc(I, src))
+ cell = I
+ to_chat(user, "You successfully install \the [cell] into [src].")
+ return
+ return ..()
+
+/// Open the cell cover when ALT+Click on the suit
+/obj/item/clothing/suit/space/AltClick(mob/living/user)
+ . = ..()
+ if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
+ return
+ toggle_spacesuit_cell(user)
+
+/// Remove the cell whent he cover is open on CTRL+Click
+/obj/item/clothing/suit/space/CtrlClick(mob/living/user)
+ if(istype(user) && user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
+ if(cell_cover_open && cell)
+ remove_cell(user)
+ return
+ return ..()
+
+// Remove suit when using the suit on its self
+/obj/item/clothing/suit/space/attack_self(mob/user)
+ remove_cell(user)
+
+/// Remove the cell from the suit if the over is open
+/obj/item/clothing/suit/space/proc/remove_cell(mob/user)
+ if(cell_cover_open && cell)
+ user.visible_message("[user] removes \the [cell] from [src]!", \
+ "You remove [cell].")
+ cell.add_fingerprint(user)
+ user.put_in_hands(cell)
+ cell = null
+
+/// Toggle the space suit's cell cover
+/obj/item/clothing/suit/space/proc/toggle_spacesuit_cell(mob/user)
+ cell_cover_open = !cell_cover_open
+ to_chat(user, "You [cell_cover_open ? "open" : "close"] the cell cover on \the [src].")
+
+/// Toggle the space suit's thermal regulator status
+/obj/item/clothing/suit/space/proc/toggle_spacesuit(mob/user)
+ thermal_on = !thermal_on
+ min_cold_protection_temperature = thermal_on ? SPACE_SUIT_MIN_TEMP_PROTECT : SPACE_SUIT_MIN_TEMP_PROTECT_OFF
+ to_chat(user, "You turn [thermal_on ? "on" : "off"] the thermal regulator on \the [src].")
+
+// let emags override the temperature settings
+/obj/item/clothing/suit/space/emag_act(mob/user)
+ if(!(obj_flags & EMAGGED))
+ obj_flags |= EMAGGED
+ user.visible_message("You emag [src], overwriting thermal regulator restrictions.")
+ log_game("[key_name(user)] emagged [src] at [AREACOORD(src)], overwriting thermal regulator restrictions.")
+ playsound(src, "sparks", 50, TRUE)
+
+// zap the cell if we get hit with an emp
+/obj/item/clothing/suit/space/emp_act(severity)
+ . = ..()
+ if(. & EMP_PROTECT_CONTENTS)
+ return
+ if(cell)
+ cell.emp_act(severity)
+
+#undef THERMAL_REGULATOR_COST
diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm
index 7889c0a7cd4..b400d9f7806 100644
--- a/code/modules/clothing/spacesuits/chronosuit.dm
+++ b/code/modules/clothing/spacesuits/chronosuit.dm
@@ -23,7 +23,7 @@
desc = "An advanced spacesuit equipped with time-bluespace teleportation and anti-compression technology."
icon_state = "chronosuit"
item_state = "chronosuit"
- actions_types = list(/datum/action/item_action/toggle)
+ actions_types = list(/datum/action/item_action/toggle_spacesuit, /datum/action/item_action/toggle)
armor = list("melee" = 60, "bullet" = 60, "laser" = 60, "energy" = 60, "bomb" = 30, "bio" = 90, "rad" = 90, "fire" = 100, "acid" = 1000)
resistance_flags = FIRE_PROOF | ACID_PROOF
var/list/chronosafe_items = list(/obj/item/chrono_eraser, /obj/item/gun/energy/chrono_gun)
@@ -166,6 +166,7 @@
finish_chronowalk(user, to_turf)
/obj/item/clothing/suit/space/chronos/process()
+ . = ..()
if(activated)
var/mob/living/carbon/human/user = src.loc
if(user && ishuman(user) && (user.wear_suit == src))
@@ -178,8 +179,6 @@
camera.remove_target_ui()
else
new_camera(user)
- else
- STOP_PROCESSING(SSobj, src)
/obj/item/clothing/suit/space/chronos/proc/activate()
if(!activating && !activated && !teleporting)
@@ -199,7 +198,6 @@
to_chat(user, "\[ ok \] Starting ui display driver")
to_chat(user, "\[ ok \] Initializing chronowalk4-view")
new_camera(user)
- START_PROCESSING(SSobj, src)
activated = 1
else
to_chat(user, "\[ fail \] Mounting /dev/helm")
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index ca9c2e1a720..37274476003 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -1,3 +1,6 @@
+/// How much damage you take from an emp when wearing a hardsuit
+#define HARDSUIT_EMP_BURN 2 // a very orange number
+
//Baseline hardsuits
/obj/item/clothing/head/helmet/space/hardsuit
name = "hardsuit helmet"
@@ -101,7 +104,7 @@
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/t_scanner, /obj/item/construction/rcd, /obj/item/pipe_dispenser)
siemens_coefficient = 0
var/obj/item/clothing/head/helmet/space/hardsuit/helmet
- actions_types = list(/datum/action/item_action/toggle_helmet)
+ actions_types = list(/datum/action/item_action/toggle_spacesuit, /datum/action/item_action/toggle_helmet)
var/helmettype = /obj/item/clothing/head/helmet/space/hardsuit
var/obj/item/tank/jetpack/suit/jetpack = null
var/hardsuit_type
@@ -134,7 +137,7 @@
jetpack = I
to_chat(user, "You successfully install the jetpack into [src].")
return
- else if(I.tool_behaviour == TOOL_SCREWDRIVER)
+ else if(!cell_cover_open && I.tool_behaviour == TOOL_SCREWDRIVER)
if(!jetpack)
to_chat(user, "[src] has no jetpack installed.")
return
@@ -165,7 +168,6 @@
new /obj/item/light/bulb/broken(drop_location())
return ..()
-
/obj/item/clothing/suit/space/hardsuit/equipped(mob/user, slot)
..()
if(jetpack)
@@ -185,6 +187,18 @@
if(slot == ITEM_SLOT_OCLOTHING) //we only give the mob the ability to toggle the helmet if he's wearing the hardsuit.
return 1
+/// Burn the person inside the hard suit just a little, the suit got really hot for a moment
+/obj/item/clothing/suit/space/emp_act(severity)
+ . = ..()
+ var/mob/living/carbon/human/user = src.loc
+ if(istype(user))
+ user.apply_damage(HARDSUIT_EMP_BURN, BURN, spread_damage=TRUE)
+ to_chat(user, "You feel \the [src] heat up from the EMP burning you slightly.")
+
+ // Chance to scream
+ if (user.stat < UNCONSCIOUS && prob(10))
+ user.emote("scream")
+
//Engineering
/obj/item/clothing/head/helmet/space/hardsuit/engine
name = "engineering hardsuit helmet"
@@ -247,6 +261,7 @@
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine/elite
jetpack = /obj/item/tank/jetpack/suit
+ cell = /obj/item/stock_parts/cell/super
//Mining hardsuit
/obj/item/clothing/head/helmet/space/hardsuit/mining
@@ -373,6 +388,7 @@
allowed = list(/obj/item/gun, /obj/item/ammo_box,/obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword/saber, /obj/item/restraints/handcuffs, /obj/item/tank/internals)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi
jetpack = /obj/item/tank/jetpack/suit
+ cell = /obj/item/stock_parts/cell/hyper
//Elite Syndie suit
/obj/item/clothing/head/helmet/space/hardsuit/syndi/elite
@@ -403,6 +419,7 @@
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | ACID_PROOF
+ cell = /obj/item/stock_parts/cell/bluespace
/obj/item/clothing/suit/space/hardsuit/syndi/elite/debug
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite/debug
@@ -453,6 +470,7 @@
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/wizard
+ cell = /obj/item/stock_parts/cell/hyper
/obj/item/clothing/suit/space/hardsuit/wizard/Initialize()
. = ..()
@@ -529,8 +547,7 @@
/obj/item/hand_tele, /obj/item/aicard)
armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 20, "bomb" = 100, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 80)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/rd
-
-
+ cell = /obj/item/stock_parts/cell/super
//Security hardsuit
/obj/item/clothing/head/helmet/space/hardsuit/security
@@ -570,6 +587,7 @@
armor = list("melee" = 45, "bullet" = 25, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 100, "rad" = 50, "fire" = 95, "acid" = 95)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security/hos
jetpack = /obj/item/tank/jetpack/suit
+ cell = /obj/item/stock_parts/cell/super
//SWAT MKII
/obj/item/clothing/head/helmet/space/hardsuit/swat
@@ -597,6 +615,7 @@
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT //this needed to be added a long fucking time ago
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/swat
+// SWAT and Captain get EMP Protection
/obj/item/clothing/suit/space/hardsuit/swat/Initialize()
. = ..()
allowed = GLOB.security_hardsuit_allowed
@@ -614,6 +633,7 @@
icon_state = "caparmor"
item_state = "capspacesuit"
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/swat/captain
+ cell = /obj/item/stock_parts/cell/super
//Clown
/obj/item/clothing/head/helmet/space/hardsuit/clown
@@ -726,8 +746,6 @@
s.start()
owner.visible_message("[owner]'s shields deflect [attack_text] in a shower of sparks!")
current_charges--
- if(recharge_rate)
- START_PROCESSING(SSobj, src)
if(current_charges <= 0)
owner.visible_message("[owner]'s shield overloads!")
shield_state = "broken"
@@ -737,16 +755,15 @@
/obj/item/clothing/suit/space/hardsuit/shielded/Destroy()
- STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/clothing/suit/space/hardsuit/shielded/process()
- if(world.time > recharge_cooldown && current_charges < max_charges)
+ . = ..()
+ if(recharge_rate && world.time > recharge_cooldown && current_charges < max_charges)
current_charges = CLAMP((current_charges + recharge_rate), 0, max_charges)
playsound(loc, 'sound/magic/charge.ogg', 50, TRUE)
if(current_charges == max_charges)
playsound(loc, 'sound/machines/ding.ogg', 50, TRUE)
- STOP_PROCESSING(SSobj, src)
shield_state = "[shield_on]"
if(ishuman(loc))
var/mob/living/carbon/human/C = loc
@@ -887,3 +904,5 @@
strip_delay = 130
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
actions_types = list()
+
+#undef HARDSUIT_EMP_BURN
diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm
index aff8f601fe7..ce4b4213dc9 100644
--- a/code/modules/clothing/spacesuits/miscellaneous.dm
+++ b/code/modules/clothing/spacesuits/miscellaneous.dm
@@ -42,6 +42,7 @@ Contains:
resistance_flags = FIRE_PROOF | ACID_PROOF
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/deathsquad
dog_fashion = /datum/dog_fashion/back/deathsquad
+ cell = /obj/item/stock_parts/cell/bluespace
//NEW SWAT suit
/obj/item/clothing/suit/space/swat
@@ -186,6 +187,12 @@ Contains:
strip_delay = 130
resistance_flags = FIRE_PROOF
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
+ cell = /obj/item/stock_parts/cell/bluespace
+
+// ERT suit's gets EMP Protection
+/obj/item/clothing/suit/space/hardsuit/ert/Initialize()
+ . = ..()
+ AddComponent(/datum/component/empprotection, EMP_PROTECT_CONTENTS)
//ERT Security
/obj/item/clothing/head/helmet/space/hardsuit/ert/sec
@@ -426,3 +433,4 @@ Contains:
armor = list("melee" = 60, "bullet" = 40, "laser" = 40, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
strip_delay = 130
resistance_flags = FIRE_PROOF | ACID_PROOF
+ cell = /obj/item/stock_parts/cell/hyper
diff --git a/code/modules/clothing/spacesuits/syndi.dm b/code/modules/clothing/spacesuits/syndi.dm
index 9c9950e06c8..e1c40d2c011 100644
--- a/code/modules/clothing/spacesuits/syndi.dm
+++ b/code/modules/clothing/spacesuits/syndi.dm
@@ -14,7 +14,7 @@
w_class = WEIGHT_CLASS_NORMAL
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword/saber, /obj/item/restraints/handcuffs, /obj/item/tank/internals)
armor = list("melee" = 40, "bullet" = 50, "laser" = 30,"energy" = 40, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 80, "acid" = 85)
-
+ cell = /obj/item/stock_parts/cell/hyper
//Green syndicate space suit
/obj/item/clothing/head/helmet/space/syndicate/green
diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm
index e9f08a780ef..ca3ace93d2f 100644
--- a/code/modules/mining/equipment/explorer_gear.dm
+++ b/code/modules/mining/equipment/explorer_gear.dm
@@ -70,13 +70,9 @@
/obj/item/clothing/suit/space/hostile_environment/Initialize()
. = ..()
AddComponent(/datum/component/spraycan_paintable)
- START_PROCESSING(SSobj, src)
-
-/obj/item/clothing/suit/space/hostile_environment/Destroy()
- STOP_PROCESSING(SSobj, src)
- return ..()
/obj/item/clothing/suit/space/hostile_environment/process()
+ . = ..()
var/mob/living/carbon/C = loc
if(istype(C) && prob(2)) //cursed by bubblegum
if(prob(15))
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 6abb83b1040..9a731ef6b9b 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -746,6 +746,10 @@
if(hud_used && hud_used.internals)
hud_used.internals.icon_state = "internal[internal_state]"
+/mob/living/carbon/proc/update_spacesuit_hud_icon(cell_state = "empty")
+ if(hud_used && hud_used.spacesuit)
+ hud_used.spacesuit.icon_state = "spacesuit_[cell_state]"
+
/mob/living/carbon/update_stat()
if(status_flags & GODMODE)
return
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 5998a8d3a01..65a15feea84 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -210,7 +210,7 @@
if(thermal_protection_flags & HAND_RIGHT)
thermal_protection += THERMAL_PROTECTION_HAND_RIGHT
- return min(1,thermal_protection)
+ return min(1, thermal_protection)
//See proc/get_heat_protection_flags(temperature) for the description of this proc.
/mob/living/carbon/human/proc/get_cold_protection_flags(temperature)
@@ -271,7 +271,7 @@
if(thermal_protection_flags & HAND_RIGHT)
thermal_protection += THERMAL_PROTECTION_HAND_RIGHT
- return min(1,thermal_protection)
+ return min(1, thermal_protection)
/mob/living/carbon/human/handle_random_events()
//Puke if toxloss is too high
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 13ae3e83e34..ac274dc98b1 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -1633,7 +1633,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
natural_bodytemperature_stabilization(environment, H)
if(!H.on_fire || areatemp > H.bodytemperature) // If we are not on fire or the area is hotter
- H.adjust_bodytemperature((areatemp - H.bodytemperature), use_insulation=TRUE, use_steps=TRUE, hardsuit_fix=bodytemp_normal - H.bodytemperature)
+ H.adjust_bodytemperature((areatemp - H.bodytemperature), use_insulation=TRUE, use_steps=TRUE)
/// Handle the body temperature status effects for the species
/// Traits for resitance to heat or cold are handled here.
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index 67da600e3bd..83709a8cc4d 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -666,21 +666,19 @@ All effects don't start immediately, but rather get worse over time; the rate is
* * max_temp (optional) The maximum body temperature after adjustment
* * use_insulation (optional) modifies the amount based on the amount of insulation the mob has
* * use_steps (optional) Use the body temp divisors and max change rates
- * * hardsuit_fix (optional) num bodytemp_normal - H.bodytemperature Use hardsuit override until hardsuits fix is done...
+ * * capped (optional) default True used to cap step mode
*/
-/mob/living/carbon/adjust_bodytemperature(amount, min_temp=0, max_temp=INFINITY, use_insulation=FALSE, use_steps=FALSE, \
- hardsuit_fix=FALSE)
+/mob/living/carbon/adjust_bodytemperature(amount, min_temp=0, max_temp=INFINITY, use_insulation=FALSE, use_steps=FALSE, capped=TRUE)
// apply insulation to the amount of change
if(use_insulation)
amount *= (1 - get_insulation_protection(bodytemperature + amount))
- // Extra calculation for hardsuits to bleed off heat
- if(hardsuit_fix)
- amount += hardsuit_fix
-
// Use the bodytemp divisors to get the change step, with max step size
if(use_steps)
- amount = (amount > 0) ? min(amount / BODYTEMP_HEAT_DIVISOR, BODYTEMP_HEATING_MAX) : max(amount / BODYTEMP_COLD_DIVISOR, BODYTEMP_COOLING_MAX)
+ amount = (amount > 0) ? (amount / BODYTEMP_HEAT_DIVISOR) : (amount / BODYTEMP_COLD_DIVISOR)
+ // Clamp the results to the min and max step size
+ if(capped)
+ amount = (amount > 0) ? min(amount, BODYTEMP_HEATING_MAX) : max(amount, BODYTEMP_COOLING_MAX)
if(bodytemperature >= min_temp && bodytemperature <= max_temp)
bodytemperature = CLAMP(bodytemperature + amount,min_temp,max_temp)
diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm
index ef862aa9fab..bfe738a5bd6 100644
--- a/code/modules/ninja/suit/suit.dm
+++ b/code/modules/ninja/suit/suit.dm
@@ -26,7 +26,6 @@ Contents:
//Important parts of the suit.
var/mob/living/carbon/human/affecting = null
- var/obj/item/stock_parts/cell/cell
var/datum/effect_system/spark_spread/spark_system
var/datum/techweb/stored_research
var/obj/item/disk/tech_disk/t_disk//To copy design onto disk.
@@ -72,10 +71,14 @@ Contents:
//Cell Init
cell = new/obj/item/stock_parts/cell/high
- cell.charge = 9000
+ cell.charge = 60000 // larger as it now heats
cell.name = "black power cell"
cell.icon_state = "bscell"
+// seal the cell in the ninja outfit
+/obj/item/clothing/suit/space/space_ninja/toggle_spacesuit_cell(mob/user)
+ return
+
//Simply deletes all the attachments and self, killing all related procs.
/obj/item/clothing/suit/space/space_ninja/proc/terminate()
qdel(n_hood)
diff --git a/code/modules/research/xenobiology/crossbreeding/_potions.dm b/code/modules/research/xenobiology/crossbreeding/_potions.dm
index 1fb17ea4d1f..3e15a818674 100644
--- a/code/modules/research/xenobiology/crossbreeding/_potions.dm
+++ b/code/modules/research/xenobiology/crossbreeding/_potions.dm
@@ -118,6 +118,9 @@ Slimecrossing Potions
if(!istype(C))
to_chat(user, "The potion can only be used on clothing!")
return
+ if(istype(C, /obj/item/clothing/suit/space))
+ to_chat(user, "The [C] is already pressure-resistant!")
+ return ..()
if(C.min_cold_protection_temperature == SPACE_SUIT_MIN_TEMP_PROTECT && C.clothing_flags & STOPSPRESSUREDAMAGE)
to_chat(user, "The [C] is already pressure-resistant!")
return ..()
diff --git a/icons/mob/actions/actions_spacesuit.dmi b/icons/mob/actions/actions_spacesuit.dmi
new file mode 100644
index 00000000000..0b77ed77335
Binary files /dev/null and b/icons/mob/actions/actions_spacesuit.dmi differ
diff --git a/icons/mob/screen_gen.dmi b/icons/mob/screen_gen.dmi
index d827a34c3cc..fd5acf71b44 100644
Binary files a/icons/mob/screen_gen.dmi and b/icons/mob/screen_gen.dmi differ