This commit is contained in:
Artur
2020-01-24 18:48:50 +01:00
parent 901d3e7a15
commit ff8289c177
4 changed files with 235 additions and 142 deletions
+31 -12
View File
@@ -91,6 +91,8 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
icon_screen = "tank"
icon_keyboard = "atmos_key"
circuit = /obj/item/circuitboard/computer/atmos_control
ui_x = 400
ui_y = 925
var/frequency = FREQ_ATMOS_STORAGE
var/list/sensors = list(
@@ -125,7 +127,7 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "atmos_control", name, 400, 925, master_ui, state)
ui = new(user, src, ui_key, "atmos_control", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/computer/atmos_control/ui_data(mob/user)
@@ -161,6 +163,20 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
frequency = new_frequency
radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA)
//Incinerator sensor only
/obj/machinery/computer/atmos_control/incinerator
name = "Incinerator Air Control"
sensors = list(ATMOS_GAS_MONITOR_SENSOR_INCINERATOR = "Incinerator Chamber")
ui_x = 400
ui_y = 300
//Toxins mix sensor only
/obj/machinery/computer/atmos_control/toxinsmix
name = "Toxins Mixing Air Control"
sensors = list(ATMOS_GAS_MONITOR_SENSOR_TOXINS_LAB = "Toxins Mixing Chamber")
ui_x = 400
ui_y = 300
/////////////////////////////////////////////////////////////
// LARGE TANK CONTROL
/////////////////////////////////////////////////////////////
@@ -174,6 +190,9 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
var/list/input_info
var/list/output_info
ui_x = 500
ui_y = 315
/obj/machinery/computer/atmos_control/tank/oxygen_tank
name = "Oxygen Supply Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_O2
@@ -216,12 +235,6 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
output_tag = ATMOS_GAS_MONITOR_OUTPUT_CO2
sensors = list(ATMOS_GAS_MONITOR_SENSOR_CO2 = "Carbon Dioxide Tank")
/obj/machinery/computer/atmos_control/tank/incinerator
name = "Incinerator Air Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_INCINERATOR
output_tag = ATMOS_GAS_MONITOR_OUTPUT_INCINERATOR
sensors = list(ATMOS_GAS_MONITOR_SENSOR_INCINERATOR = "Incinerator Chamber")
// This hacky madness is the evidence of the fact that a lot of machines were never meant to be constructable, im so sorry you had to see this
/obj/machinery/computer/atmos_control/tank/proc/reconnect(mob/user)
var/list/IO = list()
@@ -235,7 +248,7 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
IO |= text[1]
if(!IO.len)
to_chat(user, "<span class='alert'>No machinery detected.</span>")
var/S = input("Select the device set: ", "Selection", IO[1]) as anything in IO
var/S = input("Select the device set: ", "Selection", IO[1]) as anything in sortList(IO)
if(src)
src.input_tag = "[S]_in"
src.output_tag = "[S]_out"
@@ -256,7 +269,7 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "atmos_control", name, 500, 305, master_ui, state)
ui = new(user, src, ui_key, "atmos_control", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/computer/atmos_control/tank/ui_data(mob/user)
@@ -280,13 +293,19 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
if("input")
signal.data += list("tag" = input_tag, "power_toggle" = TRUE)
. = TRUE
if("rate")
var/target = text2num(params["rate"])
if(!isnull(target))
target = CLAMP(target, 0, MAX_TRANSFER_RATE)
signal.data += list("tag" = input_tag, "set_volume_rate" = target)
. = TRUE
if("output")
signal.data += list("tag" = output_tag, "power_toggle" = TRUE)
. = TRUE
if("pressure")
var/target = input("New target pressure:", name, output_info ? output_info["internal"] : 0) as num|null
if(!isnull(target) && !..())
target = CLAMP(target, 0, 50 * ONE_ATMOSPHERE)
var/target = text2num(params["pressure"])
if(!isnull(target))
target = CLAMP(target, 0, 4500)
signal.data += list("tag" = output_tag, "set_internal_pressure" = target)
. = TRUE
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
@@ -3,9 +3,10 @@
density = FALSE
name = "gas mixer"
can_unwrench = TRUE
desc = "Very useful for mixing gasses."
can_unwrench = TRUE
var/target_pressure = ONE_ATMOSPHERE
var/node1_concentration = 0.5
var/node2_concentration = 0.5
@@ -13,100 +14,43 @@
construction_type = /obj/item/pipe/trinary/flippable
pipe_state = "mixer"
ui_x = 370
ui_y = 165
//node 3 is the outlet, nodes 1 & 2 are intakes
/obj/machinery/atmospherics/components/trinary/mixer/examine(mob/user)
. = ..()
. += "<span class='notice'>You can hold <b>Ctrl</b> and click on it to toggle it on and off.</span>"
. += "<span class='notice'>You can hold <b>Alt</b> and click on it to maximize its pressure.</span>"
/obj/machinery/atmospherics/components/trinary/mixer/CtrlClick(mob/user)
var/area/A = get_area(src)
var/turf/T = get_turf(src)
if(user.canUseTopic(src, BE_CLOSE, FALSE,))
if(user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
on = !on
update_icon()
investigate_log("Mixer, [src.name], turned on by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
message_admins("Mixer, [src.name], turned [on ? "on" : "off"] by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
return ..()
return ..()
/obj/machinery/atmospherics/components/trinary/mixer/AltClick(mob/user)
. = ..()
var/area/A = get_area(src)
var/turf/T = get_turf(src)
if(user.canUseTopic(src, BE_CLOSE, FALSE,))
if(user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
target_pressure = MAX_OUTPUT_PRESSURE
to_chat(user,"<span class='notice'>You maximize the pressure on the [src].</span>")
investigate_log("Mixer, [src.name], was maximized by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
message_admins("Mixer, [src.name], was maximized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
return TRUE
//node 3 is the outlet, nodes 1 & 2 are intakes
/obj/machinery/atmospherics/components/trinary/mixer/layer1
piping_layer = PIPING_LAYER_MIN
pixel_x = -PIPING_LAYER_P_X
pixel_y = -PIPING_LAYER_P_Y
/obj/machinery/atmospherics/components/trinary/mixer/layer3
piping_layer = PIPING_LAYER_MAX
pixel_x = PIPING_LAYER_P_X
pixel_y = PIPING_LAYER_P_Y
/obj/machinery/atmospherics/components/trinary/mixer/flipped
icon_state = "mixer_off_f"
flipped = TRUE
/obj/machinery/atmospherics/components/trinary/mixer/flipped/layer1
piping_layer = PIPING_LAYER_MIN
pixel_x = -PIPING_LAYER_P_X
pixel_y = -PIPING_LAYER_P_Y
/obj/machinery/atmospherics/components/trinary/mixer/flipped/layer3
piping_layer = PIPING_LAYER_MAX
pixel_x = PIPING_LAYER_P_X
pixel_y = PIPING_LAYER_P_Y
/obj/machinery/atmospherics/components/trinary/mixer/airmix //For standard airmix to distro
name = "air mixer"
icon_state = "mixer_on"
node1_concentration = N2STANDARD
node2_concentration = O2STANDARD
on = TRUE
target_pressure = MAX_OUTPUT_PRESSURE
/obj/machinery/atmospherics/components/trinary/mixer/airmix/inverse
node1_concentration = O2STANDARD
node2_concentration = N2STANDARD
/obj/machinery/atmospherics/components/trinary/mixer/airmix/flipped
icon_state = "mixer_on_f"
flipped = TRUE
/obj/machinery/atmospherics/components/trinary/mixer/airmix/flipped/inverse
node1_concentration = O2STANDARD
node2_concentration = N2STANDARD
update_icon()
return ..()
/obj/machinery/atmospherics/components/trinary/mixer/update_icon()
cut_overlays()
for(var/direction in GLOB.cardinals)
if(direction & initialize_directions)
var/obj/machinery/atmospherics/node = findConnecting(direction)
if(node)
add_overlay(getpipeimage('icons/obj/atmospherics/components/trinary_devices.dmi', "cap", direction, node.pipe_color))
continue
add_overlay(getpipeimage('icons/obj/atmospherics/components/trinary_devices.dmi', "cap", direction))
if(!(direction & initialize_directions))
continue
var/obj/machinery/atmospherics/node = findConnecting(direction)
var/image/cap
if(node)
cap = getpipeimage(icon, "cap", direction, node.pipe_color, piping_layer = piping_layer)
else
cap = getpipeimage(icon, "cap", direction, piping_layer = piping_layer)
add_overlay(cap)
return ..()
/obj/machinery/atmospherics/components/trinary/mixer/update_icon_nopipes()
if(on && nodes[1] && nodes[2] && nodes[3] && is_operational())
icon_state = "mixer_on[flipped?"_f":""]"
return
icon_state = "mixer_off[flipped?"_f":""]"
/obj/machinery/atmospherics/components/trinary/mixer/power_change()
var/old_stat = stat
..()
if(stat != old_stat)
update_icon()
var/on_state = on && nodes[1] && nodes[2] && nodes[3] && is_operational()
icon_state = "mixer_[on_state ? "on" : "off"][flipped ? "_f" : ""]"
/obj/machinery/atmospherics/components/trinary/mixer/New()
..()
@@ -119,8 +63,13 @@
if(!on || !(nodes[1] && nodes[2] && nodes[3]) && !is_operational())
return
//Get those gases, mah boiiii
var/datum/gas_mixture/air1 = airs[1]
var/datum/gas_mixture/air2 = airs[2]
if(!air1 || !air2)
return
var/datum/gas_mixture/air3 = airs[3]
var/output_starting_pressure = air3.return_pressure()
@@ -130,60 +79,57 @@
return
//Calculate necessary moles to transfer using PV=nRT
var/general_transfer = (target_pressure - output_starting_pressure) * air3.volume / R_IDEAL_GAS_EQUATION
var/pressure_delta = target_pressure - output_starting_pressure
var/transfer_moles1 = 0
var/transfer_moles2 = 0
if(air1.temperature > 0)
transfer_moles1 = (node1_concentration * pressure_delta) * air3.volume / (air1.temperature * R_IDEAL_GAS_EQUATION)
if(air2.temperature > 0)
transfer_moles2 = (node2_concentration * pressure_delta) * air3.volume / (air2.temperature * R_IDEAL_GAS_EQUATION)
var/transfer_moles1 = air1.temperature ? node1_concentration * general_transfer / air1.temperature : 0
var/transfer_moles2 = air2.temperature ? node2_concentration * general_transfer / air2.temperature : 0
var/air1_moles = air1.total_moles()
var/air2_moles = air2.total_moles()
if((air1_moles < transfer_moles1) || (air2_moles < transfer_moles2))
var/ratio = 0
if((transfer_moles1 > 0 ) && (transfer_moles2 > 0))
if(!node2_concentration)
if(air1.temperature <= 0)
return
transfer_moles1 = min(transfer_moles1, air1_moles)
transfer_moles2 = 0
else if(!node1_concentration)
if(air2.temperature <= 0)
return
transfer_moles2 = min(transfer_moles2, air2_moles)
transfer_moles1 = 0
else
if(air1.temperature <= 0 || air2.temperature <= 0)
return
if((transfer_moles2 <= 0) || (transfer_moles1 <= 0))
return
if((air1_moles < transfer_moles1) || (air2_moles < transfer_moles2))
var/ratio = 0
ratio = min(air1_moles / transfer_moles1, air2_moles / transfer_moles2)
if((transfer_moles2 == 0 ) && ( transfer_moles1 > 0))
ratio = air1_moles / transfer_moles1
if((transfer_moles1 == 0 ) && ( transfer_moles2 > 0))
ratio = air2_moles / transfer_moles2
transfer_moles1 *= ratio
transfer_moles2 *= ratio
transfer_moles1 *= ratio
transfer_moles2 *= ratio
//Actually transfer the gas
if(transfer_moles1 > 0)
if(transfer_moles1)
var/datum/gas_mixture/removed1 = air1.remove(transfer_moles1)
air3.merge(removed1)
if(transfer_moles2 > 0)
var/datum/gas_mixture/removed2 = air2.remove(transfer_moles2)
air3.merge(removed2)
if(transfer_moles1)
var/datum/pipeline/parent1 = parents[1]
parent1.update = TRUE
if(transfer_moles2)
var/datum/gas_mixture/removed2 = air2.remove(transfer_moles2)
air3.merge(removed2)
var/datum/pipeline/parent2 = parents[2]
parent2.update = TRUE
var/datum/pipeline/parent3 = parents[3]
parent3.update = TRUE
return
/obj/machinery/atmospherics/components/trinary/mixer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "atmos_mixer", name, 370, 165, master_ui, state)
ui = new(user, src, ui_key, "atmos_mixer", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/atmospherics/components/trinary/mixer/ui_data()
@@ -191,8 +137,8 @@
data["on"] = on
data["set_pressure"] = round(target_pressure)
data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
data["node1_concentration"] = round(node1_concentration*100)
data["node2_concentration"] = round(node2_concentration*100)
data["node1_concentration"] = round(node1_concentration*100, 1)
data["node2_concentration"] = round(node2_concentration*100, 1)
return data
/obj/machinery/atmospherics/components/trinary/mixer/ui_act(action, params)
@@ -220,21 +166,84 @@
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS)
if("node1")
var/value = text2num(params["concentration"])
node1_concentration = max(0, min(1, node1_concentration + value))
node2_concentration = max(0, min(1, node2_concentration - value))
adjust_node1_value(value)
investigate_log("was set to [node1_concentration] % on node 1 by [key_name(usr)]", INVESTIGATE_ATMOS)
. = TRUE
if("node2")
var/value = text2num(params["concentration"])
node2_concentration = max(0, min(1, node2_concentration + value))
node1_concentration = max(0, min(1, node1_concentration - value))
adjust_node1_value(100 - value)
investigate_log("was set to [node2_concentration] % on node 2 by [key_name(usr)]", INVESTIGATE_ATMOS)
. = TRUE
update_icon()
/obj/machinery/atmospherics/components/trinary/mixer/proc/adjust_node1_value(newValue)
node1_concentration = newValue / 100
node2_concentration = 1 - node1_concentration
/obj/machinery/atmospherics/components/trinary/filter/can_unwrench(mob/user)
/obj/machinery/atmospherics/components/trinary/mixer/can_unwrench(mob/user)
. = ..()
if(. && on && is_operational())
to_chat(user, "<span class='warning'>You cannot unwrench [src], turn it off first!</span>")
return FALSE
// mapping
/obj/machinery/atmospherics/components/trinary/mixer/layer1
piping_layer = 1
icon_state = "mixer_off_map-1"
/obj/machinery/atmospherics/components/trinary/mixer/layer3
piping_layer = 3
icon_state = "mixer_off_map-3"
/obj/machinery/atmospherics/components/trinary/mixer/on
on = TRUE
icon_state = "mixer_on"
/obj/machinery/atmospherics/components/trinary/mixer/on/layer1
piping_layer = 1
icon_state = "mixer_on_map-1"
/obj/machinery/atmospherics/components/trinary/mixer/on/layer3
piping_layer = 3
icon_state = "mixer_on_map-3"
/obj/machinery/atmospherics/components/trinary/mixer/flipped
icon_state = "mixer_off_f"
flipped = TRUE
/obj/machinery/atmospherics/components/trinary/mixer/flipped/layer1
piping_layer = 1
icon_state = "mixer_off_f_map-1"
/obj/machinery/atmospherics/components/trinary/mixer/flipped/layer3
piping_layer = 3
icon_state = "mixer_off_f_map-3"
/obj/machinery/atmospherics/components/trinary/mixer/flipped/on
on = TRUE
icon_state = "mixer_on_f"
/obj/machinery/atmospherics/components/trinary/mixer/flipped/on/layer1
piping_layer = 1
icon_state = "mixer_on_f_map-1"
/obj/machinery/atmospherics/components/trinary/mixer/flipped/on/layer3
piping_layer = 3
icon_state = "mixer_on_f_map-3"
/obj/machinery/atmospherics/components/trinary/mixer/airmix //For standard airmix to distro
name = "air mixer"
icon_state = "mixer_on"
node1_concentration = N2STANDARD
node2_concentration = O2STANDARD
target_pressure = MAX_OUTPUT_PRESSURE
on = TRUE
/obj/machinery/atmospherics/components/trinary/mixer/airmix/inverse
node1_concentration = O2STANDARD
node2_concentration = N2STANDARD
/obj/machinery/atmospherics/components/trinary/mixer/airmix/flipped
icon_state = "mixer_on_f"
flipped = TRUE
/obj/machinery/atmospherics/components/trinary/mixer/airmix/flipped/inverse
node1_concentration = O2STANDARD
node2_concentration = N2STANDARD
+77 -12
View File
@@ -10,6 +10,27 @@ export const Cargo = props => {
const { ref } = config;
const supplies = data.supplies || {};
const requests = data.requests || [];
const cart = data.cart || [];
const cartTotalAmount = cart
.reduce((total, entry) => total + entry.cost, 0);
const cartButtons = !data.requestonly && (
<Fragment>
<Box inline mx={1}>
{cart.length === 0 && 'Cart is empty'}
{cart.length === 1 && '1 item'}
{cart.length >= 2 && cart.length + ' items'}
{' '}
{cartTotalAmount > 0 && `(${cartTotalAmount} cr)`}
</Box>
<Button
icon="times"
color="transparent"
content="Clear"
onClick={() => act(ref, 'clear')} />
</Fragment>
);
return (
<Fragment>
@@ -53,18 +74,7 @@ export const Cargo = props => {
lineHeight="23px">
{() => (
<Section
title="Catalog"
buttons={(
<Fragment>
{cartButtons}
<Button
ml={1}
icon={data.self_paid ? 'check-square-o' : 'square-o'}
content="Buy Privately"
selected={data.self_paid}
onClick={() => act(ref, 'toggleprivate')} />
</Fragment>
)}>
title="Catalog">
<Catalog state={state} supplies={supplies} />
</Section>
)}
@@ -222,6 +232,61 @@ const Requests = props => {
);
};
const Cart = props => {
const { state, cart } = props;
const { config, data } = state;
const { ref } = config;
return (
<Fragment>
{cart.length === 0 && 'Nothing in cart'}
{cart.length > 0 && (
<LabeledList>
{cart.map(entry => (
<LabeledList.Item
key={entry.id}
className="candystripe"
label={'#' + entry.id}
buttons={(
<Fragment>
<Box inline mx={2}>
{!!entry.paid && (<b>[Paid Privately]</b>)}
{' '}
{entry.cost} credits
</Box>
<Button
icon="minus"
onClick={() => act(ref, 'remove', {
id: entry.id,
})} />
</Fragment>
)}>
{entry.object}
</LabeledList.Item>
))}
</LabeledList>
)}
{cart.length > 0 && !data.requestonly && (
<Box mt={2}>
{data.away === 1 && data.docked === 1 && (
<Button
color="green"
style={{
'line-height': '28px',
'padding': '0 12px',
}}
content="Confirm the order"
onClick={() => act(ref, 'send')} />
) || (
<Box opacity={0.5}>
Shuttle in {data.location}.
</Box>
)}
</Box>
)}
</Fragment>
);
};
export const CargoExpress = props => {
const { state } = props;
const { config, data } = state;
File diff suppressed because one or more lines are too long