mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-19 06:03:14 +00:00
352 lines
13 KiB
Plaintext
352 lines
13 KiB
Plaintext
/// Charge per tick consumed by the thermal regulator
|
|
#define THERMAL_REGULATOR_COST (0.018 * STANDARD_CELL_CHARGE)
|
|
|
|
//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
|
|
name = "space helmet"
|
|
icon = 'icons/obj/clothing/head/spacehelm.dmi'
|
|
worn_icon = 'icons/mob/clothing/head/spacehelm.dmi'
|
|
icon_state = "spaceold"
|
|
inhand_icon_state = "space_helmet"
|
|
desc = "A special helmet with solar UV shielding to protect your eyes from harmful rays."
|
|
clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | SNUG_FIT | STACKABLE_HELMET_EXEMPT | HEADINTERNALS
|
|
armor_type = /datum/armor/helmet_space
|
|
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
|
|
interaction_flags_click = NEED_DEXTERITY
|
|
cold_protection = HEAD
|
|
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
|
|
heat_protection = HEAD
|
|
max_heat_protection_temperature = SPACE_HELM_MAX_TEMP_PROTECT
|
|
flash_protect = FLASH_PROTECTION_WELDER
|
|
strip_delay = 50
|
|
equip_delay_other = 50
|
|
flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF
|
|
resistance_flags = NONE
|
|
dog_fashion = null
|
|
slowdown = 0.5
|
|
sound_vary = TRUE
|
|
equip_sound = 'sound/items/handling/helmet/helmet_equip1.ogg'
|
|
pickup_sound = 'sound/items/handling/helmet/helmet_pickup1.ogg'
|
|
drop_sound = 'sound/items/handling/helmet/helmet_drop1.ogg'
|
|
///How much this helmet affects fishing difficulty
|
|
var/fishing_modifier = 3
|
|
|
|
/obj/item/clothing/head/helmet/space/Initialize(mapload)
|
|
. = ..()
|
|
if(fishing_modifier)
|
|
AddComponent(/datum/component/adjust_fishing_difficulty, fishing_modifier)
|
|
|
|
/datum/armor/helmet_space
|
|
bio = 100
|
|
fire = 80
|
|
acid = 70
|
|
|
|
/obj/item/clothing/suit/space
|
|
name = "space suit"
|
|
desc = "A suit that protects against low pressure environments. Has a big 13 on the back."
|
|
icon_state = "spaceold"
|
|
icon = 'icons/obj/clothing/suits/spacesuit.dmi'
|
|
lefthand_file = 'icons/mob/inhands/clothing/suits_lefthand.dmi'
|
|
righthand_file = 'icons/mob/inhands/clothing/suits_righthand.dmi'
|
|
worn_icon = 'icons/mob/clothing/suits/spacesuit.dmi'
|
|
inhand_icon_state = "s_suit"
|
|
w_class = WEIGHT_CLASS_BULKY
|
|
clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL
|
|
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
|
|
allowed = list(
|
|
/obj/item/flashlight,
|
|
/obj/item/tank/internals,
|
|
/obj/item/tank/jetpack/oxygen/captain,
|
|
)
|
|
slowdown = 0.5
|
|
armor_type = /datum/armor/suit_space
|
|
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDESEXTOY|HIDETAIL|HIDETAUR //SKYRAT EDIT CHANGE - ADDED HIDETAIL, HIDETAUR. ADDED HIDESEXTOY TO PREVENT VISUAL BUGS.
|
|
cold_protection = CHEST | GROIN | LEGS | FEET | ARMS | HANDS
|
|
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)
|
|
interaction_flags_click = NEED_DEXTERITY|ALLOW_RESTING
|
|
/// The default temperature setting
|
|
var/temperature_setting = BODYTEMP_NORMAL
|
|
/// If this is a path, this gets created as an object in Initialize.
|
|
var/obj/item/stock_parts/power_store/cell = /obj/item/stock_parts/power_store/cell/high
|
|
/// Status of the cell cover on the suit
|
|
var/cell_cover_open = FALSE
|
|
/// Status of the thermal regulator
|
|
var/thermal_on = FALSE
|
|
/// If this is FALSE the batery status UI will be disabled. This is used for suits that don't use bateries like the changeling's flesh suit mutation.
|
|
var/show_hud = TRUE
|
|
///How much this suit affects fishing difficulty
|
|
var/fishing_modifier = 5
|
|
|
|
/datum/armor/suit_space
|
|
bio = 100
|
|
fire = 80
|
|
acid = 70
|
|
|
|
/obj/item/clothing/suit/space/Initialize(mapload)
|
|
. = ..()
|
|
if(ispath(cell))
|
|
cell = new cell(src)
|
|
|
|
if(fishing_modifier)
|
|
AddComponent(/datum/component/adjust_fishing_difficulty, fishing_modifier)
|
|
|
|
/obj/item/clothing/suit/space/on_outfit_equip(mob/living/carbon/human/outfit_wearer, visuals_only, item_slot)
|
|
. = ..()
|
|
if(isnull(cell))
|
|
return
|
|
toggle_spacesuit(toggler = null, manual_toggle = FALSE) //turn on the thermal regulator by default.
|
|
|
|
/// Start Processing on the space suit when it is worn to heat the wearer
|
|
/obj/item/clothing/suit/space/equipped(mob/living/user, slot)
|
|
. = ..()
|
|
if(slot & ITEM_SLOT_OCLOTHING) // Check that the slot is valid
|
|
START_PROCESSING(SSobj, src)
|
|
update_hud_icon(user) // update the hud
|
|
RegisterSignal(user, COMSIG_MOB_GET_STATUS_TAB_ITEMS, PROC_REF(get_status_tab_item))
|
|
|
|
// On removal stop processing, save battery
|
|
/obj/item/clothing/suit/space/dropped(mob/living/user)
|
|
. = ..()
|
|
STOP_PROCESSING(SSobj, src)
|
|
UnregisterSignal(user, COMSIG_MOB_GET_STATUS_TAB_ITEMS)
|
|
var/mob/living/carbon/carbon_user = user
|
|
if(istype(carbon_user))
|
|
carbon_user.update_spacesuit_hud_icon("0")
|
|
|
|
/obj/item/clothing/suit/space/proc/get_status_tab_item(mob/living/source, list/items)
|
|
SIGNAL_HANDLER
|
|
items += "Thermal Regulator: [thermal_on ? "On" : "Off"]"
|
|
items += "Cell Charge: [cell ? "[round(cell.percent(), 0.1)]%" : "No Cell!"]"
|
|
|
|
// Space Suit temperature regulation and power usage
|
|
/obj/item/clothing/suit/space/process(seconds_per_tick)
|
|
var/mob/living/carbon/human/user = loc
|
|
if(!user || !ishuman(user) || user.wear_suit != src)
|
|
return
|
|
|
|
// Do nothing if thermal regulators are off
|
|
if(!thermal_on)
|
|
return
|
|
|
|
// If we got here, thermal regulators are on. If there's no cell, turn them off
|
|
if(!cell)
|
|
toggle_spacesuit(user, FALSE)
|
|
update_hud_icon(user)
|
|
return
|
|
|
|
// cell.use will return FALSE if charge is lower than THERMAL_REGULATOR_COST
|
|
if(!cell.use(THERMAL_REGULATOR_COST))
|
|
toggle_spacesuit(user, FALSE)
|
|
update_hud_icon(user)
|
|
to_chat(user, span_warning("The thermal regulator cuts off as [cell] runs out of charge."))
|
|
return
|
|
|
|
// If we got here, it means thermals are on, the cell is in and the cell has
|
|
// just had enough charge subtracted from it to power the thermal regulator
|
|
user.adjust_bodytemperature(get_temp_change_amount((temperature_setting - user.bodytemperature), 0.08 * seconds_per_tick))
|
|
update_hud_icon(user)
|
|
|
|
// Clean up the cell on destroy
|
|
/obj/item/clothing/suit/space/Destroy()
|
|
if(isatom(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/Exited(atom/movable/gone, direction)
|
|
. = ..()
|
|
if(gone == cell)
|
|
cell = null
|
|
thermal_on = FALSE
|
|
|
|
// support for items that interact with the cell
|
|
/obj/item/clothing/suit/space/get_cell(atom/movable/interface, mob/user)
|
|
if(istype(interface, /obj/item/inducer))
|
|
to_chat(user, span_alert("Error: unable to interface with [interface]."))
|
|
return null
|
|
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))
|
|
. += "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 meter shows [cell ? "[round(cell.percent(), 0.1)]%" : "!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."
|
|
|
|
/obj/item/clothing/suit/space/crowbar_act(mob/living/user, obj/item/tool)
|
|
toggle_spacesuit_cell(user)
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/item/clothing/suit/space/screwdriver_act(mob/living/user, obj/item/tool)
|
|
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, span_notice("You see the readout change to [deg_c] c."))
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
// object handling for accessing features of the suit
|
|
/obj/item/clothing/suit/space/attackby(obj/item/I, mob/user, params)
|
|
if(!cell_cover_open || !istype(I, /obj/item/stock_parts/power_store/cell))
|
|
return ..()
|
|
if(cell)
|
|
to_chat(user, span_warning("[src] already has a cell installed."))
|
|
return
|
|
if(user.transferItemToLoc(I, src))
|
|
cell = I
|
|
to_chat(user, span_notice("You successfully install \the [cell] into [src]."))
|
|
return
|
|
|
|
/// Open the cell cover when ALT+Click on the suit
|
|
/obj/item/clothing/suit/space/click_alt(mob/living/user)
|
|
toggle_spacesuit_cell(user)
|
|
return CLICK_ACTION_SUCCESS
|
|
|
|
/// Remove the cell whent he cover is open on CTRL+Click
|
|
/obj/item/clothing/suit/space/item_ctrl_click(mob/user)
|
|
. = CLICK_ACTION_BLOCKING
|
|
if(cell_cover_open && cell)
|
|
remove_cell(user)
|
|
return CLICK_ACTION_SUCCESS
|
|
|
|
// Remove the cell 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 cell cover is open
|
|
/obj/item/clothing/suit/space/proc/remove_cell(mob/user)
|
|
if(cell_cover_open && cell)
|
|
user.visible_message(span_notice("[user] removes \the [cell] from [src]!"), \
|
|
span_notice("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, span_notice("You [cell_cover_open ? "open" : "close"] the cell cover on \the [src]."))
|
|
|
|
/**
|
|
* Toggle the space suit's thermal regulator status
|
|
*
|
|
* Toggle the space suit's thermal regulator status...
|
|
* Can't do it if it has no charge.
|
|
* Arguments:
|
|
* * toggler - User mob who receives the to_chat messages.
|
|
* * manual_toggle - If false get a differently-flavored message about it being disabled by itself
|
|
*/
|
|
/obj/item/clothing/suit/space/proc/toggle_spacesuit(mob/toggler, manual_toggle = TRUE)
|
|
// If we're turning thermal protection on, check for valid cell and for enough
|
|
// charge that cell. If it's too low, we shouldn't bother with setting the
|
|
// thermal protection value and should just return out early.
|
|
if(!thermal_on && (!cell || cell.charge < THERMAL_REGULATOR_COST))
|
|
if(toggler)
|
|
to_chat(toggler, span_warning("The thermal regulator on [src] has no charge."))
|
|
return
|
|
|
|
thermal_on = !thermal_on
|
|
min_cold_protection_temperature = thermal_on ? SPACE_SUIT_MIN_TEMP_PROTECT : SPACE_SUIT_MIN_TEMP_PROTECT_OFF
|
|
|
|
update_item_action_buttons()
|
|
|
|
if(!toggler)
|
|
return
|
|
if(manual_toggle)
|
|
to_chat(toggler, span_notice("You turn [thermal_on ? "on" : "off"] [src]'s thermal regulator."))
|
|
else
|
|
to_chat(toggler, span_danger("You feel [src]'s thermal regulator switch [thermal_on ? "on" : "off"] by itself!"))
|
|
|
|
/obj/item/clothing/suit/space/ui_action_click(mob/user, actiontype)
|
|
toggle_spacesuit(user)
|
|
|
|
// let emags override the temperature settings
|
|
/obj/item/clothing/suit/space/emag_act(mob/user, obj/item/card/emag/emag_card)
|
|
if(obj_flags & EMAGGED)
|
|
return FALSE
|
|
obj_flags |= EMAGGED
|
|
if (user)
|
|
balloon_alert(user, "thermal regulator restrictions overridden")
|
|
user.log_message("emagged [src], overwriting thermal regulator restrictions.", LOG_GAME)
|
|
playsound(src, SFX_SPARKS, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
|
return TRUE
|
|
|
|
// update the HUD icon
|
|
/obj/item/clothing/suit/space/proc/update_hud_icon(mob/user)
|
|
var/mob/living/carbon/human/human = user
|
|
|
|
if(!show_hud)
|
|
return
|
|
|
|
if(!cell)
|
|
human.update_spacesuit_hud_icon("missing")
|
|
return
|
|
|
|
var/cell_percent = cell.percent()
|
|
|
|
// Check if there's enough charge to trigger a thermal regulator tick and
|
|
// if there is, whethere the cell's capacity indicates high, medium or low
|
|
// charge based on it.
|
|
if(cell.charge >= THERMAL_REGULATOR_COST)
|
|
if(cell_percent > 60)
|
|
human.update_spacesuit_hud_icon("high")
|
|
return
|
|
if(cell_percent > 20)
|
|
human.update_spacesuit_hud_icon("mid")
|
|
return
|
|
human.update_spacesuit_hud_icon("low")
|
|
return
|
|
|
|
human.update_spacesuit_hud_icon("empty")
|
|
return
|
|
|
|
// 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)
|
|
|
|
/obj/item/clothing/head/helmet/space/suicide_act(mob/living/carbon/user)
|
|
var/datum/gas_mixture/environment = user.loc.return_air()
|
|
if(HAS_TRAIT(user, TRAIT_RESISTCOLD) || !environment || environment.return_temperature() >= user.get_body_temp_cold_damage_limit())
|
|
user.visible_message(span_suicide("[user] is beating [user.p_them()]self with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!"))
|
|
return BRUTELOSS
|
|
user.say("You want proof? I'll give you proof! Here's proof of what'll happen to you if you stay here with your stuff!", forced = "space helmet suicide")
|
|
user.visible_message(span_suicide("[user] is removing [user.p_their()] helmet to make a point! Yo, holy shit, [user.p_they()] dead!")) //the use of p_they() instead of p_their() here is intentional
|
|
user.adjust_bodytemperature(-300)
|
|
user.apply_status_effect(/datum/status_effect/freon)
|
|
if(!ishuman(user))
|
|
return FIRELOSS
|
|
var/mob/living/carbon/human/humanafterall = user
|
|
var/datum/disease/advance/cold/pun = new //in the show, arnold survives his stunt, but catches a cold because of it
|
|
humanafterall.ForceContractDisease(pun, FALSE, TRUE) //this'll show up on health analyzers and the like
|
|
return FIRELOSS
|
|
|
|
#undef THERMAL_REGULATOR_COST
|