diff --git a/.travis.yml b/.travis.yml index fc1c93b83c..5a3b08a14a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ sudo: false env: global: - BYOND_MAJOR="512" - - BYOND_MINOR="1403" + - BYOND_MINOR="1411" - MACRO_COUNT=4 matrix: - TEST_DEFINE="MAP_TEST" TEST_FILE="code/_map_tests.dm" RUN="0" diff --git a/code/ATMOSPHERICS/pipes.dm b/code/ATMOSPHERICS/pipes.dm deleted file mode 100644 index 9f025138a1..0000000000 --- a/code/ATMOSPHERICS/pipes.dm +++ /dev/null @@ -1,1353 +0,0 @@ -// -// Base type of pipes -// -/obj/machinery/atmospherics/pipe - - var/datum/gas_mixture/air_temporary // used when reconstructing a pipeline that broke - var/datum/pipeline/parent - var/volume = 0 - - layer = 2.4 //under wires with their 2.44 - use_power = 0 - - var/alert_pressure = 80*ONE_ATMOSPHERE - //minimum pressure before check_pressure(...) should be called - - can_buckle = 1 - buckle_require_restraints = 1 - buckle_lying = -1 - -/obj/machinery/atmospherics/pipe/drain_power() - return -1 - -/obj/machinery/atmospherics/pipe/New() - if(istype(get_turf(src), /turf/simulated/wall) || istype(get_turf(src), /turf/simulated/shuttle/wall) || istype(get_turf(src), /turf/unsimulated/wall)) - level = 1 - ..() - -/obj/machinery/atmospherics/pipe/hides_under_flooring() - return level != 2 - -/obj/machinery/atmospherics/pipe/proc/pipeline_expansion() - return null - -/obj/machinery/atmospherics/pipe/proc/check_pressure(pressure) - //Return 1 if parent should continue checking other pipes - //Return null if parent should stop checking other pipes. Recall: qdel(src) will by default return null - - return 1 - -/obj/machinery/atmospherics/pipe/return_air() - if(!parent) - parent = new /datum/pipeline() - parent.build_pipeline(src) - - return parent.air - -/obj/machinery/atmospherics/pipe/build_network() - if(!parent) - parent = new /datum/pipeline() - parent.build_pipeline(src) - - return parent.return_network() - -/obj/machinery/atmospherics/pipe/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) - if(!parent) - parent = new /datum/pipeline() - parent.build_pipeline(src) - - return parent.network_expand(new_network, reference) - -/obj/machinery/atmospherics/pipe/return_network(obj/machinery/atmospherics/reference) - if(!parent) - parent = new /datum/pipeline() - parent.build_pipeline(src) - - return parent.return_network(reference) - -/obj/machinery/atmospherics/pipe/Destroy() - qdel_null(parent) - if(air_temporary) - loc.assume_air(air_temporary) - - . = ..() - -/obj/machinery/atmospherics/pipe/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) - if (istype(src, /obj/machinery/atmospherics/pipe/tank)) - return ..() - - if(istype(W,/obj/item/device/pipe_painter)) - return 0 - - if (!istype(W, /obj/item/weapon/wrench)) - return ..() - var/turf/T = src.loc - if (level==1 && isturf(T) && !T.is_plating()) - to_chat(user, "You must remove the plating first.") - return 1 - if(!can_unwrench()) - to_chat(user, "You cannot unwrench \the [src], it is too exerted due to internal pressure.") - add_fingerprint(user) - return 1 - playsound(src, W.usesound, 50, 1) - to_chat(user, "You begin to unfasten \the [src]...") - if (do_after(user, 40 * W.toolspeed)) - user.visible_message( \ - "\The [user] unfastens \the [src].", \ - "You have unfastened \the [src].", \ - "You hear a ratchet.") - new /obj/item/pipe(loc, make_from=src) - for (var/obj/machinery/meter/meter in T) - if (meter.target == src) - new /obj/item/pipe_meter(T) - qdel(meter) - qdel(src) - -/obj/machinery/atmospherics/pipe/proc/change_color(var/new_color) - //only pass valid pipe colors please ~otherwise your pipe will turn invisible - if(!pipe_color_check(new_color)) - return - - pipe_color = new_color - update_icon() - -/obj/machinery/atmospherics/pipe/color_cache_name(var/obj/machinery/atmospherics/node) - if(istype(src, /obj/machinery/atmospherics/pipe/tank)) - return ..() - - if(istype(node, /obj/machinery/atmospherics/pipe/manifold) || istype(node, /obj/machinery/atmospherics/pipe/manifold4w)) - if(pipe_color == node.pipe_color) - return node.pipe_color - else - return null - else if(istype(node, /obj/machinery/atmospherics/pipe/simple)) - return node.pipe_color - else - return pipe_color - -/obj/machinery/atmospherics/pipe/hide(var/i) - if(istype(loc, /turf/simulated)) - invisibility = i ? 101 : 0 - update_icon() - -/obj/machinery/atmospherics/pipe/process() - if(!parent) //This should cut back on the overhead calling build_network thousands of times per cycle - ..() - else - . = PROCESS_KILL - -// -// Simple Pipes - Just a tube, maybe bent -// -/obj/machinery/atmospherics/pipe/simple - icon = 'icons/atmos/pipes.dmi' - icon_state = "" - var/pipe_icon = "" //what kind of pipe it is and from which dmi is the icon manager getting its icons, "" for simple pipes, "hepipe" for HE pipes, "hejunction" for HE junctions - name = "pipe" - desc = "A one meter section of regular pipe" - - volume = ATMOS_DEFAULT_VOLUME_PIPE - - dir = SOUTH - initialize_directions = SOUTH|NORTH - - var/minimum_temperature_difference = 300 - var/thermal_conductivity = 0 //WALL_HEAT_TRANSFER_COEFFICIENT No - - var/maximum_pressure = 70*ONE_ATMOSPHERE - var/fatigue_pressure = 55*ONE_ATMOSPHERE - alert_pressure = 55*ONE_ATMOSPHERE - - level = 1 - -/obj/machinery/atmospherics/pipe/simple/New() - ..() - - // Pipe colors and icon states are handled by an image cache - so color and icon should - // be null. For mapping purposes color is defined in the object definitions. - icon = null - alpha = 255 - -/obj/machinery/atmospherics/pipe/simple/check_pressure(pressure) - var/datum/gas_mixture/environment = loc.return_air() - - var/pressure_difference = pressure - environment.return_pressure() - - if(pressure_difference > maximum_pressure) - burst() - - else if(pressure_difference > fatigue_pressure) - //TODO: leak to turf, doing pfshhhhh - if(prob(5)) - burst() - - else return 1 - -/obj/machinery/atmospherics/pipe/simple/init_dir() - switch(dir) - if(SOUTH || NORTH) - initialize_directions = SOUTH|NORTH - if(EAST || WEST) - initialize_directions = EAST|WEST - if(NORTHEAST) - initialize_directions = NORTH|EAST - if(NORTHWEST) - initialize_directions = NORTH|WEST - if(SOUTHEAST) - initialize_directions = SOUTH|EAST - if(SOUTHWEST) - initialize_directions = SOUTH|WEST - -/obj/machinery/atmospherics/pipe/simple/proc/burst() - src.visible_message("\The [src] bursts!"); - playsound(src.loc, 'sound/effects/bang.ogg', 25, 1) - var/datum/effect/effect/system/smoke_spread/smoke = new - smoke.set_up(1,0, src.loc, 0) - smoke.start() - qdel(src) - -/obj/machinery/atmospherics/pipe/simple/proc/normalize_dir() - if(dir==3) - set_dir(1) - else if(dir==12) - set_dir(4) - -/obj/machinery/atmospherics/pipe/simple/Destroy() - if(node1) - node1.disconnect(src) - node1 = null - if(node2) - node2.disconnect(src) - node1 = null - - . = ..() - -/obj/machinery/atmospherics/pipe/simple/pipeline_expansion() - return list(node1, node2) - -/obj/machinery/atmospherics/pipe/simple/change_color(var/new_color) - ..() - //for updating connected atmos device pipes (i.e. vents, manifolds, etc) - if(node1) - node1.update_underlays() - if(node2) - node2.update_underlays() - -/obj/machinery/atmospherics/pipe/simple/update_icon(var/safety = 0) - if(!check_icon_cache()) - return - - alpha = 255 - - overlays.Cut() - - if(node1 && node2) - overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "[pipe_icon]intact[icon_connect_type]") - else - overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "[pipe_icon]exposed[node1?1:0][node2?1:0][icon_connect_type]") - -/obj/machinery/atmospherics/pipe/simple/update_underlays() - return - -/obj/machinery/atmospherics/pipe/simple/atmos_init() - normalize_dir() - var/node1_dir - var/node2_dir - - for(var/direction in cardinal) - if(direction&initialize_directions) - if (!node1_dir) - node1_dir = direction - else if (!node2_dir) - node2_dir = direction - - for(var/obj/machinery/atmospherics/target in get_step(src,node1_dir)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node1 = target - break - for(var/obj/machinery/atmospherics/target in get_step(src,node2_dir)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node2 = target - break - - if(!node1 && !node2) - qdel(src) - return - - var/turf/T = loc - if(level == 1 && !T.is_plating()) hide(1) - update_icon() - -/obj/machinery/atmospherics/pipe/simple/disconnect(obj/machinery/atmospherics/reference) - if(reference == node1) - if(istype(node1, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node1 = null - - if(reference == node2) - if(istype(node2, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node2 = null - - update_icon() - - return null - -/obj/machinery/atmospherics/pipe/simple/visible - icon_state = "intact" - level = 2 - -/obj/machinery/atmospherics/pipe/simple/visible/scrubbers - name = "Scrubbers pipe" - desc = "A one meter section of scrubbers pipe" - icon_state = "intact-scrubbers" - connect_types = CONNECT_TYPE_SCRUBBER - layer = 2.38 - icon_connect_type = "-scrubbers" - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/simple/visible/supply - name = "Air supply pipe" - desc = "A one meter section of supply pipe" - icon_state = "intact-supply" - connect_types = CONNECT_TYPE_SUPPLY - layer = 2.39 - icon_connect_type = "-supply" - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/simple/visible/yellow - color = PIPE_COLOR_YELLOW - -/obj/machinery/atmospherics/pipe/simple/visible/cyan - color = PIPE_COLOR_CYAN - -/obj/machinery/atmospherics/pipe/simple/visible/green - color = PIPE_COLOR_GREEN - -/obj/machinery/atmospherics/pipe/simple/visible/black - color = PIPE_COLOR_BLACK - -/obj/machinery/atmospherics/pipe/simple/visible/red - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/simple/visible/blue - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/simple/visible/purple - color = PIPE_COLOR_PURPLE - -/obj/machinery/atmospherics/pipe/simple/hidden - icon_state = "intact" - level = 1 - alpha = 128 //set for the benefit of mapping - this is reset to opaque when the pipe is spawned in game - -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers - name = "Scrubbers pipe" - desc = "A one meter section of scrubbers pipe" - icon_state = "intact-scrubbers" - connect_types = CONNECT_TYPE_SCRUBBER - layer = 2.38 - icon_connect_type = "-scrubbers" - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/simple/hidden/supply - name = "Air supply pipe" - desc = "A one meter section of supply pipe" - icon_state = "intact-supply" - connect_types = CONNECT_TYPE_SUPPLY - layer = 2.39 - icon_connect_type = "-supply" - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/simple/hidden/yellow - color = PIPE_COLOR_YELLOW - -/obj/machinery/atmospherics/pipe/simple/hidden/cyan - color = PIPE_COLOR_CYAN - -/obj/machinery/atmospherics/pipe/simple/hidden/green - color = PIPE_COLOR_GREEN - -/obj/machinery/atmospherics/pipe/simple/hidden/black - color = PIPE_COLOR_BLACK - -/obj/machinery/atmospherics/pipe/simple/hidden/red - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/simple/hidden/blue - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/simple/hidden/purple - color = PIPE_COLOR_PURPLE - -/obj/machinery/atmospherics/pipe/simple/insulated - icon = 'icons/obj/atmospherics/red_pipe.dmi' - icon_state = "intact" - - minimum_temperature_difference = 10000 - thermal_conductivity = 0 - maximum_pressure = 1000*ONE_ATMOSPHERE - fatigue_pressure = 900*ONE_ATMOSPHERE - alert_pressure = 900*ONE_ATMOSPHERE - - level = 2 - -// -// Manifold Pipes - Three way "T" joints -// -/obj/machinery/atmospherics/pipe/manifold - icon = 'icons/atmos/manifold.dmi' - icon_state = "" - name = "pipe manifold" - desc = "A manifold composed of regular pipes" - - volume = ATMOS_DEFAULT_VOLUME_PIPE * 1.5 - - dir = SOUTH - initialize_directions = EAST|NORTH|WEST - - var/obj/machinery/atmospherics/node3 - - level = 1 - layer = 2.4 //under wires with their 2.44 - -/obj/machinery/atmospherics/pipe/manifold/New() - ..() - alpha = 255 - icon = null - -/obj/machinery/atmospherics/pipe/manifold/init_dir() - switch(dir) - if(NORTH) - initialize_directions = EAST|SOUTH|WEST - if(SOUTH) - initialize_directions = WEST|NORTH|EAST - if(EAST) - initialize_directions = SOUTH|WEST|NORTH - if(WEST) - initialize_directions = NORTH|EAST|SOUTH - -/obj/machinery/atmospherics/pipe/manifold/pipeline_expansion() - return list(node1, node2, node3) - -/obj/machinery/atmospherics/pipe/manifold/Destroy() - if(node1) - node1.disconnect(src) - node1 = null - if(node2) - node2.disconnect(src) - node2 = null - if(node3) - node3.disconnect(src) - node3 = null - - . = ..() - -/obj/machinery/atmospherics/pipe/manifold/disconnect(obj/machinery/atmospherics/reference) - if(reference == node1) - if(istype(node1, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node1 = null - - if(reference == node2) - if(istype(node2, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node2 = null - - if(reference == node3) - if(istype(node3, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node3 = null - - update_icon() - - ..() - -/obj/machinery/atmospherics/pipe/manifold/change_color(var/new_color) - ..() - //for updating connected atmos device pipes (i.e. vents, manifolds, etc) - if(node1) - node1.update_underlays() - if(node2) - node2.update_underlays() - if(node3) - node3.update_underlays() - -/obj/machinery/atmospherics/pipe/manifold/update_icon(var/safety = 0) - if(!check_icon_cache()) - return - - alpha = 255 - - overlays.Cut() - overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "core" + icon_connect_type) - overlays += icon_manager.get_atmos_icon("manifold", , , "clamps" + icon_connect_type) - underlays.Cut() - - var/turf/T = get_turf(src) - var/list/directions = list(NORTH, SOUTH, EAST, WEST) - var/node1_direction = get_dir(src, node1) - var/node2_direction = get_dir(src, node2) - var/node3_direction = get_dir(src, node3) - - directions -= dir - - directions -= add_underlay(T,node1,node1_direction,icon_connect_type) - directions -= add_underlay(T,node2,node2_direction,icon_connect_type) - directions -= add_underlay(T,node3,node3_direction,icon_connect_type) - - for(var/D in directions) - add_underlay(T,,D,icon_connect_type) - - -/obj/machinery/atmospherics/pipe/manifold/update_underlays() - ..() - update_icon() - -/obj/machinery/atmospherics/pipe/manifold/atmos_init() - var/connect_directions = (NORTH|SOUTH|EAST|WEST)&(~dir) - - for(var/direction in cardinal) - if(direction&connect_directions) - for(var/obj/machinery/atmospherics/target in get_step(src,direction)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node1 = target - connect_directions &= ~direction - break - if (node1) - break - - - for(var/direction in cardinal) - if(direction&connect_directions) - for(var/obj/machinery/atmospherics/target in get_step(src,direction)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node2 = target - connect_directions &= ~direction - break - if (node2) - break - - - for(var/direction in cardinal) - if(direction&connect_directions) - for(var/obj/machinery/atmospherics/target in get_step(src,direction)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node3 = target - connect_directions &= ~direction - break - if (node3) - break - - if(!node1 && !node2 && !node3) - qdel(src) - return - - var/turf/T = get_turf(src) - if(level == 1 && !T.is_plating()) hide(1) - update_icon() - -/obj/machinery/atmospherics/pipe/manifold/visible - icon_state = "map" - level = 2 - -/obj/machinery/atmospherics/pipe/manifold/visible/scrubbers - name="Scrubbers pipe manifold" - desc = "A manifold composed of scrubbers pipes" - icon_state = "map-scrubbers" - connect_types = CONNECT_TYPE_SCRUBBER - layer = 2.38 - icon_connect_type = "-scrubbers" - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/manifold/visible/supply - name="Air supply pipe manifold" - desc = "A manifold composed of supply pipes" - icon_state = "map-supply" - connect_types = CONNECT_TYPE_SUPPLY - layer = 2.39 - icon_connect_type = "-supply" - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/manifold/visible/yellow - color = PIPE_COLOR_YELLOW - -/obj/machinery/atmospherics/pipe/manifold/visible/cyan - color = PIPE_COLOR_CYAN - -/obj/machinery/atmospherics/pipe/manifold/visible/green - color = PIPE_COLOR_GREEN - -/obj/machinery/atmospherics/pipe/manifold/visible/black - color = PIPE_COLOR_BLACK - -/obj/machinery/atmospherics/pipe/manifold/visible/red - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/manifold/visible/blue - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/manifold/visible/purple - color = PIPE_COLOR_PURPLE - -/obj/machinery/atmospherics/pipe/manifold/hidden - icon_state = "map" - level = 1 - alpha = 128 //set for the benefit of mapping - this is reset to opaque when the pipe is spawned in game - -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers - name="Scrubbers pipe manifold" - desc = "A manifold composed of scrubbers pipes" - icon_state = "map-scrubbers" - connect_types = CONNECT_TYPE_SCRUBBER - layer = 2.38 - icon_connect_type = "-scrubbers" - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/manifold/hidden/supply - name="Air supply pipe manifold" - desc = "A manifold composed of supply pipes" - icon_state = "map-supply" - connect_types = CONNECT_TYPE_SUPPLY - layer = 2.39 - icon_connect_type = "-supply" - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/manifold/hidden/yellow - color = PIPE_COLOR_YELLOW - -/obj/machinery/atmospherics/pipe/manifold/hidden/cyan - color = PIPE_COLOR_CYAN - -/obj/machinery/atmospherics/pipe/manifold/hidden/green - color = PIPE_COLOR_GREEN - -/obj/machinery/atmospherics/pipe/manifold/hidden/black - color = PIPE_COLOR_BLACK - -/obj/machinery/atmospherics/pipe/manifold/hidden/red - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/manifold/hidden/blue - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/manifold/hidden/purple - color = PIPE_COLOR_PURPLE - - -// -// 4-Way Manifold Pipes - 4 way "cross" junction -// -/obj/machinery/atmospherics/pipe/manifold4w - icon = 'icons/atmos/manifold.dmi' - icon_state = "" - name = "4-way pipe manifold" - desc = "A manifold composed of regular pipes" - - volume = ATMOS_DEFAULT_VOLUME_PIPE * 2 - - dir = SOUTH - initialize_directions = NORTH|SOUTH|EAST|WEST - - var/obj/machinery/atmospherics/node3 - var/obj/machinery/atmospherics/node4 - - level = 1 - layer = 2.4 //under wires with their 2.44 - -/obj/machinery/atmospherics/pipe/manifold4w/New() - ..() - alpha = 255 - icon = null - -/obj/machinery/atmospherics/pipe/manifold4w/pipeline_expansion() - return list(node1, node2, node3, node4) - -/obj/machinery/atmospherics/pipe/manifold4w/Destroy() - if(node1) - node1.disconnect(src) - node1 = null - if(node2) - node2.disconnect(src) - node2 = null - if(node3) - node3.disconnect(src) - node3 = null - if(node4) - node4.disconnect(src) - node4 = null - - . = ..() - -/obj/machinery/atmospherics/pipe/manifold4w/disconnect(obj/machinery/atmospherics/reference) - if(reference == node1) - if(istype(node1, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node1 = null - - if(reference == node2) - if(istype(node2, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node2 = null - - if(reference == node3) - if(istype(node3, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node3 = null - - if(reference == node4) - if(istype(node4, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node4 = null - - update_icon() - - ..() - -/obj/machinery/atmospherics/pipe/manifold4w/change_color(var/new_color) - ..() - //for updating connected atmos device pipes (i.e. vents, manifolds, etc) - if(node1) - node1.update_underlays() - if(node2) - node2.update_underlays() - if(node3) - node3.update_underlays() - if(node4) - node4.update_underlays() - -/obj/machinery/atmospherics/pipe/manifold4w/update_icon(var/safety = 0) - if(!check_icon_cache()) - return - - alpha = 255 - - overlays.Cut() - overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "4way" + icon_connect_type) - overlays += icon_manager.get_atmos_icon("manifold", , , "clamps_4way" + icon_connect_type) - underlays.Cut() - - /* - var/list/directions = list(NORTH, SOUTH, EAST, WEST) - - - directions -= add_underlay(node1) - directions -= add_underlay(node2) - directions -= add_underlay(node3) - directions -= add_underlay(node4) - - for(var/D in directions) - add_underlay(,D) - */ - - var/turf/T = get_turf(src) - var/list/directions = list(NORTH, SOUTH, EAST, WEST) - var/node1_direction = get_dir(src, node1) - var/node2_direction = get_dir(src, node2) - var/node3_direction = get_dir(src, node3) - var/node4_direction = get_dir(src, node4) - - directions -= dir - - directions -= add_underlay(T,node1,node1_direction,icon_connect_type) - directions -= add_underlay(T,node2,node2_direction,icon_connect_type) - directions -= add_underlay(T,node3,node3_direction,icon_connect_type) - directions -= add_underlay(T,node4,node4_direction,icon_connect_type) - - for(var/D in directions) - add_underlay(T,,D,icon_connect_type) - - -/obj/machinery/atmospherics/pipe/manifold4w/update_underlays() - ..() - update_icon() - -/obj/machinery/atmospherics/pipe/manifold4w/atmos_init() - - for(var/obj/machinery/atmospherics/target in get_step(src,1)) - if(target.initialize_directions & 2) - if (check_connect_types(target,src)) - node1 = target - break - - for(var/obj/machinery/atmospherics/target in get_step(src,2)) - if(target.initialize_directions & 1) - if (check_connect_types(target,src)) - node2 = target - break - - for(var/obj/machinery/atmospherics/target in get_step(src,4)) - if(target.initialize_directions & 8) - if (check_connect_types(target,src)) - node3 = target - break - - for(var/obj/machinery/atmospherics/target in get_step(src,8)) - if(target.initialize_directions & 4) - if (check_connect_types(target,src)) - node4 = target - break - - if(!node1 && !node2 && !node3 && !node4) - qdel(src) - return - - var/turf/T = get_turf(src) - if(level == 1 && !T.is_plating()) hide(1) - update_icon() - -/obj/machinery/atmospherics/pipe/manifold4w/visible - icon_state = "map_4way" - level = 2 - -/obj/machinery/atmospherics/pipe/manifold4w/visible/scrubbers - name="4-way scrubbers pipe manifold" - desc = "A manifold composed of scrubbers pipes" - icon_state = "map_4way-scrubbers" - connect_types = CONNECT_TYPE_SCRUBBER - layer = 2.38 - icon_connect_type = "-scrubbers" - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/manifold4w/visible/supply - name="4-way air supply pipe manifold" - desc = "A manifold composed of supply pipes" - icon_state = "map_4way-supply" - connect_types = CONNECT_TYPE_SUPPLY - layer = 2.39 - icon_connect_type = "-supply" - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/manifold4w/visible/yellow - color = PIPE_COLOR_YELLOW - -/obj/machinery/atmospherics/pipe/manifold4w/visible/cyan - color = PIPE_COLOR_CYAN - -/obj/machinery/atmospherics/pipe/manifold4w/visible/green - color = PIPE_COLOR_GREEN - -/obj/machinery/atmospherics/pipe/manifold4w/visible/black - color = PIPE_COLOR_BLACK - -/obj/machinery/atmospherics/pipe/manifold4w/visible/red - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/manifold4w/visible/blue - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/manifold4w/visible/purple - color = PIPE_COLOR_PURPLE - -/obj/machinery/atmospherics/pipe/manifold4w/hidden - icon_state = "map_4way" - level = 1 - alpha = 128 //set for the benefit of mapping - this is reset to opaque when the pipe is spawned in game - -/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers - name="4-way scrubbers pipe manifold" - desc = "A manifold composed of scrubbers pipes" - icon_state = "map_4way-scrubbers" - connect_types = CONNECT_TYPE_SCRUBBER - layer = 2.38 - icon_connect_type = "-scrubbers" - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply - name="4-way air supply pipe manifold" - desc = "A manifold composed of supply pipes" - icon_state = "map_4way-supply" - connect_types = CONNECT_TYPE_SUPPLY - layer = 2.39 - icon_connect_type = "-supply" - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/manifold4w/hidden/yellow - color = PIPE_COLOR_YELLOW - -/obj/machinery/atmospherics/pipe/manifold4w/hidden/cyan - color = PIPE_COLOR_CYAN - -/obj/machinery/atmospherics/pipe/manifold4w/hidden/green - color = PIPE_COLOR_GREEN - -/obj/machinery/atmospherics/pipe/manifold4w/hidden/black - color = PIPE_COLOR_BLACK - -/obj/machinery/atmospherics/pipe/manifold4w/hidden/red - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/manifold4w/hidden/blue - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/manifold4w/hidden/purple - color = PIPE_COLOR_PURPLE - -// -// Pipe Cap - They go on the end -// -/obj/machinery/atmospherics/pipe/cap - name = "pipe endcap" - desc = "An endcap for pipes" - icon = 'icons/atmos/pipes.dmi' - icon_state = "" - level = 2 - layer = 2.4 //under wires with their 2.44 - - volume = 35 - - dir = SOUTH - initialize_directions = SOUTH - - var/obj/machinery/atmospherics/node - -/obj/machinery/atmospherics/pipe/cap/init_dir() - initialize_directions = dir - -/obj/machinery/atmospherics/pipe/cap/pipeline_expansion() - return list(node) - -/obj/machinery/atmospherics/pipe/cap/Destroy() - if(node) - node.disconnect(src) - node = null - - . = ..() - -/obj/machinery/atmospherics/pipe/cap/disconnect(obj/machinery/atmospherics/reference) - if(reference == node) - if(istype(node, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node = null - - update_icon() - - ..() - -/obj/machinery/atmospherics/pipe/cap/change_color(var/new_color) - ..() - //for updating connected atmos device pipes (i.e. vents, manifolds, etc) - if(node) - node.update_underlays() - -/obj/machinery/atmospherics/pipe/cap/update_icon(var/safety = 0) - if(!check_icon_cache()) - return - - alpha = 255 - - overlays.Cut() - overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "cap") - -/obj/machinery/atmospherics/pipe/cap/atmos_init() - for(var/obj/machinery/atmospherics/target in get_step(src, dir)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node = target - break - - var/turf/T = src.loc // hide if turf is not intact - if(level == 1 && !T.is_plating()) hide(1) - update_icon() - -/obj/machinery/atmospherics/pipe/cap/can_unwrench() - return 1 - -/obj/machinery/atmospherics/pipe/cap/visible - level = 2 - icon_state = "cap" - -/obj/machinery/atmospherics/pipe/cap/visible/scrubbers - name = "scrubbers pipe endcap" - desc = "An endcap for scrubbers pipes" - icon_state = "cap-scrubbers" - connect_types = CONNECT_TYPE_SCRUBBER - layer = 2.38 - icon_connect_type = "-scrubbers" - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/cap/visible/supply - name = "supply pipe endcap" - desc = "An endcap for supply pipes" - icon_state = "cap-supply" - connect_types = CONNECT_TYPE_SUPPLY - layer = 2.39 - icon_connect_type = "-supply" - color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/cap/hidden - level = 1 - icon_state = "cap" - alpha = 128 - -/obj/machinery/atmospherics/pipe/cap/hidden/scrubbers - name = "scrubbers pipe endcap" - desc = "An endcap for scrubbers pipes" - icon_state = "cap-f-scrubbers" - connect_types = CONNECT_TYPE_SCRUBBER - layer = 2.38 - icon_connect_type = "-scrubbers" - color = PIPE_COLOR_RED - -/obj/machinery/atmospherics/pipe/cap/hidden/supply - name = "supply pipe endcap" - desc = "An endcap for supply pipes" - icon_state = "cap-f-supply" - connect_types = CONNECT_TYPE_SUPPLY - layer = 2.39 - icon_connect_type = "-supply" - color = PIPE_COLOR_BLUE - -// -// Tanks - These are implemented as pipes with large volume -// -/obj/machinery/atmospherics/pipe/tank - icon = 'icons/atmos/tank_vr.dmi' //VOREStation Edit - New Icons - icon_state = "air_map" - - name = "Pressure Tank" - desc = "A large vessel containing pressurized gas." - - volume = 10000 //in liters, 1 meters by 1 meters by 2 meters ~tweaked it a little to simulate a pressure tank without needing to recode them yet - var/start_pressure = 75*ONE_ATMOSPHERE //Vorestation edit - - level = 1 - dir = SOUTH - initialize_directions = SOUTH - density = 1 - -/obj/machinery/atmospherics/pipe/tank/New() - icon_state = "air" - ..() - -/obj/machinery/atmospherics/pipe/tank/init_dir() - initialize_directions = dir - -/obj/machinery/atmospherics/pipe/tank/Destroy() - if(node1) - node1.disconnect(src) - node1 = null - - . = ..() - -/obj/machinery/atmospherics/pipe/tank/pipeline_expansion() - return list(node1) - -/obj/machinery/atmospherics/pipe/tank/update_underlays() - if(..()) - underlays.Cut() - var/turf/T = get_turf(src) - if(!istype(T)) - return - add_underlay(T, node1, dir) - -/obj/machinery/atmospherics/pipe/tank/hide() - update_underlays() - -/obj/machinery/atmospherics/pipe/tank/atmos_init() - var/connect_direction = dir - - for(var/obj/machinery/atmospherics/target in get_step(src,connect_direction)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node1 = target - break - - update_underlays() - -/obj/machinery/atmospherics/pipe/tank/disconnect(obj/machinery/atmospherics/reference) - if(reference == node1) - if(istype(node1, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node1 = null - - update_underlays() - - return null - -/obj/machinery/atmospherics/pipe/tank/attackby(var/obj/item/W as obj, var/mob/user as mob) - if(istype(W, /obj/item/device/pipe_painter)) - return - - if(istype(W, /obj/item/device/analyzer) && in_range(user, src)) - var/obj/item/device/analyzer/A = W - A.analyze_gases(src, user) - -/obj/machinery/atmospherics/pipe/tank/air - name = "Pressure Tank (Air)" - icon_state = "air_map" - -/obj/machinery/atmospherics/pipe/tank/air/New() - air_temporary = new - air_temporary.volume = volume - air_temporary.temperature = T20C - - air_temporary.adjust_multi("oxygen", (start_pressure*O2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature), \ - "nitrogen",(start_pressure*N2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) - - - ..() - icon_state = "air" - -/obj/machinery/atmospherics/pipe/tank/oxygen - name = "Pressure Tank (Oxygen)" - icon_state = "o2_map" - -/obj/machinery/atmospherics/pipe/tank/oxygen/New() - air_temporary = new - air_temporary.volume = volume - air_temporary.temperature = T20C - - air_temporary.adjust_gas("oxygen", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) - - ..() - icon_state = "o2" - -/obj/machinery/atmospherics/pipe/tank/nitrogen - name = "Pressure Tank (Nitrogen)" - icon_state = "n2_map" - volume = 40000 //Vorestation edit - -/obj/machinery/atmospherics/pipe/tank/nitrogen/New() - air_temporary = new - air_temporary.volume = volume - air_temporary.temperature = T20C - - air_temporary.adjust_gas("nitrogen", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) - - ..() - icon_state = "n2" - -/obj/machinery/atmospherics/pipe/tank/carbon_dioxide - name = "Pressure Tank (Carbon Dioxide)" - icon_state = "co2_map" - -/obj/machinery/atmospherics/pipe/tank/carbon_dioxide/New() - air_temporary = new - air_temporary.volume = volume - air_temporary.temperature = T20C - - air_temporary.adjust_gas("carbon_dioxide", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) - - ..() - icon_state = "co2" - -/obj/machinery/atmospherics/pipe/tank/phoron - name = "Pressure Tank (Phoron)" - icon_state = "phoron_map" - -/obj/machinery/atmospherics/pipe/tank/phoron/New() - air_temporary = new - air_temporary.volume = volume - air_temporary.temperature = T20C - - air_temporary.adjust_gas("phoron", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) - - ..() - icon_state = "phoron" - -/obj/machinery/atmospherics/pipe/tank/nitrous_oxide - name = "Pressure Tank (Nitrous Oxide)" - icon_state = "n2o_map" - -/obj/machinery/atmospherics/pipe/tank/nitrous_oxide/New() - air_temporary = new - air_temporary.volume = volume - air_temporary.temperature = T0C - - air_temporary.adjust_gas("sleeping_agent", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) - - ..() - icon_state = "n2o" - -// -// Vent Pipe - Unpowered vent -// -/obj/machinery/atmospherics/pipe/vent - icon = 'icons/obj/atmospherics/pipe_vent.dmi' - icon_state = "intact" - - name = "Vent" - desc = "A large air vent" - - level = 1 - - volume = 250 - - dir = SOUTH - initialize_directions = SOUTH - - var/build_killswitch = 1 - -/obj/machinery/atmospherics/pipe/vent/init_dir() - initialize_directions = dir - -/obj/machinery/atmospherics/pipe/vent/high_volume - name = "Larger vent" - volume = 1000 - -/obj/machinery/atmospherics/pipe/vent/process() - if(!parent) - if(build_killswitch <= 0) - . = PROCESS_KILL - else - build_killswitch-- - ..() - return - else - parent.mingle_with_turf(loc, volume) - -/obj/machinery/atmospherics/pipe/vent/Destroy() - if(node1) - node1.disconnect(src) - node1 = null - - . = ..() - -/obj/machinery/atmospherics/pipe/vent/pipeline_expansion() - return list(node1) - -/obj/machinery/atmospherics/pipe/vent/update_icon() - if(node1) - icon_state = "intact" - - set_dir(get_dir(src, node1)) - - else - icon_state = "exposed" - -/obj/machinery/atmospherics/pipe/vent/atmos_init() - var/connect_direction = dir - - for(var/obj/machinery/atmospherics/target in get_step(src,connect_direction)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node1 = target - break - - update_icon() - -/obj/machinery/atmospherics/pipe/vent/disconnect(obj/machinery/atmospherics/reference) - if(reference == node1) - if(istype(node1, /obj/machinery/atmospherics/pipe)) - qdel(parent) - node1 = null - - update_icon() - - return null - -/obj/machinery/atmospherics/pipe/vent/hide(var/i) //to make the little pipe section invisible, the icon changes. - if(node1) - icon_state = "[i == 1 && istype(loc, /turf/simulated) ? "h" : "" ]intact" - set_dir(get_dir(src, node1)) - else - icon_state = "exposed" - -// -// Universal Pipe Adapter - Designed for connecting scrubbers, normal, and supply pipes together. -// -/obj/machinery/atmospherics/pipe/simple/visible/universal - name="Universal pipe adapter" - desc = "An adapter for regular, supply and scrubbers pipes" - connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER - icon_state = "map_universal" - -/obj/machinery/atmospherics/pipe/simple/visible/universal/update_icon(var/safety = 0) - if(!check_icon_cache()) - return - - alpha = 255 - - overlays.Cut() - overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "universal") - underlays.Cut() - - if (node1) - universal_underlays(node1) - if(node2) - universal_underlays(node2) - else - var/node1_dir = get_dir(node1,src) - universal_underlays(,node1_dir) - else if (node2) - universal_underlays(node2) - else - universal_underlays(,dir) - universal_underlays(dir, -180) - -/obj/machinery/atmospherics/pipe/simple/visible/universal/update_underlays() - ..() - update_icon() - - - -/obj/machinery/atmospherics/pipe/simple/hidden/universal - name="Universal pipe adapter" - desc = "An adapter for regular, supply and scrubbers pipes" - connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER - icon_state = "map_universal" - -/obj/machinery/atmospherics/pipe/simple/hidden/universal/update_icon(var/safety = 0) - if(!check_icon_cache()) - return - - alpha = 255 - - overlays.Cut() - overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "universal") - underlays.Cut() - - if (node1) - universal_underlays(node1) - if(node2) - universal_underlays(node2) - else - var/node2_dir = turn(get_dir(src,node1),-180) - universal_underlays(,node2_dir) - else if (node2) - universal_underlays(node2) - var/node1_dir = turn(get_dir(src,node2),-180) - universal_underlays(,node1_dir) - else - universal_underlays(,dir) - universal_underlays(,turn(dir, -180)) - -/obj/machinery/atmospherics/pipe/simple/hidden/universal/update_underlays() - ..() - update_icon() - -/obj/machinery/atmospherics/proc/universal_underlays(var/obj/machinery/atmospherics/node, var/direction) - var/turf/T = loc - if(node) - var/node_dir = get_dir(src,node) - if(node.icon_connect_type == "-supply") - add_underlay_adapter(T, , node_dir, "") - add_underlay_adapter(T, node, node_dir, "-supply") - add_underlay_adapter(T, , node_dir, "-scrubbers") - else if (node.icon_connect_type == "-scrubbers") - add_underlay_adapter(T, , node_dir, "") - add_underlay_adapter(T, , node_dir, "-supply") - add_underlay_adapter(T, node, node_dir, "-scrubbers") - else - add_underlay_adapter(T, node, node_dir, "") - add_underlay_adapter(T, , node_dir, "-supply") - add_underlay_adapter(T, , node_dir, "-scrubbers") - else - add_underlay_adapter(T, , direction, "-supply") - add_underlay_adapter(T, , direction, "-scrubbers") - add_underlay_adapter(T, , direction, "") - -/obj/machinery/atmospherics/proc/add_underlay_adapter(var/turf/T, var/obj/machinery/atmospherics/node, var/direction, var/icon_connect_type) //modified from add_underlay, does not make exposed underlays - if(node) - if(!T.is_plating() && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe)) - underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type) - else - underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type) - else - underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "retracted" + icon_connect_type) diff --git a/code/ATMOSPHERICS/pipes/cap.dm b/code/ATMOSPHERICS/pipes/cap.dm new file mode 100644 index 0000000000..de81c60200 --- /dev/null +++ b/code/ATMOSPHERICS/pipes/cap.dm @@ -0,0 +1,114 @@ +// +// Pipe Cap - They go on the end +// +/obj/machinery/atmospherics/pipe/cap + name = "pipe endcap" + desc = "An endcap for pipes" + icon = 'icons/atmos/pipes.dmi' + icon_state = "" + level = 2 + layer = 2.4 //under wires with their 2.44 + + volume = 35 + + dir = SOUTH + initialize_directions = SOUTH + + var/obj/machinery/atmospherics/node + +/obj/machinery/atmospherics/pipe/cap/init_dir() + initialize_directions = dir + +/obj/machinery/atmospherics/pipe/cap/pipeline_expansion() + return list(node) + +/obj/machinery/atmospherics/pipe/cap/Destroy() + if(node) + node.disconnect(src) + node = null + + . = ..() + +/obj/machinery/atmospherics/pipe/cap/disconnect(obj/machinery/atmospherics/reference) + if(reference == node) + if(istype(node, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node = null + + update_icon() + + ..() + +/obj/machinery/atmospherics/pipe/cap/change_color(var/new_color) + ..() + //for updating connected atmos device pipes (i.e. vents, manifolds, etc) + if(node) + node.update_underlays() + +/obj/machinery/atmospherics/pipe/cap/update_icon(var/safety = 0) + if(!check_icon_cache()) + return + + alpha = 255 + + overlays.Cut() + overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "cap") + +/obj/machinery/atmospherics/pipe/cap/atmos_init() + for(var/obj/machinery/atmospherics/target in get_step(src, dir)) + if(target.initialize_directions & get_dir(target,src)) + if (check_connect_types(target,src)) + node = target + break + + var/turf/T = src.loc // hide if turf is not intact + if(level == 1 && !T.is_plating()) hide(1) + update_icon() + +/obj/machinery/atmospherics/pipe/cap/can_unwrench() + return 1 + +/obj/machinery/atmospherics/pipe/cap/visible + level = 2 + icon_state = "cap" + +/obj/machinery/atmospherics/pipe/cap/visible/scrubbers + name = "scrubbers pipe endcap" + desc = "An endcap for scrubbers pipes" + icon_state = "cap-scrubbers" + connect_types = CONNECT_TYPE_SCRUBBER + layer = 2.38 + icon_connect_type = "-scrubbers" + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/cap/visible/supply + name = "supply pipe endcap" + desc = "An endcap for supply pipes" + icon_state = "cap-supply" + connect_types = CONNECT_TYPE_SUPPLY + layer = 2.39 + icon_connect_type = "-supply" + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/cap/hidden + level = 1 + icon_state = "cap" + alpha = 128 + +/obj/machinery/atmospherics/pipe/cap/hidden/scrubbers + name = "scrubbers pipe endcap" + desc = "An endcap for scrubbers pipes" + icon_state = "cap-f-scrubbers" + connect_types = CONNECT_TYPE_SCRUBBER + layer = 2.38 + icon_connect_type = "-scrubbers" + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/cap/hidden/supply + name = "supply pipe endcap" + desc = "An endcap for supply pipes" + icon_state = "cap-f-supply" + connect_types = CONNECT_TYPE_SUPPLY + layer = 2.39 + icon_connect_type = "-supply" + color = PIPE_COLOR_BLUE diff --git a/code/ATMOSPHERICS/he_pipes.dm b/code/ATMOSPHERICS/pipes/he_pipes.dm similarity index 96% rename from code/ATMOSPHERICS/he_pipes.dm rename to code/ATMOSPHERICS/pipes/he_pipes.dm index bff838cfdd..8953739a9c 100644 --- a/code/ATMOSPHERICS/he_pipes.dm +++ b/code/ATMOSPHERICS/pipes/he_pipes.dm @@ -1,153 +1,155 @@ - -/obj/machinery/atmospherics/pipe/simple/heat_exchanging - icon = 'icons/atmos/heat.dmi' - icon_state = "intact" - pipe_icon = "hepipe" - color = "#404040" - level = 2 - connect_types = CONNECT_TYPE_HE - layer = 2.41 - var/initialize_directions_he - var/surface = 2 //surface area in m^2 - var/icon_temperature = T20C //stop small changes in temperature causing an icon refresh - - minimum_temperature_difference = 20 - thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT - - buckle_lying = 1 - - // BubbleWrap -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/New() - ..() -// BubbleWrap END - color = "#404040" //we don't make use of the fancy overlay system for colours, use this to set the default. - -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/init_dir() - ..() - initialize_directions_he = initialize_directions // The auto-detection from /pipe is good enough for a simple HE pipe - -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/atmos_init() - normalize_dir() - var/node1_dir - var/node2_dir - - for(var/direction in cardinal) - if(direction&initialize_directions_he) - if (!node1_dir) - node1_dir = direction - else if (!node2_dir) - node2_dir = direction - - for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,node1_dir)) - if(target.initialize_directions_he & get_dir(target,src)) - node1 = target - break - for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,node2_dir)) - if(target.initialize_directions_he & get_dir(target,src)) - node2 = target - break - if(!node1 && !node2) - qdel(src) - return - - update_icon() - return - - -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/process() - if(!parent) - ..() - else - var/datum/gas_mixture/pipe_air = return_air() - if(istype(loc, /turf/simulated/)) - var/environment_temperature = 0 - if(loc:blocks_air) - environment_temperature = loc:temperature - else - var/datum/gas_mixture/environment = loc.return_air() - environment_temperature = environment.temperature - if(abs(environment_temperature-pipe_air.temperature) > minimum_temperature_difference) - parent.temperature_interact(loc, volume, thermal_conductivity) - else if(istype(loc, /turf/space/)) - parent.radiate_heat_to_space(surface, 1) - - if(has_buckled_mobs()) - for(var/M in buckled_mobs) - var/mob/living/L = M - - var/hc = pipe_air.heat_capacity() - var/avg_temp = (pipe_air.temperature * hc + L.bodytemperature * 3500) / (hc + 3500) - pipe_air.temperature = avg_temp - L.bodytemperature = avg_temp - - var/heat_limit = 1000 - - var/mob/living/carbon/human/H = L - if(istype(H) && H.species) - heat_limit = H.species.heat_level_3 - - if(pipe_air.temperature > heat_limit + 1) - L.apply_damage(4 * log(pipe_air.temperature - heat_limit), BURN, BP_TORSO, used_weapon = "Excessive Heat") - - //fancy radiation glowing - if(pipe_air.temperature && (icon_temperature > 500 || pipe_air.temperature > 500)) //start glowing at 500K - if(abs(pipe_air.temperature - icon_temperature) > 10) - icon_temperature = pipe_air.temperature - - var/h_r = heat2color_r(icon_temperature) - var/h_g = heat2color_g(icon_temperature) - var/h_b = heat2color_b(icon_temperature) - - if(icon_temperature < 2000) //scale up overlay until 2000K - var/scale = (icon_temperature - 500) / 1500 - h_r = 64 + (h_r - 64)*scale - h_g = 64 + (h_g - 64)*scale - h_b = 64 + (h_b - 64)*scale - - animate(src, color = rgb(h_r, h_g, h_b), time = 20, easing = SINE_EASING) - - - - -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction - icon = 'icons/atmos/junction.dmi' - icon_state = "intact" - pipe_icon = "hejunction" - level = 2 - connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_HE - minimum_temperature_difference = 300 - thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT - -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/init_dir() - ..() - switch ( dir ) - if ( SOUTH ) - initialize_directions = NORTH - initialize_directions_he = SOUTH - if ( NORTH ) - initialize_directions = SOUTH - initialize_directions_he = NORTH - if ( EAST ) - initialize_directions = WEST - initialize_directions_he = EAST - if ( WEST ) - initialize_directions = EAST - initialize_directions_he = WEST - - -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/atmos_init() - for(var/obj/machinery/atmospherics/target in get_step(src,initialize_directions)) - if(target.initialize_directions & get_dir(target,src)) - node1 = target - break - for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,initialize_directions_he)) - if(target.initialize_directions_he & get_dir(target,src)) - node2 = target - break - - if(!node1&&!node2) - qdel(src) - return - - update_icon() - return +// +// Heat Exchanging Pipes - Behave like simple pipes +// +/obj/machinery/atmospherics/pipe/simple/heat_exchanging + icon = 'icons/atmos/heat.dmi' + icon_state = "intact" + pipe_icon = "hepipe" + color = "#404040" + level = 2 + connect_types = CONNECT_TYPE_HE + layer = 2.41 + var/initialize_directions_he + var/surface = 2 //surface area in m^2 + var/icon_temperature = T20C //stop small changes in temperature causing an icon refresh + + minimum_temperature_difference = 20 + thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT + + buckle_lying = 1 + + // BubbleWrap +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/New() + ..() +// BubbleWrap END + color = "#404040" //we don't make use of the fancy overlay system for colours, use this to set the default. + +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/init_dir() + ..() + initialize_directions_he = initialize_directions // The auto-detection from /pipe is good enough for a simple HE pipe + +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/atmos_init() + normalize_dir() + var/node1_dir + var/node2_dir + + for(var/direction in cardinal) + if(direction&initialize_directions_he) + if (!node1_dir) + node1_dir = direction + else if (!node2_dir) + node2_dir = direction + + for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,node1_dir)) + if(target.initialize_directions_he & get_dir(target,src)) + node1 = target + break + for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,node2_dir)) + if(target.initialize_directions_he & get_dir(target,src)) + node2 = target + break + if(!node1 && !node2) + qdel(src) + return + + update_icon() + return + + +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/process() + if(!parent) + ..() + else + var/datum/gas_mixture/pipe_air = return_air() + if(istype(loc, /turf/simulated/)) + var/environment_temperature = 0 + if(loc:blocks_air) + environment_temperature = loc:temperature + else + var/datum/gas_mixture/environment = loc.return_air() + environment_temperature = environment.temperature + if(abs(environment_temperature-pipe_air.temperature) > minimum_temperature_difference) + parent.temperature_interact(loc, volume, thermal_conductivity) + else if(istype(loc, /turf/space/)) + parent.radiate_heat_to_space(surface, 1) + + if(has_buckled_mobs()) + for(var/M in buckled_mobs) + var/mob/living/L = M + + var/hc = pipe_air.heat_capacity() + var/avg_temp = (pipe_air.temperature * hc + L.bodytemperature * 3500) / (hc + 3500) + pipe_air.temperature = avg_temp + L.bodytemperature = avg_temp + + var/heat_limit = 1000 + + var/mob/living/carbon/human/H = L + if(istype(H) && H.species) + heat_limit = H.species.heat_level_3 + + if(pipe_air.temperature > heat_limit + 1) + L.apply_damage(4 * log(pipe_air.temperature - heat_limit), BURN, BP_TORSO, used_weapon = "Excessive Heat") + + //fancy radiation glowing + if(pipe_air.temperature && (icon_temperature > 500 || pipe_air.temperature > 500)) //start glowing at 500K + if(abs(pipe_air.temperature - icon_temperature) > 10) + icon_temperature = pipe_air.temperature + + var/h_r = heat2color_r(icon_temperature) + var/h_g = heat2color_g(icon_temperature) + var/h_b = heat2color_b(icon_temperature) + + if(icon_temperature < 2000) //scale up overlay until 2000K + var/scale = (icon_temperature - 500) / 1500 + h_r = 64 + (h_r - 64)*scale + h_g = 64 + (h_g - 64)*scale + h_b = 64 + (h_b - 64)*scale + + animate(src, color = rgb(h_r, h_g, h_b), time = 20, easing = SINE_EASING) + +// +// Heat Exchange Junction - Interfaces HE pipes to normal pipes +// +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction + icon = 'icons/atmos/junction.dmi' + icon_state = "intact" + pipe_icon = "hejunction" + level = 2 + connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_HE + minimum_temperature_difference = 300 + thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT + +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/init_dir() + ..() + switch ( dir ) + if ( SOUTH ) + initialize_directions = NORTH + initialize_directions_he = SOUTH + if ( NORTH ) + initialize_directions = SOUTH + initialize_directions_he = NORTH + if ( EAST ) + initialize_directions = WEST + initialize_directions_he = EAST + if ( WEST ) + initialize_directions = EAST + initialize_directions_he = WEST + + +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/atmos_init() + for(var/obj/machinery/atmospherics/target in get_step(src,initialize_directions)) + if(target.initialize_directions & get_dir(target,src)) + node1 = target + break + for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,initialize_directions_he)) + if(target.initialize_directions_he & get_dir(target,src)) + node2 = target + break + + if(!node1&&!node2) + qdel(src) + return + + update_icon() + return diff --git a/code/ATMOSPHERICS/pipes/manifold.dm b/code/ATMOSPHERICS/pipes/manifold.dm new file mode 100644 index 0000000000..1b9afd9c63 --- /dev/null +++ b/code/ATMOSPHERICS/pipes/manifold.dm @@ -0,0 +1,244 @@ +// +// Manifold Pipes - Three way "T" joints +// +/obj/machinery/atmospherics/pipe/manifold + icon = 'icons/atmos/manifold.dmi' + icon_state = "" + name = "pipe manifold" + desc = "A manifold composed of regular pipes" + + volume = ATMOS_DEFAULT_VOLUME_PIPE * 1.5 + + dir = SOUTH + initialize_directions = EAST|NORTH|WEST + + var/obj/machinery/atmospherics/node3 + + level = 1 + layer = 2.4 //under wires with their 2.44 + +/obj/machinery/atmospherics/pipe/manifold/New() + ..() + alpha = 255 + icon = null + +/obj/machinery/atmospherics/pipe/manifold/init_dir() + switch(dir) + if(NORTH) + initialize_directions = EAST|SOUTH|WEST + if(SOUTH) + initialize_directions = WEST|NORTH|EAST + if(EAST) + initialize_directions = SOUTH|WEST|NORTH + if(WEST) + initialize_directions = NORTH|EAST|SOUTH + +/obj/machinery/atmospherics/pipe/manifold/pipeline_expansion() + return list(node1, node2, node3) + +/obj/machinery/atmospherics/pipe/manifold/Destroy() + if(node1) + node1.disconnect(src) + node1 = null + if(node2) + node2.disconnect(src) + node2 = null + if(node3) + node3.disconnect(src) + node3 = null + + . = ..() + +/obj/machinery/atmospherics/pipe/manifold/disconnect(obj/machinery/atmospherics/reference) + if(reference == node1) + if(istype(node1, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node1 = null + + if(reference == node2) + if(istype(node2, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node2 = null + + if(reference == node3) + if(istype(node3, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node3 = null + + update_icon() + + ..() + +/obj/machinery/atmospherics/pipe/manifold/change_color(var/new_color) + ..() + //for updating connected atmos device pipes (i.e. vents, manifolds, etc) + if(node1) + node1.update_underlays() + if(node2) + node2.update_underlays() + if(node3) + node3.update_underlays() + +/obj/machinery/atmospherics/pipe/manifold/update_icon(var/safety = 0) + if(!check_icon_cache()) + return + + alpha = 255 + + overlays.Cut() + overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "core" + icon_connect_type) + overlays += icon_manager.get_atmos_icon("manifold", , , "clamps" + icon_connect_type) + underlays.Cut() + + var/turf/T = get_turf(src) + var/list/directions = list(NORTH, SOUTH, EAST, WEST) + var/node1_direction = get_dir(src, node1) + var/node2_direction = get_dir(src, node2) + var/node3_direction = get_dir(src, node3) + + directions -= dir + + directions -= add_underlay(T,node1,node1_direction,icon_connect_type) + directions -= add_underlay(T,node2,node2_direction,icon_connect_type) + directions -= add_underlay(T,node3,node3_direction,icon_connect_type) + + for(var/D in directions) + add_underlay(T,,D,icon_connect_type) + + +/obj/machinery/atmospherics/pipe/manifold/update_underlays() + ..() + update_icon() + +/obj/machinery/atmospherics/pipe/manifold/atmos_init() + var/connect_directions = (NORTH|SOUTH|EAST|WEST)&(~dir) + + for(var/direction in cardinal) + if(direction&connect_directions) + for(var/obj/machinery/atmospherics/target in get_step(src,direction)) + if(target.initialize_directions & get_dir(target,src)) + if (check_connect_types(target,src)) + node1 = target + connect_directions &= ~direction + break + if (node1) + break + + + for(var/direction in cardinal) + if(direction&connect_directions) + for(var/obj/machinery/atmospherics/target in get_step(src,direction)) + if(target.initialize_directions & get_dir(target,src)) + if (check_connect_types(target,src)) + node2 = target + connect_directions &= ~direction + break + if (node2) + break + + + for(var/direction in cardinal) + if(direction&connect_directions) + for(var/obj/machinery/atmospherics/target in get_step(src,direction)) + if(target.initialize_directions & get_dir(target,src)) + if (check_connect_types(target,src)) + node3 = target + connect_directions &= ~direction + break + if (node3) + break + + if(!node1 && !node2 && !node3) + qdel(src) + return + + var/turf/T = get_turf(src) + if(level == 1 && !T.is_plating()) hide(1) + update_icon() + +/obj/machinery/atmospherics/pipe/manifold/visible + icon_state = "map" + level = 2 + +/obj/machinery/atmospherics/pipe/manifold/visible/scrubbers + name="Scrubbers pipe manifold" + desc = "A manifold composed of scrubbers pipes" + icon_state = "map-scrubbers" + connect_types = CONNECT_TYPE_SCRUBBER + layer = 2.38 + icon_connect_type = "-scrubbers" + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/manifold/visible/supply + name="Air supply pipe manifold" + desc = "A manifold composed of supply pipes" + icon_state = "map-supply" + connect_types = CONNECT_TYPE_SUPPLY + layer = 2.39 + icon_connect_type = "-supply" + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/manifold/visible/yellow + color = PIPE_COLOR_YELLOW + +/obj/machinery/atmospherics/pipe/manifold/visible/cyan + color = PIPE_COLOR_CYAN + +/obj/machinery/atmospherics/pipe/manifold/visible/green + color = PIPE_COLOR_GREEN + +/obj/machinery/atmospherics/pipe/manifold/visible/black + color = PIPE_COLOR_BLACK + +/obj/machinery/atmospherics/pipe/manifold/visible/red + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/manifold/visible/blue + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/manifold/visible/purple + color = PIPE_COLOR_PURPLE + +/obj/machinery/atmospherics/pipe/manifold/hidden + icon_state = "map" + level = 1 + alpha = 128 //set for the benefit of mapping - this is reset to opaque when the pipe is spawned in game + +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers + name="Scrubbers pipe manifold" + desc = "A manifold composed of scrubbers pipes" + icon_state = "map-scrubbers" + connect_types = CONNECT_TYPE_SCRUBBER + layer = 2.38 + icon_connect_type = "-scrubbers" + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/manifold/hidden/supply + name="Air supply pipe manifold" + desc = "A manifold composed of supply pipes" + icon_state = "map-supply" + connect_types = CONNECT_TYPE_SUPPLY + layer = 2.39 + icon_connect_type = "-supply" + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/manifold/hidden/yellow + color = PIPE_COLOR_YELLOW + +/obj/machinery/atmospherics/pipe/manifold/hidden/cyan + color = PIPE_COLOR_CYAN + +/obj/machinery/atmospherics/pipe/manifold/hidden/green + color = PIPE_COLOR_GREEN + +/obj/machinery/atmospherics/pipe/manifold/hidden/black + color = PIPE_COLOR_BLACK + +/obj/machinery/atmospherics/pipe/manifold/hidden/red + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/manifold/hidden/blue + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/manifold/hidden/purple + color = PIPE_COLOR_PURPLE diff --git a/code/ATMOSPHERICS/pipes/manifold4w.dm b/code/ATMOSPHERICS/pipes/manifold4w.dm new file mode 100644 index 0000000000..ba360eefd8 --- /dev/null +++ b/code/ATMOSPHERICS/pipes/manifold4w.dm @@ -0,0 +1,247 @@ +// +// 4-Way Manifold Pipes - 4 way "cross" junction +// +/obj/machinery/atmospherics/pipe/manifold4w + icon = 'icons/atmos/manifold.dmi' + icon_state = "" + name = "4-way pipe manifold" + desc = "A manifold composed of regular pipes" + + volume = ATMOS_DEFAULT_VOLUME_PIPE * 2 + + dir = SOUTH + initialize_directions = NORTH|SOUTH|EAST|WEST + + var/obj/machinery/atmospherics/node3 + var/obj/machinery/atmospherics/node4 + + level = 1 + layer = 2.4 //under wires with their 2.44 + +/obj/machinery/atmospherics/pipe/manifold4w/New() + ..() + alpha = 255 + icon = null + +/obj/machinery/atmospherics/pipe/manifold4w/pipeline_expansion() + return list(node1, node2, node3, node4) + +/obj/machinery/atmospherics/pipe/manifold4w/Destroy() + if(node1) + node1.disconnect(src) + node1 = null + if(node2) + node2.disconnect(src) + node2 = null + if(node3) + node3.disconnect(src) + node3 = null + if(node4) + node4.disconnect(src) + node4 = null + + . = ..() + +/obj/machinery/atmospherics/pipe/manifold4w/disconnect(obj/machinery/atmospherics/reference) + if(reference == node1) + if(istype(node1, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node1 = null + + if(reference == node2) + if(istype(node2, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node2 = null + + if(reference == node3) + if(istype(node3, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node3 = null + + if(reference == node4) + if(istype(node4, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node4 = null + + update_icon() + + ..() + +/obj/machinery/atmospherics/pipe/manifold4w/change_color(var/new_color) + ..() + //for updating connected atmos device pipes (i.e. vents, manifolds, etc) + if(node1) + node1.update_underlays() + if(node2) + node2.update_underlays() + if(node3) + node3.update_underlays() + if(node4) + node4.update_underlays() + +/obj/machinery/atmospherics/pipe/manifold4w/update_icon(var/safety = 0) + if(!check_icon_cache()) + return + + alpha = 255 + + overlays.Cut() + overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "4way" + icon_connect_type) + overlays += icon_manager.get_atmos_icon("manifold", , , "clamps_4way" + icon_connect_type) + underlays.Cut() + + /* + var/list/directions = list(NORTH, SOUTH, EAST, WEST) + + + directions -= add_underlay(node1) + directions -= add_underlay(node2) + directions -= add_underlay(node3) + directions -= add_underlay(node4) + + for(var/D in directions) + add_underlay(,D) + */ + + var/turf/T = get_turf(src) + var/list/directions = list(NORTH, SOUTH, EAST, WEST) + var/node1_direction = get_dir(src, node1) + var/node2_direction = get_dir(src, node2) + var/node3_direction = get_dir(src, node3) + var/node4_direction = get_dir(src, node4) + + directions -= dir + + directions -= add_underlay(T,node1,node1_direction,icon_connect_type) + directions -= add_underlay(T,node2,node2_direction,icon_connect_type) + directions -= add_underlay(T,node3,node3_direction,icon_connect_type) + directions -= add_underlay(T,node4,node4_direction,icon_connect_type) + + for(var/D in directions) + add_underlay(T,,D,icon_connect_type) + + +/obj/machinery/atmospherics/pipe/manifold4w/update_underlays() + ..() + update_icon() + +/obj/machinery/atmospherics/pipe/manifold4w/atmos_init() + + for(var/obj/machinery/atmospherics/target in get_step(src,1)) + if(target.initialize_directions & 2) + if (check_connect_types(target,src)) + node1 = target + break + + for(var/obj/machinery/atmospherics/target in get_step(src,2)) + if(target.initialize_directions & 1) + if (check_connect_types(target,src)) + node2 = target + break + + for(var/obj/machinery/atmospherics/target in get_step(src,4)) + if(target.initialize_directions & 8) + if (check_connect_types(target,src)) + node3 = target + break + + for(var/obj/machinery/atmospherics/target in get_step(src,8)) + if(target.initialize_directions & 4) + if (check_connect_types(target,src)) + node4 = target + break + + if(!node1 && !node2 && !node3 && !node4) + qdel(src) + return + + var/turf/T = get_turf(src) + if(level == 1 && !T.is_plating()) hide(1) + update_icon() + +/obj/machinery/atmospherics/pipe/manifold4w/visible + icon_state = "map_4way" + level = 2 + +/obj/machinery/atmospherics/pipe/manifold4w/visible/scrubbers + name="4-way scrubbers pipe manifold" + desc = "A manifold composed of scrubbers pipes" + icon_state = "map_4way-scrubbers" + connect_types = CONNECT_TYPE_SCRUBBER + layer = 2.38 + icon_connect_type = "-scrubbers" + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/manifold4w/visible/supply + name="4-way air supply pipe manifold" + desc = "A manifold composed of supply pipes" + icon_state = "map_4way-supply" + connect_types = CONNECT_TYPE_SUPPLY + layer = 2.39 + icon_connect_type = "-supply" + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/manifold4w/visible/yellow + color = PIPE_COLOR_YELLOW + +/obj/machinery/atmospherics/pipe/manifold4w/visible/cyan + color = PIPE_COLOR_CYAN + +/obj/machinery/atmospherics/pipe/manifold4w/visible/green + color = PIPE_COLOR_GREEN + +/obj/machinery/atmospherics/pipe/manifold4w/visible/black + color = PIPE_COLOR_BLACK + +/obj/machinery/atmospherics/pipe/manifold4w/visible/red + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/manifold4w/visible/blue + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/manifold4w/visible/purple + color = PIPE_COLOR_PURPLE + +/obj/machinery/atmospherics/pipe/manifold4w/hidden + icon_state = "map_4way" + level = 1 + alpha = 128 //set for the benefit of mapping - this is reset to opaque when the pipe is spawned in game + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers + name="4-way scrubbers pipe manifold" + desc = "A manifold composed of scrubbers pipes" + icon_state = "map_4way-scrubbers" + connect_types = CONNECT_TYPE_SCRUBBER + layer = 2.38 + icon_connect_type = "-scrubbers" + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply + name="4-way air supply pipe manifold" + desc = "A manifold composed of supply pipes" + icon_state = "map_4way-supply" + connect_types = CONNECT_TYPE_SUPPLY + layer = 2.39 + icon_connect_type = "-supply" + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/yellow + color = PIPE_COLOR_YELLOW + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/cyan + color = PIPE_COLOR_CYAN + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/green + color = PIPE_COLOR_GREEN + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/black + color = PIPE_COLOR_BLACK + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/red + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/blue + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/purple + color = PIPE_COLOR_PURPLE diff --git a/code/ATMOSPHERICS/pipes/pipe_base.dm b/code/ATMOSPHERICS/pipes/pipe_base.dm new file mode 100644 index 0000000000..94167e01f6 --- /dev/null +++ b/code/ATMOSPHERICS/pipes/pipe_base.dm @@ -0,0 +1,137 @@ +// +// Base type of pipes +// +/obj/machinery/atmospherics/pipe + + var/datum/gas_mixture/air_temporary // used when reconstructing a pipeline that broke + var/datum/pipeline/parent + var/volume = 0 + + layer = 2.4 //under wires with their 2.44 + use_power = 0 + + var/alert_pressure = 80*ONE_ATMOSPHERE + //minimum pressure before check_pressure(...) should be called + + can_buckle = 1 + buckle_require_restraints = 1 + buckle_lying = -1 + +/obj/machinery/atmospherics/pipe/drain_power() + return -1 + +/obj/machinery/atmospherics/pipe/New() + if(istype(get_turf(src), /turf/simulated/wall) || istype(get_turf(src), /turf/simulated/shuttle/wall) || istype(get_turf(src), /turf/unsimulated/wall)) + level = 1 + ..() + +/obj/machinery/atmospherics/pipe/hides_under_flooring() + return level != 2 + +/obj/machinery/atmospherics/pipe/proc/pipeline_expansion() + return null + +/obj/machinery/atmospherics/pipe/proc/check_pressure(pressure) + //Return 1 if parent should continue checking other pipes + //Return null if parent should stop checking other pipes. Recall: qdel(src) will by default return null + + return 1 + +/obj/machinery/atmospherics/pipe/return_air() + if(!parent) + parent = new /datum/pipeline() + parent.build_pipeline(src) + + return parent.air + +/obj/machinery/atmospherics/pipe/build_network() + if(!parent) + parent = new /datum/pipeline() + parent.build_pipeline(src) + + return parent.return_network() + +/obj/machinery/atmospherics/pipe/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) + if(!parent) + parent = new /datum/pipeline() + parent.build_pipeline(src) + + return parent.network_expand(new_network, reference) + +/obj/machinery/atmospherics/pipe/return_network(obj/machinery/atmospherics/reference) + if(!parent) + parent = new /datum/pipeline() + parent.build_pipeline(src) + + return parent.return_network(reference) + +/obj/machinery/atmospherics/pipe/Destroy() + qdel_null(parent) + if(air_temporary) + loc.assume_air(air_temporary) + + . = ..() + +/obj/machinery/atmospherics/pipe/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) + if (istype(src, /obj/machinery/atmospherics/pipe/tank)) + return ..() + + if(istype(W,/obj/item/device/pipe_painter)) + return 0 + + if (!istype(W, /obj/item/weapon/wrench)) + return ..() + var/turf/T = src.loc + if (level==1 && isturf(T) && !T.is_plating()) + to_chat(user, "You must remove the plating first.") + return 1 + if(!can_unwrench()) + to_chat(user, "You cannot unwrench \the [src], it is too exerted due to internal pressure.") + add_fingerprint(user) + return 1 + playsound(src, W.usesound, 50, 1) + to_chat(user, "You begin to unfasten \the [src]...") + if (do_after(user, 40 * W.toolspeed)) + user.visible_message( \ + "\The [user] unfastens \the [src].", \ + "You have unfastened \the [src].", \ + "You hear a ratchet.") + new /obj/item/pipe(loc, make_from=src) + for (var/obj/machinery/meter/meter in T) + if (meter.target == src) + new /obj/item/pipe_meter(T) + qdel(meter) + qdel(src) + +/obj/machinery/atmospherics/pipe/proc/change_color(var/new_color) + //only pass valid pipe colors please ~otherwise your pipe will turn invisible + if(!pipe_color_check(new_color)) + return + + pipe_color = new_color + update_icon() + +/obj/machinery/atmospherics/pipe/color_cache_name(var/obj/machinery/atmospherics/node) + if(istype(src, /obj/machinery/atmospherics/pipe/tank)) + return ..() + + if(istype(node, /obj/machinery/atmospherics/pipe/manifold) || istype(node, /obj/machinery/atmospherics/pipe/manifold4w)) + if(pipe_color == node.pipe_color) + return node.pipe_color + else + return null + else if(istype(node, /obj/machinery/atmospherics/pipe/simple)) + return node.pipe_color + else + return pipe_color + +/obj/machinery/atmospherics/pipe/hide(var/i) + if(istype(loc, /turf/simulated)) + invisibility = i ? 101 : 0 + update_icon() + +/obj/machinery/atmospherics/pipe/process() + if(!parent) //This should cut back on the overhead calling build_network thousands of times per cycle + ..() + else + . = PROCESS_KILL diff --git a/code/ATMOSPHERICS/pipes/simple.dm b/code/ATMOSPHERICS/pipes/simple.dm new file mode 100644 index 0000000000..f676c1ac38 --- /dev/null +++ b/code/ATMOSPHERICS/pipes/simple.dm @@ -0,0 +1,257 @@ +// +// Simple Pipes - Just a tube, maybe bent +// +/obj/machinery/atmospherics/pipe/simple + icon = 'icons/atmos/pipes.dmi' + icon_state = "" + var/pipe_icon = "" //what kind of pipe it is and from which dmi is the icon manager getting its icons, "" for simple pipes, "hepipe" for HE pipes, "hejunction" for HE junctions + name = "pipe" + desc = "A one meter section of regular pipe" + + volume = ATMOS_DEFAULT_VOLUME_PIPE + + dir = SOUTH + initialize_directions = SOUTH|NORTH + + var/minimum_temperature_difference = 300 + var/thermal_conductivity = 0 //WALL_HEAT_TRANSFER_COEFFICIENT No + + var/maximum_pressure = 70*ONE_ATMOSPHERE + var/fatigue_pressure = 55*ONE_ATMOSPHERE + alert_pressure = 55*ONE_ATMOSPHERE + + level = 1 + +/obj/machinery/atmospherics/pipe/simple/New() + ..() + + // Pipe colors and icon states are handled by an image cache - so color and icon should + // be null. For mapping purposes color is defined in the object definitions. + icon = null + alpha = 255 + +/obj/machinery/atmospherics/pipe/simple/check_pressure(pressure) + var/datum/gas_mixture/environment = loc.return_air() + + var/pressure_difference = pressure - environment.return_pressure() + + if(pressure_difference > maximum_pressure) + burst() + + else if(pressure_difference > fatigue_pressure) + //TODO: leak to turf, doing pfshhhhh + if(prob(5)) + burst() + + else return 1 + +/obj/machinery/atmospherics/pipe/simple/init_dir() + switch(dir) + if(SOUTH || NORTH) + initialize_directions = SOUTH|NORTH + if(EAST || WEST) + initialize_directions = EAST|WEST + if(NORTHEAST) + initialize_directions = NORTH|EAST + if(NORTHWEST) + initialize_directions = NORTH|WEST + if(SOUTHEAST) + initialize_directions = SOUTH|EAST + if(SOUTHWEST) + initialize_directions = SOUTH|WEST + +/obj/machinery/atmospherics/pipe/simple/proc/burst() + src.visible_message("\The [src] bursts!"); + playsound(src.loc, 'sound/effects/bang.ogg', 25, 1) + var/datum/effect/effect/system/smoke_spread/smoke = new + smoke.set_up(1,0, src.loc, 0) + smoke.start() + qdel(src) + +/obj/machinery/atmospherics/pipe/simple/proc/normalize_dir() + if(dir==3) + set_dir(1) + else if(dir==12) + set_dir(4) + +/obj/machinery/atmospherics/pipe/simple/Destroy() + if(node1) + node1.disconnect(src) + node1 = null + if(node2) + node2.disconnect(src) + node1 = null + + . = ..() + +/obj/machinery/atmospherics/pipe/simple/pipeline_expansion() + return list(node1, node2) + +/obj/machinery/atmospherics/pipe/simple/change_color(var/new_color) + ..() + //for updating connected atmos device pipes (i.e. vents, manifolds, etc) + if(node1) + node1.update_underlays() + if(node2) + node2.update_underlays() + +/obj/machinery/atmospherics/pipe/simple/update_icon(var/safety = 0) + if(!check_icon_cache()) + return + + alpha = 255 + + overlays.Cut() + + if(node1 && node2) + overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "[pipe_icon]intact[icon_connect_type]") + else + overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "[pipe_icon]exposed[node1?1:0][node2?1:0][icon_connect_type]") + +/obj/machinery/atmospherics/pipe/simple/update_underlays() + return + +/obj/machinery/atmospherics/pipe/simple/atmos_init() + normalize_dir() + var/node1_dir + var/node2_dir + + for(var/direction in cardinal) + if(direction&initialize_directions) + if (!node1_dir) + node1_dir = direction + else if (!node2_dir) + node2_dir = direction + + for(var/obj/machinery/atmospherics/target in get_step(src,node1_dir)) + if(target.initialize_directions & get_dir(target,src)) + if (check_connect_types(target,src)) + node1 = target + break + for(var/obj/machinery/atmospherics/target in get_step(src,node2_dir)) + if(target.initialize_directions & get_dir(target,src)) + if (check_connect_types(target,src)) + node2 = target + break + + if(!node1 && !node2) + qdel(src) + return + + var/turf/T = loc + if(level == 1 && !T.is_plating()) hide(1) + update_icon() + +/obj/machinery/atmospherics/pipe/simple/disconnect(obj/machinery/atmospherics/reference) + if(reference == node1) + if(istype(node1, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node1 = null + + if(reference == node2) + if(istype(node2, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node2 = null + + update_icon() + + return null + +/obj/machinery/atmospherics/pipe/simple/visible + icon_state = "intact" + level = 2 + +/obj/machinery/atmospherics/pipe/simple/visible/scrubbers + name = "Scrubbers pipe" + desc = "A one meter section of scrubbers pipe" + icon_state = "intact-scrubbers" + connect_types = CONNECT_TYPE_SCRUBBER + layer = 2.38 + icon_connect_type = "-scrubbers" + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/simple/visible/supply + name = "Air supply pipe" + desc = "A one meter section of supply pipe" + icon_state = "intact-supply" + connect_types = CONNECT_TYPE_SUPPLY + layer = 2.39 + icon_connect_type = "-supply" + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/simple/visible/yellow + color = PIPE_COLOR_YELLOW + +/obj/machinery/atmospherics/pipe/simple/visible/cyan + color = PIPE_COLOR_CYAN + +/obj/machinery/atmospherics/pipe/simple/visible/green + color = PIPE_COLOR_GREEN + +/obj/machinery/atmospherics/pipe/simple/visible/black + color = PIPE_COLOR_BLACK + +/obj/machinery/atmospherics/pipe/simple/visible/red + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/simple/visible/blue + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/simple/visible/purple + color = PIPE_COLOR_PURPLE + +/obj/machinery/atmospherics/pipe/simple/hidden + icon_state = "intact" + level = 1 + alpha = 128 //set for the benefit of mapping - this is reset to opaque when the pipe is spawned in game + +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers + name = "Scrubbers pipe" + desc = "A one meter section of scrubbers pipe" + icon_state = "intact-scrubbers" + connect_types = CONNECT_TYPE_SCRUBBER + layer = 2.38 + icon_connect_type = "-scrubbers" + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/simple/hidden/supply + name = "Air supply pipe" + desc = "A one meter section of supply pipe" + icon_state = "intact-supply" + connect_types = CONNECT_TYPE_SUPPLY + layer = 2.39 + icon_connect_type = "-supply" + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/simple/hidden/yellow + color = PIPE_COLOR_YELLOW + +/obj/machinery/atmospherics/pipe/simple/hidden/cyan + color = PIPE_COLOR_CYAN + +/obj/machinery/atmospherics/pipe/simple/hidden/green + color = PIPE_COLOR_GREEN + +/obj/machinery/atmospherics/pipe/simple/hidden/black + color = PIPE_COLOR_BLACK + +/obj/machinery/atmospherics/pipe/simple/hidden/red + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/simple/hidden/blue + color = PIPE_COLOR_BLUE + +/obj/machinery/atmospherics/pipe/simple/hidden/purple + color = PIPE_COLOR_PURPLE + +/obj/machinery/atmospherics/pipe/simple/insulated + icon = 'icons/obj/atmospherics/red_pipe.dmi' + icon_state = "intact" + + minimum_temperature_difference = 10000 + thermal_conductivity = 0 + maximum_pressure = 1000*ONE_ATMOSPHERE + fatigue_pressure = 900*ONE_ATMOSPHERE + alert_pressure = 900*ONE_ATMOSPHERE + + level = 2 diff --git a/code/ATMOSPHERICS/pipes/tank.dm b/code/ATMOSPHERICS/pipes/tank.dm new file mode 100644 index 0000000000..07ce8d5b71 --- /dev/null +++ b/code/ATMOSPHERICS/pipes/tank.dm @@ -0,0 +1,161 @@ +// +// Tanks - These are implemented as pipes with large volume +// +/obj/machinery/atmospherics/pipe/tank + icon = 'icons/atmos/tank_vr.dmi' //VOREStation Edit - New Icons + icon_state = "air_map" + + name = "Pressure Tank" + desc = "A large vessel containing pressurized gas." + + volume = 10000 //in liters, 1 meters by 1 meters by 2 meters ~tweaked it a little to simulate a pressure tank without needing to recode them yet + var/start_pressure = 75*ONE_ATMOSPHERE //Vorestation edit + + level = 1 + dir = SOUTH + initialize_directions = SOUTH + density = 1 + +/obj/machinery/atmospherics/pipe/tank/New() + icon_state = "air" + ..() + +/obj/machinery/atmospherics/pipe/tank/init_dir() + initialize_directions = dir + +/obj/machinery/atmospherics/pipe/tank/Destroy() + if(node1) + node1.disconnect(src) + node1 = null + + . = ..() + +/obj/machinery/atmospherics/pipe/tank/pipeline_expansion() + return list(node1) + +/obj/machinery/atmospherics/pipe/tank/update_underlays() + if(..()) + underlays.Cut() + var/turf/T = get_turf(src) + if(!istype(T)) + return + add_underlay(T, node1, dir) + +/obj/machinery/atmospherics/pipe/tank/hide() + update_underlays() + +/obj/machinery/atmospherics/pipe/tank/atmos_init() + var/connect_direction = dir + + for(var/obj/machinery/atmospherics/target in get_step(src,connect_direction)) + if(target.initialize_directions & get_dir(target,src)) + if (check_connect_types(target,src)) + node1 = target + break + + update_underlays() + +/obj/machinery/atmospherics/pipe/tank/disconnect(obj/machinery/atmospherics/reference) + if(reference == node1) + if(istype(node1, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node1 = null + + update_underlays() + + return null + +/obj/machinery/atmospherics/pipe/tank/attackby(var/obj/item/W as obj, var/mob/user as mob) + if(istype(W, /obj/item/device/pipe_painter)) + return + + if(istype(W, /obj/item/device/analyzer) && in_range(user, src)) + var/obj/item/device/analyzer/A = W + A.analyze_gases(src, user) + +/obj/machinery/atmospherics/pipe/tank/air + name = "Pressure Tank (Air)" + icon_state = "air_map" + +/obj/machinery/atmospherics/pipe/tank/air/New() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T20C + + air_temporary.adjust_multi("oxygen", (start_pressure*O2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature), \ + "nitrogen",(start_pressure*N2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) + + + ..() + icon_state = "air" + +/obj/machinery/atmospherics/pipe/tank/oxygen + name = "Pressure Tank (Oxygen)" + icon_state = "o2_map" + +/obj/machinery/atmospherics/pipe/tank/oxygen/New() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T20C + + air_temporary.adjust_gas("oxygen", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) + + ..() + icon_state = "o2" + +/obj/machinery/atmospherics/pipe/tank/nitrogen + name = "Pressure Tank (Nitrogen)" + icon_state = "n2_map" + volume = 40000 //Vorestation edit + +/obj/machinery/atmospherics/pipe/tank/nitrogen/New() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T20C + + air_temporary.adjust_gas("nitrogen", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) + + ..() + icon_state = "n2" + +/obj/machinery/atmospherics/pipe/tank/carbon_dioxide + name = "Pressure Tank (Carbon Dioxide)" + icon_state = "co2_map" + +/obj/machinery/atmospherics/pipe/tank/carbon_dioxide/New() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T20C + + air_temporary.adjust_gas("carbon_dioxide", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) + + ..() + icon_state = "co2" + +/obj/machinery/atmospherics/pipe/tank/phoron + name = "Pressure Tank (Phoron)" + icon_state = "phoron_map" + +/obj/machinery/atmospherics/pipe/tank/phoron/New() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T20C + + air_temporary.adjust_gas("phoron", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) + + ..() + icon_state = "phoron" + +/obj/machinery/atmospherics/pipe/tank/nitrous_oxide + name = "Pressure Tank (Nitrous Oxide)" + icon_state = "n2o_map" + +/obj/machinery/atmospherics/pipe/tank/nitrous_oxide/New() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T0C + + air_temporary.adjust_gas("sleeping_agent", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) + + ..() + icon_state = "n2o" diff --git a/code/ATMOSPHERICS/pipes/universal.dm b/code/ATMOSPHERICS/pipes/universal.dm new file mode 100644 index 0000000000..1017751aa1 --- /dev/null +++ b/code/ATMOSPHERICS/pipes/universal.dm @@ -0,0 +1,102 @@ +// +// Universal Pipe Adapter - Designed for connecting scrubbers, normal, and supply pipes together. +// +/obj/machinery/atmospherics/pipe/simple/visible/universal + name="Universal pipe adapter" + desc = "An adapter for regular, supply and scrubbers pipes" + connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER + icon_state = "map_universal" + +/obj/machinery/atmospherics/pipe/simple/visible/universal/update_icon(var/safety = 0) + if(!check_icon_cache()) + return + + alpha = 255 + + overlays.Cut() + overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "universal") + underlays.Cut() + + if (node1) + universal_underlays(node1) + if(node2) + universal_underlays(node2) + else + var/node1_dir = get_dir(node1,src) + universal_underlays(,node1_dir) + else if (node2) + universal_underlays(node2) + else + universal_underlays(,dir) + universal_underlays(dir, -180) + +/obj/machinery/atmospherics/pipe/simple/visible/universal/update_underlays() + ..() + update_icon() + + + +/obj/machinery/atmospherics/pipe/simple/hidden/universal + name="Universal pipe adapter" + desc = "An adapter for regular, supply and scrubbers pipes" + connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER + icon_state = "map_universal" + +/obj/machinery/atmospherics/pipe/simple/hidden/universal/update_icon(var/safety = 0) + if(!check_icon_cache()) + return + + alpha = 255 + + overlays.Cut() + overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "universal") + underlays.Cut() + + if (node1) + universal_underlays(node1) + if(node2) + universal_underlays(node2) + else + var/node2_dir = turn(get_dir(src,node1),-180) + universal_underlays(,node2_dir) + else if (node2) + universal_underlays(node2) + var/node1_dir = turn(get_dir(src,node2),-180) + universal_underlays(,node1_dir) + else + universal_underlays(,dir) + universal_underlays(,turn(dir, -180)) + +/obj/machinery/atmospherics/pipe/simple/hidden/universal/update_underlays() + ..() + update_icon() + +/obj/machinery/atmospherics/proc/universal_underlays(var/obj/machinery/atmospherics/node, var/direction) + var/turf/T = loc + if(node) + var/node_dir = get_dir(src,node) + if(node.icon_connect_type == "-supply") + add_underlay_adapter(T, , node_dir, "") + add_underlay_adapter(T, node, node_dir, "-supply") + add_underlay_adapter(T, , node_dir, "-scrubbers") + else if (node.icon_connect_type == "-scrubbers") + add_underlay_adapter(T, , node_dir, "") + add_underlay_adapter(T, , node_dir, "-supply") + add_underlay_adapter(T, node, node_dir, "-scrubbers") + else + add_underlay_adapter(T, node, node_dir, "") + add_underlay_adapter(T, , node_dir, "-supply") + add_underlay_adapter(T, , node_dir, "-scrubbers") + else + add_underlay_adapter(T, , direction, "-supply") + add_underlay_adapter(T, , direction, "-scrubbers") + add_underlay_adapter(T, , direction, "") + +/obj/machinery/atmospherics/proc/add_underlay_adapter(var/turf/T, var/obj/machinery/atmospherics/node, var/direction, var/icon_connect_type) //modified from add_underlay, does not make exposed underlays + if(node) + if(!T.is_plating() && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe)) + underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type) + else + underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type) + else + underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "retracted" + icon_connect_type) diff --git a/code/ATMOSPHERICS/pipes/vent.dm b/code/ATMOSPHERICS/pipes/vent.dm new file mode 100644 index 0000000000..74eebb29a1 --- /dev/null +++ b/code/ATMOSPHERICS/pipes/vent.dm @@ -0,0 +1,83 @@ +// +// Vent Pipe - Unpowered vent +// +/obj/machinery/atmospherics/pipe/vent + icon = 'icons/obj/atmospherics/pipe_vent.dmi' + icon_state = "intact" + + name = "Vent" + desc = "A large air vent" + + level = 1 + + volume = 250 + + dir = SOUTH + initialize_directions = SOUTH + + var/build_killswitch = 1 + +/obj/machinery/atmospherics/pipe/vent/init_dir() + initialize_directions = dir + +/obj/machinery/atmospherics/pipe/vent/high_volume + name = "Larger vent" + volume = 1000 + +/obj/machinery/atmospherics/pipe/vent/process() + if(!parent) + if(build_killswitch <= 0) + . = PROCESS_KILL + else + build_killswitch-- + ..() + return + else + parent.mingle_with_turf(loc, volume) + +/obj/machinery/atmospherics/pipe/vent/Destroy() + if(node1) + node1.disconnect(src) + node1 = null + + . = ..() + +/obj/machinery/atmospherics/pipe/vent/pipeline_expansion() + return list(node1) + +/obj/machinery/atmospherics/pipe/vent/update_icon() + if(node1) + icon_state = "intact" + + set_dir(get_dir(src, node1)) + + else + icon_state = "exposed" + +/obj/machinery/atmospherics/pipe/vent/atmos_init() + var/connect_direction = dir + + for(var/obj/machinery/atmospherics/target in get_step(src,connect_direction)) + if(target.initialize_directions & get_dir(target,src)) + if (check_connect_types(target,src)) + node1 = target + break + + update_icon() + +/obj/machinery/atmospherics/pipe/vent/disconnect(obj/machinery/atmospherics/reference) + if(reference == node1) + if(istype(node1, /obj/machinery/atmospherics/pipe)) + qdel(parent) + node1 = null + + update_icon() + + return null + +/obj/machinery/atmospherics/pipe/vent/hide(var/i) //to make the little pipe section invisible, the icon changes. + if(node1) + icon_state = "[i == 1 && istype(loc, /turf/simulated) ? "h" : "" ]intact" + set_dir(get_dir(src, node1)) + else + icon_state = "exposed" diff --git a/code/ZAS/Turf.dm b/code/ZAS/Turf.dm index a309cd3a08..f61d1cf4fc 100644 --- a/code/ZAS/Turf.dm +++ b/code/ZAS/Turf.dm @@ -6,9 +6,9 @@ /turf/simulated/proc/update_graphic(list/graphic_add = null, list/graphic_remove = null) if(LAZYLEN(graphic_add)) - overlays += graphic_add + add_overlay(graphic_add, priority = TRUE) if(LAZYLEN(graphic_remove)) - overlays -= graphic_remove + cut_overlay(graphic_remove, priority = TRUE) /turf/proc/update_air_properties() var/block = c_airblock(src) diff --git a/code/__defines/atmos.dm b/code/__defines/atmos.dm index bd9175aab1..13964a6f80 100644 --- a/code/__defines/atmos.dm +++ b/code/__defines/atmos.dm @@ -21,8 +21,6 @@ #define HUMAN_NEEDED_OXYGEN (MOLES_CELLSTANDARD * BREATH_PERCENTAGE * 0.16) #define HUMAN_HEAT_CAPACITY 280000 //J/K For 80kg person -#define SOUND_MINIMUM_PRESSURE 10 - #define PRESSURE_DAMAGE_COEFFICIENT 4 // The amount of pressure damage someone takes is equal to (pressure / HAZARD_HIGH_PRESSURE)*PRESSURE_DAMAGE_COEFFICIENT, with the maximum of MAX_PRESSURE_DAMAGE. #define MAX_HIGH_PRESSURE_DAMAGE 4 // This used to be 20... I got this much random rage for some retarded decision by polymorph?! Polymorph now lies in a pool of blood with a katana jammed in his spleen. ~Errorage --PS: The katana did less than 20 damage to him :( #define LOW_PRESSURE_DAMAGE 2 // The amount of damage someone takes when in a low pressure area. (The pressure threshold is so low that it doesn't make sense to do any calculations, so it just applies this flat value). diff --git a/code/__defines/sound.dm b/code/__defines/sound.dm new file mode 100644 index 0000000000..6fae2fadcb --- /dev/null +++ b/code/__defines/sound.dm @@ -0,0 +1,56 @@ +//max channel is 1024. Only go lower from here, because byond tends to pick the first availiable channel to play sounds on +#define CHANNEL_LOBBYMUSIC 1024 +#define CHANNEL_ADMIN 1023 +#define CHANNEL_VOX 1022 +#define CHANNEL_JUKEBOX 1021 +#define CHANNEL_HEARTBEAT 1020 //sound channel for heartbeats +#define CHANNEL_AMBIENCE_FORCED 1019 +#define CHANNEL_AMBIENCE 1018 +#define CHANNEL_BUZZ 1017 +#define CHANNEL_BICYCLE 1016 + +//THIS SHOULD ALWAYS BE THE LOWEST ONE! +//KEEP IT UPDATED + +#define CHANNEL_HIGHEST_AVAILABLE 1015 + +#define SOUND_MINIMUM_PRESSURE 10 +#define FALLOFF_SOUNDS 0.5 + +//Sound environment defines. Reverb preset for sounds played in an area, see sound datum reference for more. +#define GENERIC 0 +#define PADDED_CELL 1 +#define ROOM 2 +#define BATHROOM 3 +#define LIVINGROOM 4 +#define STONEROOM 5 +#define AUDITORIUM 6 +#define CONCERT_HALL 7 +#define CAVE 8 +#define ARENA 9 +#define HANGAR 10 +#define CARPETED_HALLWAY 11 +#define HALLWAY 12 +#define STONE_CORRIDOR 13 +#define ALLEY 14 +#define FOREST 15 +#define CITY 16 +#define MOUNTAINS 17 +#define QUARRY 18 +#define PLAIN 19 +#define PARKING_LOT 20 +#define SEWER_PIPE 21 +#define UNDERWATER 22 +#define DRUGGED 23 +#define DIZZY 24 +#define PSYCHOTIC 25 + +#define STANDARD_STATION STONEROOM +#define LARGE_ENCLOSED HANGAR +#define SMALL_ENCLOSED BATHROOM +#define TUNNEL_ENCLOSED CAVE +#define LARGE_SOFTFLOOR CARPETED_HALLWAY +#define MEDIUM_SOFTFLOOR LIVINGROOM +#define SMALL_SOFTFLOOR ROOM +#define ASTEROID CAVE +#define SPACE UNDERWATER diff --git a/code/__defines/species_languages.dm b/code/__defines/species_languages.dm index 5cfb5f37d0..cf60bbc602 100644 --- a/code/__defines/species_languages.dm +++ b/code/__defines/species_languages.dm @@ -45,6 +45,9 @@ #define LANGUAGE_OCCULT "Occult" #define LANGUAGE_CHANGELING "Changeling" #define LANGUAGE_VOX "Vox-Pidgin" +#define LANGUAGE_TERMINUS "Terminus" +#define LANGUAGE_SKRELLIANFAR "High Skrellian" +#define LANGUAGE_MINBUS "Minbus" // Language flags. #define WHITELISTED 1 // Language is available if the speaker is whitelisted. diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index b11cd33d32..11a22d5938 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -803,7 +803,6 @@ proc/GaussRandRound(var/sigma,var/roundto) var/old_dir1 = T.dir var/old_icon_state1 = T.icon_state var/old_icon1 = T.icon - var/old_overlays = T.overlays.Copy() var/old_underlays = T.underlays.Copy() var/old_decals = T.decals ? T.decals.Copy() : null @@ -811,11 +810,9 @@ proc/GaussRandRound(var/sigma,var/roundto) X.set_dir(old_dir1) X.icon_state = old_icon_state1 X.icon = old_icon1 - X.overlays = old_overlays + X.copy_overlays(T, TRUE) X.underlays = old_underlays X.decals = old_decals - if(old_decals) - X.apply_decals() //Move the air from source to dest var/turf/simulated/ST = T @@ -841,14 +838,10 @@ proc/GaussRandRound(var/sigma,var/roundto) if(shuttlework) var/turf/simulated/shuttle/SS = T SS.landed_holder.leave_turf() - else if(turftoleave) T.ChangeTurf(turftoleave) - T.apply_decals() - else T.ChangeTurf(get_base_turf_by_area(T)) - T.apply_decals() refined_src -= T refined_trg -= B diff --git a/code/_macros_vr.dm b/code/_macros_vr.dm new file mode 100644 index 0000000000..daa1123574 --- /dev/null +++ b/code/_macros_vr.dm @@ -0,0 +1,2 @@ +#define isbelly(A) istype(A, /obj/belly) +#define isstorage(A) istype(A, /obj/item/weapon/storage) \ No newline at end of file diff --git a/code/controllers/subsystems/bellies_vr.dm b/code/controllers/subsystems/bellies_vr.dm new file mode 100644 index 0000000000..faaa297ca3 --- /dev/null +++ b/code/controllers/subsystems/bellies_vr.dm @@ -0,0 +1,41 @@ +#define SSBELLIES_PROCESSED 1 +#define SSBELLIES_IGNORED 2 + +// +// Bellies subsystem - Process vore bellies +// + +SUBSYSTEM_DEF(bellies) + name = "Bellies" + priority = 5 + wait = 1 SECONDS + flags = SS_KEEP_TIMING|SS_NO_INIT + runlevels = RUNLEVEL_GAME|RUNLEVEL_POSTGAME + + var/static/list/belly_list = list() + var/list/currentrun = list() + var/ignored_bellies = 0 + +/datum/controller/subsystem/bellies/stat_entry() + ..("#: [belly_list.len] | P: [ignored_bellies]") + +/datum/controller/subsystem/bellies/fire(resumed = 0) + if (!resumed) + ignored_bellies = 0 + src.currentrun = belly_list.Copy() + + //cache for sanic speed (lists are references anyways) + var/list/currentrun = src.currentrun + var/times_fired = src.times_fired + while(currentrun.len) + var/obj/belly/B = currentrun[currentrun.len] + currentrun.len-- + + if(QDELETED(B)) + belly_list -= B + else + if(B.process_belly(times_fired,wait) == SSBELLIES_IGNORED) + ignored_bellies++ + + if (MC_TICK_CHECK) + return diff --git a/code/controllers/subsystems/floor_decals.dm b/code/controllers/subsystems/floor_decals.dm deleted file mode 100644 index 39e4515d0d..0000000000 --- a/code/controllers/subsystems/floor_decals.dm +++ /dev/null @@ -1,28 +0,0 @@ -// -// Floor Decals Initialization Subsystem -// This is part of the giant decal hack that works around a BYOND bug where DreamDaemon will crash if you -// update overlays on turfs too much. -// The master_controller on Polaris used to init decals prior to initializing areas (which initilized turfs) -// Now that we switched to subsystems we still want to do the same thing, so this takes care of it. -// -SUBSYSTEM_DEF(floor_decals) - name = "Floor Decals" - init_order = INIT_ORDER_DECALS - flags = SS_NO_FIRE - -/datum/controller/subsystem/floor_decals/Initialize(timeofday) - if(floor_decals_initialized) - return ..() - to_world_log("Initializing Floor Decals") - admin_notice("Initializing Floor Decals", R_DEBUG) - var/list/turfs_with_decals = list() - for(var/obj/effect/floor_decal/D in world) - var/T = D.add_to_turf_decals() - if(T) turfs_with_decals |= T - CHECK_TICK - for(var/item in turfs_with_decals) - var/turf/T = item - if(T.decals) T.apply_decals() - CHECK_TICK - floor_decals_initialized = TRUE - return ..() diff --git a/code/controllers/subsystems/overlays.dm b/code/controllers/subsystems/overlays.dm index 6d7581e126..352102e175 100644 --- a/code/controllers/subsystems/overlays.dm +++ b/code/controllers/subsystems/overlays.dm @@ -11,6 +11,8 @@ SUBSYSTEM_DEF(overlays) var/list/overlay_icon_state_caches // Cache thing var/list/overlay_icon_cache // Cache thing +var/global/image/appearance_bro = new() // Temporarily super-global because of BYOND init order dumbness. + /datum/controller/subsystem/overlays/PreInit() overlay_icon_state_caches = list() overlay_icon_cache = list() @@ -90,7 +92,7 @@ SUBSYSTEM_DEF(overlays) icon_cache[icon] = . /atom/proc/build_appearance_list(old_overlays) - var/static/image/appearance_bro = new() + // var/static/image/appearance_bro = new() // Moved to be superglobal due to BYOND insane init order stupidness. var/list/new_overlays = list() if (!islist(old_overlays)) old_overlays = list(old_overlays) diff --git a/code/controllers/subsystems/transcore_vr.dm b/code/controllers/subsystems/transcore_vr.dm index f98bf6d2c0..4958d87f3d 100644 --- a/code/controllers/subsystems/transcore_vr.dm +++ b/code/controllers/subsystems/transcore_vr.dm @@ -152,9 +152,7 @@ SUBSYSTEM_DEF(transcore) // Send a past-due notification to the medical radio channel. /datum/controller/subsystem/transcore/proc/notify(var/name) ASSERT(name) - var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/heads/captain(null) - a.autosay("[name] is past-due for a mind backup. This will be the only notification.", "TransCore Oversight", "Medical") - qdel(a) + global_announcer.autosay("[name] is past-due for a mind backup. This will be the only notification.", "TransCore Oversight", "Medical") // Called from mind_record to add itself to the transcore. /datum/controller/subsystem/transcore/proc/add_backup(var/datum/transhuman/mind_record/MR) @@ -187,10 +185,8 @@ SUBSYSTEM_DEF(transcore) // Moves all mind records from the databaes into the disk and shuts down all backup canary processing. /datum/controller/subsystem/transcore/proc/core_dump(var/obj/item/weapon/disk/transcore/disk) ASSERT(disk) - var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/heads/captain(null) - a.autosay("An emergency core dump has been initiated!", "TransCore Oversight", "Command") - a.autosay("An emergency core dump has been initiated!", "TransCore Oversight", "Medical") - qdel(a) + global_announcer.autosay("An emergency core dump has been initiated!", "TransCore Oversight", "Command") + global_announcer.autosay("An emergency core dump has been initiated!", "TransCore Oversight", "Medical") disk.stored += backed_up backed_up.Cut() diff --git a/code/datums/helper_datums/teleport_vr.dm b/code/datums/helper_datums/teleport_vr.dm index cbae240cff..1cb73d6ad9 100644 --- a/code/datums/helper_datums/teleport_vr.dm +++ b/code/datums/helper_datums/teleport_vr.dm @@ -1,22 +1,13 @@ /datum/teleport/proc/try_televore() - var/datum/belly/target_belly - - //Destination is a living thing - target_belly = check_belly(destination) - - //Destination has a living thing on it - if(!target_belly) - for(var/mob/living/M in get_turf(destination)) - if(M.vore_organs.len) - var/I = M.vore_organs[1] - target_belly = M.vore_organs[I] - - if(target_belly) - teleatom.forceMove(destination.loc) + //Destination is in a belly + if(isbelly(destination.loc)) + var/obj/belly/B = destination.loc + + teleatom.forceMove(get_turf(B)) //So we can splash the sound and sparks and everything. playSpecials(destination,effectout,soundout) - target_belly.internal_contents |= teleatom - playsound(destination, target_belly.vore_sound, 100, 1) + teleatom.forceMove(B) return 1 //No fun! - return 0 \ No newline at end of file + return 0 + \ No newline at end of file diff --git a/code/datums/supplypacks/robotics.dm b/code/datums/supplypacks/robotics.dm index 3e861e354b..d9f20c5aa6 100644 --- a/code/datums/supplypacks/robotics.dm +++ b/code/datums/supplypacks/robotics.dm @@ -116,14 +116,6 @@ containername = "Robolimb blueprints (Bishop)" access = access_robotics -/datum/supply_packs/robotics/robolimbs/veymed - name = "Vey-Med robolimb blueprints" - contains = list(/obj/item/weapon/disk/limb/veymed) - cost = 70 - containertype = /obj/structure/closet/crate/secure/science - containername = "Robolimb blueprints (Vey-Med)" - access = access_robotics - /datum/supply_packs/robotics/mecha_ripley name = "Circuit Crate (\"Ripley\" APLU)" contains = list( diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index ae21bf8093..0902bd3871 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -260,26 +260,26 @@ var/list/mob/living/forced_ambiance_list = new // If we previously were in an area with force-played ambiance, stop it. if(L in forced_ambiance_list) - L << sound(null, channel = 1) + L << sound(null, channel = CHANNEL_AMBIENCE_FORCED) forced_ambiance_list -= L if(!L.client.ambience_playing) L.client.ambience_playing = 1 - L << sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = 2) + L << sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = CHANNEL_AMBIENCE) if(forced_ambience) if(forced_ambience.len) forced_ambiance_list |= L var/sound/chosen_ambiance = pick(forced_ambience) if(!istype(chosen_ambiance)) - chosen_ambiance = sound(chosen_ambiance, repeat = 1, wait = 0, volume = 25, channel = 1) + chosen_ambiance = sound(chosen_ambiance, repeat = 1, wait = 0, volume = 25, channel = CHANNEL_AMBIENCE_FORCED) L << chosen_ambiance else L << sound(null, channel = 1) else if(src.ambience.len && prob(35)) if((world.time >= L.client.played + 600)) var/sound = pick(ambience) - L << sound(sound, repeat = 0, wait = 0, volume = 25, channel = 1) + L << sound(sound, repeat = 0, wait = 0, volume = 25, channel = CHANNEL_AMBIENCE) L.client.played = world.time /area/proc/gravitychange(var/gravitystate = 0, var/area/A) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 0cd09b8a57..3ae19b1e4f 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -296,3 +296,7 @@ /atom/movable/proc/adjust_scale(new_scale) icon_scale = new_scale update_transform() + +// Stub for now, override with better things. +/atom/movable/proc/drop_location() + return loc \ No newline at end of file diff --git a/code/game/machinery/adv_med_vr.dm b/code/game/machinery/adv_med_vr.dm index 68185bcf46..6c11b6cf34 100644 --- a/code/game/machinery/adv_med_vr.dm +++ b/code/game/machinery/adv_med_vr.dm @@ -12,9 +12,9 @@ var/livingprey = 0 var/objectprey = 0 - for(var/I in H.vore_organs) - var/datum/belly/B = H.vore_organs[I] - for(var/C in B.internal_contents) + for(var/belly in H.vore_organs) + var/obj/belly/B = belly + for(var/C in B) if(ishuman(C)) humanprey++ else if(isliving(C)) diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index 76eafc2a05..6a435ef388 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -824,7 +824,7 @@ FIRE ALARM alarms_hidden = TRUE /obj/machinery/firealarm/update_icon() - overlays.Cut() + cut_overlays() if(panel_open) set_light(0) @@ -847,8 +847,7 @@ FIRE ALARM if("blue") set_light(l_range = 2, l_power = 0.5, l_color = "#1024A9") if("red") set_light(l_range = 4, l_power = 2, l_color = "#ff0000") if("delta") set_light(l_range = 4, l_power = 2, l_color = "#FF6633") - - overlays += image('icons/obj/monitors.dmi', "overlay_[seclevel]") + add_overlay("overlay_[seclevel]") /obj/machinery/firealarm/fire_act(datum/gas_mixture/air, temperature, volume) if(detecting) diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm index 9b6b503237..ceea16ec3b 100644 --- a/code/game/machinery/kitchen/gibber.dm +++ b/code/game/machinery/kitchen/gibber.dm @@ -225,13 +225,12 @@ playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) operating = 0 - for (var/obj/thing in contents) - // Todo: unify limbs and internal organs + for (var/obj/item/thing in contents) // There's a chance that the gibber will fail to destroy some evidence. - if((istype(thing,/obj/item/organ) || istype(thing,/obj/item/organ)) && prob(80)) + if(istype(thing,/obj/item/organ) && prob(80)) qdel(thing) continue - thing.loc = get_turf(thing) // Drop it onto the turf for throwing. + thing.forceMove(get_turf(thing)) // Drop it onto the turf for throwing. thing.throw_at(get_edge_target_turf(src,gib_throw_dir),rand(0,3),emagged ? 100 : 50) // Being pelted with bits of meat and bone would hurt. update_icon() diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index b5e98dab70..3b05f4e27c 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -1112,8 +1112,8 @@ /obj/item/toy/plushie/kitten = 2, /obj/item/toy/plushie/lizard = 2, /obj/item/toy/plushie/spider = 2, - /obj/item/toy/plushie/farwa = 2) - // /obj/item/weapon/storage/trinketbox = 2 (readding later due to conflict) + /obj/item/toy/plushie/farwa = 2, + /obj/item/weapon/storage/trinketbox = 2) prices = list(/obj/item/weapon/storage/fancy/heartbox = 15, /obj/item/toy/bouquet = 10, /obj/item/toy/bouquet/fake = 3, diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index ef4e196309..eb3ac7cb12 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -50,6 +50,12 @@ name = "entertainment intercom" frequency = ENT_FREQ +/obj/item/device/radio/intercom/omni + name = "global announcer" +/obj/item/device/radio/intercom/omni/initialize() + channels = radiochannels.Copy() + return ..() + /obj/item/device/radio/intercom/New() ..() processing_objects += src diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 89f10c8140..d408a033f7 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -53,14 +53,13 @@ var/global/list/default_medbay_channels = list( var/const/FREQ_LISTENING = 1 var/list/internal_channels -/obj/item/device/radio var/datum/radio_frequency/radio_connection var/list/datum/radio_frequency/secure_radio_connections = new - proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) - frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT) +/obj/item/device/radio/proc/set_frequency(new_frequency) + radio_controller.remove_object(src, frequency) + frequency = new_frequency + radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT) /obj/item/device/radio/New() ..() diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 225ac96012..f10767a49c 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -213,8 +213,10 @@ R.add_language(LANGUAGE_UNATHI, 1) R.add_language(LANGUAGE_SIIK, 1) R.add_language(LANGUAGE_SKRELLIAN, 1) + R.add_language(LANGUAGE_SKRELLIANFAR, 0) R.add_language(LANGUAGE_GUTTER, 1) R.add_language(LANGUAGE_SCHECHI, 1) R.add_language(LANGUAGE_ROOTLOCAL, 1) + R.add_language(LANGUAGE_TERMINUS, 1) return 1 diff --git a/code/game/objects/items/stacks/tiles/fifty_spawner_tiles.dm b/code/game/objects/items/stacks/tiles/fifty_spawner_tiles.dm index b3605c6b1f..256d2c8582 100644 --- a/code/game/objects/items/stacks/tiles/fifty_spawner_tiles.dm +++ b/code/game/objects/items/stacks/tiles/fifty_spawner_tiles.dm @@ -10,7 +10,7 @@ /obj/fiftyspawner/wood/sif name = "stack of alien wood" - type_to_spawn = /obj/item/stack/tile/sifwood + type_to_spawn = /obj/item/stack/tile/wood/sif /obj/fiftyspawner/carpet name = "stack of carpet" diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index f31a3a6edf..bc93d20bb5 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -37,9 +37,6 @@ flags = 0 origin_tech = list(TECH_BIO = 1) no_variants = FALSE - -/obj/item/stack/tile/grass/fifty - amount = 50 /* * Wood */ @@ -55,23 +52,11 @@ flags = 0 no_variants = FALSE -/obj/item/stack/tile/sifwood +/obj/item/stack/tile/wood/sif name = "alien wood tile" singular_name = "alien wood tile" desc = "An easy to fit wooden floor tile. It's blue!" icon_state = "tile-sifwood" - force = 1.0 - throwforce = 1.0 - throw_speed = 5 - throw_range = 20 - flags = 0 - no_variants = FALSE - -/obj/item/stack/tile/wood/fifty - amount = 50 - -/obj/item/stack/tile/sifwood/fifty - amount = 50 /obj/item/stack/tile/wood/cyborg name = "wood floor tile synthesizer" diff --git a/code/game/objects/items/trash_vr.dm b/code/game/objects/items/trash_vr.dm index 38c434b973..942b571aa5 100644 --- a/code/game/objects/items/trash_vr.dm +++ b/code/game/objects/items/trash_vr.dm @@ -12,10 +12,7 @@ if(H.species.trashcan == 1) playsound(H.loc,'sound/items/eatfood.ogg', rand(10,50), 1) user.drop_item() - var/belly = H.vore_selected - var/datum/belly/selected = H.vore_organs[belly] - forceMove(H) - selected.internal_contents |= src + forceMove(H.vore_selected) to_chat(H, "You can taste the flavor of garbage. Wait what?") return @@ -24,10 +21,7 @@ if(R.module.type == /obj/item/weapon/robot_module/robot/scrubpup) // You can now feed the trash borg yay. playsound(R.loc,'sound/items/eatfood.ogg', rand(10,50), 1) user.drop_item() - var/belly = R.vore_selected - var/datum/belly/selected = R.vore_organs[belly] - forceMove(R) - selected.internal_contents |= src // Too many hoops and obstacles to stick it into the sleeper module. + forceMove(R.vore_selected) R.visible_message("[user] feeds [R] with [src]!") return ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 84a17ac9d1..64d6252a2f 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -96,7 +96,8 @@ name = "box of syringes" desc = "A box full of syringes." icon_state = "syringe" - starts_with = list(/obj/item/weapon/reagent_containers/syringe = 7) + can_hold = list(/obj/item/weapon/reagent_containers/syringe) //VOREStation Edit + starts_with = list(/obj/item/weapon/reagent_containers/syringe = 20) //VOREStation Edit /obj/item/weapon/storage/box/syringegun name = "box of syringe gun cartridges" diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index 6bddb28769..799169bad5 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -674,7 +674,6 @@ /* * Trinket Box - READDING SOON */ -/* /obj/item/weapon/storage/trinketbox name = "trinket box" desc = "A box that can hold small trinkets, such as a ring." @@ -724,5 +723,4 @@ ..() if(open && contents.len) var/display_item = contents[1] - to_chat(user, "\The [src] contains \the [display_item]!") - */ \ No newline at end of file + to_chat(user, "\The [src] contains \the [display_item]!") \ No newline at end of file diff --git a/code/game/objects/items/weapons/syndie.dm b/code/game/objects/items/weapons/syndie.dm index 5406b05a26..3ba85b0bfc 100644 --- a/code/game/objects/items/weapons/syndie.dm +++ b/code/game/objects/items/weapons/syndie.dm @@ -13,9 +13,9 @@ desc = "A small wrapped package." w_class = ITEMSIZE_NORMAL - var/devastate = 0 - var/heavy_impact = 1 - var/light_impact = 2 + var/devastate = 1 + var/heavy_impact = 2 + var/light_impact = 4 var/flash_range = 5 var/size = "small" /*Used for the icon, this one will make c-4small_0 for the off state.*/ @@ -24,7 +24,7 @@ item_state = "radio" desc = "A mysterious package, it's quite heavy." devastate = 1 - heavy_impact = 2 + heavy_impact = 3 light_impact = 5 flash_range = 7 size = "large" diff --git a/code/game/objects/random/random_vr.dm b/code/game/objects/random/random_vr.dm index 7b7b25379f..2a68c1496f 100644 --- a/code/game/objects/random/random_vr.dm +++ b/code/game/objects/random/random_vr.dm @@ -199,3 +199,11 @@ T = get_step_rand(this_mob) || T if(T) this_mob.forceMove(T) + +//Just overriding this here, no more super medkit so those can be reserved for PoIs and such +/obj/random/firstaid/item_to_spawn() + return pick(prob(4);/obj/item/weapon/storage/firstaid/regular, + prob(3);/obj/item/weapon/storage/firstaid/toxin, + prob(3);/obj/item/weapon/storage/firstaid/o2, + prob(2);/obj/item/weapon/storage/firstaid/adv, + prob(3);/obj/item/weapon/storage/firstaid/fire) diff --git a/code/game/objects/structures/crates_lockers/closets/egg_vr.dm b/code/game/objects/structures/crates_lockers/closets/egg_vr.dm index d1c37221cf..b47a49c4b5 100644 --- a/code/game/objects/structures/crates_lockers/closets/egg_vr.dm +++ b/code/game/objects/structures/crates_lockers/closets/egg_vr.dm @@ -18,13 +18,6 @@ src.dump_contents() qdel(src) -/obj/structure/closet/secure_closet/egg/dump_contents() - var/datum/belly/belly = check_belly(src) - if(belly) - for(var/atom/movable/M in src) - belly.internal_contents |= M - return ..() - /obj/structure/closet/secure_closet/egg/unathi name = "unathi egg" desc = "Some species of Unathi apparently lay soft-shelled eggs!" diff --git a/code/game/sound.dm b/code/game/sound.dm index 0a440db1c4..12d0e5ed8c 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -1,107 +1,50 @@ -//Sound environment defines. Reverb preset for sounds played in an area, see sound datum reference for more. -#define GENERIC 0 -#define PADDED_CELL 1 -#define ROOM 2 -#define BATHROOM 3 -#define LIVINGROOM 4 -#define STONEROOM 5 -#define AUDITORIUM 6 -#define CONCERT_HALL 7 -#define CAVE 8 -#define ARENA 9 -#define HANGAR 10 -#define CARPETED_HALLWAY 11 -#define HALLWAY 12 -#define STONE_CORRIDOR 13 -#define ALLEY 14 -#define FOREST 15 -#define CITY 16 -#define MOUNTAINS 17 -#define QUARRY 18 -#define PLAIN 19 -#define PARKING_LOT 20 -#define SEWER_PIPE 21 -#define UNDERWATER 22 -#define DRUGGED 23 -#define DIZZY 24 -#define PSYCHOTIC 25 - -#define STANDARD_STATION STONEROOM -#define LARGE_ENCLOSED HANGAR -#define SMALL_ENCLOSED BATHROOM -#define TUNNEL_ENCLOSED CAVE -#define LARGE_SOFTFLOOR CARPETED_HALLWAY -#define MEDIUM_SOFTFLOOR LIVINGROOM -#define SMALL_SOFTFLOOR ROOM -#define ASTEROID CAVE -#define SPACE UNDERWATER - -var/list/shatter_sound = list('sound/effects/Glassbr1.ogg','sound/effects/Glassbr2.ogg','sound/effects/Glassbr3.ogg') -var/list/explosion_sound = list('sound/effects/Explosion1.ogg','sound/effects/Explosion2.ogg','sound/effects/Explosion3.ogg','sound/effects/Explosion4.ogg','sound/effects/Explosion5.ogg','sound/effects/Explosion6.ogg') -var/list/spark_sound = list('sound/effects/sparks1.ogg','sound/effects/sparks2.ogg','sound/effects/sparks3.ogg','sound/effects/sparks5.ogg','sound/effects/sparks6.ogg','sound/effects/sparks7.ogg') -var/list/rustle_sound = list('sound/effects/rustle1.ogg','sound/effects/rustle2.ogg','sound/effects/rustle3.ogg','sound/effects/rustle4.ogg','sound/effects/rustle5.ogg') -var/list/punch_sound = list('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg') -var/list/clown_sound = list('sound/effects/clownstep1.ogg','sound/effects/clownstep2.ogg') -var/list/swing_hit_sound = list('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg') -var/list/hiss_sound = list('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg') -var/list/page_sound = list('sound/effects/pageturn1.ogg', 'sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg') -var/list/fracture_sound = list('sound/effects/bonebreak1.ogg','sound/effects/bonebreak2.ogg','sound/effects/bonebreak3.ogg','sound/effects/bonebreak4.ogg') -var/list/casing_sound = list ('sound/weapons/casingfall1.ogg','sound/weapons/casingfall2.ogg','sound/weapons/casingfall3.ogg') -var/list/keyboard_sound = list ('sound/effects/keyboard/keyboard1.ogg','sound/effects/keyboard/keyboard2.ogg','sound/effects/keyboard/keyboard3.ogg', 'sound/effects/keyboard/keyboard4.ogg') -var/list/mechstep_sound = list('sound/mecha/mechstep1.ogg', 'sound/mecha/mechstep2.ogg') -var/list/bodyfall_sound = list('sound/effects/bodyfall1.ogg','sound/effects/bodyfall2.ogg','sound/effects/bodyfall3.ogg','sound/effects/bodyfall4.ogg') -var/list/can_sound = list('sound/effects/can_open1.ogg','sound/effects/can_open2.ogg','sound/effects/can_open3.ogg','sound/effects/can_open4.ogg') -var/list/geiger_sound = list('sound/items/geiger1.ogg', 'sound/items/geiger2.ogg', 'sound/items/geiger3.ogg', 'sound/items/geiger4.ogg', 'sound/items/geiger5.ogg') -var/list/geiger_weak_sound = list('sound/items/geiger_weak1.ogg', 'sound/items/geiger_weak2.ogg', 'sound/items/geiger_weak3.ogg', 'sound/items/geiger_weak4.ogg') - -//var/list/gun_sound = list('sound/weapons/Gunshot.ogg', 'sound/weapons/Gunshot2.ogg','sound/weapons/Gunshot3.ogg','sound/weapons/Gunshot4.ogg') - -/proc/playsound(var/atom/source, soundin, vol as num, vary, extrarange as num, falloff, var/is_global, var/frequency) - - soundin = get_sfx(soundin) // same sound for everyone - +/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, is_global, frequency = null, channel = 0, pressure_affected = TRUE, ignore_walls = TRUE, preference = null) if(isarea(source)) - error("[source] is an area and is trying to make the sound: [soundin]") + throw EXCEPTION("playsound(): source is an area") return - frequency = isnull(frequency) ? get_rand_frequency() : frequency // Same frequency for everybody var/turf/turf_source = get_turf(source) + //allocate a channel if necessary now so its the same for everyone + channel = channel || open_sound_channel() + // Looping through the player list has the added bonus of working for mobs inside containers - for (var/P in player_list) + var/sound/S = sound(get_sfx(soundin)) + var/maxdistance = (world.view + extrarange) * 3 + var/list/listeners = player_list + if(!ignore_walls) //these sounds don't carry through walls + listeners = listeners & hearers(maxdistance,turf_source) + for(var/P in listeners) var/mob/M = P if(!M || !M.client) continue + var/turf/T = get_turf(M) + var/distance = get_dist(T, turf_source) - var/distance = get_dist(M, turf_source) - if(distance <= (world.view + extrarange) * 3) - var/turf/T = get_turf(M) - + if(distance <= maxdistance) if(T && T.z == turf_source.z) - M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, is_global) + M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, is_global, channel, pressure_affected, S) -var/const/FALLOFF_SOUNDS = 0.5 +/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, is_global, channel = 0, pressure_affected = TRUE, sound/S, preference) + if(!client || ear_deaf > 0) + return + if(preference && !client.is_preference_enabled(preference)) + return -/mob/proc/playsound_local(var/turf/turf_source, soundin, vol as num, vary, frequency, falloff, is_global) - if(!src.client || ear_deaf > 0) return - soundin = get_sfx(soundin) + if(!S) + S = sound(get_sfx(soundin)) - var/sound/S = sound(soundin) S.wait = 0 //No queue - S.channel = 0 //Any channel + S.channel = channel || open_sound_channel() S.volume = vol - S.environment = -1 - if (vary) + + if(vary) if(frequency) S.frequency = frequency else S.frequency = get_rand_frequency() - //sound volume falloff with pressure - var/pressure_factor = 1.0 - if(isturf(turf_source)) - // 3D sounds, the technology is here! var/turf/T = get_turf(src) //sound volume falloff with distance @@ -109,24 +52,32 @@ var/const/FALLOFF_SOUNDS = 0.5 S.volume -= max(distance - world.view, 0) * 2 //multiplicative falloff to add on top of natural audio falloff. - var/datum/gas_mixture/hearer_env = T.return_air() - var/datum/gas_mixture/source_env = turf_source.return_air() + //Atmosphere affects sound + var/pressure_factor = 1 + if(pressure_affected) + var/datum/gas_mixture/hearer_env = T.return_air() + var/datum/gas_mixture/source_env = turf_source.return_air() - if (hearer_env && source_env) - var/pressure = min(hearer_env.return_pressure(), source_env.return_pressure()) + if(hearer_env && source_env) + var/pressure = min(hearer_env.return_pressure(), source_env.return_pressure()) + if(pressure < ONE_ATMOSPHERE) + pressure_factor = max((pressure - SOUND_MINIMUM_PRESSURE)/(ONE_ATMOSPHERE - SOUND_MINIMUM_PRESSURE), 0) + else //space + pressure_factor = 0 - if (pressure < ONE_ATMOSPHERE) - pressure_factor = max((pressure - SOUND_MINIMUM_PRESSURE)/(ONE_ATMOSPHERE - SOUND_MINIMUM_PRESSURE), 0) - else //in space - pressure_factor = 0 + if(distance <= 1) + pressure_factor = max(pressure_factor, 0.15) //touching the source of the sound - if (distance <= 1) - pressure_factor = max(pressure_factor, 0.15) //hearing through contact + S.volume *= pressure_factor + //End Atmosphere affecting sound - S.volume *= pressure_factor + //Don't bother with doing anything below. + if(S.volume <= 0) + return //No sound - if (S.volume <= 0) - return //no volume means no sound + //Apply a sound environment. + if(!is_global) + S.environment = get_sound_env(pressure_factor) var/dx = turf_source.x - T.x // Hearing from the right/left S.x = dx @@ -136,34 +87,27 @@ var/const/FALLOFF_SOUNDS = 0.5 S.y = 1 S.falloff = (falloff ? falloff : FALLOFF_SOUNDS) - if(!is_global) - - if(istype(src,/mob/living/)) - var/mob/living/M = src - if (M.hallucination) - S.environment = PSYCHOTIC - else if (M.druggy) - S.environment = DRUGGED - else if (M.drowsyness) - S.environment = DIZZY - else if (M.confused) - S.environment = DIZZY - else if (M.sleeping) - S.environment = UNDERWATER - else if (pressure_factor < 0.5) - S.environment = SPACE - else - var/area/A = get_area(src) - S.environment = A.sound_env - - else if (pressure_factor < 0.5) - S.environment = SPACE - else - var/area/A = get_area(src) - S.environment = A.sound_env - src << S +/proc/sound_to_playing_players(sound, volume = 100, vary) + sound = get_sfx(sound) + for(var/M in player_list) + if(ismob(M) && !isnewplayer(M)) + var/mob/MO = M + MO.playsound_local(get_turf(MO), sound, volume, vary, pressure_affected = FALSE) + +/proc/open_sound_channel() + var/static/next_channel = 1 //loop through the available 1024 - (the ones we reserve) channels and pray that its not still being used + . = ++next_channel + if(next_channel > CHANNEL_HIGHEST_AVAILABLE) + next_channel = 1 + +/mob/proc/stop_sound_channel(chan) + src << sound(null, repeat = 0, wait = 0, channel = chan) + +/proc/get_rand_frequency() + return rand(32000, 55000) //Frequency stuff only works with 45kbps oggs. + /client/proc/playtitlemusic() if(!ticker || !all_lobby_tracks.len || !media) return if(is_preference_enabled(/datum/client_preference/play_lobby_music)) @@ -171,25 +115,26 @@ var/const/FALLOFF_SOUNDS = 0.5 media.push_music(T.url, world.time, 0.85) to_chat(src,"Lobby music: [T.title] by [T.artist].") -/proc/get_rand_frequency() - return rand(32000, 55000) //Frequency stuff only works with 45kbps oggs. - /proc/get_sfx(soundin) if(istext(soundin)) switch(soundin) - if ("shatter") soundin = pick(shatter_sound) - if ("explosion") soundin = pick(explosion_sound) - if ("sparks") soundin = pick(spark_sound) - if ("rustle") soundin = pick(rustle_sound) - if ("punch") soundin = pick(punch_sound) - if ("clownstep") soundin = pick(clown_sound) - if ("swing_hit") soundin = pick(swing_hit_sound) - if ("hiss") soundin = pick(hiss_sound) - if ("pageturn") soundin = pick(page_sound) - if ("fracture") soundin = pick(fracture_sound) - if ("canopen") soundin = pick(can_sound) - if ("mechstep") soundin = pick(mechstep_sound) - //if ("gunshot") soundin = pick(gun_sound) - if("geiger") soundin = pick(geiger_sound) - if("geiger_weak") soundin = pick(geiger_weak_sound) + if ("shatter") soundin = pick('sound/effects/Glassbr1.ogg','sound/effects/Glassbr2.ogg','sound/effects/Glassbr3.ogg') + if ("explosion") soundin = pick('sound/effects/Explosion1.ogg','sound/effects/Explosion2.ogg','sound/effects/Explosion3.ogg','sound/effects/Explosion4.ogg','sound/effects/Explosion5.ogg','sound/effects/Explosion6.ogg') + if ("sparks") soundin = pick('sound/effects/sparks1.ogg','sound/effects/sparks2.ogg','sound/effects/sparks3.ogg','sound/effects/sparks5.ogg','sound/effects/sparks6.ogg','sound/effects/sparks7.ogg') + if ("rustle") soundin = pick('sound/effects/rustle1.ogg','sound/effects/rustle2.ogg','sound/effects/rustle3.ogg','sound/effects/rustle4.ogg','sound/effects/rustle5.ogg') + if ("punch") soundin = pick('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg') + if ("clownstep") soundin = pick('sound/effects/clownstep1.ogg','sound/effects/clownstep2.ogg') + if ("swing_hit") soundin = pick('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg') + if ("hiss") soundin = pick('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg') + if ("pageturn") soundin = pick('sound/effects/pageturn1.ogg', 'sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg') + if ("fracture") soundin = pick('sound/effects/bonebreak1.ogg','sound/effects/bonebreak2.ogg','sound/effects/bonebreak3.ogg','sound/effects/bonebreak4.ogg') + if ("canopen") soundin = pick('sound/effects/can_open1.ogg','sound/effects/can_open2.ogg','sound/effects/can_open3.ogg','sound/effects/can_open4.ogg') + if ("mechstep") soundin = pick('sound/mecha/mechstep1.ogg', 'sound/mecha/mechstep2.ogg') + if ("geiger") soundin = pick('sound/items/geiger1.ogg', 'sound/items/geiger2.ogg', 'sound/items/geiger3.ogg', 'sound/items/geiger4.ogg', 'sound/items/geiger5.ogg') + if ("geiger_weak") soundin = pick('sound/items/geiger_weak1.ogg', 'sound/items/geiger_weak2.ogg', 'sound/items/geiger_weak3.ogg', 'sound/items/geiger_weak4.ogg') return soundin + +//Are these even used? +var/list/casing_sound = list ('sound/weapons/casingfall1.ogg','sound/weapons/casingfall2.ogg','sound/weapons/casingfall3.ogg') +var/list/keyboard_sound = list ('sound/effects/keyboard/keyboard1.ogg','sound/effects/keyboard/keyboard2.ogg','sound/effects/keyboard/keyboard3.ogg', 'sound/effects/keyboard/keyboard4.ogg') +var/list/bodyfall_sound = list('sound/effects/bodyfall1.ogg','sound/effects/bodyfall2.ogg','sound/effects/bodyfall3.ogg','sound/effects/bodyfall4.ogg') diff --git a/code/game/turfs/flooring/flooring.dm b/code/game/turfs/flooring/flooring.dm index e7d3ff5926..1affecf04f 100644 --- a/code/game/turfs/flooring/flooring.dm +++ b/code/game/turfs/flooring/flooring.dm @@ -1,5 +1,10 @@ var/list/flooring_types +/proc/populate_flooring_types() + flooring_types = list() + for (var/flooring_path in typesof(/decl/flooring)) + flooring_types["[flooring_path]"] = new flooring_path + /proc/get_flooring_data(var/flooring_path) if(!flooring_types) flooring_types = list() @@ -285,22 +290,12 @@ var/list/flooring_types 'sound/effects/footstep/wood4.ogg', 'sound/effects/footstep/wood5.ogg')) -/decl/flooring/sifwood +/decl/flooring/wood/sif name = "alien wooden floor" desc = "Polished alien wood planks." icon = 'icons/turf/flooring/wood.dmi' icon_base = "sifwood" - has_damage_range = 6 - damage_temperature = T0C+200 - descriptor = "planks" - build_type = /obj/item/stack/tile/sifwood - flags = TURF_CAN_BREAK | TURF_IS_FRAGILE | TURF_REMOVE_SCREWDRIVER - footstep_sounds = list("human" = list( - 'sound/effects/footstep/wood1.ogg', - 'sound/effects/footstep/wood2.ogg', - 'sound/effects/footstep/wood3.ogg', - 'sound/effects/footstep/wood4.ogg', - 'sound/effects/footstep/wood5.ogg')) + build_type = /obj/item/stack/tile/wood/sif /decl/flooring/reinforced name = "reinforced floor" diff --git a/code/game/turfs/flooring/flooring_decals.dm b/code/game/turfs/flooring/flooring_decals.dm index 84a243e35f..ea9a7f77fb 100644 --- a/code/game/turfs/flooring/flooring_decals.dm +++ b/code/game/turfs/flooring/flooring_decals.dm @@ -14,17 +14,29 @@ var/list/floor_decals = list() if(newcolour) color = newcolour ..(newloc) -// Hack to workaround byond crash bug /obj/effect/floor_decal/initialize() - if(!floor_decals_initialized || !loc || QDELETED(src)) - return add_to_turf_decals() - var/turf/T = get_turf(src) - if(T) //VOREStation Edit - T.apply_decals() initialized = TRUE return INITIALIZE_HINT_QDEL +// This is a separate proc from initialize() to facilitiate its caching and other stuff. Look into it someday. +/obj/effect/floor_decal/proc/add_to_turf_decals() + if(supplied_dir) + set_dir(supplied_dir) // TODO - Why can't this line be done in initialize/New()? + var/turf/T = get_turf(src) + if(istype(T, /turf/simulated/floor) || istype(T, /turf/unsimulated/floor) || istype(T, /turf/simulated/shuttle/floor)) + var/cache_key = "[alpha]-[color]-[dir]-[icon_state]-[T.layer]" + var/image/I = floor_decals[cache_key] + if(!I) + I = image(icon = icon, icon_state = icon_state, dir = dir) + I.layer = T.layer + I.color = color + I.alpha = alpha + floor_decals[cache_key] = I + LAZYADD(T.decals, I) // Add to its decals list (so it remembers to re-apply after it cuts overlays) + T.add_overlay(I) // Add to its current overlays too. + return T + /obj/effect/floor_decal/reset name = "reset marker" diff --git a/code/game/turfs/flooring/flooring_premade.dm b/code/game/turfs/flooring/flooring_premade.dm index cde55e50e3..106ba48422 100644 --- a/code/game/turfs/flooring/flooring_premade.dm +++ b/code/game/turfs/flooring/flooring_premade.dm @@ -68,11 +68,11 @@ icon_state = "wood" initial_flooring = /decl/flooring/wood -/turf/simulated/floor/sifwood +/turf/simulated/floor/wood/sif name = "alien wooden floor" icon = 'icons/turf/flooring/wood.dmi' icon_state = "sifwood" - initial_flooring = /decl/flooring/sifwood + initial_flooring = /decl/flooring/wood/sif /turf/simulated/floor/grass name = "grass patch" @@ -230,9 +230,8 @@ oxygen = 0 nitrogen = 0 -/turf/simulated/floor/reinforced/n20/New() - ..() - sleep(-1) +/turf/simulated/floor/reinforced/n20/initialize() + . = ..() if(!air) make_air() air.adjust_gas("sleeping_agent", ATMOSTANK_NITROUSOXIDE) @@ -412,11 +411,11 @@ . = ..() /turf/snow/update_icon() - overlays.Cut() + cut_overlays() for(var/d in crossed_dirs) var/amt = crossed_dirs[d] for(var/i in 1 to amt) - overlays += icon(icon, "footprint[i]", text2num(d)) + add_overlay(image(icon, "footprint[i]", text2num(d))) //**** Here ends snow **** \ No newline at end of file diff --git a/code/game/turfs/flooring/turf_overlay_holder.dm b/code/game/turfs/flooring/turf_overlay_holder.dm deleted file mode 100644 index c12f727a0b..0000000000 --- a/code/game/turfs/flooring/turf_overlay_holder.dm +++ /dev/null @@ -1,95 +0,0 @@ -// -// Initialize floor decals! Woo! This is crazy. -// - -var/global/floor_decals_initialized = FALSE - -// The Turf Decal Holder -// Since it is unsafe to add overlays to turfs, we hold them here for now. -// Since I want this object to basically not exist, I am modeling it in part after lighting_overlay -/atom/movable/turf_overlay_holder - name = "turf overlay holder" - density = 0 - simulated = 0 - anchored = 1 - layer = TURF_LAYER - icon = null - icon_state = null - mouse_opacity = 0 - // auto_init = 0 - -/atom/movable/turf_overlay_holder/initialize() - // doesn't need special init - initialized = TRUE - return INITIALIZE_HINT_NORMAL - -/atom/movable/turf_overlay_holder/New(var/atom/newloc) - ..() - verbs.Cut() - var/turf/T = loc - T.overlay_holder = src - -/atom/movable/turf_overlay_holder/Destroy() - if(loc) - var/turf/T = loc - if(T.overlay_holder == src) - T.overlay_holder = null - . = ..() - -// Variety of overrides so the overlays don't get affected by weird things. -/atom/movable/turf_overlay_holder/ex_act() - return - -/atom/movable/turf_overlay_holder/singularity_act() - return - -/atom/movable/turf_overlay_holder/singularity_pull() - return - -/atom/movable/turf_overlay_holder/forceMove() - return 0 //should never move - -/atom/movable/turf_overlay_holder/Move() - return 0 - -/atom/movable/turf_overlay_holder/throw_at() - return 0 - -/obj/effect/floor_decal/proc/add_to_turf_decals() - if(src.supplied_dir) src.set_dir(src.supplied_dir) - var/turf/T = get_turf(src) - if(istype(T, /turf/simulated/floor) || istype(T, /turf/unsimulated/floor) || istype(T, /turf/simulated/shuttle/floor)) - var/cache_key = "[src.alpha]-[src.color]-[src.dir]-[src.icon_state]-[T.layer]" - var/image/I = floor_decals[cache_key] - if(!I) - I = image(icon = src.icon, icon_state = src.icon_state, dir = src.dir) - I.layer = T.layer - I.color = src.color - I.alpha = src.alpha - floor_decals[cache_key] = I - if(!T.decals) T.decals = list() - //world.log << "About to add img:\ref[I] onto decals at turf:\ref[T] ([T.x],[T.y],[T.z]) which has appearance:\ref[T.appearance] and decals.len=[T.decals.len]" - T.decals += I - return T - // qdel(D) - src.loc = null - src.tag = null - -// Changes to turf to let us do this -/turf - var/atom/movable/turf_overlay_holder/overlay_holder = null - -// After a turf change, destroy the old overlay holder since we will have lost access to it. -/turf/post_change() - var/atom/movable/turf_overlay_holder/TOH = locate(/atom/movable/turf_overlay_holder, src) - if(TOH) - qdel(TOH) - ..() - -/turf/proc/apply_decals() - if(decals) - if(!overlay_holder) - overlay_holder = new(src) - overlay_holder.overlays = src.decals - else if(overlay_holder) - overlay_holder.overlays.Cut() diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index 789ec20a17..e156588937 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -21,16 +21,15 @@ spawn(0) wet = wet_val if(wet_overlay) - overlays -= wet_overlay - wet_overlay = null - wet_overlay = image('icons/effects/water.dmi',src,"wet_floor") - overlays += wet_overlay + cut_overlay(wet_overlay) + wet_overlay = image('icons/effects/water.dmi', icon_state = "wet_floor") + add_overlay(wet_overlay) sleep(800) if(wet == 2) sleep(3200) wet = 0 if(wet_overlay) - overlays -= wet_overlay + cut_overlay(wet_overlay) wet_overlay = null /turf/simulated/proc/freeze_floor() @@ -38,14 +37,14 @@ return wet = 3 // icy if(wet_overlay) - overlays -= wet_overlay + cut_overlay(wet_overlay) wet_overlay = null wet_overlay = image('icons/turf/overlays.dmi',src,"snowfloor") - overlays += wet_overlay + add_overlay(wet_overlay) spawn(5 MINUTES) wet = 0 if(wet_overlay) - overlays -= wet_overlay + cut_overlay(wet_overlay) wet_overlay = null /turf/simulated/clean_blood() diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index f906335819..9f3a8e67b0 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -60,7 +60,7 @@ //This proc auto corrects the grass tiles' siding. /turf/simulated/floor/proc/make_plating(var/place_product, var/defer_icon_update) - overlays.Cut() + cut_overlays() // VOREStation Edit - We are flooring switching to plating, swap out old_decals for decals. if(flooring) var/tmp/list/underfloor_decals = old_decals diff --git a/code/game/turfs/simulated/floor_attackby.dm b/code/game/turfs/simulated/floor_attackby.dm index ef36121b12..5602eac320 100644 --- a/code/game/turfs/simulated/floor_attackby.dm +++ b/code/game/turfs/simulated/floor_attackby.dm @@ -4,40 +4,15 @@ return 0 if(flooring) - if(istype(C, /obj/item/weapon/crowbar)) - if(broken || burnt) - to_chat(user, "You remove the broken [flooring.descriptor].") - make_plating() - else if(flooring.flags & TURF_IS_FRAGILE) - to_chat(user, "You forcefully pry off the [flooring.descriptor], destroying them in the process.") - make_plating() - else if(flooring.flags & TURF_REMOVE_CROWBAR) - to_chat(user, "You lever off the [flooring.descriptor].") - make_plating(1) - else - return - playsound(src, C.usesound, 80, 1) - return - else if(istype(C, /obj/item/weapon/screwdriver) && (flooring.flags & TURF_REMOVE_SCREWDRIVER)) - if(broken || burnt) - return - to_chat(user, "You unscrew and remove the [flooring.descriptor].") - make_plating(1) - playsound(src, C.usesound, 80, 1) - return - else if(istype(C, /obj/item/weapon/wrench) && (flooring.flags & TURF_REMOVE_WRENCH)) - to_chat(user, "You unwrench and remove the [flooring.descriptor].") - make_plating(1) - playsound(src, C.usesound, 80, 1) - return - else if(istype(C, /obj/item/weapon/shovel) && (flooring.flags & TURF_REMOVE_SHOVEL)) - to_chat(user, "You shovel off the [flooring.descriptor].") - make_plating(1) - playsound(src, 'sound/items/Deconstruct.ogg', 80, 1) + if(istype(C, /obj/item/weapon)) + try_deconstruct_tile(C, user) return else if(istype(C, /obj/item/stack/cable_coil)) to_chat(user, "You must remove the [flooring.descriptor] first.") return + else if(istype(C, /obj/item/stack/tile)) + try_replace_tile(C, user) + return else if(istype(C, /obj/item/stack/cable_coil)) @@ -87,4 +62,48 @@ burnt = null broken = null else - to_chat(user, "You need more welding fuel to complete this task.") \ No newline at end of file + to_chat(user, "You need more welding fuel to complete this task.") + +/turf/simulated/floor/proc/try_deconstruct_tile(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/crowbar)) + if(broken || burnt) + to_chat(user, "You remove the broken [flooring.descriptor].") + make_plating() + else if(flooring.flags & TURF_IS_FRAGILE) + to_chat(user, "You forcefully pry off the [flooring.descriptor], destroying them in the process.") + make_plating() + else if(flooring.flags & TURF_REMOVE_CROWBAR) + to_chat(user, "You lever off the [flooring.descriptor].") + make_plating(1) + else + return 0 + playsound(src, W.usesound, 80, 1) + return 1 + else if(istype(W, /obj/item/weapon/screwdriver) && (flooring.flags & TURF_REMOVE_SCREWDRIVER)) + if(broken || burnt) + return 0 + to_chat(user, "You unscrew and remove the [flooring.descriptor].") + make_plating(1) + playsound(src, W.usesound, 80, 1) + return 1 + else if(istype(W, /obj/item/weapon/wrench) && (flooring.flags & TURF_REMOVE_WRENCH)) + to_chat(user, "You unwrench and remove the [flooring.descriptor].") + make_plating(1) + playsound(src, W.usesound, 80, 1) + return 1 + else if(istype(W, /obj/item/weapon/shovel) && (flooring.flags & TURF_REMOVE_SHOVEL)) + to_chat(user, "You shovel off the [flooring.descriptor].") + make_plating(1) + playsound(src, 'sound/items/Deconstruct.ogg', 80, 1) + return 1 + return 0 + +/turf/simulated/floor/proc/try_replace_tile(obj/item/stack/tile/T as obj, mob/user as mob) + if(T.type == flooring.build_type) + return + var/obj/item/weapon/W = user.is_holding_item_of_type(/obj/item/weapon) + if(!try_deconstruct_tile(W, user)) + return + if(flooring) + return + attackby(T, user) \ No newline at end of file diff --git a/code/game/turfs/simulated/floor_icon.dm b/code/game/turfs/simulated/floor_icon.dm index 940a170cdb..1faf198ced 100644 --- a/code/game/turfs/simulated/floor_icon.dm +++ b/code/game/turfs/simulated/floor_icon.dm @@ -15,7 +15,7 @@ var/image/no_ceiling_image = null if(lava) return - overlays.Cut() + cut_overlays() if(flooring) // Set initial icon and strings. @@ -38,17 +38,17 @@ var/image/no_ceiling_image = null var/turf/simulated/floor/T = get_step(src, step_dir) if(!istype(T) || !T.flooring || T.flooring.name != flooring.name) has_border |= step_dir - overlays |= get_flooring_overlay("[flooring.icon_base]-edge-[step_dir]", "[flooring.icon_base]_edges", step_dir) + add_overlay(get_flooring_overlay("[flooring.icon_base]-edge-[step_dir]", "[flooring.icon_base]_edges", step_dir)) // There has to be a concise numerical way to do this but I am too noob. if((has_border & NORTH) && (has_border & EAST)) - overlays |= get_flooring_overlay("[flooring.icon_base]-edge-[NORTHEAST]", "[flooring.icon_base]_edges", NORTHEAST) + add_overlay(get_flooring_overlay("[flooring.icon_base]-edge-[NORTHEAST]", "[flooring.icon_base]_edges", NORTHEAST)) if((has_border & NORTH) && (has_border & WEST)) - overlays |= get_flooring_overlay("[flooring.icon_base]-edge-[NORTHWEST]", "[flooring.icon_base]_edges", NORTHWEST) + add_overlay(get_flooring_overlay("[flooring.icon_base]-edge-[NORTHWEST]", "[flooring.icon_base]_edges", NORTHWEST)) if((has_border & SOUTH) && (has_border & EAST)) - overlays |= get_flooring_overlay("[flooring.icon_base]-edge-[SOUTHEAST]", "[flooring.icon_base]_edges", SOUTHEAST) + add_overlay(get_flooring_overlay("[flooring.icon_base]-edge-[SOUTHEAST]", "[flooring.icon_base]_edges", SOUTHEAST)) if((has_border & SOUTH) && (has_border & WEST)) - overlays |= get_flooring_overlay("[flooring.icon_base]-edge-[SOUTHWEST]", "[flooring.icon_base]_edges", SOUTHWEST) + add_overlay(get_flooring_overlay("[flooring.icon_base]-edge-[SOUTHWEST]", "[flooring.icon_base]_edges", SOUTHWEST)) if(flooring.flags & TURF_HAS_CORNERS) // As above re: concise numerical way to do this. @@ -56,37 +56,36 @@ var/image/no_ceiling_image = null if(!(has_border & EAST)) var/turf/simulated/floor/T = get_step(src, NORTHEAST) if(!(istype(T) && T.flooring && T.flooring.name == flooring.name)) - overlays |= get_flooring_overlay("[flooring.icon_base]-corner-[NORTHEAST]", "[flooring.icon_base]_corners", NORTHEAST) + add_overlay(get_flooring_overlay("[flooring.icon_base]-corner-[NORTHEAST]", "[flooring.icon_base]_corners", NORTHEAST)) if(!(has_border & WEST)) var/turf/simulated/floor/T = get_step(src, NORTHWEST) if(!(istype(T) && T.flooring && T.flooring.name == flooring.name)) - overlays |= get_flooring_overlay("[flooring.icon_base]-corner-[NORTHWEST]", "[flooring.icon_base]_corners", NORTHWEST) + add_overlay(get_flooring_overlay("[flooring.icon_base]-corner-[NORTHWEST]", "[flooring.icon_base]_corners", NORTHWEST)) if(!(has_border & SOUTH)) if(!(has_border & EAST)) var/turf/simulated/floor/T = get_step(src, SOUTHEAST) if(!(istype(T) && T.flooring && T.flooring.name == flooring.name)) - overlays |= get_flooring_overlay("[flooring.icon_base]-corner-[SOUTHEAST]", "[flooring.icon_base]_corners", SOUTHEAST) + add_overlay(get_flooring_overlay("[flooring.icon_base]-corner-[SOUTHEAST]", "[flooring.icon_base]_corners", SOUTHEAST)) if(!(has_border & WEST)) var/turf/simulated/floor/T = get_step(src, SOUTHWEST) if(!(istype(T) && T.flooring && T.flooring.name == flooring.name)) - overlays |= get_flooring_overlay("[flooring.icon_base]-corner-[SOUTHWEST]", "[flooring.icon_base]_corners", SOUTHWEST) + add_overlay(get_flooring_overlay("[flooring.icon_base]-corner-[SOUTHWEST]", "[flooring.icon_base]_corners", SOUTHWEST)) - // Hack workaround to byond crash bug - //if(decals && decals.len) - //overlays |= decals - apply_decals() + // Re-apply floor decals + if(LAZYLEN(decals)) + add_overlay(decals) if(is_plating() && !(isnull(broken) && isnull(burnt))) //temp, todo icon = 'icons/turf/flooring/plating.dmi' icon_state = "dmg[rand(1,4)]" else if(flooring) if(!isnull(broken) && (flooring.flags & TURF_CAN_BREAK)) - overlays |= get_flooring_overlay("[flooring.icon_base]-broken-[broken]","broken[broken]") // VOREStation Edit - Eris overlays + add_overlay(get_flooring_overlay("[flooring.icon_base]-broken-[broken]","broken[broken]")) // VOREStation Edit - Eris overlays if(!isnull(burnt) && (flooring.flags & TURF_CAN_BURN)) - overlays |= get_flooring_overlay("[flooring.icon_base]-burned-[burnt]","burned[burnt]") // VOREStation Edit - Eris overlays + add_overlay(get_flooring_overlay("[flooring.icon_base]-burned-[burnt]","burned[burnt]")) // VOREStation Edit - Eris overlays if(weather_overlay) - overlays += weather_overlay + add_overlay(weather_overlay) if(update_neighbors) for(var/turf/simulated/floor/F in range(src, 1)) @@ -97,7 +96,7 @@ var/image/no_ceiling_image = null // Show 'ceilingless' overlay. var/turf/above = GetAbove(src) if(above && isopenspace(above) && !istype(src, /turf/simulated/floor/outdoors)) // This won't apply to outdoor turfs since its assumed they don't have a ceiling anyways. - overlays |= no_ceiling_image + add_overlay(no_ceiling_image) /turf/simulated/floor/proc/get_flooring_overlay(var/cache_key, var/icon_base, var/icon_dir = 0) if(!flooring_cache[cache_key]) diff --git a/code/game/turfs/simulated/floor_types.dm b/code/game/turfs/simulated/floor_types.dm index 07c686df99..3c4856cf00 100644 --- a/code/game/turfs/simulated/floor_types.dm +++ b/code/game/turfs/simulated/floor_types.dm @@ -15,17 +15,19 @@ var/list/decals New(var/location = null, var/turf/simulated/shuttle/turf) + ..(null) my_turf = turf /obj/landed_holder/proc/land_on(var/turf/T) //Gather destination information - var/old_dest_type = T.type - var/old_dest_dir = T.dir - var/old_dest_icon_state = T.icon_state - var/old_dest_icon = T.icon - var/list/old_dest_overlays = T.overlays.Copy() - var/list/old_dest_underlays = T.underlays.Copy() - var/list/old_dest_decals = T.decals ? T.decals.Copy() : null + var/obj/landed_holder/new_holder = new(null) + new_holder.turf_type = T.type + new_holder.dir = T.dir + new_holder.icon = T.icon + new_holder.icon_state = T.icon_state + new_holder.copy_overlays(T, TRUE) + new_holder.underlays = T.underlays.Copy() + new_holder.decals = T.decals ? T.decals.Copy() : null //Set the destination to be like us T.Destroy() @@ -33,7 +35,7 @@ new_dest.set_dir(my_turf.dir) new_dest.icon_state = my_turf.icon_state new_dest.icon = my_turf.icon - new_dest.overlays = my_turf.overlays + new_dest.copy_overlays(my_turf, TRUE) new_dest.underlays = my_turf.underlays new_dest.decals = my_turf.decals //Shuttle specific stuff @@ -43,18 +45,9 @@ new_dest.join_flags = my_turf.join_flags new_dest.join_group = my_turf.join_group - if(new_dest.decals) - new_dest.apply_decals() - - //Tell the new turf about what was there before - new_dest.landed_holder = new(turf = new_dest) - new_dest.landed_holder.turf_type = old_dest_type - new_dest.landed_holder.dir = old_dest_dir - new_dest.landed_holder.icon = old_dest_icon - new_dest.landed_holder.icon_state = old_dest_icon_state - new_dest.landed_holder.overlays = old_dest_overlays - new_dest.landed_holder.underlays = old_dest_underlays - new_dest.landed_holder.decals = old_dest_decals + // Associate the holder with the new turf. + new_holder.my_turf = new_dest + new_dest.landed_holder = new_holder //Update underlays if necessary (interior corners won't have changed). if(new_dest.takes_underlays && !new_dest.interior_corner) @@ -70,11 +63,9 @@ new_source.set_dir(dir) new_source.icon_state = icon_state new_source.icon = icon - new_source.overlays = overlays + new_source.copy_overlays(src, TRUE) new_source.underlays = underlays new_source.decals = decals - if(new_source.decals) - new_source.apply_decals() else new_source = my_turf.ChangeTurf(get_base_turf_by_area(my_turf),,1) diff --git a/code/game/turfs/simulated/outdoors/outdoors.dm b/code/game/turfs/simulated/outdoors/outdoors.dm index 13d983a9e1..cd358b7d5e 100644 --- a/code/game/turfs/simulated/outdoors/outdoors.dm +++ b/code/game/turfs/simulated/outdoors/outdoors.dm @@ -44,7 +44,9 @@ var/list/outdoor_turfs = list() planet_controller.unallocateTurf(src) else // This is happening during map gen, if there's no planet_controller (hopefully). outdoor_turfs -= src - qdel(weather_overlay) + if(weather_overlay) + cut_overlay(weather_overlay) + qdel_null(weather_overlay) update_icon() /turf/simulated/post_change() @@ -67,15 +69,14 @@ var/list/outdoor_turfs = list() var/image/I = image(icon = 'icons/turf/outdoors_edge.dmi', icon_state = "[T.get_edge_icon_state()]-edge", dir = checkdir) I.plane = 0 turf_edge_cache[cache_key] = I - overlays += turf_edge_cache[cache_key] + add_overlay(turf_edge_cache[cache_key]) /turf/simulated/proc/get_edge_icon_state() return icon_state /turf/simulated/floor/outdoors/update_icon() - overlays.Cut() - update_icon_edge() ..() + update_icon_edge() /turf/simulated/floor/outdoors/mud name = "mud" diff --git a/code/game/turfs/simulated/outdoors/snow.dm b/code/game/turfs/simulated/outdoors/snow.dm index 8e60c925e5..9926c4704a 100644 --- a/code/game/turfs/simulated/outdoors/snow.dm +++ b/code/game/turfs/simulated/outdoors/snow.dm @@ -17,10 +17,9 @@ . = ..() /turf/simulated/floor/outdoors/snow/update_icon() - overlays.Cut() ..() for(var/d in crossed_dirs) - overlays += image(icon = 'icons/turf/outdoors.dmi', icon_state = "snow_footprints", dir = text2num(d)) + add_overlay(image(icon = 'icons/turf/outdoors.dmi', icon_state = "snow_footprints", dir = text2num(d))) /turf/simulated/floor/outdoors/snow/attackby(var/obj/item/W, var/mob/user) if(istype(W, /obj/item/weapon/shovel)) diff --git a/code/game/turfs/simulated/wall_icon.dm b/code/game/turfs/simulated/wall_icon.dm index 2dac063723..b8a0980de4 100644 --- a/code/game/turfs/simulated/wall_icon.dm +++ b/code/game/turfs/simulated/wall_icon.dm @@ -47,36 +47,36 @@ if(!damage_overlays[1]) //list hasn't been populated generate_overlays() - overlays.Cut() + cut_overlays() var/image/I if(!density) I = image('icons/turf/wall_masks.dmi', "[material.icon_base]fwall_open") I.color = material.icon_colour - overlays += I + add_overlay(I) return for(var/i = 1 to 4) I = image('icons/turf/wall_masks.dmi', "[material.icon_base][wall_connections[i]]", dir = 1<<(i-1)) I.color = material.icon_colour - overlays += I + add_overlay(I) if(reinf_material) if(construction_stage != null && construction_stage < 6) I = image('icons/turf/wall_masks.dmi', "reinf_construct-[construction_stage]") I.color = reinf_material.icon_colour - overlays += I + add_overlay(I) else if("[reinf_material.icon_reinf]0" in icon_states('icons/turf/wall_masks.dmi')) // Directional icon for(var/i = 1 to 4) I = image('icons/turf/wall_masks.dmi', "[reinf_material.icon_reinf][wall_connections[i]]", dir = 1<<(i-1)) I.color = reinf_material.icon_colour - overlays += I + add_overlay(I) else I = image('icons/turf/wall_masks.dmi', reinf_material.icon_reinf) I.color = reinf_material.icon_colour - overlays += I + add_overlay(I) if(damage != 0) var/integrity = material.integrity @@ -87,7 +87,7 @@ if(overlay > damage_overlays.len) overlay = damage_overlays.len - overlays += damage_overlays[overlay] + add_overlay(damage_overlays[overlay]) return /turf/simulated/wall/proc/generate_overlays() diff --git a/code/game/turfs/simulated/wall_types.dm b/code/game/turfs/simulated/wall_types.dm index 6118c2741f..7fefbf8a3c 100644 --- a/code/game/turfs/simulated/wall_types.dm +++ b/code/game/turfs/simulated/wall_types.dm @@ -230,15 +230,7 @@ /turf/simulated/shuttle/wall/voidcraft/update_icon() if(stripe_color) - overlays = list() //VOREStation Edit - Another place with overlay nonsense. + cut_overlays() var/image/I = image(icon = src.icon, icon_state = "o_[icon_state]") I.color = stripe_color - //VOREStation Add - Shenanigans around this because of the bullshit byond bug - var/pre_overlays = overlays.len - overlays.Add(I) - var/post_overlays = overlays.len - if(post_overlays != (pre_overlays + 1)) - world.log << "Corrupted overlays on [x],[y],[z] voidcraft wall" - new type(src) - return - //VOREStation Add End + add_overlay(I) diff --git a/code/game/turfs/simulated/wall_types_vr.dm b/code/game/turfs/simulated/wall_types_vr.dm index 90d389bf53..4d939c2004 100644 --- a/code/game/turfs/simulated/wall_types_vr.dm +++ b/code/game/turfs/simulated/wall_types_vr.dm @@ -26,7 +26,7 @@ var/list/flesh_overlay_cache = list() /turf/simulated/flesh/update_icon(var/update_neighbors) - overlays.Cut() + cut_overlays() if(density) icon = 'icons/turf/stomach_vr.dmi' @@ -37,7 +37,7 @@ var/list/flesh_overlay_cache = list() var/place_dir = turn(direction, 180) if(!flesh_overlay_cache["flesh_side_[place_dir]"]) flesh_overlay_cache["flesh_side_[place_dir]"] = image('icons/turf/stomach_vr.dmi', "flesh_side", dir = place_dir) - T.overlays += flesh_overlay_cache["flesh_side_[place_dir]"] + add_overlay(flesh_overlay_cache["flesh_side_[place_dir]"]) if(update_neighbors) for(var/direction in alldirs) diff --git a/code/game/turfs/simulated/water.dm b/code/game/turfs/simulated/water.dm index a47578f102..e4b762d733 100644 --- a/code/game/turfs/simulated/water.dm +++ b/code/game/turfs/simulated/water.dm @@ -16,7 +16,6 @@ update_icon() /turf/simulated/floor/water/update_icon() - overlays.Cut() ..() // To get the edges. icon_state = water_state var/image/floorbed_sprite = image(icon = 'icons/turf/outdoors.dmi', icon_state = under_state) @@ -129,16 +128,16 @@ var/list/shoreline_icon_cache = list() // Water sprites are really annoying, so let BYOND sort it out. /turf/simulated/floor/water/shoreline/update_icon() underlays.Cut() - overlays.Cut() + cut_overlays() ..() // Get the underlay first. var/cache_string = "[initial(icon_state)]_[water_state]_[dir]" if(cache_string in shoreline_icon_cache) // Check to see if an icon already exists. - overlays += shoreline_icon_cache[cache_string] + add_overlay(shoreline_icon_cache[cache_string]) else // If not, make one, but only once. var/icon/shoreline_water = icon(src.icon, "shoreline_water", src.dir) var/icon/shoreline_subtract = icon(src.icon, "[initial(icon_state)]_subtract", src.dir) shoreline_water.Blend(shoreline_subtract,ICON_SUBTRACT) shoreline_icon_cache[cache_string] = shoreline_water - overlays += shoreline_icon_cache[cache_string] + add_overlay(shoreline_icon_cache[cache_string]) diff --git a/code/game/turfs/snow/snow.dm b/code/game/turfs/snow/snow.dm index b09275ca41..a8ccd5b63b 100644 --- a/code/game/turfs/snow/snow.dm +++ b/code/game/turfs/snow/snow.dm @@ -26,12 +26,12 @@ . = ..() /turf/snow/update_icon() - overlays.Cut() + cut_overlays() for(var/d in crossed_dirs) var/amt = crossed_dirs[d] for(var/i in 1 to amt) - overlays += icon(icon, "footprint[i]", text2num(d)) + add_overlay(image(icon, "footprint[i]", text2num(d))) /turf/snow/snow2 name = "snow" diff --git a/code/game/turfs/space/cracked_asteroid.dm b/code/game/turfs/space/cracked_asteroid.dm index b9f43af82e..dae0d5a129 100644 --- a/code/game/turfs/space/cracked_asteroid.dm +++ b/code/game/turfs/space/cracked_asteroid.dm @@ -10,7 +10,8 @@ /turf/space/cracked_asteroid/is_space() // So people don't start floating when standing on it. return FALSE -/turf/space/cracked_asteroid/New() - ..() - spawn(2 SECONDS) - overlays.Cut() \ No newline at end of file +// u wot m8? ~Leshana +// /turf/space/cracked_asteroid/New() +// ..() +// spawn(2 SECONDS) +// overlays.Cut() diff --git a/code/game/turfs/unsimulated/beach.dm b/code/game/turfs/unsimulated/beach.dm index 57dee24951..28cebacb8a 100644 --- a/code/game/turfs/unsimulated/beach.dm +++ b/code/game/turfs/unsimulated/beach.dm @@ -17,7 +17,7 @@ /turf/unsimulated/beach/water/New() ..() - overlays += image("icon"='icons/misc/beach.dmi',"icon_state"="water2","layer"=MOB_LAYER+0.1) + add_overlay(image("icon"='icons/misc/beach.dmi',"icon_state"="water2","layer"=MOB_LAYER+0.1)) /turf/simulated/floor/beach name = "Beach" @@ -56,4 +56,4 @@ /turf/simulated/floor/beach/water/New() ..() - overlays += image("icon"='icons/misc/beach.dmi',"icon_state"="water5","layer"=MOB_LAYER+0.1) + add_overlay(image("icon"='icons/misc/beach.dmi',"icon_state"="water5","layer"=MOB_LAYER+0.1)) diff --git a/code/global.dm b/code/global.dm index a65e010c03..efb58b3318 100644 --- a/code/global.dm +++ b/code/global.dm @@ -184,7 +184,7 @@ var/static/list/scarySounds = list( var/max_explosion_range = 14 // Announcer intercom, because too much stuff creates an intercom for one message then hard del()s it. -var/global/obj/item/device/radio/intercom/global_announcer = new /obj/item/device/radio/intercom{channels=list("Engineering")}(null) +var/global/obj/item/device/radio/intercom/omni/global_announcer = new /obj/item/device/radio/intercom/omni(null) var/list/station_departments = list("Command", "Medical", "Engineering", "Science", "Security", "Cargo", "Civilian") diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 4eefda8d1d..9a5ac33c22 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -380,7 +380,7 @@ proc/admin_notice(var/message, var/rights) if(3) dat+={" Creating new Feed Message... -
Receiving Channel: [src.admincaster_feed_channel.channel_name]
" //MARK +
Receiving Channel: [src.admincaster_feed_channel.channel_name]
Message Author: [src.admincaster_signature]
Message Body: [src.admincaster_feed_message.body]

Submit

Cancel
@@ -677,10 +677,7 @@ var/datum/announcement/minor/admin_min_announcer = new set desc = "Send an intercom message, like an arrivals announcement." if(!check_rights(0)) return - //This is basically how death alarms do it - var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/omni(null) - - var/channel = input("Channel for message:","Channel", null) as null|anything in (list("Common") + a.keyslot2.channels) // + a.keyslot1.channels + var/channel = input("Channel for message:","Channel", null) as null|anything in radiochannels if(channel) //They picked a channel var/sender = input("Name of sender (max 75):", "Announcement", "Announcement Computer") as null|text @@ -691,11 +688,94 @@ var/datum/announcement/minor/admin_min_announcer = new if(message) //They put a message message = sanitize(message, 500, extra = 0) - a.autosay("[message]", "[sender]", "[channel == "Common" ? null : channel]") //Common is a weird case, as it's not a "channel", it's just talking into a radio without a channel set. + global_announcer.autosay("[message]", "[sender]", "[channel == "Common" ? null : channel]") //Common is a weird case, as it's not a "channel", it's just talking into a radio without a channel set. log_admin("Intercom: [key_name(usr)] : [sender]:[message]") - qdel(a) + feedback_add_details("admin_verb","IN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/datum/admins/proc/intercom_convo() + set category = "Fun" + set name = "Intercom Convo" + set desc = "Send an intercom conversation, like several uses of the Intercom Msg verb." + set waitfor = FALSE //Why bother? We have some sleeps. You can leave tho! + if(!check_rights(0)) return + + var/channel = input("Channel for message:","Channel", null) as null|anything in radiochannels + + if(!channel) //They picked a channel + return + + to_chat(usr,"Intercom Convo Directions
Start the conversation with the sender, a pipe (|), and then the message on one line. Then hit enter to \ + add another line, and type a (whole) number of seconds to pause between that message, and the next message, then repeat the message syntax up to 20 times. For example:
\ + --- --- ---
\ + Some Guy|Hello guys, what's up?
\ + 5
\ + Other Guy|Hey, good to see you.
\ + 5
\ + Some Guy|Yeah, you too.
\ + --- --- ---
\ + The above will result in those messages playing, with a 5 second gap between each. Maximum of 20 messages allowed.
") + + var/list/decomposed + var/message = input(usr,"See your chat box for instructions. Keep a copy elsewhere in case it is rejected when you click OK.", "Input Conversation", "") as null|message + + if(!message) + return + + //Split on pipe or \n + decomposed = splittext(message,regex("\\||$","m")) + decomposed += "0" //Tack on a final 0 sleep to make 3-per-message evenly + + //Time to find how they screwed up. + //Wasn't the right length + if((decomposed.len) % 3) //+1 to accomidate the lack of a wait time for the last message + to_chat(usr,"You passed [decomposed.len] segments (senders+messages+pauses). You must pass a multiple of 3, minus 1 (no pause after the last message). That means a sender and message on every other line (starting on the first), separated by a pipe character (|), and a number every other line that is a pause in seconds.") + return + + //Too long a conversation + if((decomposed.len / 3) > 20) + to_chat(usr,"This conversation is too long! 20 messages maximum, please.") + return + + //Missed some sleeps, or sanitized to nothing. + for(var/i = 1; i < decomposed.len; i++) + + //Sanitize sender + var/clean_sender = sanitize(decomposed[i]) + if(!clean_sender) + to_chat(usr,"One part of your conversation was not able to be sanitized. It was the sender of the [(i+2)/3]\th message.") + return + decomposed[i] = clean_sender + + //Sanitize message + var/clean_message = sanitize(decomposed[++i]) + if(!clean_message) + to_chat(usr,"One part of your conversation was not able to be sanitized. It was the body of the [(i+2)/3]\th message.") + return + decomposed[i] = clean_message + + //Sanitize wait time + var/clean_time = text2num(decomposed[++i]) + if(!isnum(clean_time)) + to_chat(usr,"One part of your conversation was not able to be sanitized. It was the wait time after the [(i+2)/3]\th message.") + return + if(clean_time > 60) + to_chat(usr,"Max 60 second wait time between messages for sanity's sake please.") + return + decomposed[i] = clean_time + + log_admin("Intercom convo started by: [key_name(usr)] : [sanitize(message)]") + feedback_add_details("admin_verb","IN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + + //Sanitized AND we still have a chance to send it? Wow! + if(LAZYLEN(decomposed)) + for(var/i = 1; i < decomposed.len; i++) + var/this_sender = decomposed[i] + var/this_message = decomposed[++i] + var/this_wait = decomposed[++i] + global_announcer.autosay("[this_message]", "[this_sender]", "[channel == "Common" ? null : channel]") //Common is a weird case, as it's not a "channel", it's just talking into a radio without a channel set. + sleep(this_wait SECONDS) + /datum/admins/proc/toggleooc() set category = "Server" set desc="Globally Toggles OOC" diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index bbd10a20dc..59a787a2ae 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -26,6 +26,7 @@ var/list/admin_verbs_admin = list( /datum/admins/proc/toggleguests, //toggles whether guests can join the current game, /datum/admins/proc/announce, //priority announce something to all clients., /datum/admins/proc/intercom, //send a fake intercom message, like an arrivals announcement, + /datum/admins/proc/intercom_convo, //send a fake intercom conversation, like an ATC exchange, /client/proc/colorooc, //allows us to set a custom colour for everythign we say in ooc, /client/proc/admin_ghost, //allows us to ghost/reenter body at will, /client/proc/toggle_view_range, //changes how far we can see, diff --git a/code/modules/admin/view_variables/view_variables.dm b/code/modules/admin/view_variables/view_variables.dm index e624d2df05..cb110d4e86 100644 --- a/code/modules/admin/view_variables/view_variables.dm +++ b/code/modules/admin/view_variables/view_variables.dm @@ -143,7 +143,12 @@ vtext = "\ref[C] - [C] ([C.type])" else if(islist(value)) var/list/L = value - vtext = "/list ([L.len])" + var/removed = 0 + if(varname == "contents") + var/list/original = value + L = original.Copy() //We'll take a copy to manipulate + removed = D.view_variables_filter_contents(L) + vtext = "/list ([L.len]+[removed]H)" if(!(varname in view_variables_dont_expand) && L.len > 0 && L.len < 100) extra = "