General maintenance for canisters (#80145)

## About The Pull Request
1. Fixes #80139
The greyscale config was not applied correctly and run timing halfway
causing the appearance of the canister to be broken. That's fixed now.

2. Removes prototype canisters. They are not available in game and even
as an admin tool their only function is to open the valve after an
elapsed time interval. Even this was broken cause the UI for adjusting
the timer was never added and the params had to be manually var edited
all for a pretty pointless function.
A better solution would be to allow players to attach signallers to
canisters to control the delay but that could be a future PR

4. Other smaller optimizations include
- converted vars like `can_min_release_pressure` and
`can_max_release_pressure` & `temperature_resistance` into defines. Vars
take up memory but not defines and so we saved some memory from this
    - removed var `starter_temp` cause its unused
    - removed var `protected_contents` cause it did nothing
- moved the global canister list to its appropriate
`code/define/globalvars/lists` folder where it belongs
    - Auto doc some vars & procs

5. Converted UI to typescript

## Changelog
🆑
fix: canisters don't disappear when their colours are changed
code: changed some vars into defines to save memory, removed
unused/useless vars & added auto docs
code: converted UI to typescript. moved global canister list to its
appropriate folder
refactor: removed prototype canisters and optimized canisters as a
whole.
/🆑
This commit is contained in:
SyncIt21
2023-12-08 18:13:36 +01:00
committed by GitHub
parent 6819568b6e
commit ed17dde468
9 changed files with 175 additions and 313 deletions
@@ -77,3 +77,8 @@
///What direction is the machine pumping (into pump/port or out to the tank/area)?
#define PUMP_IN TRUE
#define PUMP_OUT FALSE
///Max allowed pressure for canisters to release air per tick
#define CAN_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE * 25)
///Min allowed pressure for canisters to release air per tick
#define CAN_MIN_RELEASE_PRESSURE (ONE_ATMOSPHERE * 0.1)
+29
View File
@@ -0,0 +1,29 @@
///List of all the gases, used in labelling the canisters
GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
///Returns a map of canister id to its type path
/proc/init_gas_id_to_canister()
return sort_list(list(
GAS_N2 = /obj/machinery/portable_atmospherics/canister/nitrogen,
GAS_O2 = /obj/machinery/portable_atmospherics/canister/oxygen,
GAS_CO2 = /obj/machinery/portable_atmospherics/canister/carbon_dioxide,
GAS_PLASMA = /obj/machinery/portable_atmospherics/canister/plasma,
GAS_N2O = /obj/machinery/portable_atmospherics/canister/nitrous_oxide,
GAS_NITRIUM = /obj/machinery/portable_atmospherics/canister/nitrium,
GAS_BZ = /obj/machinery/portable_atmospherics/canister/bz,
GAS_AIR = /obj/machinery/portable_atmospherics/canister/air,
GAS_WATER_VAPOR = /obj/machinery/portable_atmospherics/canister/water_vapor,
GAS_TRITIUM = /obj/machinery/portable_atmospherics/canister/tritium,
GAS_HYPER_NOBLIUM = /obj/machinery/portable_atmospherics/canister/nob,
GAS_PLUOXIUM = /obj/machinery/portable_atmospherics/canister/pluoxium,
"caution" = /obj/machinery/portable_atmospherics/canister,
GAS_MIASMA = /obj/machinery/portable_atmospherics/canister/miasma,
GAS_FREON = /obj/machinery/portable_atmospherics/canister/freon,
GAS_HYDROGEN = /obj/machinery/portable_atmospherics/canister/hydrogen,
GAS_HEALIUM = /obj/machinery/portable_atmospherics/canister/healium,
GAS_PROTO_NITRATE = /obj/machinery/portable_atmospherics/canister/proto_nitrate,
GAS_ZAUKER = /obj/machinery/portable_atmospherics/canister/zauker,
GAS_HELIUM = /obj/machinery/portable_atmospherics/canister/helium,
GAS_ANTINOBLIUM = /obj/machinery/portable_atmospherics/canister/antinoblium,
GAS_HALON = /obj/machinery/portable_atmospherics/canister/halon
))
@@ -112,11 +112,6 @@
name = "Hazard Striped Canister"
json_config = 'code/datums/greyscale/json_configs/canister_hazard.json'
/datum/greyscale_config/prototype_canister
name = "Prototype Canister"
icon_file = 'icons/obj/pipes_n_cables/prototype_canister.dmi'
json_config = 'code/datums/greyscale/json_configs/canister_proto.json'
/datum/greyscale_config/stationary_canister
name = "Stationary Canister"
icon_file = 'icons/obj/pipes_n_cables/stationary_canisters.dmi'
@@ -1,39 +0,0 @@
{
"": [
{
"type": "icon_state",
"icon_state": "can_base",
"blend_mode": "overlay",
"color_ids": [ 1 ]
},
{
"type": "icon_state",
"icon_state": "can_shader",
"blend_mode": "multiply"
},
{
"type": "icon_state",
"icon_state": "stand",
"blend_mode": "overlay"
},
{
"type": "icon_state",
"icon_state": "decals",
"blend_mode": "overlay"
},
[
{
"type": "icon_state",
"icon_state": "light_base",
"blend_mode": "overlay",
"color_ids": [ 2 ]
},
{
"type": "icon_state",
"icon_state": "light",
"blend_mode": "overlay",
"color_ids": [ 3 ]
}
]
]
}
@@ -1,33 +1,7 @@
///The default pressure for releasing air into an holding tank or the turf
#define CAN_DEFAULT_RELEASE_PRESSURE (ONE_ATMOSPHERE)
///List of all the gases, used in labelling the canisters
GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
/proc/init_gas_id_to_canister()
return sort_list(list(
GAS_N2 = /obj/machinery/portable_atmospherics/canister/nitrogen,
GAS_O2 = /obj/machinery/portable_atmospherics/canister/oxygen,
GAS_CO2 = /obj/machinery/portable_atmospherics/canister/carbon_dioxide,
GAS_PLASMA = /obj/machinery/portable_atmospherics/canister/plasma,
GAS_N2O = /obj/machinery/portable_atmospherics/canister/nitrous_oxide,
GAS_NITRIUM = /obj/machinery/portable_atmospherics/canister/nitrium,
GAS_BZ = /obj/machinery/portable_atmospherics/canister/bz,
GAS_AIR = /obj/machinery/portable_atmospherics/canister/air,
GAS_WATER_VAPOR = /obj/machinery/portable_atmospherics/canister/water_vapor,
GAS_TRITIUM = /obj/machinery/portable_atmospherics/canister/tritium,
GAS_HYPER_NOBLIUM = /obj/machinery/portable_atmospherics/canister/nob,
GAS_PLUOXIUM = /obj/machinery/portable_atmospherics/canister/pluoxium,
"caution" = /obj/machinery/portable_atmospherics/canister,
GAS_MIASMA = /obj/machinery/portable_atmospherics/canister/miasma,
GAS_FREON = /obj/machinery/portable_atmospherics/canister/freon,
GAS_HYDROGEN = /obj/machinery/portable_atmospherics/canister/hydrogen,
GAS_HEALIUM = /obj/machinery/portable_atmospherics/canister/healium,
GAS_PROTO_NITRATE = /obj/machinery/portable_atmospherics/canister/proto_nitrate,
GAS_ZAUKER = /obj/machinery/portable_atmospherics/canister/zauker,
GAS_HELIUM = /obj/machinery/portable_atmospherics/canister/helium,
GAS_ANTINOBLIUM = /obj/machinery/portable_atmospherics/canister/antinoblium,
GAS_HALON = /obj/machinery/portable_atmospherics/canister/halon
))
///The temperature resistance of this canister
#define TEMPERATURE_RESISTANCE (1000 + T0C)
/obj/machinery/portable_atmospherics/canister
name = "canister"
@@ -44,8 +18,6 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
pressure_resistance = 7 * ONE_ATMOSPHERE
req_access = list()
var/icon/canister_overlay_file = 'icons/obj/pipes_n_cables/canisters.dmi'
///Is the valve open?
var/valve_open = FALSE
///Used to log opening and closing of the valve, available on VV
@@ -55,40 +27,17 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
///Maximum pressure allowed on initialize inside the canister, multiplied by the filled var
var/maximum_pressure = 90 * ONE_ATMOSPHERE
///Stores the path of the gas for mapped canisters
var/gas_type
var/datum/gas/gas_type
///Player controlled var that set the release pressure of the canister
var/release_pressure = ONE_ATMOSPHERE
///Maximum pressure allowed for release_pressure var
var/can_max_release_pressure = (ONE_ATMOSPHERE * 25)
///Minimum pressure allower for release_pressure var
var/can_min_release_pressure = (ONE_ATMOSPHERE * 0.1)
///Maximum amount of external heat that the canister can handle before taking damage
var/temperature_resistance = 1000 + T0C
///Initial temperature gas mixture
var/starter_temp
// Prototype vars
///Is the canister a prototype one?
var/prototype = FALSE
///Timer variables
var/valve_timer = null
var/timer_set = 30
var/default_timer_set = 30
var/minimum_timer_set = 1
var/maximum_timer_set = 300
var/timing = FALSE
///If true, the prototype canister requires engi access to be used
var/restricted = FALSE
///Window overlay showing the gas inside the canister
var/image/window
///Is shielding turned on/off
var/shielding_powered = FALSE
///The powercell used to enable shielding
var/obj/item/stock_parts/cell/internal_cell
///Is the cell hatch opened
var/cell_container_opened = FALSE
var/protected_contents = FALSE
///used while processing to update appearance only when its pressure state changes
var/current_pressure_state
@@ -308,46 +257,6 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
air_contents.gases[/datum/gas/nitrous_oxide][MOLES] = (N2O_ANESTHETIC * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
SSair.start_processing_machine(src)
/**
* Getter for the amount of time left in the timer of prototype canisters
*/
/obj/machinery/portable_atmospherics/canister/proc/get_time_left()
if(timing)
. = round(max(0, valve_timer - world.time) * 0.1, 1)
else
. = timer_set
/**
* Starts the timer of prototype canisters
*/
/obj/machinery/portable_atmospherics/canister/proc/set_active()
timing = !timing
if(timing)
valve_timer = world.time + (timer_set SECONDS)
update_appearance()
/obj/machinery/portable_atmospherics/canister/proto
name = "prototype canister"
greyscale_config = /datum/greyscale_config/prototype_canister
greyscale_colors = "#ffffff#a50021#ffffff"
/obj/machinery/portable_atmospherics/canister/proto/default
name = "prototype canister"
desc = "The best way to fix an atmospheric emergency... or the best way to introduce one."
volume = 5000
max_integrity = 300
temperature_resistance = 2000 + T0C
can_max_release_pressure = (ONE_ATMOSPHERE * 30)
can_min_release_pressure = (ONE_ATMOSPHERE / 30)
prototype = TRUE
/obj/machinery/portable_atmospherics/canister/proto/default/oxygen
name = "prototype canister"
desc = "A prototype canister for a prototype bike, what could go wrong?"
gas_type = /datum/gas/oxygen
filled = 1
release_pressure = ONE_ATMOSPHERE*2
/**
* Called on Initialize(), fill the canister with the gas_type specified up to the filled level (half if 0.5, full if 1)
* Used for canisters spawned in maps and by admins
@@ -356,8 +265,6 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
if(!gas_type)
return
air_contents.add_gas(gas_type)
if(starter_temp)
air_contents.temperature = starter_temp
air_contents.gases[gas_type][MOLES] = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
SSair.start_processing_machine(src)
@@ -376,25 +283,24 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
. = ..()
if(shielding_powered)
. += mutable_appearance(canister_overlay_file, "shielding")
. += emissive_appearance(canister_overlay_file, "shielding", src)
. += mutable_appearance('icons/obj/pipes_n_cables/canisters.dmi', "shielding")
. += emissive_appearance('icons/obj/pipes_n_cables/canisters.dmi', "shielding", src)
if(cell_container_opened)
. += mutable_appearance(canister_overlay_file, "cell_hatch")
. += mutable_appearance('icons/obj/pipes_n_cables/canisters.dmi', "cell_hatch")
var/isBroken = machine_stat & BROKEN
///Function is used to actually set the overlays
if(isBroken)
. += mutable_appearance(canister_overlay_file, "broken")
if(machine_stat & BROKEN)
. += mutable_appearance('icons/obj/pipes_n_cables/canisters.dmi', "broken")
if(holding)
. += mutable_appearance(canister_overlay_file, "can-open")
. += mutable_appearance('icons/obj/pipes_n_cables/canisters.dmi', "can-open")
if(connected_port)
. += mutable_appearance(canister_overlay_file, "can-connector")
. += mutable_appearance('icons/obj/pipes_n_cables/canisters.dmi', "can-connector")
var/light_state = get_pressure_state(air_contents.return_pressure())
var/light_state = get_pressure_state()
if(light_state) //happens when pressure is below 10kpa which means no light
. += mutable_appearance(canister_overlay_file, light_state)
. += emissive_appearance(canister_overlay_file, "[light_state]-light", src, alpha = src.alpha)
. += mutable_appearance('icons/obj/pipes_n_cables/canisters.dmi', light_state)
. += emissive_appearance('icons/obj/pipes_n_cables/canisters.dmi', "[light_state]-light", src, alpha = src.alpha)
update_window()
@@ -402,18 +308,20 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
. = ..()
update_window()
///Updates the overlays of this canister based on its air contents
/obj/machinery/portable_atmospherics/canister/proc/update_window()
if(!air_contents)
return
var/static/alpha_filter
if(!alpha_filter) // Gotta do this separate since the icon may not be correct at world init
alpha_filter = filter(type="alpha", icon=icon(icon, "window-base"))
alpha_filter = filter(type="alpha", icon = icon('icons/obj/pipes_n_cables/canisters.dmi', "window-base"))
cut_overlay(window)
window = image(icon, icon_state="window-base", layer=FLOAT_LAYER)
window = image('icons/obj/pipes_n_cables/canisters.dmi', icon_state = "window-base", layer = FLOAT_LAYER)
var/list/window_overlays = list()
for(var/visual in air_contents.return_visuals(get_turf(src)))
var/image/new_visual = image(visual, layer=FLOAT_LAYER)
var/image/new_visual = image(visual, layer = FLOAT_LAYER)
new_visual.filters = alpha_filter
window_overlays += new_visual
window.overlays = window_overlays
@@ -421,7 +329,7 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
// Both of these procs handle the external temperature damage.
/obj/machinery/portable_atmospherics/canister/should_atmos_process(datum/gas_mixture/air, exposed_temperature)
return (exposed_temperature > temperature_resistance && !shielding_powered)
return (exposed_temperature > TEMPERATURE_RESISTANCE && !shielding_powered)
/obj/machinery/portable_atmospherics/canister/atmos_expose(datum/gas_mixture/air, exposed_temperature)
take_damage(5, BURN, 0)
@@ -446,38 +354,40 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
var/obj/item/stock_parts/cell/active_cell = item
if(!cell_container_opened)
balloon_alert(user, "open the hatch first")
return
return TRUE
if(!user.transferItemToLoc(active_cell, src))
return
return TRUE
if(internal_cell)
user.put_in_hands(internal_cell)
balloon_alert(user, "you successfully replace the cell")
else
balloon_alert(user, "you successfully install the cell")
internal_cell = active_cell
return
return TRUE
return ..()
/obj/machinery/portable_atmospherics/canister/screwdriver_act(mob/living/user, obj/item/screwdriver)
if(screwdriver.tool_behaviour != TOOL_SCREWDRIVER)
return
screwdriver.play_tool_sound(src, 50)
cell_container_opened = !cell_container_opened
to_chat(user, span_notice("You [cell_container_opened ? "open" : "close"] the cell container hatch of [src]."))
update_appearance()
return TRUE
return TOOL_ACT_TOOLTYPE_SUCCESS
/obj/machinery/portable_atmospherics/canister/crowbar_act(mob/living/user, obj/item/tool)
. = TOOL_ACT_TOOLTYPE_SUCCESS
if(!cell_container_opened || !internal_cell)
return
internal_cell.forceMove(drop_location())
balloon_alert(user, "you successfully remove the cell")
return TRUE
balloon_alert(user, "cell removed")
/obj/machinery/portable_atmospherics/canister/welder_act_secondary(mob/living/user, obj/item/I)
. = ..()
. = TOOL_ACT_TOOLTYPE_SUCCESS
if(!I.tool_start_check(user, amount=1))
return TRUE
return
var/pressure = air_contents.return_pressure()
if(pressure > 300)
to_chat(user, span_alert("The pressure gauge on [src] indicates a high pressure inside... maybe you want to reconsider?"))
@@ -487,26 +397,21 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
if(I.use_tool(src, user, 3 SECONDS, volume=50))
to_chat(user, span_notice("You cut [src] apart."))
deconstruct(TRUE)
return TRUE
/obj/machinery/portable_atmospherics/canister/welder_act(mob/living/user, obj/item/tool)
. = ..()
. = TOOL_ACT_TOOLTYPE_SUCCESS
if(user.combat_mode)
return FALSE
if(atom_integrity >= max_integrity)
return TRUE
if(machine_stat & BROKEN)
return TRUE
if(!tool.tool_start_check(user, amount=1))
return TRUE
if(atom_integrity >= max_integrity || (machine_stat & BROKEN) || !tool.tool_start_check(user, amount = 1))
return
to_chat(user, span_notice("You begin repairing cracks in [src]..."))
while(tool.use_tool(src, user, 2.5 SECONDS, volume=40))
atom_integrity = min(atom_integrity + 25, max_integrity)
if(atom_integrity >= max_integrity)
to_chat(user, span_notice("You've finished repairing [src]."))
return TRUE
return
to_chat(user, span_notice("You repair some of the cracks in [src]..."))
return TRUE
/obj/machinery/portable_atmospherics/canister/Exited(atom/movable/gone, direction)
. = ..()
@@ -525,9 +430,7 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
return
canister_break()
/**
* Handle canisters disassemble, releases the gas content in the turf
*/
///Handle canisters disassemble, releases the gas content in the turf
/obj/machinery/portable_atmospherics/canister/proc/canister_break()
disconnect()
var/datum/gas_mixture/expelled_gas = air_contents.remove(air_contents.total_moles())
@@ -550,6 +453,7 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
. = ..()
if(!.)
return
if(close_valve)
valve_open = FALSE
update_appearance()
@@ -558,26 +462,22 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
user.investigate_log("started a transfer into [holding].", INVESTIGATE_ATMOS)
/obj/machinery/portable_atmospherics/canister/process(seconds_per_tick)
var/our_pressure = air_contents.return_pressure()
var/our_temperature = air_contents.return_temperature()
protected_contents = FALSE
if(shielding_powered)
var/power_factor = round(log(10, max(our_pressure - pressure_limit, 1)) + log(10, max(our_temperature - temp_limit, 1)))
var/power_consumed = power_factor * 250 * seconds_per_tick
if(powered(AREA_USAGE_EQUIP, ignore_use_power = TRUE))
use_power(power_consumed, AREA_USAGE_EQUIP)
protected_contents = TRUE
else if(internal_cell?.use(power_consumed * 0.025))
protected_contents = TRUE
else
else if(!internal_cell?.use(power_consumed * 0.025))
shielding_powered = FALSE
SSair.start_processing_machine(src)
investigate_log("shielding turned off due to power loss")
///return the icon_state component for the canister's indicator light based on its current pressure reading
/obj/machinery/portable_atmospherics/canister/proc/get_pressure_state(air_pressure)
/obj/machinery/portable_atmospherics/canister/proc/get_pressure_state()
var/air_pressure = air_contents.return_pressure()
switch(air_pressure)
if((40 * ONE_ATMOSPHERE) to INFINITY)
return "can-3"
@@ -593,9 +493,6 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
/obj/machinery/portable_atmospherics/canister/process_atmos()
if(machine_stat & BROKEN)
return PROCESS_KILL
if(timing && valve_timer < world.time)
valve_open = !valve_open
timing = FALSE
// Handle gas transfer.
if(valve_open)
@@ -613,7 +510,7 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
excited = TRUE
return ..() //we have already updated appearance so dont need to update again below
var/new_pressure_state = get_pressure_state(air_contents.return_pressure())
var/new_pressure_state = get_pressure_state()
if(current_pressure_state != new_pressure_state) //update apperance only when its pressure changes significantly from its current value
update_appearance()
current_pressure_state = new_pressure_state
@@ -632,8 +529,8 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
/obj/machinery/portable_atmospherics/canister/ui_static_data(mob/user)
return list(
"defaultReleasePressure" = round(CAN_DEFAULT_RELEASE_PRESSURE),
"minReleasePressure" = round(can_min_release_pressure),
"maxReleasePressure" = round(can_max_release_pressure),
"minReleasePressure" = round(CAN_MIN_RELEASE_PRESSURE),
"maxReleasePressure" = round(CAN_MAX_RELEASE_PRESSURE),
"pressureLimit" = round(pressure_limit),
"holdingTankLeakPressure" = round(TANK_LEAK_PRESSURE),
"holdingTankFragPressure" = round(TANK_FRAGMENT_PRESSURE)
@@ -645,85 +542,69 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
"tankPressure" = round(air_contents.return_pressure()),
"releasePressure" = round(release_pressure),
"valveOpen" = !!valve_open,
"isPrototype" = !!prototype,
"hasHoldingTank" = !!holding,
"hasHypernobCrystal" = !!nob_crystal_inserted,
"reactionSuppressionEnabled" = !!suppress_reactions
)
if (prototype)
. += list(
"restricted" = restricted,
"timing" = timing,
"time_left" = get_time_left(),
"timer_set" = timer_set,
"timer_is_not_default" = timer_set != default_timer_set,
"timer_is_not_min" = timer_set != minimum_timer_set,
"timer_is_not_max" = timer_set != maximum_timer_set
)
if (holding)
var/datum/gas_mixture/holding_mix = holding.return_air()
. += list(
"holdingTank" = list(
"name" = holding.name,
"tankPressure" = round(holding_mix.return_pressure())
)
.["holdingTank"] = list(
"name" = holding.name,
"tankPressure" = round(holding_mix.return_pressure())
)
else
.["holdingTank"] = null
. += list(
"shielding" = shielding_powered,
"hasCell" = (internal_cell ? TRUE : FALSE),
"cellCharge" = internal_cell?.percent()
"cellCharge" = internal_cell ? internal_cell.percent() : 0
)
/obj/machinery/portable_atmospherics/canister/ui_act(action, params)
. = ..()
if(.)
return
switch(action)
if("relabel")
var/label = tgui_input_list(usr, "New canister label", "Canister", GLOB.gas_id_to_canister)
if(isnull(label))
return
if(!..())
var/newtype = GLOB.gas_id_to_canister[label]
if(newtype)
var/obj/machinery/portable_atmospherics/canister/replacement = newtype
investigate_log("was relabelled to [initial(replacement.name)] by [key_name(usr)].", INVESTIGATE_ATMOS)
name = initial(replacement.name)
desc = initial(replacement.desc)
icon_state = initial(replacement.icon_state)
base_icon_state = icon_state
set_greyscale(initial(replacement.greyscale_colors), initial(replacement.greyscale_config))
if("restricted")
restricted = !restricted
if(restricted)
req_access = list(ACCESS_ENGINEERING)
else
req_access = list()
. = TRUE
var/newtype = GLOB.gas_id_to_canister[label]
if(isnull(newtype))
return
var/obj/machinery/portable_atmospherics/canister/replacement = newtype
investigate_log("was relabelled to [initial(replacement.name)] by [key_name(usr)].", INVESTIGATE_ATMOS)
name = initial(replacement.name)
desc = initial(replacement.desc)
icon_state = initial(replacement.icon_state)
base_icon_state = icon_state
set_greyscale(initial(replacement.greyscale_colors), initial(replacement.greyscale_config))
if("pressure")
var/pressure = params["pressure"]
if(pressure == "reset")
pressure = CAN_DEFAULT_RELEASE_PRESSURE
. = TRUE
else if(pressure == "min")
pressure = can_min_release_pressure
pressure = CAN_MIN_RELEASE_PRESSURE
. = TRUE
else if(pressure == "max")
pressure = can_max_release_pressure
pressure = CAN_MAX_RELEASE_PRESSURE
. = TRUE
else if(pressure == "input")
pressure = tgui_input_number(usr, "New release pressure", "Canister Pressure", release_pressure, can_max_release_pressure, can_min_release_pressure)
if(!isnull(pressure) && !..())
pressure = tgui_input_number(usr, "New release pressure", "Canister Pressure", release_pressure, CAN_MAX_RELEASE_PRESSURE, CAN_MIN_RELEASE_PRESSURE)
if(!isnull(pressure))
. = TRUE
else if(text2num(pressure) != null)
pressure = text2num(pressure)
. = TRUE
if(.)
release_pressure = clamp(round(pressure), can_min_release_pressure, can_max_release_pressure)
release_pressure = clamp(round(pressure), CAN_MIN_RELEASE_PRESSURE, CAN_MAX_RELEASE_PRESSURE)
investigate_log("was set to [release_pressure] kPa by [key_name(usr)].", INVESTIGATE_ATMOS)
if("valve") //logging for openning canisters
if("valve")
var/logmsg
var/admin_msg
var/danger = FALSE
@@ -757,24 +638,7 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
investigate_log(logmsg, INVESTIGATE_ATMOS)
release_log += logmsg
. = TRUE
if("timer")
var/change = params["change"]
switch(change)
if("reset")
timer_set = default_timer_set
if("decrease")
timer_set = max(minimum_timer_set, timer_set - 10)
if("increase")
timer_set = min(maximum_timer_set, timer_set + 10)
if("input")
var/user_input = tgui_input_number(usr, "Set time to valve toggle", "Canister Timer", timer_set, maximum_timer_set, minimum_timer_set)
if(isnull(user_input) || QDELETED(usr) || QDELETED(src) || !usr.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
timer_set = user_input
log_admin("[key_name(usr)] has activated a prototype valve timer")
. = TRUE
if("toggle_timer")
set_active()
if("eject")
if(holding)
if(valve_open)
@@ -788,7 +652,9 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
SSair.start_processing_machine(src)
message_admins("[ADMIN_LOOKUPFLW(usr)] turned [shielding_powered ? "on" : "off"] the [src] powered shielding.")
usr.investigate_log("turned [shielding_powered ? "on" : "off"] the [src] powered shielding.")
update_appearance()
. = TRUE
if("reaction_suppression")
if(!nob_crystal_inserted)
stack_trace("[usr] tried to toggle reaction suppression on a canister without a noblium crystal inside, possible href exploit attempt.")
@@ -798,38 +664,32 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
message_admins("[ADMIN_LOOKUPFLW(usr)] turned [suppress_reactions ? "on" : "off"] the [src] reaction suppression.")
usr.investigate_log("turned [suppress_reactions ? "on" : "off"] the [src] reaction suppression.")
. = TRUE
if("recolor")
select_colors()
var/initial_config = initial(greyscale_config)
if(isnull(initial_config))
return FALSE
var/datum/greyscale_modify_menu/menu = new(
src, usr, list("[initial_config]"), CALLBACK(src, PROC_REF(recolor)),
starting_icon_state = initial(icon_state),
starting_config = initial_config,
starting_colors = initial(greyscale_colors)
)
menu.ui_interact(usr)
. = TRUE
update_appearance()
/obj/machinery/portable_atmospherics/canister/proc/select_colors()
var/atom/fake_atom = src
var/list/allowed_configs = list()
var/config = initial(fake_atom.greyscale_config)
if(!config)
return
allowed_configs += "[config]"
var/datum/greyscale_modify_menu/menu = new(
src, usr, allowed_configs, CALLBACK(src, PROC_REF(recolor)),
starting_icon_state=initial(fake_atom.icon_state),
starting_config=initial(fake_atom.greyscale_config),
starting_colors=initial(fake_atom.greyscale_colors)
)
menu.ui_interact(usr)
/obj/machinery/portable_atmospherics/canister/proc/recolor(datum/greyscale_modify_menu/menu)
set_greyscale(menu.split_colors)
set_greyscale(menu.split_colors, menu.config.type)
/obj/machinery/portable_atmospherics/canister/unregister_holding()
valve_open = FALSE
return ..()
/obj/machinery/portable_atmospherics/canister/take_atmos_damage()
if(shielding_powered)
return FALSE
return ..()
return shielding_powered ? FALSE : ..()
#undef CAN_DEFAULT_RELEASE_PRESSURE
#undef TEMPERATURE_RESISTANCE
@@ -107,8 +107,8 @@
"auto_pressurize_on_seal" = auto_pressurize_on_seal,
"port_connected" = internal_tank?.connected_port ? TRUE : FALSE,
"tank_release_pressure" = round(internal_tank.release_pressure),
"tank_release_pressure_min" = internal_tank.can_min_release_pressure,
"tank_release_pressure_max" = internal_tank.can_max_release_pressure,
"tank_release_pressure_min" = CAN_MIN_RELEASE_PRESSURE,
"tank_release_pressure_max" = CAN_MAX_RELEASE_PRESSURE,
"tank_pump_active" = tank_pump_active,
"tank_pump_direction" = tank_pump_direction,
"tank_pump_pressure" = round(tank_pump_pressure),
@@ -122,7 +122,7 @@
switch(action)
if("set_cabin_pressure")
var/new_pressure = text2num(params["new_pressure"])
internal_tank.release_pressure = clamp(round(new_pressure), internal_tank.can_min_release_pressure, internal_tank.can_max_release_pressure)
internal_tank.release_pressure = clamp(round(new_pressure), CAN_MIN_RELEASE_PRESSURE, CAN_MAX_RELEASE_PRESSURE)
return TRUE
if("toggle_port")
if(internal_tank.connected_port)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

+1
View File
@@ -508,6 +508,7 @@
#include "code\_globalvars\time_vars.dm"
#include "code\_globalvars\lists\achievements.dm"
#include "code\_globalvars\lists\ambience.dm"
#include "code\_globalvars\lists\canisters.dm"
#include "code\_globalvars\lists\client.dm"
#include "code\_globalvars\lists\color.dm"
#include "code\_globalvars\lists\crafting.dm"
@@ -1,38 +1,60 @@
import { toFixed } from 'common/math';
import { BooleanLike } from 'common/react';
import { useBackend } from '../backend';
import { Box, Button, Flex, Icon, Knob, LabeledControls, LabeledList, RoundGauge, Section, Tooltip } from '../components';
import { formatSiUnit } from '../format';
import { Window } from '../layouts';
const formatPressure = (value) => {
const formatPressure = (value: number) => {
if (value < 10000) {
return toFixed(value) + ' kPa';
}
return formatSiUnit(value * 1000, 1, 'Pa');
};
type HoldingTank = {
name: string;
tankPressure: number;
};
type Data = {
portConnected: BooleanLike;
tankPressure: number;
releasePressure: number;
defaultReleasePressure: number;
minReleasePressure: number;
maxReleasePressure: number;
hasHypernobCrystal: BooleanLike;
cellCharge: number;
pressureLimit: number;
valveOpen: BooleanLike;
holdingTank: HoldingTank;
holdingTankLeakPressure: number;
holdingTankFragPressure: number;
shielding: BooleanLike;
reactionSuppressionEnabled: BooleanLike;
};
export const Canister = (props) => {
const { act, data } = useBackend();
const { act, data } = useBackend<Data>();
const {
portConnected,
shielding,
holdingTank,
pressureLimit,
valveOpen,
tankPressure,
releasePressure,
defaultReleasePressure,
minReleasePressure,
maxReleasePressure,
portConnected,
cellCharge,
hasHypernobCrystal,
reactionSuppressionEnabled,
hasCell,
cellCharge,
pressureLimit,
valveOpen,
isPrototype,
hasHoldingTank,
holdingTank,
holdingTankLeakPressure,
holdingTankFragPressure,
restricted,
holdingTankLeakPressure,
} = data;
return (
<Window width={350} height={335}>
<Window.Content>
@@ -42,19 +64,10 @@ export const Canister = (props) => {
title="Canister"
buttons={
<>
{!!isPrototype && (
<Button
mr={1}
icon={restricted ? 'lock' : 'unlock'}
color="caution"
content={restricted ? 'Engineering' : 'Public'}
onClick={() => act('restricted')}
/>
)}
<Button
icon={data.shielding ? 'power-off' : 'times'}
content={data.shielding ? 'Shielding-ON' : 'Shielding-OFF'}
selected={data.shielding}
icon={shielding ? 'power-off' : 'times'}
content={shielding ? 'Shielding-ON' : 'Shielding-OFF'}
selected={shielding}
onClick={() => act('shielding')}
/>
<Button
@@ -133,7 +146,7 @@ export const Canister = (props) => {
lineHeight={2}
fontSize="11px"
color={
valveOpen ? (hasHoldingTank ? 'caution' : 'danger') : null
valveOpen ? (holdingTank ? 'caution' : 'danger') : null
}
content={valveOpen ? 'Open' : 'Closed'}
onClick={() => act('valve')}
@@ -157,18 +170,16 @@ export const Canister = (props) => {
<Section>
<LabeledList>
<LabeledList.Item label="Cell Charge">
{hasCell ? cellCharge + '%' : 'Missing Cell'}
{cellCharge > 0 ? cellCharge + '%' : 'Missing Cell'}
</LabeledList.Item>
{!!hasHypernobCrystal && (
<LabeledList.Item label="Reaction Suppression">
<Button
icon={
data.reactionSuppressionEnabled ? 'snowflake' : 'times'
}
icon={reactionSuppressionEnabled ? 'snowflake' : 'times'}
content={
data.reactionSuppressionEnabled ? 'Enabled' : 'Disabled'
reactionSuppressionEnabled ? 'Enabled' : 'Disabled'
}
selected={data.reactionSuppressionEnabled}
selected={reactionSuppressionEnabled}
onClick={() => act('reaction_suppression')}
/>
</LabeledList.Item>
@@ -181,7 +192,7 @@ export const Canister = (props) => {
height="100%"
title="Holding Tank"
buttons={
!!hasHoldingTank && (
!!holdingTank && (
<Button
icon="eject"
color={valveOpen && 'danger'}
@@ -190,7 +201,7 @@ export const Canister = (props) => {
/>
)
}>
{!!hasHoldingTank && (
{!!holdingTank && (
<LabeledList>
<LabeledList.Item label="Label">
{holdingTank.name}
@@ -218,7 +229,7 @@ export const Canister = (props) => {
</LabeledList.Item>
</LabeledList>
)}
{!hasHoldingTank && <Box color="average">No Holding Tank</Box>}
{!holdingTank && <Box color="average">No Holding Tank</Box>}
</Section>
</Flex.Item>
</Flex>