diff --git a/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm b/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm index 9082fc1bd0..ba64adc61e 100644 --- a/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm +++ b/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm @@ -11,7 +11,6 @@ #define ATM_P 6 //Phoron #define ATM_N2O 7 - //-------------------------------------------- // Omni device cached icon list //-------------------------------------------- @@ -52,7 +51,6 @@ var/global/list/omni_icons[] var/mode = 0 var/concentration = 1 var/con_lock = 0 - var/target_pressure = 0 var/transfer_moles = 0 var/datum/gas_mixture/air var/obj/machinery/atmospherics/node @@ -92,10 +90,7 @@ var/global/list/omni_icons[] #define PIPE_COLOR_YELLOW "#ffcc00" #define PIPE_COLOR_PURPLE "#5c1ec0" -var/global/list/pipe_colors = list("Grey" = null, "Red" = PIPE_COLOR_RED, "Blue" = PIPE_COLOR_BLUE, "Cyan" = PIPE_COLOR_CYAN, "Green" = PIPE_COLOR_GREEN, "Yellow" = PIPE_COLOR_YELLOW, "Purple" = PIPE_COLOR_PURPLE) - -/proc/dout(var/string) - world << "\blue DEBUG: [string]" +var/global/list/pipe_colors = list("grey" = null, "red" = PIPE_COLOR_RED, "blue" = PIPE_COLOR_BLUE, "cyan" = PIPE_COLOR_CYAN, "green" = PIPE_COLOR_GREEN, "yellow" = PIPE_COLOR_YELLOW, "purple" = PIPE_COLOR_PURPLE) /proc/dir_name(var/dir = 0) switch(dir) diff --git a/code/ATMOSPHERICS/components/omni_devices/filter.dm b/code/ATMOSPHERICS/components/omni_devices/filter.dm index 69e3d76bf5..ff558a13e9 100644 --- a/code/ATMOSPHERICS/components/omni_devices/filter.dm +++ b/code/ATMOSPHERICS/components/omni_devices/filter.dm @@ -1,7 +1,7 @@ //-------------------------------------------- // Gas filter - omni variant //-------------------------------------------- -obj/machinery/atmospherics/omni/filter +/obj/machinery/atmospherics/omni/filter name = "Omni gas filter" icon = 'icons/obj/atmospherics/omni_devices.dmi' icon_state = "" @@ -14,3 +14,275 @@ obj/machinery/atmospherics/omni/filter var/list/filters = new() var/datum/omni_port/input var/datum/omni_port/output + +/obj/machinery/atmospherics/omni/filter/Del() + input = null + output = null + filters.Cut() + ..() + +/obj/machinery/atmospherics/omni/filter/sort_ports() + for(var/datum/omni_port/P in ports) + if(P.update) + if(output == P) + output = null + if(input == P) + input = null + if(filters.Find(P)) + filters -= P + + P.air.volume = 200 + switch(P.mode) + if(ATM_INPUT) + input = P + if(ATM_OUTPUT) + output = P + if(ATM_O2 to ATM_N2O) + filters += P + +/obj/machinery/atmospherics/omni/filter/error_check() + if(!input || !output || !filters) + return 1 + if(filters.len < 1 || filters.len > 2) //requires 1 or 2 filters ~otherwise why are you using a filter? + return 1 + + return 0 + +/obj/machinery/atmospherics/omni/filter/process() + ..() + if(!on) + return 0 + + if(!input || !output) + return + + var/datum/gas_mixture/output_air = output.air //BYOND doesn't like referencing "output.air.return_pressure()" so we need to make a direct reference + var/datum/gas_mixture/input_air = input.air // it's completely happy with them if they're in a loop though i.e. "P.air.return_pressure()"... *shrug* + + var/output_pressure = output_air.return_pressure() + + if(output_pressure >= target_pressure) + return + for(var/datum/omni_port/P in filters) + if(P.air.return_pressure() >= target_pressure) + return + + var/pressure_delta = target_pressure - output_pressure + + if(input_air.return_temperature() > 0) + input.transfer_moles = pressure_delta * output_air.volume / (input_air.return_temperature() * R_IDEAL_GAS_EQUATION) + + if(input.transfer_moles > 0) + var/datum/gas_mixture/removed = input_air.remove(input.transfer_moles) + + if(!removed) + return + + for(var/datum/omni_port/P in filters) + var/datum/gas_mixture/filtered_out = new + filtered_out.temperature = removed.return_temperature() + + switch(P.mode) + if(ATM_O2) + filtered_out.oxygen = removed.oxygen + removed.oxygen = 0 + if(ATM_N2) + filtered_out.nitrogen = removed.nitrogen + removed.nitrogen = 0 + if(ATM_CO2) + filtered_out.carbon_dioxide = removed.carbon_dioxide + removed.carbon_dioxide = 0 + if(ATM_P) + filtered_out.phoron = removed.phoron + removed.phoron = 0 + if(ATM_N2O) + if(removed.trace_gases.len>0) + for(var/datum/gas/sleeping_agent/trace_gas in removed.trace_gases) + if(istype(trace_gas)) + removed.trace_gases -= trace_gas + filtered_out.trace_gases += trace_gas + else + filtered_out = null + + P.air.merge(filtered_out) + if(P.network) + P.network.update = 1 + + output_air.merge(removed) + if(output.network) + output.network.update = 1 + + input.transfer_moles = 0 + if(input.network) + input.network.update = 1 + + return + +/obj/machinery/atmospherics/omni/filter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null) + usr.set_machine(src) + + var/list/data = new() + + data = build_uidata() + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data) + + if (!ui) + ui = new(user, src, ui_key, "omni_filter.tmpl", name, 330, 330) + ui.set_initial_data(data) + + ui.open() + +/obj/machinery/atmospherics/omni/filter/proc/build_uidata() + var/list/data = new() + + data["power"] = on + data["config"] = configuring + + var/portData[0] + for(var/datum/omni_port/P in ports) + if(!configuring && P.mode == 0) + continue + + var/input = 0 + var/output = 0 + var/filter = 1 + var/f_type = null + switch(P.mode) + if(ATM_INPUT) + input = 1 + filter = 0 + if(ATM_OUTPUT) + output = 1 + filter = 0 + if(ATM_O2 to ATM_N2O) + f_type = mode_send_switch(P.mode) + + portData[++portData.len] = list("dir" = dir_name(P.dir), \ + "input" = input, \ + "output" = output, \ + "filter" = filter, \ + "f_type" = f_type) + + if(portData.len) + data["ports"] = portData + if(output) + data["pressure"] = target_pressure + + return data + +/obj/machinery/atmospherics/omni/filter/proc/mode_send_switch(var/mode = ATM_NONE) + switch(mode) + if(ATM_O2) + return "Oxygen" + if(ATM_N2) + return "Nitrogen" + if(ATM_CO2) + return "Carbon Dioxide" + if(ATM_P) + return "Phoron" //*cough* Plasma *cough* + if(ATM_N2O) + return "Nitrous Oxide" + else + return null + +/obj/machinery/atmospherics/omni/filter/Topic(href, href_list) + if(..()) return + switch(href_list["command"]) + if("power") + if(!configuring) + on = !on + else + on = 0 + if("configure") + configuring = !configuring + if(configuring) + on = 0 + + //only allows config changes when in configuring mode ~otherwise you'll get weird pressure stuff going on + if(configuring && !on) + switch(href_list["command"]) + if("set_pressure") + var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",target_pressure) as num + target_pressure = between(0, new_pressure, 4500) + if("switch_mode") + switch_mode(dir_flag(href_list["dir"]), mode_return_switch(href_list["mode"])) + if("switch_filter") + var/new_filter = input(usr,"Select filter mode:","Change filter",href_list["mode"]) in list("None", "Oxygen", "Nitrogen", "Carbon Dioxide", "Phoron", "Nitrous Oxide") + switch_filter(dir_flag(href_list["dir"]), mode_return_switch(new_filter)) + + update_icon() + nanomanager.update_uis(src) + return + +/obj/machinery/atmospherics/omni/filter/proc/mode_return_switch(var/mode) + switch(mode) + if("Oxygen") + return ATM_O2 + if("Nitrogen") + return ATM_N2 + if("Carbon Dioxide") + return ATM_CO2 + if("Phoron") + return ATM_P + if("Nitrous Oxide") + return ATM_N2O + if("in") + return ATM_INPUT + if("out") + return ATM_OUTPUT + if("None") + return ATM_NONE + else + return null + +/obj/machinery/atmospherics/omni/filter/proc/switch_filter(var/dir, var/mode) + //check they aren't trying to disable the input or output ~this can only happen if they hack the cached tmpl file + for(var/datum/omni_port/P in ports) + if(P.dir == dir) + if(P.mode == ATM_INPUT || P.mode == ATM_OUTPUT) + return + + switch_mode(dir, mode) + +/obj/machinery/atmospherics/omni/filter/proc/switch_mode(var/port, var/mode) + if(mode == null || !port) + return + var/datum/omni_port/target_port = null + var/list/other_ports = new() + + for(var/datum/omni_port/P in ports) + if(P.dir == port) + target_port = P + else + other_ports += P + + var/previous_mode = null + if(target_port) + previous_mode = target_port.mode + target_port.mode = mode + if(target_port.mode != previous_mode) + handle_port_change(target_port) + else + return + else + return + + for(var/datum/omni_port/P in other_ports) + if(P.mode == mode) + var/old_mode = P.mode + P.mode = previous_mode + if(P.mode != old_mode) + handle_port_change(P) + + update_ports() + +/obj/machinery/atmospherics/omni/filter/proc/handle_port_change(var/datum/omni_port/P) + switch(P.mode) + if(ATM_NONE) + initialize_directions &= ~P.dir + P.disconnect() + else + initialize_directions |= P.dir + P.connect() + P.update = 1 \ No newline at end of file diff --git a/code/ATMOSPHERICS/components/omni_devices/mixer.dm b/code/ATMOSPHERICS/components/omni_devices/mixer.dm index 368b8f2167..45d208fbb1 100644 --- a/code/ATMOSPHERICS/components/omni_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/omni_devices/mixer.dm @@ -13,10 +13,6 @@ var/list/inputs = new() var/datum/omni_port/output -/obj/machinery/atmospherics/omni/mixer/New() - ..() - icon_state = "base" - /obj/machinery/atmospherics/omni/mixer/Del() inputs.Cut() output = null @@ -31,7 +27,6 @@ inputs -= P P.air.volume = 200 - P.target_pressure = 0 switch(P.mode) if(ATM_INPUT) inputs += P @@ -43,13 +38,15 @@ if(output) output.air.volume *= 0.75 * inputs.len - output.target_pressure = target_pressure output.concentration = 1 - if(!output || inputs.len > 3 || inputs.len < 2) - config_error = 1 - else - config_error = 0 +/obj/machinery/atmospherics/omni/mixer/error_check() + if(!output || !inputs) + return 1 + if(inputs.len < 2 || inputs.len > 3) //requires 2 or 3 inputs ~otherwise why are you using a mixer? + return 1 + + return 0 /obj/machinery/atmospherics/omni/mixer/process() ..() @@ -60,13 +57,13 @@ var/output_pressure = output_air.return_pressure() - if(output_pressure >= output.target_pressure * 0.999) + if(output_pressure >= target_pressure * 0.999) //No need to mix if target is already full! - 0.1% margin of error so we minimize processing minor gas volumes return 1 //Calculate necessary moles to transfer using PV=nRT - var/pressure_delta = output.target_pressure - output_pressure + var/pressure_delta = target_pressure - output_pressure for(var/datum/omni_port/P in inputs) if(P.air.return_temperature() > 0) @@ -96,17 +93,15 @@ for(var/datum/omni_port/P in inputs) if(P.transfer_moles > 0) output_air.merge(P.air.remove(P.transfer_moles)) - - for(var/datum/omni_port/P in inputs) - if(P.network && P.transfer_moles) - P.network.update = 1 + if(P.network) + P.network.update = 1 + P.transfer_moles = 0 if(output.network) output.network.update = 1 return 1 - /obj/machinery/atmospherics/omni/mixer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null) usr.set_machine(src) @@ -117,7 +112,7 @@ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data) if (!ui) - ui = new(user, src, ui_key, "omni_mixer.tmpl", src.name, 360, 330) + ui = new(user, src, ui_key, "omni_mixer.tmpl", name, 360, 330) ui.set_initial_data(data) ui.open() @@ -135,26 +130,26 @@ var/input = 0 var/output = 0 - if(P.mode == ATM_INPUT) - input = 1 - else if(P.mode == ATM_OUTPUT) - output = 1 + switch(P.mode) + if(ATM_INPUT) + input = 1 + if(ATM_OUTPUT) + output = 1 portData[++portData.len] = list("dir" = dir_name(P.dir), \ "concentration" = P.concentration, \ "input" = input, \ "output" = output, \ - "pressure" = P.target_pressure, \ "con_lock" = P.con_lock) if(portData.len) data["ports"] = portData if(output) - data["pressure"] = output.target_pressure + data["pressure"] = target_pressure return data -/obj/machinery/atmospherics/omni/mixer/Topic(href,href_list) +/obj/machinery/atmospherics/omni/mixer/Topic(href, href_list) if(..()) return switch(href_list["command"]) @@ -168,13 +163,12 @@ if(configuring) on = 0 - //only allows config changes when in configuring mode + //only allows config changes when in configuring mode ~otherwise you'll get weird pressure stuff going on if(configuring && !on) switch(href_list["command"]) if("set_pressure") var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",target_pressure) as num - target_pressure = between(0, new_pressure, 4500) // max(0, min(4500, new_pressure)) - output.target_pressure = target_pressure + target_pressure = between(0, new_pressure, 4500) if("switch_mode") switch_mode(dir_flag(href_list["dir"]), href_list["mode"]) if("switch_con") @@ -187,13 +181,14 @@ return /obj/machinery/atmospherics/omni/mixer/proc/switch_mode(var/port = NORTH, var/mode = ATM_NONE) - switch(mode) - if("in") - mode = ATM_INPUT - if("out") - mode = ATM_OUTPUT - if("none") - mode = ATM_NONE + if(mode != ATM_INPUT && mode != ATM_OUTPUT) + switch(mode) + if("in") + mode = ATM_INPUT + if("out") + mode = ATM_OUTPUT + else + mode = ATM_NONE for(var/datum/omni_port/P in ports) var/old_mode = P.mode @@ -217,13 +212,9 @@ if(ATM_NONE) initialize_directions &= ~P.dir P.disconnect() - if(ATM_INPUT) + else initialize_directions |= P.dir P.connect() - if(ATM_OUTPUT) - initialize_directions |= P.dir - P.connect() - P.update = 1 update_ports() diff --git a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm index 635686a9a7..2fe89e72ad 100644 --- a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm +++ b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm @@ -15,8 +15,6 @@ var/icon/icon_off var/icon/icon_error - var/config_error = 0 - var/tag_north = ATM_NONE var/tag_south = ATM_NONE var/tag_east = ATM_NONE @@ -31,9 +29,9 @@ /obj/machinery/atmospherics/omni/New() ..() + icon_state = "base" ports = new() - for(var/d in cardinal) var/datum/omni_port/new_port = new(src, d) switch(d) @@ -51,22 +49,23 @@ build_icons() -/obj/machinery/atmospherics/omni/mixer/update_icon() +/obj/machinery/atmospherics/omni/update_icon() if(stat & NOPOWER) overlays = overlays_off - else if(config_error) + on = 0 + else if(error_check()) overlays = overlays_error on = 0 - else if(inputs.len > 0 && output) - overlays = on ? (overlays_on) : (overlays_off) else - overlays = overlays_off - on = 0 + overlays = on ? (overlays_on) : (overlays_off) underlays = underlays_current return +/obj/machinery/atmospherics/omni/proc/error_check() + return + /obj/machinery/atmospherics/omni/power_change() var/old_stat = stat ..() diff --git a/icons/obj/atmospherics/omni_devices.dmi b/icons/obj/atmospherics/omni_devices.dmi index 666b0279f5..8b566f5766 100644 Binary files a/icons/obj/atmospherics/omni_devices.dmi and b/icons/obj/atmospherics/omni_devices.dmi differ diff --git a/nano/templates/omni_filter.tmpl b/nano/templates/omni_filter.tmpl new file mode 100644 index 0000000000..e1e805f1dd --- /dev/null +++ b/nano/templates/omni_filter.tmpl @@ -0,0 +1,82 @@ +
+
+ {{:~link(power ? 'On' : 'Off', null, {'command' : 'power'}, null, power ? 'selected' : 'redBackground')}} +
+
+ {{:~link('Configure', null, {'command' : 'configure'}, null, config ? 'selected' : null)}} +
+ + {{if config}} + +
+
+
Port
+ {{for ports}} +
{{:dir}} Port
+ {{/for}} +
+
+
Input
+ {{for ports}} +
+ {{:~link(' ', null, {'command' : 'switch_mode', 'mode' : 'in', 'dir' : dir}, null, input ? 'selected' : null)}} +
+ {{/for}} +
+
+
Output
+ {{for ports}} +
+ {{:~link(' ', null, {'command' : 'switch_mode', 'mode' : 'out', 'dir' : dir}, null, output ? 'selected' : null)}} +
+ {{/for}} +
+
+
Filter
+ {{for ports}} +
+ {{:~link(f_type ? f_type : 'None', null, {'command' : 'switch_filter', 'mode' : f_type, 'dir' : dir}, filter ? null : 'disabled', f_type ? 'selected' : null)}} +
+ {{/for}} +
+
+ +
+ Target Output Pressure: {{:~round(pressure)}} kPa +
+
+ {{:~link('Set Target Pressure', null, {'command' : 'set_pressure'})}} +
+ + {{else}} + +
+
+
Port
+ {{for ports}} +
{{:dir}} Port
+ {{/for}} +
+
+
Mode
+ {{for ports}} +
+ {{if input}} + Input + {{else output}} + Output + {{else f_type}} + {{:f_type}} + {{else}} + Disabled + {{/if}} +
+ {{/for}} +
+
+ +
+ Target Output Pressure: {{:~round(pressure)}} kPa +
+ {{/if}} +
\ No newline at end of file