diff --git a/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm b/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm deleted file mode 100644 index d03329e24fc..00000000000 --- a/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm +++ /dev/null @@ -1,94 +0,0 @@ -//-------------------------------------------- -// Omni device port types -//-------------------------------------------- -#define ATM_NONE 0 -#define ATM_INPUT 1 -#define ATM_OUTPUT 2 - -#define ATM_O2 3 -#define ATM_N2 4 -#define ATM_CO2 5 -#define ATM_P 6 //Plasma -#define ATM_N2O 7 - -//-------------------------------------------- -// Omni port datum -// -// Used by omni devices to manage connections -// to other atmospheric objects. -//-------------------------------------------- -/datum/omni_port - var/obj/machinery/atmospherics/omni/master - var/dir - var/update = 1 - var/mode = 0 - var/concentration = 0 - var/con_lock = 0 - var/transfer_moles = 0 - var/datum/gas_mixture/air - var/obj/machinery/atmospherics/node - var/datum/pipeline/parent - -/datum/omni_port/New(var/obj/machinery/atmospherics/omni/M, var/direction = NORTH) - ..() - dir = direction - if(istype(M)) - master = M - air = new - air.volume = 200 - -/datum/omni_port/proc/connect() - if(node) - return - master.atmos_init() - if(node) - node.atmos_init() - node.addMember(master) - master.build_network() - -/datum/omni_port/proc/disconnect() - if(node) - node.disconnect(master) - node = null - master.nullifyPipenet(parent) - -//-------------------------------------------- -// Need to find somewhere else for these -//-------------------------------------------- - -//returns a text string based on the direction flag input -// if capitalize is true, it will return the string capitalized -// otherwise it will return the direction string in lower case -/proc/dir_name(var/dir, var/capitalize = 0) - var/string = null - switch(dir) - if(NORTH) - string = "North" - if(SOUTH) - string = "South" - if(EAST) - string = "East" - if(WEST) - string = "West" - - if(!capitalize && string) - string = lowertext(string) - - return string - -//returns a direction flag based on the string passed to it -// case insensitive -/proc/dir_flag(var/dir) - dir = lowertext(dir) - switch(dir) - if("north") - return NORTH - if("south") - return SOUTH - if("east") - return EAST - if("west") - return WEST - else - return 0 - diff --git a/code/ATMOSPHERICS/components/omni_devices/filter.dm b/code/ATMOSPHERICS/components/omni_devices/filter.dm deleted file mode 100644 index 0803d34e522..00000000000 --- a/code/ATMOSPHERICS/components/omni_devices/filter.dm +++ /dev/null @@ -1,273 +0,0 @@ -//-------------------------------------------- -// Gas filter - omni variant -//-------------------------------------------- -/obj/machinery/atmospherics/omni/filter - name = "omni gas filter" - icon_state = "map_filter" - - var/list/o_filters = new() - var/datum/omni_port/input - var/datum/omni_port/output - -/obj/machinery/atmospherics/omni/filter/Destroy() - input = null - output = null - o_filters.Cut() - return ..() - -/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(o_filters.Find(P)) - o_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) - o_filters += P - -/obj/machinery/atmospherics/omni/filter/error_check() - if(!input || !output || !o_filters) - return 1 - if(o_filters.len < 1 || o_filters.len > 2) //requires 1 or 2 o_filters ~otherwise why are you using a filter? - return 1 - - return 0 - -/obj/machinery/atmospherics/omni/filter/process_atmos() - ..() - if(!on) - return 0 - - if(!input || !output) - return 0 - - 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 1 - for(var/datum/omni_port/P in o_filters) - if(P.air.return_pressure() >= target_pressure) - return 1 - - 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 1 - - for(var/datum/omni_port/P in o_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.toxins = removed.toxins - removed.toxins = 0 - - filtered_out.agent_b = removed.agent_b - removed.agent_b = 0 - if(ATM_N2O) - filtered_out.sleeping_agent = removed.sleeping_agent - removed.sleeping_agent = 0 - else - filtered_out = null - - P.air.merge(filtered_out) - P.parent.update = 1 - - output_air.merge(removed) - output.parent.update = 1 - - input.transfer_moles = 0 - input.parent.update = 1 - - return 1 - -/obj/machinery/atmospherics/omni/filter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, force_open = 0) - usr.set_machine(src) - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "omni_filter.tmpl", "Omni Filter Control", 330, 330) - ui.open() - -/obj/machinery/atmospherics/omni/filter/ui_data(mob/user, datum/topic_state/state) - var/data[0] - - 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, capitalize = 1), \ - "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 "Plasma" //*cough* Plasma *cough* - if(ATM_N2O) - return "Nitrous Oxide" - else - return null - -/obj/machinery/atmospherics/omni/filter/Topic(href, href_list) - if(..()) - return 1 - 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", "Plasma", "Nitrous Oxide") - switch_filter(dir_flag(href_list["dir"]), mode_return_switch(new_filter)) - - update_icon() - SSnanoui.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("Plasma") - 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 diff --git a/code/ATMOSPHERICS/components/omni_devices/mixer.dm b/code/ATMOSPHERICS/components/omni_devices/mixer.dm deleted file mode 100644 index 5586bdc3a98..00000000000 --- a/code/ATMOSPHERICS/components/omni_devices/mixer.dm +++ /dev/null @@ -1,291 +0,0 @@ -//-------------------------------------------- -// Gas mixer - omni variant -//-------------------------------------------- -/obj/machinery/atmospherics/omni/mixer - name = "omni gas mixer" - icon_state = "map_mixer" - - var/list/inputs = new() - var/datum/omni_port/output - - //setup tags for initial concentration values (must be decimal) - var/tag_north_con - var/tag_south_con - var/tag_east_con - var/tag_west_con - -/obj/machinery/atmospherics/omni/mixer/New() - ..() - if(mapper_set()) - var/con = 0 - for(var/datum/omni_port/P in ports) - switch(P.dir) - if(NORTH) - if(tag_north_con && tag_north == 1) - P.concentration = tag_north_con - con += max(0, tag_north_con) - if(SOUTH) - if(tag_south_con && tag_south == 1) - P.concentration = tag_south_con - con += max(0, tag_south_con) - if(EAST) - if(tag_east_con && tag_east == 1) - P.concentration = tag_east_con - con += max(0, tag_east_con) - if(WEST) - if(tag_west_con && tag_west == 1) - P.concentration = tag_west_con - con += max(0, tag_west_con) - - //mappers who are bad at maths will be punished (total concentration must be 100%) - if(con != 1) - tag_north_con = null - tag_south_con = null - tag_east_con = null - tag_west_con = null - -/obj/machinery/atmospherics/omni/mixer/Destroy() - inputs.Cut() - output = null - return ..() - -/obj/machinery/atmospherics/omni/mixer/sort_ports() - for(var/datum/omni_port/P in ports) - if(P.update) - if(output == P) - output = null - if(inputs.Find(P)) - inputs -= P - - P.air.volume = 200 - switch(P.mode) - if(ATM_INPUT) - inputs += P - if(ATM_OUTPUT) - output = P - - if(!mapper_set()) - for(var/datum/omni_port/P in inputs) - P.concentration = 1 / max(1, inputs.len) - - if(output) - output.air.volume *= 0.75 * inputs.len - output.concentration = 1 - -/obj/machinery/atmospherics/omni/mixer/proc/mapper_set() - return (tag_north_con || tag_south_con || tag_east_con || tag_west_con) - -/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_atmos() - ..() - if(!on) - return 0 - - var/datum/gas_mixture/output_air = output.air - var/output_pressure = output_air.return_pressure() - - - 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 = target_pressure - output_pressure - - for(var/datum/omni_port/P in inputs) - if(P.air.return_temperature() > 0) - P.transfer_moles = (P.concentration * pressure_delta) * output_air.return_volume() / (P.air.return_temperature() * R_IDEAL_GAS_EQUATION) - - var/ratio_check = null - - for(var/datum/omni_port/P in inputs) - if(!P.transfer_moles) - return 1 - if(P.air.total_moles() < P.transfer_moles) - ratio_check = 1 - continue - - if(ratio_check) - var/list/ratio_list = new() - for(var/datum/omni_port/P in inputs) - ratio_list.Add(P.air.total_moles() / P.transfer_moles) - - var/ratio = min(ratio_list) - - for(var/datum/omni_port/P in inputs) - P.transfer_moles *= ratio - - for(var/datum/omni_port/P in inputs) - if(P.transfer_moles > 0) - output_air.merge(P.air.remove(P.transfer_moles)) - P.parent.update = 1 - P.transfer_moles = 0 - - output.parent.update = 1 - - return 1 - -/obj/machinery/atmospherics/omni/mixer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, force_open = 0) - usr.set_machine(src) - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "omni_mixer.tmpl", "Omni Mixer Control", 360, 330) - ui.open() - -/obj/machinery/atmospherics/omni/mixer/ui_data(mob/user, datum/topic_state/state) - var/data[0] - - 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 - switch(P.mode) - if(ATM_INPUT) - input = 1 - if(ATM_OUTPUT) - output = 1 - - portData[++portData.len] = list("dir" = dir_name(P.dir, capitalize = 1), \ - "concentration" = P.concentration, \ - "input" = input, \ - "output" = output, \ - "con_lock" = P.con_lock) - - if(portData.len) - data["ports"] = portData - if(output) - data["pressure"] = target_pressure - - return data - -/obj/machinery/atmospherics/omni/mixer/Topic(href, href_list) - if(..()) - return 1 - - 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"]), href_list["mode"]) - if("switch_con") - change_concentration(dir_flag(href_list["dir"])) - if("switch_conlock") - con_lock(dir_flag(href_list["dir"])) - - update_icon() - SSnanoui.update_uis(src) - return - -/obj/machinery/atmospherics/omni/mixer/proc/switch_mode(var/port = NORTH, var/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 - if(P.dir == port) - switch(mode) - if(ATM_INPUT) - if(P.mode == ATM_OUTPUT) - return - P.mode = mode - if(ATM_OUTPUT) - P.mode = mode - if(ATM_NONE) - if(P.mode == ATM_OUTPUT) - return - if(P.mode == ATM_INPUT && inputs.len > 2) - P.mode = mode - else if(P.mode == ATM_OUTPUT && mode == ATM_OUTPUT) - P.mode = ATM_INPUT - if(P.mode != old_mode) - switch(P.mode) - if(ATM_NONE) - initialize_directions &= ~P.dir - P.disconnect() - else - initialize_directions |= P.dir - P.connect() - P.update = 1 - - update_ports() - -/obj/machinery/atmospherics/omni/mixer/proc/change_concentration(var/port = NORTH) - tag_north_con = null - tag_south_con = null - tag_east_con = null - tag_west_con = null - - var/old_con = 0 - var/non_locked = 0 - var/remain_con = 1 - - for(var/datum/omni_port/P in inputs) - if(P.dir == port) - old_con = P.concentration - else if(!P.con_lock) - non_locked++ - else - remain_con -= P.concentration - - //return if no adjustable ports - if(non_locked < 1) - return - - var/new_con = (input(usr,"Enter a new concentration (0-[round(remain_con * 100, 0.5)])%","Concentration control", min(remain_con, old_con)*100) as num) / 100 - - //cap it between 0 and the max remaining concentration - new_con = between(0, new_con, remain_con) - - //new_con = min(remain_con, new_con) - - //clamp remaining concentration so we don't go into negatives - remain_con = max(0, remain_con - new_con) - - //distribute remaining concentration between unlocked ports evenly - remain_con /= max(1, non_locked) - - for(var/datum/omni_port/P in inputs) - if(P.dir == port) - P.concentration = new_con - else if(!P.con_lock) - P.concentration = remain_con - -/obj/machinery/atmospherics/omni/mixer/proc/con_lock(var/port = NORTH) - for(var/datum/omni_port/P in inputs) - if(P.dir == port) - P.con_lock = !P.con_lock diff --git a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm deleted file mode 100644 index d75e2e683c1..00000000000 --- a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm +++ /dev/null @@ -1,302 +0,0 @@ -//-------------------------------------------- -// Base omni device -//-------------------------------------------- -/obj/machinery/atmospherics/omni - name = "omni device" - icon = 'icons/atmos/omni_devices.dmi' - icon_state = "base" - use_power = IDLE_POWER_USE - initialize_directions = 0 - - can_unwrench = 1 - - var/on = 0 - var/configuring = 0 - var/target_pressure = ONE_ATMOSPHERE - - var/tag_north = ATM_NONE - var/tag_south = ATM_NONE - var/tag_east = ATM_NONE - var/tag_west = ATM_NONE - - var/overlays_on[5] - var/overlays_off[5] - var/overlays_error[2] - var/underlays_current[4] - - var/list/ports = new() - -/obj/machinery/atmospherics/omni/New() - ..() - icon_state = "base" - - ports = new() - for(var/d in GLOB.cardinal) - var/datum/omni_port/new_port = new(src, d) - switch(d) - if(NORTH) - new_port.mode = tag_north - if(SOUTH) - new_port.mode = tag_south - if(EAST) - new_port.mode = tag_east - if(WEST) - new_port.mode = tag_west - if(new_port.mode > 0) - initialize_directions |= d - ports += new_port - - build_icons() - -/obj/machinery/atmospherics/omni/Destroy() - for(var/datum/omni_port/P in ports) - if(P.node) - P.node.disconnect(src) - P.node = null - nullifyPipenet(P.parent) - return ..() - -/obj/machinery/atmospherics/omni/atmos_init() - ..() - for(var/datum/omni_port/P in ports) - if(P.node || P.mode == 0) - continue - for(var/obj/machinery/atmospherics/target in get_step(src, P.dir)) - if(target.initialize_directions & get_dir(target,src)) - P.node = target - break - - for(var/datum/omni_port/P in ports) - P.update = 1 - - update_ports() - -/obj/machinery/atmospherics/omni/update_icon() - ..() - - if(stat & NOPOWER) - overlays = overlays_off - on = 0 - else if(error_check()) - overlays = overlays_error - on = 0 - else - overlays = on ? (overlays_on) : (overlays_off) - - underlays = underlays_current - -/obj/machinery/atmospherics/omni/proc/error_check() - return - -/obj/machinery/atmospherics/omni/power_change() - var/old_stat = stat - ..() - if(old_stat != stat) - update_icon() - -/obj/machinery/atmospherics/omni/attackby(var/obj/item/W as obj, var/mob/user as mob, params) - if(!istype(W, /obj/item/wrench)) - return ..() - - if(can_unwrench) - var/int_pressure = 0 - for(var/datum/omni_port/P in ports) - int_pressure += P.air.return_pressure() - var/datum/gas_mixture/env_air = loc.return_air() - if((int_pressure - env_air.return_pressure()) > 2*ONE_ATMOSPHERE) - to_chat(user, "You cannot unwrench [src], it is too exerted due to internal pressure.") - add_fingerprint(user) - return 1 - playsound(loc, W.usesound, 50, 1) - to_chat(user, "You begin to unfasten \the [src]...") - if(do_after(user, 40 * W.toolspeed, target = src)) - user.visible_message( \ - "[user] unfastens \the [src].", \ - "You have unfastened \the [src].", \ - "You hear a ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) - else - return ..() - -/obj/machinery/atmospherics/omni/attack_hand(mob/user) - if(..()) - return - - add_fingerprint(usr) - ui_interact(user) - -/obj/machinery/atmospherics/omni/attack_ghost(mob/user) - ui_interact(user) - -/obj/machinery/atmospherics/omni/proc/build_icons() - if(!check_icon_cache()) - return - - var/core_icon = null - if(istype(src, /obj/machinery/atmospherics/omni/mixer)) - core_icon = "mixer" - else if(istype(src, /obj/machinery/atmospherics/omni/filter)) - core_icon = "filter" - else - return - - //directional icons are layers 1-4, with the core icon on layer 5 - if(core_icon) - overlays_off[5] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon) - overlays_on[5] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon + "_glow") - - overlays_error[1] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon) - overlays_error[2] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , "error") - -/obj/machinery/atmospherics/omni/proc/update_port_icons() - if(!check_icon_cache()) - return - - for(var/datum/omni_port/P in ports) - if(P.update) - var/ref_layer = 0 - switch(P.dir) - if(NORTH) - ref_layer = 1 - if(SOUTH) - ref_layer = 2 - if(EAST) - ref_layer = 3 - if(WEST) - ref_layer = 4 - - if(!ref_layer) - continue - - var/list/port_icons = select_port_icons(P) - if(port_icons) - if(P.node) - underlays_current[ref_layer] = port_icons["pipe_icon"] - else - underlays_current[ref_layer] = null - overlays_off[ref_layer] = port_icons["off_icon"] - overlays_on[ref_layer] = port_icons["on_icon"] - else - underlays_current[ref_layer] = null - overlays_off[ref_layer] = null - overlays_on[ref_layer] = null - - update_icon() - -/obj/machinery/atmospherics/omni/proc/select_port_icons(var/datum/omni_port/P) - if(!istype(P)) - return - - if(P.mode > 0) - var/ic_dir = dir_name(P.dir) - var/ic_on = ic_dir - var/ic_off = ic_dir - switch(P.mode) - if(ATM_INPUT) - ic_on += "_in_glow" - ic_off += "_in" - if(ATM_OUTPUT) - ic_on += "_out_glow" - ic_off += "_out" - if(ATM_O2 to ATM_N2O) - ic_on += "_filter" - ic_off += "_out" - - ic_on = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , ic_on) - ic_off = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , ic_off) - - var/pipe_state - var/turf/T = get_turf(src) - if(!istype(T)) - return - if(T.intact && istype(P.node, /obj/machinery/atmospherics/pipe) && P.node.level == 1 ) - //pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay_down", P.dir, color_cache_name(P.node)) - pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "down") - else - //pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay_intact", P.dir, color_cache_name(P.node)) - pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "intact") - - return list("on_icon" = ic_on, "off_icon" = ic_off, "pipe_icon" = pipe_state) - -/obj/machinery/atmospherics/omni/update_underlays() - for(var/datum/omni_port/P in ports) - P.update = 1 - update_ports() - -/obj/machinery/atmospherics/omni/hide(var/i) - update_underlays() - -/obj/machinery/atmospherics/omni/proc/update_ports() - sort_ports() - update_port_icons() - for(var/datum/omni_port/P in ports) - P.update = 0 - -/obj/machinery/atmospherics/omni/proc/sort_ports() - return - -// Pipenet procs -/obj/machinery/atmospherics/omni/build_network(remove_deferral = FALSE) - for(var/datum/omni_port/P in ports) - if(!P.parent) - P.parent = new /datum/pipeline() - P.parent.build_pipeline(src) - ..() - -/obj/machinery/atmospherics/omni/disconnect(obj/machinery/atmospherics/reference) - for(var/datum/omni_port/P in ports) - if(reference == P.node) - if(istype(P.node, /obj/machinery/atmospherics/pipe)) - qdel(P.parent) - P.node = null - update_ports() - -/obj/machinery/atmospherics/omni/nullifyPipenet(datum/pipeline/P) - ..() - if(!P) - return - for(var/datum/omni_port/PO in ports) - if(P == PO.parent) - PO.parent.other_airs -= PO.air - PO.parent = null - -/obj/machinery/atmospherics/omni/returnPipenetAir(datum/pipeline/P) - for(var/datum/omni_port/PO in ports) - if(P == PO.parent) - return PO.air - -/obj/machinery/atmospherics/omni/pipeline_expansion(datum/pipeline/P) - if(P) - for(var/datum/omni_port/PO in ports) - if(PO.parent == P) - return list(PO.node) - else - var/list/nodes = list() - for(var/datum/omni_port/PO in ports) - nodes += PO.node - - return nodes - -/obj/machinery/atmospherics/omni/setPipenet(datum/pipeline/P, obj/machinery/atmospherics/A) - for(var/datum/omni_port/PO in ports) - if(A == PO.node) - PO.parent = P - -/obj/machinery/atmospherics/omni/returnPipenet(obj/machinery/atmospherics/A) - for(var/datum/omni_port/P in ports) - if(A == P.node) - return P.parent - -/obj/machinery/atmospherics/omni/replacePipenet(datum/pipeline/Old, datum/pipeline/New) - for(var/datum/omni_port/P in ports) - if(Old == P.parent) - P.parent = New - - -/obj/machinery/atmospherics/omni/process_atmos() - ..() - for(var/datum/omni_port/port in ports) - if(!port.parent) - return 0 - return 1 diff --git a/code/ATMOSPHERICS/datum_icon_manager.dm b/code/ATMOSPHERICS/datum_icon_manager.dm index 2286b3523a0..014fafc5c18 100644 --- a/code/ATMOSPHERICS/datum_icon_manager.dm +++ b/code/ATMOSPHERICS/datum_icon_manager.dm @@ -33,7 +33,6 @@ //var/list/underlays_intact[] //var/list/pipe_underlays_exposed[] //var/list/pipe_underlays_intact[] - var/list/omni_icons[] /datum/pipe_icon_manager/New() check_icons() @@ -53,8 +52,6 @@ return manifold_icons[state + color] if("device") return device_icons[state] - if("omni") - return omni_icons[state] if("underlay") return underlays[state + dir + color] //if("underlay_intact") @@ -75,8 +72,6 @@ gen_manifold_icons() if(!device_icons) gen_device_icons() - if(!omni_icons) - gen_omni_icons() //if(!underlays_intact || !underlays_down || !underlays_exposed || !pipe_underlays_exposed || !pipe_underlays_intact) if(!underlays) gen_underlay_icons() @@ -150,18 +145,6 @@ continue device_icons["scrubber" + state] = image('icons/atmos/vent_scrubber.dmi', icon_state = state) -/datum/pipe_icon_manager/proc/gen_omni_icons() - if(!omni_icons) - omni_icons = new() - - var/icon/omni = new('icons/atmos/omni_devices.dmi') - - for(var/state in omni.IconStates()) - if(!state || findtext(state, "map")) - continue - omni_icons[state] = image('icons/atmos/omni_devices.dmi', icon_state = state) - - /datum/pipe_icon_manager/proc/gen_underlay_icons() if(!underlays) diff --git a/code/__DEFINES/pipes.dm b/code/__DEFINES/pipes.dm index c855a5e4260..d56d446ca1d 100644 --- a/code/__DEFINES/pipes.dm +++ b/code/__DEFINES/pipes.dm @@ -21,8 +21,6 @@ #define PIPE_TVALVE 18 #define PIPE_MANIFOLD4W 19 #define PIPE_CAP 20 -#define PIPE_OMNI_MIXER 21 -#define PIPE_OMNI_FILTER 22 #define PIPE_UNIVERSAL 23 #define PIPE_SUPPLY_STRAIGHT 24 #define PIPE_SUPPLY_BENT 25 diff --git a/code/datums/pipe_datums.dm b/code/datums/pipe_datums.dm index 83b77425447..8d3b0807f9c 100644 --- a/code/datums/pipe_datums.dm +++ b/code/datums/pipe_datums.dm @@ -351,16 +351,6 @@ GLOBAL_LIST_EMPTY(rpd_pipe_list) //Some pipes we don't want to be dispensable pipe_id = PIPE_CIRCULATOR pipe_icon = "circ" -/datum/pipes/atmospheric/omni_filter - pipe_name = "omni filter" - pipe_id = PIPE_OMNI_FILTER - pipe_icon = "omni_filter" - -/datum/pipes/atmospheric/omni_mixer - pipe_name = "omni mixer" - pipe_id = PIPE_OMNI_MIXER - pipe_icon = "omni_mixer" - /datum/pipes/atmospheric/insulated pipe_name = "insulated pipe" pipe_id = PIPE_INSULATED_STRAIGHT diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index 42452a9f8e2..a8c9710ff6c 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -106,10 +106,6 @@ else if(istype(make_from, /obj/machinery/atmospherics/unary/passive_vent)) src.pipe_type = PIPE_PASV_VENT - else if(istype(make_from, /obj/machinery/atmospherics/omni/mixer)) - src.pipe_type = PIPE_OMNI_MIXER - else if(istype(make_from, /obj/machinery/atmospherics/omni/filter)) - src.pipe_type = PIPE_OMNI_FILTER else if(istype(make_from, /obj/machinery/atmospherics/binary/circulator)) src.pipe_type = PIPE_CIRCULATOR @@ -259,7 +255,7 @@ return dir //dir|acw if(PIPE_CONNECTOR, PIPE_UVENT, PIPE_PASV_VENT, PIPE_SCRUBBER, PIPE_HEAT_EXCHANGE, PIPE_INJECTOR) return dir|flip - if(PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W, PIPE_OMNI_MIXER, PIPE_OMNI_FILTER) + if(PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W) return dir|flip|cw|acw if(PIPE_MANIFOLD, PIPE_SUPPLY_MANIFOLD, PIPE_SCRUBBERS_MANIFOLD) return flip|cw|acw @@ -317,7 +313,7 @@ dir = 1 else if(dir==8) dir = 4 - else if(pipe_type in list(PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W, PIPE_OMNI_MIXER, PIPE_OMNI_FILTER)) + else if(pipe_type in list(PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W)) dir = 2 /obj/item/pipe/attack_self(mob/user as mob) @@ -499,14 +495,6 @@ P.name = pipename P.on_construction(dir, pipe_dir, color) - if(PIPE_OMNI_MIXER) - var/obj/machinery/atmospherics/omni/mixer/P = new(loc) - P.on_construction(dir, pipe_dir, color) - - if(PIPE_OMNI_FILTER) - var/obj/machinery/atmospherics/omni/filter/P = new(loc) - P.on_construction(dir, pipe_dir, color) - user.visible_message( \ "[user] fastens the [src].", \ "You have fastened the [src].", \ diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index 59bae3174c4..005e6720b8b 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -1,16 +1,24 @@ +#define REGIME_TELEPORT 0 +#define REGIME_GATE 1 +#define REGIME_GPS 2 + /obj/machinery/computer/teleporter name = "teleporter control console" desc = "Used to control a linked teleportation Hub and Station." icon_screen = "teleport" icon_keyboard = "teleport_key" circuit = /obj/item/circuitboard/teleporter - var/obj/item/gps/locked = null - var/regime_set = "Teleporter" + var/obj/item/gps/locked = null /// A GPS with a locked destination + var/regime = REGIME_TELEPORT /// Switches mode between teleporter, gate and gps var/id = null - var/obj/machinery/teleport/station/power_station - var/calibrating - var/turf/target //Used for one-time-use teleport cards (such as clown planet coordinates.) - //Setting this to 1 will set src.locked to null after a player enters the portal and will not allow hand-teles to open portals to that location. + var/obj/machinery/teleport/station/power_station /// The power station that's connected to the console + var/calibrating = FALSE /// Whether calibration is in progress or not. Calibration prevents changes. + var/turf/target ///The target turf of the teleporter + var/target_list ///lists of suitable teleport targets, dependent on regime. Used in the UI + + /* var/area_bypass is for one-time-use teleport cards (such as clown planet coordinates.) + Setting this to TRUE will set var/obj/item/gps/locked to null after a player enters the portal and will not allow hand-teles to open portals to that location. + */ var/area_bypass = FALSE var/cc_beacon = FALSE @@ -24,6 +32,7 @@ ..() link_power_station() update_icon() + target_list = targets_teleport() /obj/machinery/computer/teleporter/Destroy() if(power_station) @@ -55,202 +64,238 @@ /obj/machinery/computer/teleporter/emag_act(mob/user) if(!emagged) - emagged = 1 + emagged = TRUE to_chat(user, "The teleporter can now lock on to Syndicate beacons!") else - ui_interact(user) + tgui_interact(user) /obj/machinery/computer/teleporter/attack_ai(mob/user) - src.attack_hand(user) + attack_hand(user) /obj/machinery/computer/teleporter/attack_hand(mob/user) - ui_interact(user) + tgui_interact(user) -/obj/machinery/computer/teleporter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + +/obj/machinery/computer/teleporter/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) if(stat & (NOPOWER|BROKEN)) return - - // Set up the Nano UI - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "teleporter_console.tmpl", "Teleporter Console UI", 400, 400) + ui = new(user, src, ui_key, "Teleporter", "Teleporter Console", 380, 260) ui.open() -/obj/machinery/computer/teleporter/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) - var/data[0] +/obj/machinery/computer/teleporter/tgui_data(mob/user) + var/list/data = list() data["powerstation"] = power_station if(power_station?.teleporter_hub) data["teleporterhub"] = power_station.teleporter_hub data["calibrated"] = power_station.teleporter_hub.calibrated - data["accurate"] = power_station.teleporter_hub.accurate else data["teleporterhub"] = null data["calibrated"] = null - data["accurate"] = null - data["regime"] = regime_set + data["regime"] = regime var/area/targetarea = get_area(target) data["target"] = (!target || !targetarea) ? "None" : sanitize(targetarea.name) data["calibrating"] = calibrating - data["locked"] = locked + data["locked"] = locked ? TRUE : FALSE + data["targetsTeleport"] = target_list return data -/obj/machinery/computer/teleporter/Topic(href, href_list) +/obj/machinery/computer/teleporter/tgui_act(action, params) if(..()) - return 1 - - if(href_list["eject"]) - eject() - SSnanoui.update_uis(src) return if(!check_hub_connection()) - to_chat(usr, "Error: Unable to detect hub.") - SSnanoui.update_uis(src) + atom_say("Error: Unable to detect hub.") return if(calibrating) - to_chat(usr, "Error: Calibration in progress. Stand by.") - SSnanoui.update_uis(src) + atom_say("Error: Calibration in progress. Stand by.") return - if(href_list["regimeset"]) - power_station.engaged = 0 - power_station.teleporter_hub.update_icon() - power_station.teleporter_hub.calibrated = 0 - reset_regime() - SSnanoui.update_uis(src) - if(href_list["settarget"]) - power_station.engaged = 0 - power_station.teleporter_hub.update_icon() - power_station.teleporter_hub.calibrated = 0 - set_target(usr) - SSnanoui.update_uis(src) - if(href_list["lock"]) - power_station.engaged = 0 - power_station.teleporter_hub.update_icon() - power_station.teleporter_hub.calibrated = 0 - target = get_turf(locked.locked_location) - SSnanoui.update_uis(src) - if(href_list["calibrate"]) - if(!target) - to_chat(usr, "Error: No target set to calibrate to.") - SSnanoui.update_uis(src) - return - if(power_station.teleporter_hub.calibrated || power_station.teleporter_hub.accurate >= 3) - to_chat(usr, "Hub is already calibrated.") - SSnanoui.update_uis(src) - return - src.visible_message("Processing hub calibration to target...") + . = TRUE - calibrating = 1 - SSnanoui.update_uis(src) - spawn(50 * (3 - power_station.teleporter_hub.accurate)) //Better parts mean faster calibration - calibrating = 0 - if(check_hub_connection()) - power_station.teleporter_hub.calibrated = 1 - src.visible_message("Calibration complete.") - else - src.visible_message("Error: Unable to detect hub.") - SSnanoui.update_uis(src) + switch(action) + if("eject") //eject gps device + eject() + if("load") //load gps coordinates + target = locate(locked.locked_location.x,locked.locked_location.y,locked.locked_location.z) + if("setregime") + regime = text2num(params["regime"]) + if(regime == REGIME_TELEPORT) + target_list = targets_teleport() + if(regime == REGIME_GATE) + target_list = targets_gate() + if(regime == REGIME_GPS) + target_list = null //clears existing entries, target is added by load action + resetPowerstation() + target = null + if("settarget") + resetPowerstation() + var/turf/tmpTarget = locate(text2num(params["x"]),text2num(params["y"]),text2num(params["z"])) + if(!istype(tmpTarget, /turf)) + atom_say("No valid targets available.") + return + target = tmpTarget + if(regime == REGIME_TELEPORT) + teleport_helper() + if(regime == REGIME_GATE) + gate_helper() + if("calibrate") + if(!target) + atom_say("Error: No target set to calibrate to.") + return + if(power_station.teleporter_hub.calibrated || power_station.teleporter_hub.accurate >= 3) + atom_say("Hub is already calibrated.") + return - SSnanoui.update_uis(src) + atom_say("Processing hub calibration to target...") + calibrating = TRUE + addtimer(CALLBACK(src, .proc/calibrateCallback), 50 * (3 - power_station.teleporter_hub.accurate)) //Better parts mean faster calibration + +/** +* Resets the connected powerstation to initial values. Helper function of tgui_act +*/ +/obj/machinery/computer/teleporter/proc/resetPowerstation() + power_station.engaged = FALSE + power_station.teleporter_hub.calibrated = FALSE + power_station.teleporter_hub.update_icon() + +/** +* Calibrates the hub. Helper function of tgui_act +*/ +/obj/machinery/computer/teleporter/proc/calibrateCallback() + calibrating = FALSE + if(check_hub_connection()) + power_station.teleporter_hub.calibrated = TRUE + atom_say("Calibration complete.") + else + atom_say("Error: Unable to detect hub.") /obj/machinery/computer/teleporter/proc/check_hub_connection() if(!power_station) return if(!power_station.teleporter_hub) return - return 1 - -/obj/machinery/computer/teleporter/proc/reset_regime() - target = null - if(regime_set == "Teleporter") - regime_set = "Gate" - else - regime_set = "Teleporter" + return TRUE +/** +* Helper function of tgui_act +* +* Triggered when ejecting a gps device. Sets the gps to the ground and resets the console +*/ /obj/machinery/computer/teleporter/proc/eject() if(locked) locked.loc = loc locked = null + regime = REGIME_TELEPORT + target_list = targets_teleport() -/obj/machinery/computer/teleporter/proc/set_target(mob/user) - area_bypass = FALSE - if(regime_set == "Teleporter") - var/list/L = list() - var/list/areaindex = list() +/** +* Creates a list of viable targets for the teleport. Helper function of tgui_data +*/ +/obj/machinery/computer/teleporter/proc/targets_teleport() + var/list/L = list() + var/list/areaindex = list() - for(var/obj/item/radio/beacon/R in GLOB.beacons) - var/turf/T = get_turf(R) - if(!T) - continue - if(!is_teleport_allowed(T.z) && !R.cc_beacon) - continue - if(R.syndicate == 1 && emagged == 0) - continue - var/tmpname = T.loc.name + for(var/obj/item/radio/beacon/R in GLOB.beacons) + var/turf/T = get_turf(R) + if(!T) + continue + if(!is_teleport_allowed(T.z) && !R.cc_beacon) + continue + if(R.syndicate && !emagged) + continue + var/tmpname = T.loc.name + if(areaindex[tmpname]) + tmpname = "[tmpname] ([++areaindex[tmpname]])" + else + areaindex[tmpname] = 1 + L[tmpname] = list( + "name" = tmpname, + "x" = T.x, + "y" = T.y, + "z" = T.z) + + for(var/obj/item/implant/tracking/I in GLOB.tracked_implants) + if(!I.implanted || !ismob(I.loc)) + continue + else + var/mob/M = I.loc + if(M.stat == DEAD) + if(M.timeofdeath + 6000 < world.time) + continue + var/turf/T = get_turf(M) + if(!T) continue + if(!is_teleport_allowed(T.z)) continue + var/tmpname = M.real_name if(areaindex[tmpname]) tmpname = "[tmpname] ([++areaindex[tmpname]])" else areaindex[tmpname] = 1 - L[tmpname] = R + L[tmpname] = list( + "name" = tmpname, + "x" = T.x, + "y" = T.y, + "z" = T.z) + return L - for(var/obj/item/implant/tracking/I in GLOB.tracked_implants) - if(!I.implanted || !ismob(I.loc)) - continue - else - var/mob/M = I.loc - if(M.stat == DEAD) - if(M.timeofdeath + 6000 < world.time) - continue - var/turf/T = get_turf(M) - if(!T) continue - if(!is_teleport_allowed(T.z)) continue - var/tmpname = M.real_name - if(areaindex[tmpname]) - tmpname = "[tmpname] ([++areaindex[tmpname]])" - else - areaindex[tmpname] = 1 - L[tmpname] = I +/** +* Creates a list of viable targets for the gate. Helper function of tgui_data +*/ +/obj/machinery/computer/teleporter/proc/targets_gate(mob/users) + var/list/L = list() + var/list/areaindex = list() + var/list/S = power_station.linked_stations + if(!S.len) + return L + for(var/obj/machinery/teleport/station/R in S) + var/turf/T = get_turf(R) + if(!T || !R.teleporter_hub || !R.teleporter_console) + continue + if(!is_teleport_allowed(T.z)) + continue + var/tmpname = T.loc.name + if(areaindex[tmpname]) + tmpname = "[tmpname] ([++areaindex[tmpname]])" + else + areaindex[tmpname] = 1 + L[tmpname] = list( + "name" = tmpname, + "x" = T.x, + "y" = T.y, + "z" = T.z) + return L - var/desc = input("Please select a location to lock in.", "Locking Computer") in L - target = L[desc] - if(istype(target, /obj/item/radio/beacon)) - var/obj/item/radio/beacon/B = target +/** +* Helper function of tgui_act. +* +* Called after selecting a target for the gate in the UI. Sets area_bypass and cc_beacon. +*/ +/obj/machinery/computer/teleporter/proc/teleport_helper() + area_bypass = FALSE + for(var/item in target.contents) + if(istype(item, /obj/item/radio/beacon)) + var/obj/item/radio/beacon/B = item if(B.area_bypass) area_bypass = TRUE cc_beacon = B.cc_beacon - else - var/list/L = list() - var/list/areaindex = list() - var/list/S = power_station.linked_stations - if(!S.len) - to_chat(user, "No connected stations located.") - return - for(var/obj/machinery/teleport/station/R in S) - var/turf/T = get_turf(R) - if(!T || !R.teleporter_hub || !R.teleporter_console) - continue - if(!is_teleport_allowed(T.z)) - continue - var/tmpname = T.loc.name - if(areaindex[tmpname]) - tmpname = "[tmpname] ([++areaindex[tmpname]])" - else - areaindex[tmpname] = 1 - L[tmpname] = R - var/desc = input("Please select a station to lock in.", "Locking Computer") in L - target = L[desc] - if(target) - var/obj/machinery/teleport/station/trg = target - trg.linked_stations |= power_station - trg.stat &= ~NOPOWER - if(trg.teleporter_hub) - trg.teleporter_hub.stat &= ~NOPOWER - trg.teleporter_hub.update_icon() - if(trg.teleporter_console) - trg.teleporter_console.stat &= ~NOPOWER - trg.teleporter_console.update_icon() - return + +/** +* Helper function of tgui_act. +* +* Called after selecting a target for the teleporter in the UI. +*/ +/obj/machinery/computer/teleporter/proc/gate_helper() + area_bypass = FALSE + var/obj/machinery/teleport/station/trg = target + trg.linked_stations |= power_station + trg.stat &= ~NOPOWER + if(trg.teleporter_hub) + trg.teleporter_hub.stat &= ~NOPOWER + trg.teleporter_hub.update_icon() + if(trg.teleporter_console) + trg.teleporter_console.stat &= ~NOPOWER + trg.teleporter_console.update_icon() /proc/find_loc(obj/R as obj) if(!R) return null @@ -263,20 +308,20 @@ /obj/machinery/teleport name = "teleport" icon = 'icons/obj/stationobjs.dmi' - density = 1 - anchored = 1.0 + density = TRUE + anchored = TRUE /obj/machinery/teleport/hub name = "teleporter hub" desc = "It's the hub of a teleporting machine." icon_state = "tele0" - var/accurate = 0 + var/accurate = FALSE use_power = IDLE_POWER_USE idle_power_usage = 10 active_power_usage = 2000 var/obj/machinery/teleport/station/power_station var/calibrated //Calibration prevents mutation - var/admin_usage = 0 // if 1, works on z2. If 0, doesn't. Used for admin room teleport. + var/admin_usage = FALSE // if 1, works on z2. If 0, doesn't. Used for admin room teleport. /obj/machinery/teleport/hub/New() ..() @@ -317,6 +362,7 @@ for(dir in list(NORTH,EAST,SOUTH,WEST)) power_station = locate(/obj/machinery/teleport/station, get_step(src, dir)) if(power_station) + power_station.link_console_and_hub() break return power_station @@ -324,27 +370,12 @@ if(!is_teleport_allowed(z) && !admin_usage) to_chat(M, "You can't use this here.") return - if(power_station && power_station.engaged && !panel_open) - //--FalseIncarnate - //Prevents AI cores from using the teleporter, prints out failure messages for clarity - if(istype(M, /mob/living/silicon/ai) || istype(M, /obj/structure/AIcore)) - visible_message("The teleporter rejects the AI unit.") - if(istype(M, /mob/living/silicon/ai)) - var/mob/living/silicon/ai/T = M - var/list/TPError = list("Firmware instructions dictate you must remain on your assigned station!", - "You cannot interface with this technology and get rejected!", - "External firewalls prevent you from utilizing this machine!", - "Your AI core's anti-bluespace failsafes trigger and prevent teleportation!") - to_chat(T, "[pick(TPError)]") - return - else - if(!teleport(M) && isliving(M)) // the isliving(M) is needed to avoid triggering errors if a spark bumps the telehub - visible_message("[src] emits a loud buzz, as its teleport portal flickers and fails!") - playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0) - power_station.toggle() // turn off the portal. - - use_power(5000) - //--FalseIncarnate + if(power_station && power_station.engaged && !panel_open && !blockAI(M) && !istype(M, /obj/spacepod)) + if(!teleport(M) && isliving(M)) // the isliving(M) is needed to avoid triggering errors if a spark bumps the telehub + visible_message("[src] emits a loud buzz, as its teleport portal flickers and fails!") + playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + power_station.toggle() // turn off the portal. + use_power(5000) return /obj/machinery/teleport/hub/attackby(obj/item/I, mob/user, params) @@ -375,7 +406,7 @@ . = do_teleport(M, locate(rand((2*TRANSITIONEDGE), world.maxx - (2*TRANSITIONEDGE)), rand((2*TRANSITIONEDGE), world.maxy - (2*TRANSITIONEDGE)), 3), 2, bypass_area_flag = com.area_bypass) else . = do_teleport(M, com.target, bypass_area_flag = com.area_bypass) - calibrated = 0 + calibrated = FALSE /obj/machinery/teleport/hub/update_icon() if(panel_open) @@ -389,7 +420,7 @@ name = "permanent teleporter" desc = "A teleporter with the target pre-set on the circuit board." icon_state = "tele0" - var/recalibrating = 0 + var/recalibrating = FALSE use_power = IDLE_POWER_USE idle_power_usage = 10 active_power_usage = 2000 @@ -406,37 +437,42 @@ tele_delay = max(A, 0) update_icon() -/obj/machinery/teleport/perma/Bumped(M as mob|obj) +/** + Internal helper function + + Prevents AI from using the teleporter, prints out failure messages for clarity +*/ +/obj/machinery/teleport/proc/blockAI(atom/A) + if(istype(A, /mob/living/silicon/ai) || istype(A, /obj/structure/AIcore)) + visible_message("The teleporter rejects the AI unit.") + if(istype(A, /mob/living/silicon/ai)) + var/mob/living/silicon/ai/T = A + var/list/TPError = list("Firmware instructions dictate you must remain on your assigned station!", + "You cannot interface with this technology and get rejected!", + "External firewalls prevent you from utilizing this machine!", + "Your AI core's anti-bluespace failsafes trigger and prevent teleportation!") + to_chat(T, "[pick(TPError)]") + return TRUE + return FALSE + +/obj/machinery/teleport/perma/Bumped(atom/A) if(stat & (BROKEN|NOPOWER)) return if(!is_teleport_allowed(z)) - to_chat(M, "You can't use this here.") + to_chat(A, "You can't use this here.") return - if(target && !recalibrating && !panel_open) - //--FalseIncarnate - //Prevents AI cores from using the teleporter, prints out failure messages for clarity - if(istype(M, /mob/living/silicon/ai) || istype(M, /obj/structure/AIcore)) - visible_message("The teleporter rejects the AI unit.") - if(istype(M, /mob/living/silicon/ai)) - var/mob/living/silicon/ai/T = M - var/list/TPError = list("Firmware instructions dictate you must remain on your assigned station!", - "You cannot interface with this technology and get rejected!", - "External firewalls prevent you from utilizing this machine!", - "Your AI core's anti-bluespace failsafes trigger and prevent teleportation!") - to_chat(T, "[pick(TPError)]") - return - else - do_teleport(M, target) - use_power(5000) - if(tele_delay) - recalibrating = 1 - update_icon() - spawn(tele_delay) - recalibrating = 0 - update_icon() - //--FalseIncarnate - return + if(target && !recalibrating && !panel_open && !blockAI(A)) + do_teleport(A, target) + use_power(5000) + if(tele_delay) + recalibrating = TRUE + update_icon() + addtimer(CALLBACK(src, .proc/BumpedCallback), tele_delay) + +/obj/machinery/teleport/perma/proc/BumpedCallback() + recalibrating = FALSE + update_icon() /obj/machinery/teleport/perma/power_change() ..() @@ -467,7 +503,7 @@ name = "station" desc = "The power control station for a bluespace teleporter." icon_state = "controller" - var/engaged = 0 + var/engaged = FALSE use_power = IDLE_POWER_USE idle_power_usage = 10 active_power_usage = 2000 @@ -568,7 +604,7 @@ /obj/machinery/teleport/station/attack_ai() - src.attack_hand() + attack_hand() /obj/machinery/teleport/station/attack_hand(mob/user) if(!panel_open) @@ -583,12 +619,12 @@ to_chat(user, "Close the hub's maintenance panel first.") return if(teleporter_console.target) - src.engaged = !src.engaged + engaged = !engaged use_power(5000) visible_message("Teleporter [engaged ? "" : "dis"]engaged!") else visible_message("No target detected.") - src.engaged = 0 + engaged = FALSE teleporter_hub.update_icon() if(istype(user)) add_fingerprint(user) diff --git a/code/modules/examine/descriptions/atmospherics.dm b/code/modules/examine/descriptions/atmospherics.dm index 2b113a303d8..fb723336d85 100644 --- a/code/modules/examine/descriptions/atmospherics.dm +++ b/code/modules/examine/descriptions/atmospherics.dm @@ -127,15 +127,6 @@ description_info = "This filters the atmosphere of harmful gas. Filtered gas goes to the pipes connected to it, typically a scrubber pipe. \ It can be controlled from an Air Alarm. It can be configured to drain all air rapidly with a 'panic syphon' from an air alarm." -//Omni filters -/obj/machinery/atmospherics/omni/filter - description_info = "Filters gas from a custom input direction, with up to two filtered outputs and a 'everything else' \ - output. The filtered output's arrows glow orange." - -//Omni mixers -/obj/machinery/atmospherics/omni/mixer - description_info = "Combines gas from custom input and output directions. The percentage of combined gas can be defined." - //Canisters /obj/machinery/portable_atmospherics/canister description_info = "The canister can be connected to a connector port with a wrench. Tanks of gas (the kind you can hold in your hand) \ diff --git a/code/modules/instruments/songs/_song.dm b/code/modules/instruments/songs/_song.dm index 142eab1fd2d..fc4a9b63579 100644 --- a/code/modules/instruments/songs/_song.dm +++ b/code/modules/instruments/songs/_song.dm @@ -167,6 +167,8 @@ hearing_mobs.len = 0 var/turf/source = get_turf(parent) for(var/mob/M in GLOB.player_list) + if(M.z != source.z) // Z-level check + continue var/dist = get_dist(M, source) if(dist > instrument_range) // Distance check continue @@ -253,16 +255,20 @@ * Processes our song. */ /datum/song/proc/process_song(wait) - if(!length(compiled_chords) || current_chord > length(compiled_chords) || should_stop_playing(user_playing)) + if(!length(compiled_chords) || should_stop_playing(user_playing)) stop_playing() return - var/list/chord = compiled_chords[current_chord] if(++elapsed_delay >= delay_by) + // We were sustaining the final note but not anymore + if(current_chord > length(compiled_chords)) + stop_playing() + return + var/list/chord = compiled_chords[current_chord] play_chord(chord) elapsed_delay = 0 delay_by = tempodiv_to_delay(chord[length(chord)]) current_chord++ - if(current_chord > length(compiled_chords)) + if(current_chord > length(compiled_chords) + 1) if(repeat) repeat-- current_chord = 1 @@ -284,6 +290,8 @@ */ /datum/song/proc/compile_chords() legacy ? compile_legacy() : compile_synthesized() + // Some chords may be null for some reason - exclude them. + listclearnulls(compiled_chords) /** * Plays a chord. diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 9e9724d20ec..883b781c43c 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -927,6 +927,8 @@ . += T.slowdown if(slowed) . += 10 + if(forced_look) + . += 3 if(ignorewalk) . += config.run_speed else diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index d4f8e7c4c3d..4bff2c100bf 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -319,10 +319,9 @@ return verb /mob/living/simple_animal/movement_delay() - . = ..() - . = speed - + if(forced_look) + . += 3 . += config.animal_delay /mob/living/simple_animal/Stat() diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm index e90789f9d8b..9797951f290 100644 --- a/code/modules/reagents/chemistry/reagents/medicine.dm +++ b/code/modules/reagents/chemistry/reagents/medicine.dm @@ -849,7 +849,7 @@ /datum/reagent/medicine/stimulants name = "Stimulants" id = "stimulants" - description = "Increases run speed and eliminates stuns, can heal minor damage. If overdosed it will deal toxin damage and stun." + description = "An illegal compound that dramatically enhances the body's performance and healing capabilities." color = "#C8A5DC" harmless = FALSE can_synth = FALSE @@ -886,7 +886,7 @@ /datum/reagent/medicine/stimulative_agent name = "Stimulative Agent" id = "stimulative_agent" - description = "An illegal compound that dramatically enhances the body's performance and healing capabilities." + description = "Increases run speed and eliminates stuns, can heal minor damage. If overdosed it will deal toxin damage and be less effective for healing stamina." color = "#C8A5DC" metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 60 diff --git a/icons/atmos/omni_devices.dmi b/icons/atmos/omni_devices.dmi deleted file mode 100644 index 3e7325b0556..00000000000 Binary files a/icons/atmos/omni_devices.dmi and /dev/null differ diff --git a/icons/mob/inhands/clothing_lefthand.dmi b/icons/mob/inhands/clothing_lefthand.dmi index 379c727930f..d168010e92c 100644 Binary files a/icons/mob/inhands/clothing_lefthand.dmi and b/icons/mob/inhands/clothing_lefthand.dmi differ diff --git a/nano/templates/omni_filter.tmpl b/nano/templates/omni_filter.tmpl deleted file mode 100644 index 8a3ffac0af7..00000000000 --- a/nano/templates/omni_filter.tmpl +++ /dev/null @@ -1,86 +0,0 @@ -