Adds the Temperature Gate (#30812)

* introducing, the temperature gate!

* why is are the icons not workinggg, perhaps CI to the rescue

* rebuilding tgui

* tgui fix!

* icon fixes and tgui

* if i had a nickel for everytime i got told to rebuild tgui

* as funny as "the temperature thing" is, it should have a proper description

* T0C rounded to 273

* small typo

* some small sprite work
This commit is contained in:
Hayden Redacted
2025-11-28 16:36:47 +00:00
committed by GitHub
parent 6d0cf05591
commit b0f2dbaf23
9 changed files with 232 additions and 3 deletions
+1
View File
@@ -37,6 +37,7 @@
#define PIPE_PASV_VENT 37
#define PIPE_DTVALVE 38
#define PIPE_CIRCULATOR 39
#define PIPE_TEMPERATURE_GATE 40
#define PIPE_GAS_SENSOR 98
#define PIPE_METER 99
+8
View File
@@ -193,6 +193,14 @@ GLOBAL_LIST_EMPTY(rpd_pipe_list) //Some pipes we don't want to be dispensable
pipe_category = RPD_DEVICES
rpd_dispensable = TRUE
/datum/pipes/atmospheric/temperature_gate
pipe_name = "temperature gate"
pipe_id = PIPE_TEMPERATURE_GATE
orientations = 4
pipe_icon = "temperature_gate"
pipe_category = RPD_DEVICES
rpd_dispensable = TRUE
/datum/pipes/atmospheric/filter
pipe_name = "gas filter"
pipe_id = PIPE_GAS_FILTER
@@ -22,6 +22,7 @@ GLOBAL_LIST_INIT(pipe_path2type, list(
/obj/machinery/atmospherics/trinary/mixer = PIPE_GAS_MIXER,
/obj/machinery/atmospherics/unary/vent_scrubber = PIPE_SCRUBBER,
/obj/machinery/atmospherics/binary/passive_gate = PIPE_PASSIVE_GATE,
/obj/machinery/atmospherics/binary/temperature_gate = PIPE_TEMPERATURE_GATE,
/obj/machinery/atmospherics/binary/volume_pump = PIPE_VOLUME_PUMP,
/obj/machinery/atmospherics/unary/heat_exchanger = PIPE_HEAT_EXCHANGE,
/obj/machinery/atmospherics/trinary/tvalve/digital = PIPE_DTVALVE,
@@ -61,6 +62,7 @@ GLOBAL_LIST_INIT(pipe_path2type, list(
"[PIPE_GAS_MIXER]" = /obj/machinery/atmospherics/trinary/mixer,
"[PIPE_SCRUBBER]" = /obj/machinery/atmospherics/unary/vent_scrubber,
"[PIPE_PASSIVE_GATE]" = /obj/machinery/atmospherics/binary/passive_gate,
"[PIPE_TEMPERATURE_GATE]" = /obj/machinery/atmospherics/binary/temperature_gate,
"[PIPE_VOLUME_PUMP]" = /obj/machinery/atmospherics/binary/volume_pump,
"[PIPE_HEAT_EXCHANGE]" = /obj/machinery/atmospherics/unary/heat_exchanger,
"[PIPE_DTVALVE]" = /obj/machinery/atmospherics/trinary/tvalve/digital,
@@ -257,7 +259,7 @@ GLOBAL_LIST_INIT(pipe_path2type, list(
return dir
if(PIPE_SIMPLE_STRAIGHT, PIPE_HE_STRAIGHT, PIPE_JUNCTION,
PIPE_PUMP, PIPE_VOLUME_PUMP, PIPE_PASSIVE_GATE, PIPE_MVALVE, PIPE_DVALVE, PIPE_DP_VENT,
PIPE_PUMP, PIPE_VOLUME_PUMP, PIPE_PASSIVE_GATE, PIPE_TEMPERATURE_GATE, PIPE_MVALVE, PIPE_DVALVE, PIPE_DP_VENT,
PIPE_SUPPLY_STRAIGHT, PIPE_SCRUBBERS_STRAIGHT, PIPE_UNIVERSAL,
PIPE_CONNECTOR, PIPE_HEAT_EXCHANGE)
return dir|flip
@@ -316,7 +318,7 @@ GLOBAL_LIST_INIT(pipe_path2type, list(
to_chat(user, "<span class='warning'>There is already a pipe of the same type at this location.</span>")
return
if(pipe_type in list(PIPE_SUPPLY_STRAIGHT, PIPE_SUPPLY_BENT, PIPE_SCRUBBERS_STRAIGHT, PIPE_SCRUBBERS_BENT, PIPE_HE_STRAIGHT, PIPE_HE_BENT, PIPE_SUPPLY_MANIFOLD, PIPE_SCRUBBERS_MANIFOLD, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W, PIPE_UVENT, PIPE_SUPPLY_CAP, PIPE_SCRUBBERS_CAP, PIPE_PASV_VENT, PIPE_DP_VENT, PIPE_PASSIVE_GATE))
if(pipe_type in list(PIPE_SUPPLY_STRAIGHT, PIPE_SUPPLY_BENT, PIPE_SCRUBBERS_STRAIGHT, PIPE_SCRUBBERS_BENT, PIPE_HE_STRAIGHT, PIPE_HE_BENT, PIPE_SUPPLY_MANIFOLD, PIPE_SCRUBBERS_MANIFOLD, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W, PIPE_UVENT, PIPE_SUPPLY_CAP, PIPE_SCRUBBERS_CAP, PIPE_PASV_VENT, PIPE_DP_VENT, PIPE_PASSIVE_GATE, PIPE_TEMPERATURE_GATE))
if(T.transparent_floor) //stops jank with transparent floors and pipes
to_chat(user, "<span class='warning'>You can only fix simple pipes and devices over glass floors!</span>")
return
@@ -0,0 +1,148 @@
/obj/machinery/atmospherics/binary/temperature_gate
name = "temperature gate"
icon = 'icons/atmos/temperature_gate.dmi'
icon_state = "map"
name = "temperature gate"
can_unwrench = TRUE
can_unwrench_while_on = FALSE
// if the temperature of the input mix is lower than this, gas will flow (or higher if inverted)
var/target_temperature = 273 // 0C but rounded to nearest whole number
// minimum allowed temperature - can't have anything under the coldest temperature, now can we?
var/minimum_temperature = TCMB
// maximum allowed temperature
var/maximum_temperature = 4500
var/inverted = FALSE
/obj/machinery/atmospherics/binary/temperature_gate/can_be_pulled(user, grab_state, force, show_message)
return FALSE
/obj/machinery/atmospherics/binary/temperature_gate/CtrlClick(mob/living/user)
if(can_use_shortcut(user))
toggle(user)
investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", INVESTIGATE_ATMOS)
return ..()
/obj/machinery/atmospherics/binary/temperature_gate/examine(mob/user)
. = ..()
. += "<span class='notice'>A toggleable gate that compares the temperature on the interface with the incoming gas and allows it to pass if it is [inverted ? "is higher than" : "is lower than"] the set temperature.</span>"
. += "<span class='notice'>It is currently set to [target_temperature] K and is [on ? "on" : "off"].</span>"
/obj/machinery/atmospherics/binary/temperature_gate/update_icon_state()
icon_state = "[on ? "on" : "off"]"
/obj/machinery/atmospherics/binary/temperature_gate/update_underlays()
if(..())
underlays.Cut()
var/turf/T = get_turf(src)
if(!istype(T))
return
add_underlay(T, node1, turn(dir, 180))
add_underlay(T, node2, dir)
/obj/machinery/atmospherics/binary/temperature_gate/multitool_act(mob/living/user, obj/item/I)
. = ..()
if(inverted)
to_chat(user, "<span class='notice'>You set [src] to normal operation mode.</span>")
inverted = FALSE
else
to_chat(user, "<span class='notice'>You set [src] to inverted operation mode.</span>")
inverted = TRUE
/obj/machinery/atmospherics/binary/temperature_gate/process_atmos()
if((stat & (NOPOWER|BROKEN)) || !on)
return 0
var/input_temp = air1.temperature()
var/allow_flow = FALSE
if(inverted)
if(input_temp > target_temperature)
allow_flow = TRUE
else
if(input_temp < target_temperature)
allow_flow = TRUE
if(!allow_flow)
return 1
var/datum/gas_mixture/removed = air1.remove(air1.total_moles())
if(removed && removed.total_moles() > 0)
air2.merge(removed)
parent1.update = 1
parent2.update = 1
return 1
/obj/machinery/atmospherics/binary/temperature_gate/attack_hand(mob/user)
if(..())
return
if(!allowed(user))
to_chat(user, "<span class='alert'>Access denied.</span>")
return
add_fingerprint(user)
ui_interact(user)
/obj/machinery/atmospherics/binary/temperature_gate/attack_ghost(mob/user)
ui_interact(user)
/obj/machinery/atmospherics/binary/temperature_gate/ui_state(mob/user)
return GLOB.default_state
/obj/machinery/atmospherics/binary/temperature_gate/ui_interact(mob/user, datum/tgui/ui = null)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "AtmosTemperatureGate", name)
ui.open()
/obj/machinery/atmospherics/binary/temperature_gate/ui_data(mob/user)
var/list/data = list(
"on" = on,
"inverted" = inverted,
"temperature" = round(target_temperature),
"max_temp" = maximum_temperature,
"temp_unit" = "K",
"step" = 10, // This is for the TGUI <NumberInput> step. It's here since multiple pumps share the same UI, but need different values.
)
return data
/obj/machinery/atmospherics/binary/temperature_gate/ui_act(action, list/params)
if(..())
return
switch(action)
if("power")
toggle()
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", INVESTIGATE_ATMOS)
return TRUE
if("inverted")
if(inverted)
inverted = FALSE
else
inverted = TRUE
if("max_temp")
target_temperature = maximum_temperature
. = TRUE
if("min_temp")
target_temperature = 0
. = TRUE
if("custom_temperature")
target_temperature = clamp(text2num(params["temperature"]), 0 , maximum_temperature)
. = TRUE
if(.)
investigate_log("was set to [target_temperature] K by [key_name(usr)]", INVESTIGATE_ATMOS)
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 29 KiB

+1
View File
@@ -1812,6 +1812,7 @@
#include "code\modules\atmospherics\machinery\components\binary_devices\circulator.dm"
#include "code\modules\atmospherics\machinery\components\binary_devices\passive_gate.dm"
#include "code\modules\atmospherics\machinery\components\binary_devices\pump.dm"
#include "code\modules\atmospherics\machinery\components\binary_devices\temperature_gate.dm"
#include "code\modules\atmospherics\machinery\components\binary_devices\valve.dm"
#include "code\modules\atmospherics\machinery\components\binary_devices\volume_pump.dm"
#include "code\modules\atmospherics\machinery\components\trinary_devices\filter.dm"
@@ -0,0 +1,69 @@
import { Button, LabeledList, NumberInput, Section } from 'tgui-core/components';
import { useBackend } from '../backend';
import { Window } from '../layouts';
export const AtmosTemperatureGate = (props) => {
const { act, data } = useBackend();
const { on, temperature, max_temp, temp_unit, step, inverted } = data;
return (
<Window width={330} height={130}>
<Window.Content>
<Section>
<LabeledList>
<LabeledList.Item label="Power">
<Button
icon={on ? 'power-off' : 'power-off'}
content={on ? 'On' : 'Off'}
color={on ? null : 'red'}
selected={on}
onClick={() => act('power')}
/>
</LabeledList.Item>
<LabeledList.Item label="Inverted">
<Button
icon={inverted ? 'arrow-up' : 'arrow-down'}
content={inverted ? 'Yes' : 'No'}
color={inverted ? null : 'red'}
selected={inverted}
onClick={() => act('inverted')}
/>
</LabeledList.Item>
<LabeledList.Item label="Temperature">
<Button
icon="fast-backward"
textAlign="center"
disabled={temperature === 0}
width={2.2}
onClick={() => act('min_temp')}
/>
<NumberInput
animated
unit={temp_unit}
width={6.1}
lineHeight={1.5}
step={step}
minValue={0}
maxValue={max_temp}
value={temperature}
onChange={(value) =>
act('custom_temperature', {
temperature: value,
})
}
/>
<Button
icon="fast-forward"
textAlign="center"
disabled={temperature === max_temp}
width={2.2}
onClick={() => act('max_temp')}
/>
</LabeledList.Item>
</LabeledList>
</Section>
</Window.Content>
</Window>
);
};
File diff suppressed because one or more lines are too long