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/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index 64fb308c2db..c06e863406d 100755 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -1,26 +1,39 @@ + +/// Nothing will be filtered. +#define FILTER_NOTHING -1 +/// Plasma, and Oxygen Agent B. +#define FILTER_TOXINS 0 +/// Oxygen only. +#define FILTER_OXYGEN 1 +/// Nitrogen only. +#define FILTER_NITROGEN 2 +/// Carbon dioxide only. +#define FILTER_CO2 3 +/// Nitrous oxide only. +#define FILTER_N2O 4 + /obj/machinery/atmospherics/trinary/filter + name = "gas filter" icon = 'icons/atmos/filter.dmi' icon_state = "map" - - can_unwrench = 1 - - name = "gas filter" - + can_unwrench = TRUE + /// The amount of pressure the filter wants to operate at. var/target_pressure = ONE_ATMOSPHERE - - var/filter_type = 0 -/* -Filter types: --1: Nothing - 0: Toxins: Toxins, Oxygen Agent B - 1: Oxygen: Oxygen ONLY - 2: Nitrogen: Nitrogen ONLY - 3: Carbon Dioxide: Carbon Dioxide ONLY - 4: Sleeping Agent (N2O) -*/ - - var/frequency = 0 + /// The type of gas we want to filter. Valid values that go here are from the `FILTER` defines at the top of the file. + var/filter_type = FILTER_NOTHING + /// The frequency of the filter. Used with `radio_connection`. + var/frequency = NONE + /// A reference to the filter's `datum/radio_frequency`. var/datum/radio_frequency/radio_connection + /// A list of available filter options. Used with `tgui_data`. + var/list/filter_list = list( + "Nothing" = FILTER_NOTHING, + "Plasma" = FILTER_TOXINS, + "O2" = FILTER_OXYGEN, + "N2" = FILTER_NITROGEN, + "CO2" = FILTER_CO2, + "N2O" = FILTER_N2O + ) /obj/machinery/atmospherics/trinary/filter/CtrlClick(mob/living/user) if(!istype(user) || user.incapacitated()) @@ -146,26 +159,26 @@ Filter types: filtered_out.temperature = removed.temperature switch(filter_type) - if(0) //removing hydrocarbons + if(FILTER_TOXINS) filtered_out.toxins = removed.toxins removed.toxins = 0 filtered_out.agent_b = removed.agent_b removed.agent_b = 0 - if(1) //removing O2 + if(FILTER_OXYGEN) filtered_out.oxygen = removed.oxygen removed.oxygen = 0 - if(2) //removing N2 + if(FILTER_NITROGEN) filtered_out.nitrogen = removed.nitrogen removed.nitrogen = 0 - if(3) //removing CO2 + if(FILTER_CO2) filtered_out.carbon_dioxide = removed.carbon_dioxide removed.carbon_dioxide = 0 - if(4)//removing N2O + if(FILTER_N2O) filtered_out.sleeping_agent = removed.sleeping_agent removed.sleeping_agent = 0 else @@ -188,7 +201,7 @@ Filter types: ..() /obj/machinery/atmospherics/trinary/filter/attack_ghost(mob/user) - ui_interact(user) + tgui_interact(user) /obj/machinery/atmospherics/trinary/filter/attack_hand(mob/user) if(..()) @@ -199,53 +212,56 @@ Filter types: return add_fingerprint(user) - ui_interact(user) + tgui_interact(user) -/obj/machinery/atmospherics/trinary/filter/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state) +/obj/machinery/atmospherics/trinary/filter/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) user.set_machine(src) - 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, "atmos_filter.tmpl", name, 475, 155, state = state) + ui = new(user, src, ui_key, "AtmosFilter", name, 380, 140, master_ui, state) ui.open() -/obj/machinery/atmospherics/trinary/filter/ui_data(mob/user) - var/list/data = list() - data["on"] = on - data["pressure"] = round(target_pressure) - data["max_pressure"] = round(MAX_OUTPUT_PRESSURE) - data["filter_type"] = filter_type +/obj/machinery/atmospherics/trinary/filter/tgui_data(mob/user) + var/list/data = list( + "on" = on, + "pressure" = round(target_pressure), + "max_pressure" = round(MAX_OUTPUT_PRESSURE), + "filter_type" = filter_type + ) + data["filter_type_list"] = list() + for(var/label in filter_list) + data["filter_type_list"] += list(list("label" = label, "gas_type" = filter_list[label])) + return data -/obj/machinery/atmospherics/trinary/filter/Topic(href, href_list) // -- TLE +/obj/machinery/atmospherics/trinary/filter/tgui_act(action, list/params) if(..()) - return 1 + return - if(href_list["power"]) - on = !on - investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos") - . = TRUE - if(href_list["pressure"]) - var/pressure = href_list["pressure"] - if(pressure == "max") - pressure = MAX_OUTPUT_PRESSURE - . = TRUE - else if(pressure == "input") - pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null - if(!isnull(pressure) && !..()) - . = TRUE - else if(text2num(pressure) != null) - pressure = text2num(pressure) - . = TRUE - if(.) - target_pressure = clamp(pressure, 0, MAX_OUTPUT_PRESSURE) - investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos") - if(href_list["filter"]) - filter_type = text2num(href_list["filter"]) - investigate_log("was set to filter [filter_type] by [key_name(usr)]", "atmos") - . = TRUE + switch(action) + if("power") + toggle() + investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos") + return TRUE - update_icon() - SSnanoui.update_uis(src) + if("set_filter") + filter_type = text2num(params["filter"]) + investigate_log("was set to filter [filter_type] by [key_name(usr)]", "atmos") + return TRUE + + if("max_pressure") + target_pressure = MAX_OUTPUT_PRESSURE + . = TRUE + + if("min_pressure") + target_pressure = 0 + . = TRUE + + if("custom_pressure") + target_pressure = clamp(text2num(params["pressure"]), 0, MAX_OUTPUT_PRESSURE) + . = TRUE + if(.) + investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos") /obj/machinery/atmospherics/trinary/filter/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/pen)) 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/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 6e3603f83a3..11732a22375 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -48,7 +48,7 @@ #define INIT_ORDER_GARBAGE 21 #define INIT_ORDER_DBCORE 20 #define INIT_ORDER_BLACKBOX 19 -#define INIT_ORDER_SERVER_MAINT 18 +#define INIT_ORDER_CLEANUP 18 #define INIT_ORDER_INPUT 17 #define INIT_ORDER_SOUNDS 16 #define INIT_ORDER_INSTRUMENTS 15 @@ -90,7 +90,7 @@ #define FIRE_PRIORITY_NANOMOB 10 #define FIRE_PRIORITY_NIGHTSHIFT 10 #define FIRE_PRIORITY_IDLE_NPC 10 -#define FIRE_PRIORITY_SERVER_MAINT 10 +#define FIRE_PRIORITY_CLEANUP 10 #define FIRE_PRIORITY_TICKETS 10 #define FIRE_PRIORITY_RESEARCH 10 #define FIRE_PRIORITY_GARBAGE 15 diff --git a/code/controllers/subsystem/cleanup.dm b/code/controllers/subsystem/cleanup.dm new file mode 100644 index 00000000000..f5962c45547 --- /dev/null +++ b/code/controllers/subsystem/cleanup.dm @@ -0,0 +1,44 @@ +/** + * # Cleanup Subsystem + * + * For now, all it does is periodically clean the supplied global lists of any null values they may contain. + * + * Why is this important? + * + * Sometimes, these lists can gain nulls due to errors. + * For example, when a dead player trasitions from the `dead_mob_list` to the `alive_mob_list`, a null value may get stuck in the dead mob list. + * This can cause issues when other code tries to do things with the values in the list, but are instead met with null values. + * These problems are incredibly hard to track down and fix, so this subsystem is a solution to that. + */ +SUBSYSTEM_DEF(cleanup) + name = "Null cleanup" + wait = 30 SECONDS + flags = SS_POST_FIRE_TIMING + priority = FIRE_PRIORITY_CLEANUP + init_order = INIT_ORDER_CLEANUP + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT + offline_implications = "Certain global lists will no longer be cleared of nulls, which may result in runtimes. No immediate action is needed." + /// A list of global lists we want the subsystem to clean. + var/list/lists_to_clean + +/datum/controller/subsystem/cleanup/Initialize(start_timeofday) + // If you want this subsystem to clean out nulls from a specific list, add it here. + lists_to_clean = list( + GLOB.clients = "clients", + GLOB.player_list = "player_list", + GLOB.mob_list = "mob_list", + GLOB.alive_mob_list = "alive_mob_list", + GLOB.dead_mob_list = "dead_mob_list", + GLOB.human_list = "human_list", + GLOB.carbon_list = "carbon_list" + ) + return ..() + +/datum/controller/subsystem/cleanup/fire(resumed) + for(var/L in lists_to_clean) + var/list/_list = L + var/prev_length = length(_list) + listclearnulls(_list) + + if(length(_list) < prev_length) + stack_trace("Found a null value in GLOB.[lists_to_clean[_list]]!") diff --git a/code/datums/dog_fashion.dm b/code/datums/dog_fashion.dm index 3bf109eabd9..964fba34c9b 100644 --- a/code/datums/dog_fashion.dm +++ b/code/datums/dog_fashion.dm @@ -191,6 +191,10 @@ ..() desc = "That's Definitely Not [M.real_name]." +/datum/dog_fashion/head/cone + name = "REAL_NAME" + desc = "Omnicone's Chosen Champion" + /datum/dog_fashion/back/hardsuit name = "Space Explorer REAL_NAME" desc = "That's one small step for a corgi. One giant yap for corgikind." 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/datums/spells/devil.dm b/code/datums/spells/devil.dm index 27b2fcb8851..1a1069481cf 100644 --- a/code/datums/spells/devil.dm +++ b/code/datums/spells/devil.dm @@ -75,7 +75,7 @@ action_background_icon_state = "bg_demon" /obj/effect/proc_holder/spell/fireball/hellish/cast(list/targets, mob/living/user = usr) - msg_admin_attack("[key_name_admin(usr)] has fired a fireball.", ATKLOG_FEW) + add_attack_logs(user, targets, "has fired a Hellfire ball", ATKLOG_FEW) .=..() 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/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index 2a476c215ef..37dd2c6d439 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -260,9 +260,9 @@ var/turf/bombturf = get_turf(src) var/area/A = get_area(bombturf) if(payload && !istype(payload, /obj/item/bombcore/training)) - msg_admin_attack("[key_name_admin(user)] has primed a [name] ([payload]) for detonation at [A.name] (JMP).", ATKLOG_FEW) log_game("[key_name(user)] has primed a [name] ([payload]) for detonation at [A.name] [COORD(bombturf)]") investigate_log("[key_name(user)] has has primed a [name] ([payload]) for detonation at [A.name] [COORD(bombturf)]", INVESTIGATE_BOMB) + add_attack_logs(user, src, "has primed a [name] ([payload]) for detonation", ATKLOG_FEW) payload.adminlog = "\The [src] that [key_name(user)] had primed detonated!" ///Bomb Subtypes/// @@ -652,8 +652,8 @@ var/turf/T = get_turf(src) var/area/A = get_area(T) detonated-- - message_admins("[key_name_admin(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] (JMP).") investigate_log("[key_name(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] ([T.x],[T.y],[T.z])", INVESTIGATE_BOMB) + add_attack_logs(user, src, "has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using", ATKLOG_FEW) log_game("[key_name(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] ([T.x],[T.y],[T.z])") detonated = 0 existant = 0 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/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index e05fef18e5a..d1e63deaf0c 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -60,7 +60,7 @@ set_ready_state(0) log_message("Fired from [name], targeting [target].") var/turf/T = get_turf(src) - msg_admin_attack("[key_name_admin(chassis.occupant)] fired a [src] in ([T.x], [T.y], [T.z] - [ADMIN_JMP(T)])") + add_attack_logs(chassis.occupant, target, "fired a [src]", ATKLOG_FEW) log_game("[key_name(chassis.occupant)] fired a [src] in [T.x], [T.y], [T.z]") do_after_cooldown() return @@ -238,7 +238,7 @@ chassis.use_power(energy_drain) log_message("Honked from [name]. HONK!") var/turf/T = get_turf(src) - msg_admin_attack("[key_name_admin(chassis.occupant)] used a Mecha Honker in ([T.x], [T.y], [T.z] - [ADMIN_JMP(T)])") + add_attack_logs(chassis.occupant, target, "used a Mecha Honker", ATKLOG_MOST) log_game("[key_name(chassis.occupant)] used a Mecha Honker in [T.x], [T.y], [T.z]") do_after_cooldown() return @@ -357,7 +357,7 @@ projectiles-- log_message("Fired from [name], targeting [target].") var/turf/T = get_turf(src) - msg_admin_attack("[key_name_admin(chassis.occupant)] fired a [src] in ([T.x], [T.y], [T.z] - [ADMIN_JMP(T)])") + add_attack_logs(chassis.occupant, target, "fired a [src]", ATKLOG_FEW) log_game("[key_name(chassis.occupant)] fired a [src] in [T.x], [T.y], [T.z]") do_after_cooldown() return diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index a55c2a731eb..3f8eb81c6b9 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -481,7 +481,7 @@ would spawn and follow the beaker, even if it is carried or thrown. var/more = "" if(M) more = " " - msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink])[contained]. Last associated key is [carry.my_atom.fingerprintslast][more].", 0, 1) + add_attack_logs(M, location, "Caused a chemical smoke reaction containing [contained]. Last associated key is [carry.my_atom.fingerprintslast][more]", ATKLOG_FEW) log_game("A chemical smoke reaction has taken place in ([where])[contained]. Last associated key is [carry.my_atom.fingerprintslast].") else msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink]). No associated key.", 0, 1) diff --git a/code/game/objects/effects/effect_system/effects_chem_smoke.dm b/code/game/objects/effects/effect_system/effects_chem_smoke.dm index 8c28c7f11c5..2ebad516beb 100644 --- a/code/game/objects/effects/effect_system/effects_chem_smoke.dm +++ b/code/game/objects/effects/effect_system/effects_chem_smoke.dm @@ -83,13 +83,13 @@ var/more = "" if(M) more = " " - msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink])[contained]. Last associated key is [carry.my_atom.fingerprintslast][more].", ATKLOG_FEW) + add_attack_logs(M, location, "Caused a chemical smoke reaction containing [contained]. Last associated key is [carry.my_atom.fingerprintslast][more]", ATKLOG_FEW) log_game("A chemical smoke reaction has taken place in ([where])[contained]. Last associated key is [carry.my_atom.fingerprintslast].") else - msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink]). No associated key.", ATKLOG_FEW) + msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink])[contained]. No associated key.", ATKLOG_FEW) log_game("A chemical smoke reaction has taken place in ([where])[contained]. No associated key.") else - msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink]). No associated key. CODERS: carry.my_atom may be null.", ATKLOG_FEW) + msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink])[contained]. No associated key. CODERS: carry.my_atom may be null.", ATKLOG_FEW) log_game("A chemical smoke reaction has taken place in ([where])[contained]. No associated key. CODERS: carry.my_atom may be null.") diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index 093f28692ec..3b3391b506b 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -83,8 +83,7 @@ if(href_list["wipe"]) var/confirm = alert("Are you sure you want to wipe this card's memory? This cannot be undone once started.", "Confirm Wipe", "Yes", "No") if(confirm == "Yes" && (CanUseTopic(user, state) == STATUS_INTERACTIVE)) - msg_admin_attack("[key_name_admin(user)] wiped [key_name_admin(AI)] with \the [src].", ATKLOG_FEW) - add_attack_logs(user, AI, "Wiped with [src].") + add_attack_logs(user, AI, "Wiped with [src].", ATKLOG_FEW) flush = 1 AI.suiciding = 1 to_chat(AI, "Your core files are being wiped!") diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index fdef93dc7a3..1eba4e54056 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -64,7 +64,7 @@ A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb). investigate_log("[key_name(user)] attached a [A] to a transfer valve.", INVESTIGATE_BOMB) - msg_admin_attack("[key_name_admin(user)]attached [A] to a transfer valve.", ATKLOG_FEW) + add_attack_logs(user, src, "attached [A] to a transfer valve", ATKLOG_FEW) log_game("[key_name_admin(user)] attached [A] to a transfer valve.") attacher = user SSnanoui.update_uis(src) // update all UIs attached to src @@ -128,7 +128,7 @@ if((!tank_one || tank_one.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL)) w_class = WEIGHT_CLASS_NORMAL if("toggle") - toggle_valve() + toggle_valve(usr) if("device") if(attached_device) attached_device.attack_self(usr) @@ -190,7 +190,7 @@ it explodes properly when it gets a signal (and it does). */ -/obj/item/transfer_valve/proc/toggle_valve() +/obj/item/transfer_valve/proc/toggle_valve(mob/user) if(!valve_open && tank_one && tank_two) valve_open = 1 var/turf/bombturf = get_turf(src) @@ -207,6 +207,8 @@ investigate_log("Bomb valve opened at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]", INVESTIGATE_BOMB) message_admins("Bomb valve opened at [A.name] (JMP) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name_admin(mob)]") log_game("Bomb valve opened at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]") + if(user) + add_attack_logs(user, src, "Bomb valve opened with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]", ATKLOG_FEW) merge_gases() spawn(20) // In case one tank bursts for(var/i in 1 to 5) diff --git a/code/game/objects/items/flag.dm b/code/game/objects/items/flag.dm index f33e504a3e6..0dda06d3e5c 100644 --- a/code/game/objects/items/flag.dm +++ b/code/game/objects/items/flag.dm @@ -242,15 +242,15 @@ to_chat(user, "You hide [I] in the [src]. It will detonate some time after the flag is lit on fire.") var/turf/bombturf = get_turf(src) var/area/A = get_area(bombturf) - message_admins("[key_name_admin(user)] has hidden [I] in the [src] ready for detonation at [A.name] (JMP).") log_game("[key_name(user)] has hidden [I] in the [src] ready for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).") investigate_log("[key_name(user)] has hidden [I] in the [src] ready for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).", INVESTIGATE_BOMB) + add_attack_logs(user, src, "has hidden [I] ready for detonation in", ATKLOG_MOST) else if(is_hot(I) && !(resistance_flags & ON_FIRE) && boobytrap && trapper) var/turf/bombturf = get_turf(src) var/area/A = get_area(bombturf) - message_admins("[key_name_admin(user)] has lit the [src] trapped with [boobytrap] by [key_name_admin(trapper)] at [A.name] (JMP).") log_game("[key_name_admin(user)] has lit the [src] trapped with [boobytrap] by [key_name_admin(trapper)] at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).") investigate_log("[key_name_admin(user)] has lit the [src] trapped with [boobytrap] by [key_name_admin(trapper)] at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).", INVESTIGATE_BOMB) + add_attack_logs(user, src, "has lit (booby trapped with [boobytrap]", ATKLOG_FEW) burn() else return ..() diff --git a/code/game/objects/items/weapons/dice.dm b/code/game/objects/items/weapons/dice.dm index 629942860be..ae49512853a 100644 --- a/code/game/objects/items/weapons/dice.dm +++ b/code/game/objects/items/weapons/dice.dm @@ -189,8 +189,8 @@ var/turf/bombturf = get_turf(src) var/area/A = get_area(bombturf) investigate_log("E20 detonated at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with a roll of [result]. Triggered by: [key_name(user)]", INVESTIGATE_BOMB) - message_admins("E20 detonated at [A.name] (JMP) with a roll of [result]. Triggered by: [key_name_admin(user)]") log_game("E20 detonated at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with a roll of [result]. Triggered by: [key_name(user)]") + add_attack_logs(user, src, "detonated with a roll of [result]", ATKLOG_FEW) /obj/item/dice/update_icon() diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index 79612afd1f3..3aa658b0812 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -101,9 +101,9 @@ update_icon() else if(clown_check(user)) // This used to go before the assembly check, but that has absolutely zero to do with priming the damn thing. You could spam the admins with it. - message_admins("[key_name_admin(usr)] has primed a [name] for detonation at [A.name] (JMP) [contained].") log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) [contained].") investigate_log("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])[contained].", INVESTIGATE_BOMB) + add_attack_logs(user, src, "has primed (contained [contained])", ATKLOG_FEW) to_chat(user, "You prime the [name]! [det_time / 10] second\s!") playsound(user.loc, 'sound/weapons/armbomb.ogg', 60, 1) active = 1 @@ -120,7 +120,7 @@ owner.visible_message("[attack_text] hits [owner]'s [src], setting it off! What a shot!") var/turf/T = get_turf(src) log_game("A projectile ([hitby]) detonated a grenade held by [key_name(owner)] at [COORD(T)]") - message_admins("A projectile ([hitby]) detonated a grenade held by [key_name_admin(owner)] at [ADMIN_COORDJMP(T)]") + add_attack_logs(P.firer, owner, "A projectile ([hitby]) detonated a grenade held", ATKLOG_FEW) prime() return 1 //It hit the grenade, not them @@ -149,16 +149,16 @@ if(!O.reagents) continue if(istype(O,/obj/item/slime_extract)) cores += " [O]" - for(var/reagent in O.reagents.reagent_list) - contained += " [reagent] " + for(var/R in O.reagents.reagent_list) + var/datum/reagent/reagent = R + contained += "[reagent.volume] [reagent], " if(contained) if(cores) - contained = "\[[cores];[contained]\]" + contained = "\[[cores]; [contained]\]" else - contained = "\[[contained]\]" + contained = "\[ [contained]\]" var/turf/bombturf = get_turf(loc) - var/area/A = bombturf.loc - message_admins("[key_name_admin(usr)] has completed [name] at [A.name] (JMP) [contained].") + add_attack_logs(user, src, "has completed with [contained]", ATKLOG_MOST) log_game("[key_name(usr)] has completed [name] at [bombturf.x], [bombturf.y], [bombturf.z]. [contained]") else to_chat(user, "You need to add at least one beaker before locking the assembly.") diff --git a/code/game/objects/items/weapons/grenades/ghettobomb.dm b/code/game/objects/items/weapons/grenades/ghettobomb.dm index b58330a248b..c2303dd2937 100644 --- a/code/game/objects/items/weapons/grenades/ghettobomb.dm +++ b/code/game/objects/items/weapons/grenades/ghettobomb.dm @@ -48,9 +48,9 @@ var/turf/bombturf = get_turf(src) var/area/A = get_area(bombturf) - message_admins("[ADMIN_LOOKUPFLW(user)] has primed a [name] for detonation at [ADMIN_COORDJMP(bombturf)].") log_game("[key_name(user)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].") investigate_log("[key_name(user)] has primed a [name] for detonation at [A.name] [COORD(bombturf)])", INVESTIGATE_BOMB) + add_attack_logs(user, src, "has primed for detonation", ATKLOG_FEW) if(iscarbon(user)) var/mob/living/carbon/C = user C.throw_mode_on() diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm index 8cbc041c146..da546836dc6 100644 --- a/code/game/objects/items/weapons/grenades/grenade.dm +++ b/code/game/objects/items/weapons/grenades/grenade.dm @@ -73,6 +73,7 @@ message_admins("[key_name_admin(usr)] has primed a [name] for detonation at [A.name] (JMP)") log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])") investigate_log("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])", INVESTIGATE_BOMB) + add_attack_logs(user, src, "has primed for detonation", ATKLOG_FEW) if(iscarbon(user)) var/mob/living/carbon/C = user C.throw_mode_on() diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index e31e98789a3..0be9178967c 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -310,6 +310,18 @@ item_state = "utility" use_item_overlays = 1 // So it will still show tools in it in case sec get lazy and just glance at it. +/obj/item/storage/belt/military/traitor/hacker + +/obj/item/storage/belt/military/traitor/hacker/New() + ..() + new /obj/item/screwdriver(src, "red") + new /obj/item/wrench(src) + new /obj/item/weldingtool/largetank(src) + new /obj/item/crowbar/red(src) + new /obj/item/wirecutters(src, "red") + new /obj/item/stack/cable_coil(src, 30, COLOR_RED) + update_icon() + /obj/item/storage/belt/grenade name = "grenadier belt" desc = "A belt for holding grenades." diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index 6cf011bc2c3..704538ee2af 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -1,7 +1,7 @@ /obj/item/storage/box/syndicate/New() ..() switch(pickweight(list("bloodyspai" = 1, "thief" = 1, "bond" = 1, "sabotage" = 1, "payday" = 1, "implant" = 1, "hacker" = 1, "darklord" = 1, "professional" = 1))) - if("bloodyspai") // 35TC + one 0TC + if("bloodyspai") // 37TC + one 0TC new /obj/item/clothing/under/chameleon(src) // 2TC new /obj/item/clothing/mask/chameleon(src) // 0TC new /obj/item/card/id/syndicate(src) // 2TC @@ -14,12 +14,12 @@ new /obj/item/storage/fancy/cigarettes/cigpack_syndicate(src) // 2TC new /obj/item/flashlight/emp(src) // 2TC new /obj/item/clothing/glasses/hud/security/chameleon(src) // 2TC - new /obj/item/chameleon(src) // 8TC + new /obj/item/chameleon(src) // 7TC return - if("thief") // 40TC + if("thief") // 39TC new /obj/item/gun/energy/kinetic_accelerator/crossbow(src) // 12TC - new /obj/item/chameleon(src) // 8TC + new /obj/item/chameleon(src) // 7TC new /obj/item/clothing/glasses/chameleon/thermal(src) // 6TC new /obj/item/clothing/gloves/color/black/thief(src) // 6TC new /obj/item/card/id/syndicate(src) // 2TC @@ -43,7 +43,7 @@ new /obj/item/CQC_manual(src) // 13TC return - if("sabotage") // 47TC + three 0TC + if("sabotage") // 41TC + two 0TC new /obj/item/grenade/plastic/c4(src) // 1TC new /obj/item/grenade/plastic/c4(src) // 1TC new /obj/item/camera_bug(src) // 1TC @@ -53,23 +53,23 @@ new /obj/item/card/emag(src) // 6TC new /obj/item/clothing/gloves/color/yellow(src) // 0TC new /obj/item/grenade/syndieminibomb(src) // 6TC - new /obj/item/grenade/clusterbuster/n2o(src) // 0TC + new /obj/item/grenade/clusterbuster/n2o(src) // 4TC new /obj/item/storage/box/syndie_kit/space(src) // 4TC new /obj/item/encryptionkey/syndicate(src) // 2TC return - if("payday") // 33TC + four 0TC + if("payday") // 35TC + four 0TC new /obj/item/gun/projectile/revolver(src) // 13TC new /obj/item/ammo_box/a357(src) // 3TC new /obj/item/ammo_box/a357(src) // 3TC new /obj/item/card/emag(src) // 6TC - new /obj/item/grenade/plastic/c4(src) // 1TC + new /obj/item/jammer(src) // 5TC new /obj/item/card/id/syndicate(src) // 2TC new /obj/item/clothing/under/suit_jacket/really_black(src) //0TC new /obj/item/clothing/suit/storage/lawyer/blackjacket/armored(src) //0TC new /obj/item/clothing/gloves/color/latex/nitrile(src) //0 TC new /obj/item/clothing/mask/gas/clown_hat(src) // 0TC - new /obj/item/thermal_drill(src) // 3TC + new /obj/item/thermal_drill/diamond_drill(src) // 1TC new /obj/item/encryptionkey/syndicate(src) // 2TC return @@ -83,17 +83,20 @@ new /obj/item/encryptionkey/syndicate(src) // 2TC return - if("hacker") // 30TC + one 0TC + if("hacker") // 37TC + two 0TC new /obj/item/aiModule/syndicate(src) // 12TC new /obj/item/card/emag(src) // 6TC new /obj/item/encryptionkey/syndicate(src) // 2TC new /obj/item/encryptionkey/binary(src) // 5TC new /obj/item/aiModule/toyAI(src) // 0TC + new /obj/item/clothing/glasses/chameleon/thermal(src) // 6TC + new /obj/item/storage/belt/military/traitor/hacker(src) // 3TC + new /obj/item/clothing/gloves/combat(src) // 0TC new /obj/item/multitool/ai_detect(src) // 1TC - new /obj/item/storage/box/syndie_kit/c4 // 4TC + new /obj/item/flashlight/emp(src) // 2TC return - if("darklord") // 22TC + two 0TC + if("darklord") // 24TC + two 0TC new /obj/item/melee/energy/sword/saber/red(src) // 8TC new /obj/item/melee/energy/sword/saber/red(src) // 8TC new /obj/item/dnainjector/telemut/darkbundle(src) // 0TC @@ -104,7 +107,7 @@ new /obj/item/encryptionkey/syndicate(src) // 2TC return - if("professional") // 32 TC + two 0TC + if("professional") // 34TC + two 0TC new /obj/item/gun/projectile/automatic/sniper_rifle/syndicate/penetrator(src) // 16TC new /obj/item/ammo_box/magazine/sniper_rounds/penetrator(src) // 5TC new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src) // 3TC diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 2441a2d57d6..b4feccdc9e2 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -187,6 +187,7 @@ if(user) to_chat(user, "The crate's anti-tamper system activates!") investigate_log("[key_name(user)] has detonated a [src]", INVESTIGATE_BOMB) + add_attack_logs(user, src, "has detonated", ATKLOG_MOST) for(var/atom/movable/AM in src) qdel(AM) explosion(get_turf(src), 0, 1, 5, 5) diff --git a/code/game/objects/structures/lavaland/necropolis_tendril.dm b/code/game/objects/structures/lavaland/necropolis_tendril.dm index f9717956bb0..13c0ce77c0f 100644 --- a/code/game/objects/structures/lavaland/necropolis_tendril.dm +++ b/code/game/objects/structures/lavaland/necropolis_tendril.dm @@ -15,7 +15,6 @@ anchored = TRUE resistance_flags = FIRE_PROOF | LAVA_PROOF - var/gps = null var/obj/effect/light_emitter/tendril/emitted_light /obj/structure/spawner/lavaland/goliath @@ -29,7 +28,6 @@ GLOBAL_LIST_INIT(tendrils, list()) /obj/structure/spawner/lavaland/Initialize(mapload) . = ..() emitted_light = new(loc) - gps = new /obj/item/gps/internal(src) GLOB.tendrils += src return INITIALIZE_HINT_LATELOAD @@ -59,7 +57,6 @@ GLOBAL_LIST_INIT(tendrils, list()) SSmedals.SetScore(TENDRIL_CLEAR_SCORE, L.client, 1) GLOB.tendrils -= src QDEL_NULL(emitted_light) - QDEL_NULL(gps) return ..() /obj/effect/light_emitter/tendril diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index bf62e2a828a..33755fc54e8 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -52,12 +52,13 @@ if(!status) status = TRUE investigate_log("[key_name(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", INVESTIGATE_BOMB) - msg_admin_attack("[key_name_admin(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", ATKLOG_FEW) log_game("[key_name(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature - T0C]") to_chat(user, "A pressure hole has been bored to [bombtank] valve. [bombtank] can now be ignited.") + add_attack_logs(user, src, "welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", ATKLOG_FEW) else status = FALSE investigate_log("[key_name(user)] unwelded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", INVESTIGATE_BOMB) + add_attack_logs(user, src, "unwelded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", ATKLOG_ALMOSTALL) to_chat(user, "The hole has been closed.") diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index 5bbd9a26538..67be53979d8 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -101,8 +101,8 @@ if(href_list["time"]) timing = !timing if(timing && istype(holder, /obj/item/transfer_valve)) - message_admins("[key_name_admin(usr)] activated [src] attachment on [holder].") investigate_log("[key_name(usr)] activated [src] attachment for [loc]", INVESTIGATE_BOMB) + add_attack_logs(usr, holder, "activated [src] attachment on", ATKLOG_FEW) log_game("[key_name(usr)] activated [src] attachment for [loc]") update_icon() if(href_list["reset"]) diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index cac07fe5b1d..10005077d33 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -401,6 +401,7 @@ w_class = WEIGHT_CLASS_SMALL attack_verb = list("warned", "cautioned", "smashed") resistance_flags = NONE + dog_fashion = /datum/dog_fashion/head/cone /obj/item/clothing/head/jester name = "jester hat" diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 530b9095f75..4ee33f4d87e 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -272,15 +272,6 @@ new /obj/item/reagent_containers/food/drinks/cans/cola(src) -/obj/item/instrument/guitar/jello_guitar //Pineapple Salad: Dan Jello - name = "Dan Jello's Pink Guitar" - desc = "Dan Jello's special pink guitar." - icon = 'icons/obj/custom_items.dmi' - icon_state = "jello_guitar" - item_state = "jello_guitar" - righthand_file = 'icons/mob/inhands/fluff_righthand.dmi' - lefthand_file = 'icons/mob/inhands/fluff_lefthand.dmi' - /obj/item/fluff/wingler_comb name = "blue comb" desc = "A blue comb, it looks like it was made to groom a Tajaran's fur." @@ -1592,13 +1583,17 @@ item_state = "asmer_accordion" -/obj/item/clothing/head/rabbitears/fluff/pinesalad_bunny // Pineapple Salad : Dan Jello - name = "Bluespace rabbit ears" - desc = "A pair of sparkly bluespace rabbit ears, with a small tag on them that reads, 'Dan Jello~'. Yuck, \ - there's some pink slime on the part that goes on your head!" +/obj/item/clothing/head/fluff/pinesalad_horns //Pineapple Salad: Dan Jello + name = "Bluespace Horns" + desc = "A pair of fake horns. Now with added bluespace!" icon = 'icons/obj/custom_items.dmi' - icon_state = "ps_bunny" + icon_state = "ps_horns" +/obj/item/storage/backpack/fluff/hiking //Pineapple Salad: Dan Jello + name = "\improper Fancy Hiking Pack" + desc = "A black and red hiking pack with some nice little accessories." + icon = 'icons/obj/custom_items.dmi' + icon_state = "danpack" /obj/item/clothing/under/fluff/kiaoutfit //FullOfSkittles: Kiachi name = "Suspicious Outfit" 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/food_and_drinks/food/foods/baked_goods.dm b/code/modules/food_and_drinks/food/foods/baked_goods.dm index 57fd36393b5..9a7c0e89999 100644 --- a/code/modules/food_and_drinks/food/foods/baked_goods.dm +++ b/code/modules/food_and_drinks/food/foods/baked_goods.dm @@ -432,6 +432,29 @@ icon_state = "jdonut1" extra_reagent = "cherryjelly" +////////////////////// +// Pancakes // +////////////////////// + +/obj/item/reagent_containers/food/snacks/pancake + name = "pancake" + desc = "A plain pancake." + icon_state = "pancake" + filling_color = "#E7D8AB" + bitesize = 2 + list_reagents = list("nutriment" = 3, "sugar" = 3) + +/obj/item/reagent_containers/food/snacks/pancake/berry_pancake + name = "berry pancake" + desc = "A pancake loaded with berries." + icon_state = "berry_pancake" + list_reagents = list("nutriment" = 3, "sugar" = 3, "berryjuice" = 3) + +/obj/item/reagent_containers/food/snacks/pancake/choc_chip_pancake + name = "choc-chip pancake" + desc = "A pancake loaded with chocolate chips." + icon_state = "choc_chip_pancake" + list_reagents = list("nutriment" = 3, "sugar" = 3, "cocoa" = 3) ////////////////////// // Misc // diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index db078675db1..f65b78f3ca2 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -234,7 +234,7 @@ return if(UserOverride) - msg_admin_attack("[key_name_admin(occupant)] was gibbed by an autogibber (\the [src]) [ADMIN_JMP(src)]") + add_attack_logs(user, occupant, "gibbed by an autogibber ([src])") log_game("[key_name(occupant)] was gibbed by an autogibber ([src]) (X:[x] Y:[y] Z:[z])") if(operating) diff --git a/code/modules/food_and_drinks/recipes/recipes_grill.dm b/code/modules/food_and_drinks/recipes/recipes_grill.dm index 047b3968176..73b181b8bbb 100644 --- a/code/modules/food_and_drinks/recipes/recipes_grill.dm +++ b/code/modules/food_and_drinks/recipes/recipes_grill.dm @@ -249,3 +249,23 @@ /obj/item/stack/rods, ) result = /obj/item/reagent_containers/food/snacks/fish_skewer + +/datum/recipe/grill/pancake + items = list( + /obj/item/reagent_containers/food/snacks/cookiedough + ) + result = /obj/item/reagent_containers/food/snacks/pancake + +/datum/recipe/grill/berry_pancake + items = list( + /obj/item/reagent_containers/food/snacks/cookiedough, + /obj/item/reagent_containers/food/snacks/grown/berries + ) + result = /obj/item/reagent_containers/food/snacks/pancake/berry_pancake + +/datum/recipe/grill/choc_chip_pancake + items = list( + /obj/item/reagent_containers/food/snacks/cookiedough, + /obj/item/reagent_containers/food/snacks/choc_pile + ) + result = /obj/item/reagent_containers/food/snacks/pancake/choc_chip_pancake diff --git a/code/modules/hydroponics/grown/citrus.dm b/code/modules/hydroponics/grown/citrus.dm index 6e937f45c2a..911b8eae866 100644 --- a/code/modules/hydroponics/grown/citrus.dm +++ b/code/modules/hydroponics/grown/citrus.dm @@ -116,9 +116,8 @@ /obj/item/reagent_containers/food/snacks/grown/firelemon/attack_self(mob/living/user) var/area/A = get_area(user) user.visible_message("[user] primes the [src]!", "You prime the [src]!") - var/message = "[ADMIN_LOOKUPFLW(user)] primed a combustible lemon for detonation at [A] [ADMIN_COORDJMP(user)]" investigate_log("[key_name(user)] primed a combustible lemon for detonation at [A] [COORD(user)].", INVESTIGATE_BOMB) - message_admins(message) + add_attack_logs(user, src, "primed a combustible lemon for detonation", ATKLOG_FEW) log_game("[key_name(user)] primed a combustible lemon for detonation at [A] [COORD(user)].") if(iscarbon(user)) var/mob/living/carbon/C = user 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/power/singularity/particle_accelerator/particle_control.dm b/code/modules/power/singularity/particle_accelerator/particle_control.dm index 3ad96050123..d1c7d3433fe 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_control.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_control.dm @@ -235,6 +235,7 @@ investigate_log("turned [active?"ON":"OFF"] by [usr ? usr.key : "outside forces"]","singulo") if(active) msg_admin_attack("PA Control Computer turned ON by [key_name_admin(usr)]", ATKLOG_FEW) + usr.create_log(MISC_LOG, "PA Control Computer turned ON", src) log_game("PA Control Computer turned ON by [key_name(usr)] in ([x],[y],[z])") use_log += text("\[[time_stamp()]\] [key_name(usr)] has turned on the PA Control Computer.") if(active) 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/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 8826efa5eb8..919f388c383 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -57,7 +57,7 @@ var/attack_log_type = ATKLOG_MOST if(reagents.has_reagent("sacid") || reagents.has_reagent("facid") || reagents.has_reagent("lube")) attack_log_type = ATKLOG_FEW - msg_admin_attack("[key_name_admin(user)] used a spray bottle at [COORD(user)] - Contents: [contents_log] - Temperature: [reagents.chem_temp]K", attack_log_type) + add_attack_logs(user, A, "sprayed [contents_log] at [reagents.chem_temp]K using [src]", attack_log_type) log_game("[key_name(user)] used a spray bottle at [COORD(user)] - Contents: [contents_log] - Temperature: [reagents.chem_temp]K") return diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 48c35415387..541945f0eb1 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -84,17 +84,15 @@ ..() if(!QDELETED(src)) //wasn't deleted by the projectile's effects. if(!P.nodamage && ((P.damage_type == BURN) || (P.damage_type == BRUTE))) - message_admins("[key_name_admin(P.firer)] triggered a fueltank explosion with [P.name] at [COORD(loc)] ") - add_attack_logs(P.firer, src, "shot with [P.name]") + add_attack_logs(P.firer, src, "shot with [P.name]", ATKLOG_FEW) log_game("[key_name(P.firer)] triggered a fueltank explosion with [P.name] at [COORD(loc)]") investigate_log("[key_name(P.firer)] triggered a fueltank explosion with [P.name] at [COORD(loc)]", INVESTIGATE_BOMB) boom() /obj/structure/reagent_dispensers/fueltank/boom(rigtrigger = FALSE, log_attack = FALSE) // Prevent case where someone who rigged the tank is blamed for the explosion when the rig isn't what triggered the explosion if(rigtrigger) // If the explosion is triggered by an assembly holder - message_admins("A fueltank, last rigged by [lastrigger], was triggered at [COORD(loc)]") // Then admin is informed of the last person who rigged the fuel tank log_game("A fueltank, last rigged by [lastrigger], triggered at [COORD(loc)]") - add_attack_logs(lastrigger, src, "rigged fuel tank exploded") + add_attack_logs(lastrigger, src, "rigged fuel tank exploded", ATKLOG_FEW) investigate_log("A fueltank, last rigged by [lastrigger], triggered at [COORD(loc)]", INVESTIGATE_BOMB) if(log_attack) add_attack_logs(usr, src, "blew up", ATKLOG_FEW) @@ -142,9 +140,8 @@ var/obj/item/assembly_holder/H = I if(istype(H.a_left, /obj/item/assembly/igniter) || istype(H.a_right, /obj/item/assembly/igniter)) - msg_admin_attack("[key_name_admin(user)] rigged [src.name] with [I.name] for explosion (JMP)", ATKLOG_FEW) log_game("[key_name(user)] rigged [src.name] with [I.name] for explosion at [COORD(loc)]") - add_attack_logs(user, src, "rigged fuel tank") + add_attack_logs(user, src, "rigged fuel tank with [I.name] for explosion", ATKLOG_FEW) investigate_log("[key_name(user)] rigged [src.name] with [I.name] for explosion at [COORD(loc)]", INVESTIGATE_BOMB) lastrigger = "[key_name(user)]" 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/atmos/vent_scrubber.dmi b/icons/atmos/vent_scrubber.dmi index c6b6d6ccfe4..a062bc4675a 100644 Binary files a/icons/atmos/vent_scrubber.dmi and b/icons/atmos/vent_scrubber.dmi differ diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index e55b06fe8f1..a0fc829a922 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/corgi_head.dmi b/icons/mob/corgi_head.dmi index df2f3a66d84..b80d695a090 100644 Binary files a/icons/mob/corgi_head.dmi and b/icons/mob/corgi_head.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index 1bd516110e5..923dcf0200c 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/human_races/r_skeleton.dmi b/icons/mob/human_races/r_skeleton.dmi index a350c3f4c4d..6f98807254b 100644 Binary files a/icons/mob/human_races/r_skeleton.dmi and b/icons/mob/human_races/r_skeleton.dmi 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/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index b2f1bfa90c6..bcecfe6d17e 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index a7772c3ebf4..e5b44069320 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/robots.dmi b/icons/mob/robots.dmi index dcbce35fb27..738fb1e0933 100644 Binary files a/icons/mob/robots.dmi and b/icons/mob/robots.dmi differ diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi index c0501f9bb36..fb4063c1bf4 100644 Binary files a/icons/obj/clothing/glasses.dmi and b/icons/obj/clothing/glasses.dmi differ diff --git a/icons/obj/custom_items.dmi b/icons/obj/custom_items.dmi index 2b1c7edfa58..0cf67d92ef9 100644 Binary files a/icons/obj/custom_items.dmi and b/icons/obj/custom_items.dmi differ diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi index 303ae139574..ba64299a052 100644 Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ diff --git a/nano/templates/atmos_filter.tmpl b/nano/templates/atmos_filter.tmpl deleted file mode 100644 index e0715e243c5..00000000000 --- a/nano/templates/atmos_filter.tmpl +++ /dev/null @@ -1,24 +0,0 @@ -