diff --git a/.travis.yml b/.travis.yml index 5a3b08a14a..8fb0e58f4e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ sudo: false env: global: - BYOND_MAJOR="512" - - BYOND_MINOR="1411" + - BYOND_MINOR="1412" - 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/chemistry.dm b/code/__defines/chemistry.dm index 08131f99bb..3ae84811b5 100644 --- a/code/__defines/chemistry.dm +++ b/code/__defines/chemistry.dm @@ -36,6 +36,10 @@ #define REAGENTS_PER_SHEET 20 +#define ANTIBIO_NORM 1 +#define ANTIBIO_OD 2 +#define ANTIBIO_SUPER 3 + // Chemistry lists. var/list/tachycardics = list("coffee", "inaprovaline", "hyperzine", "nitroglycerin", "thirteenloko", "nicotine") // Increase heart rate. var/list/bradycardics = list("neurotoxin", "cryoxadone", "clonexadone", "space_drugs", "stoxin") // Decrease heart rate. 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/__defines/subsystems.dm b/code/__defines/subsystems.dm index 5b459f73ff..8460f14fce 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -30,6 +30,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G #define INIT_ORDER_SHUTTLES 3 #define INIT_ORDER_LIGHTING 0 #define INIT_ORDER_AIR -1 +#define INIT_ORDER_HOLOMAPS -5 #define INIT_ORDER_OVERLAY -6 #define INIT_ORDER_XENOARCH -20 diff --git a/code/_helpers/logging.dm b/code/_helpers/logging.dm index 07e2985bbb..83f76bcc9e 100644 --- a/code/_helpers/logging.dm +++ b/code/_helpers/logging.dm @@ -27,7 +27,7 @@ /proc/log_debug(text) if (config.log_debug) - diary << "\[[time_stamp()]]DEBUG: [text][log_end]" + debug_log << "\[[time_stamp()]]DEBUG: [text][log_end]" for(var/client/C in admins) if(C.is_preference_enabled(/datum/client_preference/debug/show_debug_logs)) @@ -41,47 +41,81 @@ if (config.log_vote) diary << "\[[time_stamp()]]VOTE: [text][log_end]" -/proc/log_access(text) +/proc/log_access_in(client/new_client) if (config.log_access) - diary << "\[[time_stamp()]]ACCESS: [text][log_end]" + var/message = "[key_name(new_client)] - IP:[new_client.address] - CID:[new_client.computer_id] - BYOND v[new_client.byond_version]" + diary << "\[[time_stamp()]]ACCESS IN: [message][log_end]" -/proc/log_say(text) +/proc/log_access_out(mob/last_mob) + if (config.log_access) + var/message = "[key_name(last_mob)] - IP:[last_mob.lastKnownIP] - CID:Logged Out - BYOND Logged Out" + diary << "\[[time_stamp()]]ACCESS OUT: [message][log_end]" + +/proc/log_say(text, mob/speaker) if (config.log_say) - diary << "\[[time_stamp()]]SAY: [text][log_end]" + diary << "\[[time_stamp()]]SAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]" -/proc/log_ooc(text) +/proc/log_ooc(text, client/user) if (config.log_ooc) - diary << "\[[time_stamp()]]OOC: [text][log_end]" + diary << "\[[time_stamp()]]OOC: [user.simple_info_line()]: [html_decode(text)][log_end]" -/proc/log_whisper(text) +/proc/log_aooc(text, client/user) + if (config.log_ooc) + diary << "\[[time_stamp()]]AOOC: [user.simple_info_line()]: [html_decode(text)][log_end]" + +/proc/log_looc(text, client/user) + if (config.log_ooc) + diary << "\[[time_stamp()]]LOOC: [user.simple_info_line()]: [html_decode(text)][log_end]" + +/proc/log_whisper(text, mob/speaker) if (config.log_whisper) - diary << "\[[time_stamp()]]WHISPER: [text][log_end]" + diary << "\[[time_stamp()]]WHISPER: [speaker.simple_info_line()]: [html_decode(text)][log_end]" -/proc/log_emote(text) +/proc/log_emote(text, mob/speaker) if (config.log_emote) - diary << "\[[time_stamp()]]EMOTE: [text][log_end]" + diary << "\[[time_stamp()]]EMOTE: [speaker.simple_info_line()]: [html_decode(text)][log_end]" -/proc/log_attack(text) +/proc/log_attack(attacker, defender, message) if (config.log_attack) - diary << "\[[time_stamp()]]ATTACK: [text][log_end]" //Seperate attack logs? Why? FOR THE GLORY OF SATAN! + diary << "\[[time_stamp()]]ATTACK: [attacker] against [defender]: [message][log_end]" -/proc/log_adminsay(text) +/proc/log_adminsay(text, mob/speaker) if (config.log_adminchat) - diary << "\[[time_stamp()]]ADMINSAY: [text][log_end]" + diary << "\[[time_stamp()]]ADMINSAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]" + +/proc/log_modsay(text, mob/speaker) + if (config.log_adminchat) + diary << "\[[time_stamp()]]MODSAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]" + +/proc/log_eventsay(text, mob/speaker) + if (config.log_adminchat) + diary << "\[[time_stamp()]]EVENTSAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]" + +/proc/log_ghostsay(text, mob/speaker) + if (config.log_say) + diary << "\[[time_stamp()]]DEADCHAT: [speaker.simple_info_line()]: [html_decode(text)][log_end]" + +/proc/log_ghostemote(text, mob/speaker) + if (config.log_emote) + diary << "\[[time_stamp()]]DEADEMOTE: [speaker.simple_info_line()]: [html_decode(text)][log_end]" /proc/log_adminwarn(text) if (config.log_adminwarn) - diary << "\[[time_stamp()]]ADMINWARN: [text][log_end]" + diary << "\[[time_stamp()]]ADMINWARN: [html_decode(text)][log_end]" -/proc/log_pda(text) +/proc/log_pda(text, mob/speaker) if (config.log_pda) - diary << "\[[time_stamp()]]PDA: [text][log_end]" + diary << "\[[time_stamp()]]PDA: [speaker.simple_info_line()]: [html_decode(text)][log_end]" /proc/log_to_dd(text) world.log << text //this comes before the config check because it can't possibly runtime if(config.log_world_output) diary << "\[[time_stamp()]]DD_OUTPUT: [text][log_end]" +/proc/log_error(text) + world.log << text + error_log << "\[[time_stamp()]]RUNTIME: [text][log_end]" + /proc/log_misc(text) diary << "\[[time_stamp()]]MISC: [text][log_end]" @@ -105,12 +139,14 @@ return english_list(comps, nothing_text="0", and_text="|", comma_text="|") //more or less a logging utility -/proc/key_name(var/whom, var/include_link = null, var/include_name = 1, var/highlight_special_characters = 1) +//Always return "Something/(Something)", even if it's an error message. +/proc/key_name(var/whom, var/include_link = FALSE, var/include_name = TRUE, var/highlight_special_characters = TRUE) var/mob/M var/client/C var/key - if(!whom) return "*null*" + if(!whom) + return "INVALID/INVALID" if(istype(whom, /client)) C = whom M = C.mob @@ -127,9 +163,11 @@ C = D.current.client else if(istype(whom, /datum)) var/datum/D = whom - return "*invalid:[D.type]*" + return "INVALID/([D.type])" + else if(istext(whom)) + return "AUTOMATED/[whom]" //Just give them the text back else - return "*invalid*" + return "INVALID/INVALID" . = "" @@ -137,7 +175,7 @@ if(include_link && C) . += "" - if(C && C.holder && C.holder.fakekey && !include_name) + if(C && C.holder && C.holder.fakekey) . += "Administrator" else . += key @@ -146,21 +184,20 @@ if(C) . += "" else . += " (DC)" else - . += "*no key*" + . += "INVALID" - if(include_name && M) - var/name + if(include_name) + var/name = "INVALID" + if(M) + if(M.real_name) + name = M.real_name + else if(M.name) + name = M.name - if(M.real_name) - name = M.real_name - else if(M.name) - name = M.name - - - if(include_link && is_special_character(M) && highlight_special_characters) - . += "/([name])" //Orange - else - . += "/([name])" + if(include_link && is_special_character(M) && highlight_special_characters) + name = "[name]" //Orange + + . += "/([name])" return . @@ -189,3 +226,9 @@ if(!istype(d)) return json_encode(d) return d.log_info_line() + +/mob/proc/simple_info_line() + return "[key_name(src)] ([x],[y],[z])" + +/client/proc/simple_info_line() + return "[key_name(src)] ([mob.x],[mob.y],[mob.z])" diff --git a/code/_helpers/logging_vr.dm b/code/_helpers/logging_vr.dm index 2f4c48acc6..66a91e0c2e 100644 --- a/code/_helpers/logging_vr.dm +++ b/code/_helpers/logging_vr.dm @@ -1,11 +1,11 @@ -/proc/log_nsay(text,inside) +/proc/log_nsay(text, inside, mob/speaker) if (config.log_say) - diary << "\[[time_stamp()]]NSAY (NIF:[inside]): [text][log_end]" + diary << "\[[time_stamp()]]NSAY (NIF:[inside]): [speaker.simple_info_line()]: [html_decode(text)][log_end]" -/proc/log_nme(text,inside) +/proc/log_nme(text, inside, mob/speaker) if (config.log_emote) - diary << "\[[time_stamp()]]NME (NIF:[inside]): [text][log_end]" + diary << "\[[time_stamp()]]NME (NIF:[inside]): [speaker.simple_info_line()]: [html_decode(text)][log_end]" -/proc/log_subtle(text) +/proc/log_subtle(text, mob/speaker) if (config.log_emote) - diary << "\[[time_stamp()]]SUBTLE: [text][log_end]" + diary << "\[[time_stamp()]]SUBTLE: [speaker.simple_info_line()]: [html_decode(text)][log_end]" diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm index 725812066c..1ba5ec30b5 100644 --- a/code/_helpers/mobs.dm +++ b/code/_helpers/mobs.dm @@ -145,13 +145,23 @@ Proc for attack log creation, because really why not 6 is additional information, anything that needs to be added */ -/proc/add_logs(mob/user, mob/target, what_done, var/admin=1, var/object=null, var/addition=null) - if(user && ismob(user)) - user.attack_log += text("\[[time_stamp()]\] Has [what_done] [target ? "[target.name][(ismob(target) && target.ckey) ? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition]") - if(target && ismob(target)) - target.attack_log += text("\[[time_stamp()]\] Has been [what_done] by [user ? "[user.name][(ismob(user) && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition]") - if(admin) - log_attack("[user ? "[user.name][(ismob(user) && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] [what_done] [target ? "[target.name][(ismob(target) && target.ckey)? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition]") +/proc/add_attack_logs(mob/user, mob/target, what_done, var/admin_notify = TRUE) + if(islist(target)) //Multi-victim adding + var/list/targets = target + for(var/mob/M in targets) + add_attack_logs(user,M,what_done,admin_notify) + return + + var/user_str = key_name(user) + var/target_str = key_name(target) + + if(ismob(user)) + user.attack_log += text("\[[time_stamp()]\] Attacked [target_str]: [what_done]") + if(ismob(target)) + target.attack_log += text("\[[time_stamp()]\] Attacked by [user_str]: [what_done]") + log_attack(user_str,target_str,what_done) + if(admin_notify) + msg_admin_attack("[key_name_admin(user)] vs [target_str]: [what_done]") //checks whether this item is a module of the robot it is located in. /proc/is_robot_module(var/obj/item/thing) @@ -213,6 +223,8 @@ Proc for attack log creation, because really why not /proc/do_after(mob/user, delay, atom/target = null, needhand = 1, progress = 1, var/incapacitation_flags = INCAPACITATION_DEFAULT) if(!user) return 0 + if(!delay) + return 1 //Okay. Done. var/atom/target_loc = null if(target) target_loc = target.loc diff --git a/code/_helpers/time.dm b/code/_helpers/time.dm index 6dad42e128..58348761f8 100644 --- a/code/_helpers/time.dm +++ b/code/_helpers/time.dm @@ -58,8 +58,11 @@ var/next_station_date_change = 1 DAY station_date = num2text((text2num(time2text(timeofday, "YYYY"))+544)) + "-" + time2text(timeofday, "MM-DD") return station_date +//ISO 8601 /proc/time_stamp() - return time2text(station_time_in_ticks, "hh:mm:ss") + var/date_portion = time2text(world.timeofday, "YYYY-MM-DD") + var/time_portion = time2text(world.timeofday, "hh:mm:ss") + return "[date_portion]T[time_portion]" /* Returns 1 if it is the selected month and day */ proc/isDay(var/month, var/day) diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index 724f5789d8..92ad017cd2 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -800,7 +800,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 @@ -808,11 +807,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 @@ -838,14 +835,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/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index daaa52e827..ae726ec481 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -278,4 +278,4 @@ var/obj/screen/robot_inventory /mob/living/silicon/robot/update_hud() ..() if(modtype) - hands.icon_state = lowertext(modtype) + hands.icon_state = lowertext(modtype) \ No newline at end of file diff --git a/code/_onclick/hud/robot_vr.dm b/code/_onclick/hud/robot_vr.dm new file mode 100644 index 0000000000..5e376182a0 --- /dev/null +++ b/code/_onclick/hud/robot_vr.dm @@ -0,0 +1,6 @@ +/mob/living/silicon/robot/update_hud() + if(ui_style_vr) + hands.icon = 'icons/mob/screen1_robot_vr.dmi' + if(modtype) + hands.icon_state = lowertext(modtype) + ..() \ No newline at end of file diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 01e87b490d..d583084791 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -82,9 +82,7 @@ avoid code duplication. This includes items that may sometimes act as a standard M.lastattacker = user if(!no_attack_log) - user.attack_log += "\[[time_stamp()]\] Attacked [M.name] ([M.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" - M.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" - msg_admin_attack("[key_name(user)] attacked [key_name(M)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" ) + add_attack_logs(user,M,"attacked with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])") ///////////////////////// user.setClickCooldown(user.get_attack_speed(src)) diff --git a/code/controllers/subsystems/atoms.dm b/code/controllers/subsystems/atoms.dm index 6b5669878c..5b09b186bb 100644 --- a/code/controllers/subsystems/atoms.dm +++ b/code/controllers/subsystems/atoms.dm @@ -135,9 +135,7 @@ SUBSYSTEM_DEF(atoms) /datum/controller/subsystem/atoms/Shutdown() var/initlog = InitLog() if(initlog) - //text2file(initlog, "[GLOB.log_directory]/initialize.log") - var/date_string = time2text(world.realtime, "YYYY/MM-Month/DD-Day") - text2file(initlog, "data/logs/[date_string]-initialize.log") + text2file(initlog, "[log_path]-initialize.log") #undef BAD_INIT_QDEL_BEFORE #undef BAD_INIT_DIDNT_INIT 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/garbage.dm b/code/controllers/subsystems/garbage.dm index 32c1e37a6e..b4d43a8d3f 100644 --- a/code/controllers/subsystems/garbage.dm +++ b/code/controllers/subsystems/garbage.dm @@ -81,7 +81,7 @@ SUBSYSTEM_DEF(garbage) dellog += "\tIgnored force: [I.no_respect_force] times" if (I.no_hint) dellog += "\tNo hint: [I.no_hint] times" - log_misc(dellog.Join()) + text2file(dellog.Join(), "[log_path]-qdel.log") /datum/controller/subsystem/garbage/fire() //the fact that this resets its processing each fire (rather then resume where it left off) is intentional. diff --git a/code/controllers/subsystems/holomaps_vr.dm b/code/controllers/subsystems/holomaps_vr.dm new file mode 100644 index 0000000000..5fcca27480 --- /dev/null +++ b/code/controllers/subsystems/holomaps_vr.dm @@ -0,0 +1,24 @@ +// +// Holo-Minimaps Generation Subsystem handles initialization of the holo minimaps. +// Look in code/modules/holomap/generate_holomap.dm to find generateHoloMinimaps() +// +SUBSYSTEM_DEF(holomaps) + name = "HoloMiniMaps" + init_order = INIT_ORDER_HOLOMAPS + flags = SS_NO_FIRE + var/static/holomaps_initialized = FALSE + var/static/list/holoMiniMaps = list() + var/static/list/extraMiniMaps = list() + var/static/list/station_holomaps = list() + +/datum/controller/subsystem/holomaps/Recover() + flags |= SS_NO_INIT // Make extra sure we don't initialize twice. + +/datum/controller/subsystem/holomaps/Initialize(timeofday) + generateHoloMinimaps() + . = ..() + +/datum/controller/subsystem/holomaps/stat_entry(msg) + if (!Debug2) + return // Only show up in stat panel if debugging is enabled. + . = ..() diff --git a/code/controllers/subsystems/overlays.dm b/code/controllers/subsystems/overlays.dm index 6d7581e126..ed9b81016f 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() @@ -27,9 +29,7 @@ SUBSYSTEM_DEF(overlays) /datum/controller/subsystem/overlays/Shutdown() - //text2file(render_stats(stats), "[GLOB.log_directory]/overlay.log") - var/date_string = time2text(world.realtime, "YYYY/MM-Month/DD-Day") - text2file(render_stats(stats), "data/logs/[date_string]-overlay.log") + text2file(render_stats(stats), "[log_path]-overlay.log") /datum/controller/subsystem/overlays/Recover() overlay_icon_state_caches = SSoverlays.overlay_icon_state_caches @@ -90,7 +90,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/defines/obj.dm b/code/defines/obj.dm index 47a24f192f..f300496aa2 100644 --- a/code/defines/obj.dm +++ b/code/defines/obj.dm @@ -203,6 +203,12 @@ var/global/list/PDA_Manifest = list() anchored = 1 unacidable = 1//temporary until I decide whether the borg can be removed. -veyveyr +/obj/structure/showcase/sign + name = "WARNING: WILDERNESS" + icon = 'icons/obj/stationobjs.dmi' + icon_state = "wilderness1" + desc = "This appears to be a sign warning people that the other side is dangerous. It also says that NanoTrasen cannot guarantee your safety beyond this point." + /obj/item/mouse_drag_pointer = MOUSE_ACTIVE_POINTER /obj/item/weapon/beach_ball diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm index d6ab3edc0c..902285bf45 100644 --- a/code/defines/procs/announce.dm +++ b/code/defines/procs/announce.dm @@ -94,7 +94,7 @@ datum/announcement/priority/command/Sound(var/message_sound) datum/announcement/proc/Log(message as text, message_title as text) if(log) - log_say("[key_name(usr)] has made \a [announcement_type]: [message_title] - [message] - [announcer]") + log_game("[key_name(usr)] has made \a [announcement_type]: [message_title] - [message] - [announcer]") message_admins("[key_name_admin(usr)] has made \a [announcement_type].", 1) /proc/GetNameAndAssignmentFromId(var/obj/item/weapon/card/id/I) diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index ae21bf8093..4673d0ef26 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) @@ -339,3 +339,9 @@ var/list/mob/living/forced_ambiance_list = new /area/proc/shuttle_departed() return TRUE + +/area/AllowDrop() + CRASH("Bad op: area/AllowDrop() called") + +/area/drop_location() + CRASH("Bad op: area/drop_location() called") diff --git a/code/game/atoms.dm b/code/game/atoms.dm index dba0ec67ab..c994aff121 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -502,3 +502,12 @@ if(A && A.has_gravity()) return TRUE return FALSE + +/atom/proc/drop_location() + var/atom/L = loc + if(!L) + return null + return L.AllowDrop() ? L : get_turf(L) + +/atom/proc/AllowDrop() + return FALSE diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm index 0af67b22ed..f76fd5ca47 100644 --- a/code/game/gamemodes/changeling/powers/absorb.dm +++ b/code/game/gamemodes/changeling/powers/absorb.dm @@ -53,9 +53,7 @@ src << "We stab [T] with the proboscis." src.visible_message("[src] stabs [T] with the proboscis!") T << "You feel a sharp stabbing pain!" - T.attack_log += text("\[[time_stamp()]\] Was absorbed by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Absorbed [key_name(T)]") - msg_admin_attack("[key_name(T)] was absorbed by [key_name(src)]") + add_attack_logs(src,T,"Absorbed (changeling)") var/obj/item/organ/external/affecting = T.get_organ(src.zone_sel.selecting) if(affecting.take_damage(39,0,1,0,"large organic needle")) T:UpdateDamageIcon() diff --git a/code/game/gamemodes/changeling/powers/bioelectrogenesis.dm b/code/game/gamemodes/changeling/powers/bioelectrogenesis.dm index 1579252628..3f3c1bd7ad 100644 --- a/code/game/gamemodes/changeling/powers/bioelectrogenesis.dm +++ b/code/game/gamemodes/changeling/powers/bioelectrogenesis.dm @@ -47,7 +47,7 @@ var/agony = 80 * siemens //Does more than if hit with an electric hand, since grabbing is slower. G.affecting.stun_effect_act(0, agony, BP_TORSO, src) - msg_admin_attack("[key_name(src)] shocked [key_name(G.affecting)] with the [src].") + add_attack_logs(src,G.affecting,"Changeling shocked") if(siemens) visible_message("Arcs of electricity strike [G.affecting]!", @@ -149,7 +149,7 @@ C.electrocute_act(electrocute_amount * siemens,src,1.0,BP_TORSO) C.stun_effect_act(0, agony_amount * siemens, BP_TORSO, src) - msg_admin_attack("[key_name(user)] shocked [key_name(C)] with the [src].") + add_attack_logs(user,C,"Shocked with [src]") if(siemens) visible_message("Arcs of electricity strike [C]!", diff --git a/code/game/gamemodes/changeling/powers/blind_sting.dm b/code/game/gamemodes/changeling/powers/blind_sting.dm index 41b14478b3..347881df9b 100644 --- a/code/game/gamemodes/changeling/powers/blind_sting.dm +++ b/code/game/gamemodes/changeling/powers/blind_sting.dm @@ -15,9 +15,7 @@ var/mob/living/carbon/T = changeling_sting(20,/mob/proc/changeling_blind_sting) if(!T) return 0 - T.attack_log += text("\[[time_stamp()]\] Was blind stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used blind sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was blind stung by [key_name(src)]") + add_attack_logs(src,T,"Blind sting (changeling)") T << "Your eyes burn horrificly!" T.disabilities |= NEARSIGHTED var/duration = 300 diff --git a/code/game/gamemodes/changeling/powers/cryo_sting.dm b/code/game/gamemodes/changeling/powers/cryo_sting.dm index 4bb92a543e..bc68428d89 100644 --- a/code/game/gamemodes/changeling/powers/cryo_sting.dm +++ b/code/game/gamemodes/changeling/powers/cryo_sting.dm @@ -16,9 +16,7 @@ var/mob/living/carbon/T = changeling_sting(20,/mob/proc/changeling_cryo_sting) if(!T) return 0 - T.attack_log += text("\[[time_stamp()]\] Was cryo stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used cryo sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was cryo stung by [key_name(src)]") + add_attack_logs(src,T,"Cryo sting (changeling)") var/inject_amount = 10 if(src.mind.changeling.recursive_enhancement) inject_amount = inject_amount * 1.5 diff --git a/code/game/gamemodes/changeling/powers/deaf_sting.dm b/code/game/gamemodes/changeling/powers/deaf_sting.dm index 24c1e5d260..a94ad1744a 100644 --- a/code/game/gamemodes/changeling/powers/deaf_sting.dm +++ b/code/game/gamemodes/changeling/powers/deaf_sting.dm @@ -15,9 +15,7 @@ var/mob/living/carbon/T = changeling_sting(5,/mob/proc/changeling_deaf_sting) if(!T) return 0 - T.attack_log += text("\[[time_stamp()]\] Was deaf stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used deaf sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was deaf stung by [key_name(src)]") + add_attack_logs(src,T,"Deaf sting (changeling)") var/duration = 300 if(src.mind.changeling.recursive_enhancement) duration = duration + 100 diff --git a/code/game/gamemodes/changeling/powers/death_sting.dm b/code/game/gamemodes/changeling/powers/death_sting.dm index 52412a4282..6dd0cdbf85 100644 --- a/code/game/gamemodes/changeling/powers/death_sting.dm +++ b/code/game/gamemodes/changeling/powers/death_sting.dm @@ -13,9 +13,7 @@ var/mob/living/carbon/T = changeling_sting(40,/mob/proc/changeling_DEATHsting) if(!T) return 0 - T.attack_log += text("\[[time_stamp()]\] Was death stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used death sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was death stung by [key_name(src)]") + add_attack_logs(src,T,"Death sting (changeling)") T << "You feel a small prick and your chest becomes tight." T.silent = 10 T.Paralyse(10) diff --git a/code/game/gamemodes/changeling/powers/delayed_toxin_sting.dm b/code/game/gamemodes/changeling/powers/delayed_toxin_sting.dm index a9b323465c..7853a9603e 100644 --- a/code/game/gamemodes/changeling/powers/delayed_toxin_sting.dm +++ b/code/game/gamemodes/changeling/powers/delayed_toxin_sting.dm @@ -28,10 +28,7 @@ var/mob/living/carbon/T = changeling_sting(20,/mob/proc/changeling_delayed_toxic_sting) if(!T) return 0 - T.attack_log += text("\[[time_stamp()]\] Was delayed toxic stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used delayed toxic sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was delayed toxic stung by [key_name(src)]") - + add_attack_logs(src,T,"Delayed toxic sting (chagneling)") var/type_to_give = /datum/modifier/delayed_toxin_sting if(src.mind.changeling.recursive_enhancement) type_to_give = /datum/modifier/delayed_toxin_sting/strong diff --git a/code/game/gamemodes/changeling/powers/enfeebling_string.dm b/code/game/gamemodes/changeling/powers/enfeebling_string.dm index b7a6c56957..16303f7c58 100644 --- a/code/game/gamemodes/changeling/powers/enfeebling_string.dm +++ b/code/game/gamemodes/changeling/powers/enfeebling_string.dm @@ -35,9 +35,7 @@ if(ishuman(T)) var/mob/living/carbon/human/H = T - T.attack_log += text("\[[time_stamp()]\] Was enfeebling stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used enfeebling sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was enfeebling stung by [key_name(src)]") + add_attack_logs(src,T,"Enfeebling sting (changeling)") var/type_to_give = /datum/modifier/enfeeble if(src.mind.changeling.recursive_enhancement) diff --git a/code/game/gamemodes/changeling/powers/extract_dna_sting.dm b/code/game/gamemodes/changeling/powers/extract_dna_sting.dm index 6198e409a6..0c5d91d83b 100644 --- a/code/game/gamemodes/changeling/powers/extract_dna_sting.dm +++ b/code/game/gamemodes/changeling/powers/extract_dna_sting.dm @@ -35,9 +35,7 @@ src << "This creature's DNA is ruined beyond useability!" return 0 - T.attack_log += text("\[[time_stamp()]\] Had DNA extracted via sting by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used DNA extraction sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was DNA extraction stung by [key_name(src)]") + add_attack_logs(src,T,"DNA extraction sting (changeling)") var/datum/absorbed_dna/newDNA = new(T.real_name, T.dna, T.species.name, T.languages) absorbDNA(newDNA) diff --git a/code/game/gamemodes/changeling/powers/lsd_sting.dm b/code/game/gamemodes/changeling/powers/lsd_sting.dm index 9adb4acd09..fabb81327e 100644 --- a/code/game/gamemodes/changeling/powers/lsd_sting.dm +++ b/code/game/gamemodes/changeling/powers/lsd_sting.dm @@ -13,9 +13,7 @@ var/mob/living/carbon/T = changeling_sting(15,/mob/proc/changeling_lsdsting) if(!T) return 0 - T.attack_log += text("\[[time_stamp()]\] Was hallucination stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used hallucination sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was hallucination stung by [key_name(src)]") + add_attack_logs(src,T,"Hallucination sting (changeling)") spawn(rand(300,600)) if(T) T.hallucination += 400 feedback_add_details("changeling_powers","HS") diff --git a/code/game/gamemodes/changeling/powers/para_sting.dm b/code/game/gamemodes/changeling/powers/para_sting.dm index efe6fe8f79..7a0020bd0f 100644 --- a/code/game/gamemodes/changeling/powers/para_sting.dm +++ b/code/game/gamemodes/changeling/powers/para_sting.dm @@ -12,9 +12,7 @@ var/mob/living/carbon/T = changeling_sting(30,/mob/proc/changeling_paralysis_sting) if(!T) return 0 - T.attack_log += text("\[[time_stamp()]\] Was paralysis stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used paralysis sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was paralysis stung by [key_name(src)]") + add_attack_logs(src,T,"Paralysis sting (changeling)") T << "Your muscles begin to painfully tighten." T.Weaken(20) feedback_add_details("changeling_powers","PS") diff --git a/code/game/gamemodes/changeling/powers/shriek.dm b/code/game/gamemodes/changeling/powers/shriek.dm index 40e796490f..4989c27f87 100644 --- a/code/game/gamemodes/changeling/powers/shriek.dm +++ b/code/game/gamemodes/changeling/powers/shriek.dm @@ -51,12 +51,8 @@ range = range * 2 to_chat(src, "We are extra loud.") - src.attack_log += text("\[[time_stamp()]\] Used Resonant Shriek.") - message_admins("[key_name(src)] used Resonant Shriek ([src.x],[src.y],[src.z]) (JMP).") - log_game("[key_name(src)] used Resonant Shriek.") - visible_message("[src] appears to shout.") - + var/list/affected = list() for(var/mob/living/M in range(range, src)) if(iscarbon(M)) if(!M.mind || !M.mind.changeling) @@ -67,7 +63,7 @@ M.adjustEarDamage(0,30) M.Confuse(20) M << sound('sound/effects/screech.ogg') - M.attack_log += text("\[[time_stamp()]\] Was affected by [key_name(src)]'s Resonant Shriek.") + affected += M else if(M != src) M << "You hear a familiar screech from nearby. It has no effect on you." @@ -77,7 +73,7 @@ M << sound('sound/weapons/flash.ogg') M << "Auditory input overloaded. Reinitializing..." M.Weaken(rand(5,10)) - M.attack_log += text("\[[time_stamp()]\] Was affected by [key_name(src)]'s Resonant Shriek.") + affected += M for(var/obj/machinery/light/L in range(range, src)) L.on = 1 @@ -85,6 +81,7 @@ changeling.last_shriek = world.time + add_attack_logs(src,affected,"Used resonant shriek") feedback_add_details("changeling_powers","RS") return 1 @@ -133,9 +130,7 @@ visible_message("[src] appears to shout.") - src.attack_log += text("\[[time_stamp()]\] Used Dissonant Shriek.") - message_admins("[key_name(src)] used Dissonant Shriek ([src.x],[src.y],[src.z]) (JMP).") - log_game("[key_name(src)] used Dissonant Shriek.") + add_attack_logs(src,null,"Use dissonant shriek") for(var/obj/machinery/light/L in range(5, src)) L.on = 1 diff --git a/code/game/gamemodes/changeling/powers/silence_sting.dm b/code/game/gamemodes/changeling/powers/silence_sting.dm index 1ab25278a4..334b0c139f 100644 --- a/code/game/gamemodes/changeling/powers/silence_sting.dm +++ b/code/game/gamemodes/changeling/powers/silence_sting.dm @@ -15,9 +15,7 @@ var/mob/living/carbon/T = changeling_sting(10,/mob/proc/changeling_silence_sting) if(!T) return 0 - T.attack_log += text("\[[time_stamp()]\] Was silence stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used silence sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was silence stung by [key_name(src)]") + add_attack_logs(src,T,"Silence sting (changeling)") var/duration = 30 if(src.mind.changeling.recursive_enhancement) duration = duration + 10 diff --git a/code/game/gamemodes/changeling/powers/transform_sting.dm b/code/game/gamemodes/changeling/powers/transform_sting.dm index 797eec92d2..678e195e22 100644 --- a/code/game/gamemodes/changeling/powers/transform_sting.dm +++ b/code/game/gamemodes/changeling/powers/transform_sting.dm @@ -36,9 +36,7 @@ if((HUSK in T.mutations) || (!ishuman(T) && !issmall(T))) src << "Our sting appears ineffective against its DNA." return 0 - T.attack_log += text("\[[time_stamp()]\] Was transform stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used transform sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was transform stung by [key_name(src)]") + add_attack_logs(src,T,"Transformation sting (changeling)") T.visible_message("[T] transforms!") T.dna = chosen_dna.Clone() T.real_name = chosen_dna.real_name diff --git a/code/game/gamemodes/changeling/powers/unfat_sting.dm b/code/game/gamemodes/changeling/powers/unfat_sting.dm index 4b42f55e30..f2e238746d 100644 --- a/code/game/gamemodes/changeling/powers/unfat_sting.dm +++ b/code/game/gamemodes/changeling/powers/unfat_sting.dm @@ -11,9 +11,7 @@ var/mob/living/carbon/T = changeling_sting(5,/mob/proc/changeling_unfat_sting) if(!T) return 0 - T.attack_log += text("\[[time_stamp()]\] Was unfat stung by [key_name(src)]") - src.attack_log += text("\[[time_stamp()]\] Used unfat sting on [key_name(T)]") - msg_admin_attack("[key_name(T)] was unfat stung by [key_name(src)]") + add_attack_logs(src,T,"Unfat sting (changeling)") T << "you feel a small prick as stomach churns violently and you become to feel skinnier." T.overeatduration = 0 T.nutrition -= 100 diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 8db7a49255..d91e2e1f47 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -292,10 +292,7 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa"," words[cultwords[V]] = V attack(mob/living/M as mob, mob/living/user as mob) - - M.attack_log += text("\[[time_stamp()]\] Has had the [name] used on them by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used [name] on [M.name] ([M.ckey])") - msg_admin_attack("[user.name] ([user.ckey]) used [name] on [M.name] ([M.ckey]) (JMP)") + add_attack_logs(user,M,"Hit with [name]") if(istype(M,/mob/observer/dead)) var/mob/observer/dead/D = M diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 0e0ff60791..d7579698d1 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -139,7 +139,7 @@ var/list/sacrificed = list() target.take_overall_damage(0, rand(5, 20)) // You dirty resister cannot handle the damage to your mind. Easily. - even cultists who accept right away should experience some effects // Resist messages go! if(initial_message) //don't do this stuff right away, only if they resist or hesitate. - admin_attack_log(attacker, target, "Used a convert rune", "Was subjected to a convert rune", "used a convert rune on") + add_attack_logs(attacker,target,"Convert rune") switch(target.getFireLoss()) if(0 to 25) target << "Your blood boils as you force yourself to resist the corruption invading every corner of your mind." @@ -247,7 +247,7 @@ var/list/sacrificed = list() if(R.word1==cultwords["travel"] && R.word2==cultwords["blood"] && R.word3==cultwords["self"]) for(var/mob/living/carbon/D in R.loc) if(D.stat!=2) - admin_attack_log(usr, D, "Used a blood drain rune.", "Was victim of a blood drain rune.", "used a blood drain rune on") + add_attack_logs(usr,D,"Blood drain rune") var/bdrain = rand(1,25) D << "You feel weakened." D.take_overall_damage(bdrain, 0) @@ -933,7 +933,7 @@ var/list/sacrificed = list() if(affected.len) usr.say("Sti[pick("'","`")] kaliedir!") usr << "The world becomes quiet as the deafening rune dissipates into fine dust." - admin_attacker_log_many_victims(usr, affected, "Used a deafen rune.", "Was victim of a deafen rune.", "used a deafen rune on") + add_attack_logs(usr,affected,"Deafen rune") qdel(src) else return fizzle() @@ -952,7 +952,7 @@ var/list/sacrificed = list() if(affected.len) usr.whisper("Sti[pick("'","`")] kaliedir!") usr << "Your talisman turns into gray dust, deafening everyone around." - admin_attacker_log_many_victims(usr, affected, "Used a deafen rune.", "Was victim of a deafen rune.", "used a deafen rune on") + add_attack_logs(usr, affected, "Deafen rune") for (var/mob/V in orange(1,src)) if(!(iscultist(V))) V.show_message("Dust flows from [usr]'s hands for a moment, and the world suddenly becomes quiet..", 3) @@ -978,7 +978,7 @@ var/list/sacrificed = list() if(affected.len) usr.say("Sti[pick("'","`")] kaliesin!") usr << "The rune flashes, blinding those who not follow the Nar-Sie, and dissipates into fine dust." - admin_attacker_log_many_victims(usr, affected, "Used a blindness rune.", "Was victim of a blindness rune.", "used a blindness rune on") + add_attack_logs(usr, affected, "Blindness rune") qdel(src) else return fizzle() @@ -998,7 +998,7 @@ var/list/sacrificed = list() if(affected.len) usr.whisper("Sti[pick("'","`")] kaliesin!") usr << "Your talisman turns into gray dust, blinding those who not follow the Nar-Sie." - admin_attacker_log_many_victims(usr, affected, "Used a blindness rune.", "Was victim of a blindness rune.", "used a blindness rune on") + add_attack_logs(usr, affected, "Blindness rune") return @@ -1035,8 +1035,7 @@ var/list/sacrificed = list() if(iscultist(C) && !C.stat) C.say("Dedo ol[pick("'","`")]btoh!") C.take_overall_damage(15, 0) - admin_attacker_log_many_victims(usr, victims, "Used a blood boil rune.", "Was the victim of a blood boil rune.", "used a blood boil rune on") - log_and_message_admins_many(cultists - usr, "assisted activating a blood boil rune.") + add_attack_logs(usr, victims, "Blood boil rune") qdel(src) else return fizzle() @@ -1084,13 +1083,13 @@ var/list/sacrificed = list() C.Weaken(1) C.Stun(1) C.show_message("The rune explodes in a bright flash.", 3) - admin_attack_log(usr, C, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on") + add_attack_logs(usr,C,"Stun rune") else if(issilicon(L)) var/mob/living/silicon/S = L S.Weaken(5) S.show_message("BZZZT... The rune has exploded in a bright flash.", 3) - admin_attack_log(usr, S, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on") + add_attack_logs(usr,S,"Stun rune") qdel(src) else ///When invoked as talisman, stun and mute the target mob. usr.say("Dream sign ''Evil sealing talisman'[pick("'","`")]!") @@ -1104,7 +1103,7 @@ var/list/sacrificed = list() if(issilicon(T)) T.Weaken(15) - admin_attack_log(usr, T, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on") + add_attack_logs(usr,T,"Stun rune") else if(iscarbon(T)) var/mob/living/carbon/C = T C.flash_eyes() @@ -1112,7 +1111,7 @@ var/list/sacrificed = list() C.silent += 15 C.Weaken(25) C.Stun(25) - admin_attack_log(usr, C, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on") + add_attack_logs(usr,C,"Stun rune") return /////////////////////////////////////////TWENTY-FIFTH RUNE 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/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index df2387e71f..2f0fce2bd3 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -28,7 +28,10 @@ /obj/random/action_figure = 1, /obj/random/plushie = 1, /obj/item/toy/cultsword = 1, - /obj/item/toy/bouquet/fake = 1 + /obj/item/toy/bouquet/fake = 1, + /obj/item/clothing/accessory/badge/sheriff = 2, + /obj/item/clothing/head/cowboy_hat/small = 2, + /obj/item/toy/stickhorse = 2 ) /obj/machinery/computer/arcade/New() diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 785d841702..5f1fe0e532 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -187,7 +187,7 @@ return CentCom_announce(input, usr) usr << "Message transmitted." - log_say("[key_name(usr)] has made an IA [using_map.boss_short] announcement: [input]") + log_game("[key_name(usr)] has made an IA [using_map.boss_short] announcement: [input]") centcomm_message_cooldown = 1 spawn(300)//10 minute cooldown centcomm_message_cooldown = 0 @@ -204,7 +204,7 @@ return Syndicate_announce(input, usr) usr << "Message transmitted." - log_say("[key_name(usr)] has made an illegal announcement: [input]") + log_game("[key_name(usr)] has made an illegal announcement: [input]") centcomm_message_cooldown = 1 spawn(300)//10 minute cooldown centcomm_message_cooldown = 0 diff --git a/code/game/machinery/computer3/computers/communications.dm b/code/game/machinery/computer3/computers/communications.dm index 6f802c54bd..acd66ebde1 100644 --- a/code/game/machinery/computer3/computers/communications.dm +++ b/code/game/machinery/computer3/computers/communications.dm @@ -197,7 +197,7 @@ return CentCom_announce(input, usr) usr << "Message transmitted." - log_say("[key_name(usr)] has made a [using_map.boss_short] announcement: [input]") + log_game("[key_name(usr)] has made a [using_map.boss_short] announcement: [input]") centcomm_message_cooldown = 1 spawn(600)//10 minute cooldown centcomm_message_cooldown = 0 @@ -214,7 +214,7 @@ return Syndicate_announce(input, usr) usr << "Message transmitted." - log_say("[key_name(usr)] has made an illegal announcement: [input]") + log_game("[key_name(usr)] has made an illegal announcement: [input]") centcomm_message_cooldown = 1 spawn(600)//10 minute cooldown centcomm_message_cooldown = 0 diff --git a/code/game/machinery/computer3/computers/prisoner.dm b/code/game/machinery/computer3/computers/prisoner.dm index 7e3ada285d..27943bb353 100644 --- a/code/game/machinery/computer3/computers/prisoner.dm +++ b/code/game/machinery/computer3/computers/prisoner.dm @@ -95,7 +95,7 @@ var/obj/item/weapon/implant/I = locate(href_list["warn"]) if( istype(I) && I.imp_in) var/mob/living/carbon/R = I.imp_in - log_say("PrisonComputer3 message: [key_name(usr)]->[key_name(R)] : [warning]") + log_game("PrisonComputer3 message: [key_name(usr)]->[key_name(R)] : [warning]") R << "You hear a voice in your head saying: '[warning]'" interact() diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 0988ceb879..344f1c9a10 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -599,7 +599,7 @@ About the new airlock wires panel: else if(duration) //electrify door for the given duration seconds if(usr) shockedby += text("\[[time_stamp()]\] - [usr](ckey:[usr.ckey])") - usr.attack_log += text("\[[time_stamp()]\] Electrified the [name] at [x] [y] [z]") + add_attack_logs(usr,name,"Electrified a door") else shockedby += text("\[[time_stamp()]\] - EMP)") message = "The door is now electrified [duration == -1 ? "permanently" : "for [duration] second\s"]." diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index b22dc27dba..5cded75805 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -218,6 +218,8 @@ /obj/machinery/door/firedoor/attackby(obj/item/weapon/C as obj, mob/user as mob) add_fingerprint(user) + if(istype(C, /obj/item/taperoll)) + return //Don't open the door if we're putting tape on it to tell people 'don't open the door'. if(operating) return//Already doing something. if(istype(C, /obj/item/weapon/weldingtool) && !repairing) diff --git a/code/game/machinery/kitchen/cooking_machines/fryer.dm b/code/game/machinery/kitchen/cooking_machines/fryer.dm index 1fc0e75ef1..7e5cc055e8 100644 --- a/code/game/machinery/kitchen/cooking_machines/fryer.dm +++ b/code/game/machinery/kitchen/cooking_machines/fryer.dm @@ -58,9 +58,7 @@ victim << "Searing hot oil scorches your [E ? E.name : "flesh"]!" if(victim.client) - user.attack_log += text("\[[time_stamp()]\] Has [cook_type] \the [victim] ([victim.ckey]) in \a [src]") - victim.attack_log += text("\[[time_stamp()]\] Has been [cook_type] in \a [src] by [user.name] ([user.ckey])") - msg_admin_attack("[user] ([user.ckey]) [cook_type] \the [victim] ([victim.ckey]) in \a [src]. (JMP)") + add_attack_logs(user,victim,"[cook_type] in [src]") icon_state = off_icon cooking = 0 diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm index 9b6b503237..d695253aa9 100644 --- a/code/game/machinery/kitchen/gibber.dm +++ b/code/game/machinery/kitchen/gibber.dm @@ -211,9 +211,7 @@ if(src.occupant.reagents) src.occupant.reagents.trans_to_obj(new_meat, round(occupant.reagents.total_volume/slab_count,1)) - src.occupant.attack_log += "\[[time_stamp()]\] Was gibbed by [user]/[user.ckey]" //One shall not simply gib a mob unnoticed! - user.attack_log += "\[[time_stamp()]\] Gibbed [src.occupant]/[src.occupant.ckey]" - msg_admin_attack("[user.name] ([user.ckey]) gibbed [src.occupant] ([src.occupant.ckey]) (JMP)") + add_attack_logs(user,occupant,"Used [src] to gib") src.occupant.ghostize() @@ -225,13 +223,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/rechargestation.dm b/code/game/machinery/rechargestation.dm index d4d3cedb47..5e0f181d82 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -289,7 +289,7 @@ set name = "Eject Recharger" set src in oview(1) - if(usr.incapacitated()) + if(usr.incapacitated() || !isliving(usr)) return go_out() @@ -301,8 +301,9 @@ set name = "Enter Recharger" set src in oview(1) - if(!usr.incapacitated()) + if(usr.incapacitated() || !isliving(usr)) return + go_in(usr) /obj/machinery/recharge_station/ghost_pod_recharger diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index b5e98dab70..ca1fa7b3b1 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -835,6 +835,7 @@ /obj/item/weapon/storage/fancy/cigarettes/luckystars = 5, /obj/item/weapon/storage/fancy/cigarettes/jerichos = 5, /obj/item/weapon/storage/fancy/cigarettes/menthols = 5, + /obj/item/weapon/storage/rollingpapers = 5, /obj/item/weapon/storage/box/matches = 10, /obj/item/weapon/flame/lighter/random = 4) contraband = list(/obj/item/weapon/flame/lighter/zippo = 4) @@ -847,6 +848,7 @@ /obj/item/weapon/storage/fancy/cigarettes/luckystars = 17, /obj/item/weapon/storage/fancy/cigarettes/jerichos = 22, /obj/item/weapon/storage/fancy/cigarettes/menthols = 18, + /obj/item/weapon/storage/rollingpapers = 10, /obj/item/weapon/storage/box/matches = 1, /obj/item/weapon/flame/lighter/random = 2) @@ -1112,8 +1114,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/machinery/vending_vr.dm b/code/game/machinery/vending_vr.dm index c7b43c3ce5..1f5424f55b 100644 --- a/code/game/machinery/vending_vr.dm +++ b/code/game/machinery/vending_vr.dm @@ -20,7 +20,7 @@ /obj/machinery/vending/medical/New() products += list(/obj/item/weapon/storage/box/khcrystal = 4,/obj/item/weapon/backup_implanter = 3, - /obj/item/clothing/glasses/omnihud/med = 4, /obj/item/device/glasses_kit = 1) + /obj/item/clothing/glasses/omnihud/med = 4, /obj/item/device/glasses_kit = 1, /obj/item/weapon/storage/quickdraw/syringe_case = 4) ..() //Custom vendors diff --git a/code/game/mecha/combat/gorilla.dm b/code/game/mecha/combat/gorilla.dm new file mode 100644 index 0000000000..b6f1915667 --- /dev/null +++ b/code/game/mecha/combat/gorilla.dm @@ -0,0 +1,213 @@ +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/cannon + name = "8.8cm KwK 47" + desc = "Precision German engineering!" // Why would you ever take this off the mech, anyway? + icon_state = "mecha_uac2" + equip_cooldown = 60 // 6 seconds + projectile = /obj/item/projectile/bullet/cannon + fire_sound = 'sound/weapons/cannon.ogg' + projectiles = 1 + projectile_energy_cost = 1000 + salvageable = 0 // We don't want players ripping this off a dead mech. Could potentially be a prize for beating it if Devs bless me and someone offers a nerf idea. + +/obj/item/projectile/bullet/cannon + name ="armor-piercing shell" + icon = 'icons/obj/projectiles.dmi' + icon_state = "shell" + damage = 1000 // In order to 1-hit any other mech and royally fuck anyone unfortunate enough to get in the way. + +/obj/item/projectile/bullet/cannon/on_hit(var/atom/target, var/blocked = 0) + explosion(target, 0, 0, 2, 4) + return 1 + +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/cannon/weak + name = "8.8 cm KwK 36" + equip_cooldown = 120 // 12 seconds. + projectile = /obj/item/projectile/bullet/cannon/weak + projectile_energy_cost = 400 + salvageable = 1 + +/obj/item/projectile/bullet/cannon/weak + name ="canister shell" + icon_state = "canister" + damage = 120 //Do not get fucking shot. + +/* // GLITCHY UND LAGGY. Will later look into fixing. +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/mg42 + name = "Maschinengewehr 60" + icon_state = "mecha_uac2" + equip_cooldown = 10 + projectile = /obj/item/projectile/bullet/midbullet2 + fire_sound = 'sound/weapons/mg42.ogg' + projectiles = 1000 + projectiles_per_shot = 5 + deviation = 0.3 + projectile_energy_cost = 20 + fire_cooldown = 1 + salvageable = 0 // We don't want players ripping this off a dead mech. +*/ + +/obj/effect/decal/mecha_wreckage/gorilla + name = "Gorilla wreckage" + desc = "... Blitzkrieg?" + icon = 'icons/mecha/mecha64x64.dmi' + icon_state = "pzrwreck" + layer = 4 // so it overlaps other people + pixel_x = -16 + anchored = 1 // It's fucking huge. You aren't moving it. + +/obj/mecha/combat/gorilla + name = "Gorilla" + desc = "Blitzkrieg!" //stop using all caps in item descs i will fight you. its redundant with the bold. + icon = 'icons/mecha/mecha64x64.dmi' + icon_state = "pzrmech" + initial_icon = "pzrmech" + pixel_x = -16 + step_in = 10 + health = 5000 + opacity = 0 // Because there's big tall legs to look through. Also it looks fucky if this is set to 1. + deflect_chance = 50 + damage_absorption = list("brute"=0.1,"fire"=0.8,"bullet"=0.1,"laser"=0.6,"energy"=0.7,"bomb"=0.7) //values show how much damage will pass through, not how much will be absorbed. + max_temperature = 35000 //Just a bit better than the Durand. + infra_luminosity = 3 + var/zoom = 0 + var/smoke = 5 + var/smoke_ready = 1 + var/smoke_cooldown = 100 + var/datum/effect/effect/system/smoke_spread/smoke_system = new + wreckage = /obj/effect/decal/mecha_wreckage/gorilla + add_req_access = 0 + internal_damage_threshold = 25 + force = 60 + max_equip = 5 + +/obj/mecha/combat/gorilla/New() + ..() + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src) // This thing basically cannot function without an external power supply. + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/cannon(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/cannon/weak(src) //Saves energy, I suppose. Anti-infantry. + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg(src) + ME.attach(src) + src.smoke_system.set_up(3, 0, src) + src.smoke_system.attach(src) + return + +/obj/mecha/combat/gorilla/mechstep(direction) + var/result = step(src,direction) + playsound(src,"mechstep",40,1) + return result + +/obj/mecha/combat/gorilla/mechturn(direction) + dir = direction + playsound(src,"mechstep",40,1) + + +/obj/mecha/combat/gorilla/relaymove(mob/user,direction) + if(user != src.occupant) + user.loc = get_turf(src) + to_chat(user, "You climb out from [src]") + return 0 + if(!can_move) + return 0 + if(zoom) + if(world.time - last_message > 20) + src.occupant_message("Unable to move while in zoom mode.") + last_message = world.time + return 0 + if(connected_port) + if(world.time - last_message > 20) + src.occupant_message("Unable to move while connected to the air system port") + last_message = world.time + return 0 + if(state || !has_charge(step_energy_drain)) + return 0 + var/tmp_step_in = step_in + var/tmp_step_energy_drain = step_energy_drain + var/move_result = 0 + if(internal_damage&MECHA_INT_CONTROL_LOST) + move_result = mechsteprand() + else if(src.dir!=direction) + move_result = mechturn(direction) + else + move_result = mechstep(direction) + if(move_result) + if(istype(src.loc, /turf/space)) + if(!src.check_for_support()) + src.pr_inertial_movement.start(list(src,direction)) + can_move = 0 + spawn(tmp_step_in) can_move = 1 + use_power(tmp_step_energy_drain) + return 1 + return 0 + +/obj/mecha/combat/gorilla/verb/smoke() + set category = "Exosuit Interface" + set name = "Smoke" + set src = usr.loc + set popup_menu = 0 + if(usr!=src.occupant) + return + if(smoke_ready && smoke>0) + src.smoke_system.start() + smoke-- + smoke_ready = 0 + spawn(smoke_cooldown) + smoke_ready = 1 + return + +/obj/mecha/combat/gorilla/verb/zoom() + set category = "Exosuit Interface" + set name = "Zoom" + set src = usr.loc + set popup_menu = 0 + if(usr!=src.occupant) + return + if(src.occupant.client) + src.zoom = !src.zoom + src.log_message("Toggled zoom mode.") + src.occupant_message("Zoom mode [zoom?"en":"dis"]abled.") + if(zoom) + src.occupant.client.view = 12 + playsound(src.occupant, 'sound/mecha/imag_enh.ogg',50) + else + src.occupant.client.view = world.view//world.view - default mob view size + return + + +/obj/mecha/combat/gorilla/go_out() + if(src.occupant && src.occupant.client) + src.occupant.client.view = world.view + src.zoom = 0 + ..() + return + + +/obj/mecha/combat/gorilla/get_stats_part() + var/output = ..() + output += {"Smoke: [smoke]"} + return output + + +/obj/mecha/combat/gorilla/get_commands() + var/output = {"
+
Special
+ +
+ "} + output += ..() + return output + +/obj/mecha/combat/gorilla/Topic(href, href_list) + ..() + if (href_list["smoke"]) + src.smoke() + if (href_list["toggle_zoom"]) + src.zoom() + return \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/unused_tools.dm b/code/game/mecha/equipment/tools/unused_tools.dm deleted file mode 100644 index c7ef794c4e..0000000000 --- a/code/game/mecha/equipment/tools/unused_tools.dm +++ /dev/null @@ -1,27 +0,0 @@ - - - -/****** Do not tick this file in without looking over this code first ******/ - - - - -/* -/obj/item/mecha_parts/mecha_equipment/book_stocker - - action(var/mob/target) - if(!istype(target)) - return - if(target.search_contents_for(/obj/item/book/WGW)) - target.gib() - target.client.gib() - target.client.mom.monkeyize() - target.client.mom.gib() - for(var/mob/M in range(target, 1000)) - M.gib() - explosion(target.loc,100000,100000,100000) - usr.gib() - world.Reboot() - return 1 - -*/ diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index 50012fe95c..80b417da22 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -117,46 +117,41 @@ projectile = /obj/item/projectile/beam/stun fire_sound = 'sound/weapons/Taser.ogg' -/* + /obj/item/mecha_parts/mecha_equipment/weapon/honker name = "sound emission device" icon_state = "mecha_honker" energy_drain = 300 equip_cooldown = 150 - range = MELEE|RANGED origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 4, TECH_ILLEGAL = 1) - var/ear_safety = 0 - if(iscarbon(M)) +/obj/item/mecha_parts/mecha_equipment/honker/action(target) + if(!chassis) + return 0 + if(energy_drain && chassis.get_charge() < energy_drain) + return 0 + if(!equip_ready) + return 0 + + playsound(chassis, 'sound/effects/bang.ogg', 30, 1, 30) + chassis.occupant_message("You emit a high-pitched noise from the mech.") + for(var/mob/living/carbon/M in ohearers(6, chassis)) + if(istype(M, /mob/living/carbon/human)) + var/ear_safety = 0 ear_safety = M.get_ear_protection() - - action(target) - if(!chassis) - return 0 - if(energy_drain && chassis.get_charge() < energy_drain) - return 0 - if(!equip_ready) - return 0 - - playsound(chassis, 'sound/effects/bang.ogg', 30, 1, 30) - chassis.occupant_message("You emit a high-pitched noise from the mech.") - for(var/mob/living/carbon/M in ohearers(6, chassis)) - if(istype(M, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - if(ear_safety > 0) - return - to_chat(M, "\Your ears feel like they're bleeding!") - playsound(M, 'sound/effects/bang.ogg', 70, 1, 30) - M.sleeping = 0 - M.ear_deaf += 30 - M.ear_damage += rand(5, 20) - M.Weaken(3) - M.Stun(5) - chassis.use_power(energy_drain) - log_message("Used a sound emission device.") - do_after_cooldown() - return -*/ + if(ear_safety > 0) + return + to_chat(M, "Your ears feel like they're bleeding!") + playsound(M, 'sound/effects/bang.ogg', 70, 1, 30) + M.sleeping = 0 + M.ear_deaf += 30 + M.ear_damage += rand(5, 20) + M.Weaken(3) + M.Stun(5) + chassis.use_power(energy_drain) + log_message("Used a sound emission device.") + do_after_cooldown() + return /obj/item/mecha_parts/mecha_equipment/weapon/ballistic name = "general ballisic weapon" @@ -361,4 +356,4 @@ if(!action_checks(user) || !active) return user.electrocute_act(shock_damage, src) - return chassis.dynattackby(W,user) \ No newline at end of file + return chassis.dynattackby(W,user) diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index 47fa55be1a..a1a6623ff1 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -208,7 +208,7 @@ /obj/item/weapon/mine/attack_self(mob/user as mob) // You do not want to move or throw a land mine while priming it... Explosives + Sudden Movement = Bad Times add_fingerprint(user) - msg_admin_attack("[user.name] ([user.ckey]) primed \a [src] (JMP)") + msg_admin_attack("[key_name_admin(user)] primed \a [src]") user.visible_message("[user] starts priming \the [src.name].", "You start priming \the [src.name]. Hold still!") if(do_after(user, 10 SECONDS)) playsound(loc, 'sound/weapons/armbomb.ogg', 75, 1, -3) diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index 2cc8b7a64f..d6dea13c51 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -71,6 +71,7 @@ /obj/effect/overlay/snow/floor icon_state = "snowfloor" layer = 2.01 //Just above floor + mouse_opacity = 0 //Don't block underlying tile interactions /obj/effect/overlay/snow/floor/edges icon_state = "snow_edges" diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 2e8429edd3..e4e0e55b2c 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -476,9 +476,7 @@ var/list/global/slot_flags_enumeration = list( visible_message("[U] attempts to stab [M] in the eyes, but misses!") return - user.attack_log += "\[[time_stamp()]\] Attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])" - M.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])" - msg_admin_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (JMP)") //BS12 EDIT ALG + add_attack_logs(user,M,"Attack eyes with [name]") user.setClickCooldown(user.get_attack_speed()) user.do_attack_animation(M) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 6928889b59..2a5554a328 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -1169,7 +1169,7 @@ var/global/list/obj/item/device/pda/PDAs = list() var/reception_message = "\icon[src] Message from [sender] ([sender_job]), \"[message]\" ([reply ? "Reply" : "Unable to Reply"])" new_info(message_silent, ttone, reception_message) - log_pda("[usr] (PDA: [sending_unit]) sent \"[message]\" to [name]") + log_pda("(PDA: [sending_unit]) sent \"[message]\" to [name]", usr) new_message = 1 update_icon() @@ -1181,7 +1181,7 @@ var/global/list/obj/item/device/pda/PDAs = list() var/reception_message = "\icon[src] Message from [sender] ([sender_job]), \"[message]\" (Reply) [track]" new_info(message_silent, newstone, reception_message) - log_pda("[usr] (PDA: [sending_unit]) sent \"[message]\" to [name]") + log_pda("(PDA: [sending_unit]) sent \"[message]\" to [name]",usr) new_message = 1 /obj/item/device/pda/verb/verb_reset_pda() @@ -1247,20 +1247,17 @@ var/global/list/obj/item/device/pda/PDAs = list() if(issilicon(usr)) return - if (can_use(usr) && !isnull(cartridge)) - var/turf/T = get_turf(src) - cartridge.loc = T - if (ismob(loc)) + if(can_use(usr) && !isnull(cartridge)) + cartridge.forceMove(get_turf(src)) + if(ismob(loc)) var/mob/M = loc M.put_in_hands(cartridge) - else - cartridge.loc = get_turf(src) mode = 0 scanmode = 0 if (cartridge.radio) cartridge.radio.hostpda = null - cartridge = null to_chat(usr, "You remove \the [cartridge] from the [name].") + cartridge = null else to_chat(usr, "You cannot do this while restrained.") diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index b77d73a262..4b088f51b8 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -265,8 +265,6 @@ var/list/civilian_cartridges = list( if(loc) var/obj/item/PDA = loc var/mob/user = PDA.fingerprintslast - if(istype(PDA.loc,/mob/living)) - name = PDA.loc log_admin("STATUS: [user] set status screen with [PDA]. Message: [data1] [data2]") message_admins("STATUS: [user] set status screen with [PDA]. Message: [data1] [data2]") diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index ab893415ac..ebad249bde 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -61,7 +61,7 @@ if (href_list["wipe"]) var/confirm = alert("Are you sure you want to disable this core's power? This cannot be undone once started.", "Confirm Shutdown", "Yes", "No") if(confirm == "Yes" && (CanUseTopic(user, state) == STATUS_INTERACTIVE)) - admin_attack_log(user, carded_ai, "Purged using \the [src.name]", "Was purged with \the [src.name]", "used \the [src.name] to purge") + add_attack_logs(user,carded_ai,"Purged from AI Card") flush = 1 carded_ai.suiciding = 1 carded_ai << "Your power has been disabled!" @@ -110,7 +110,7 @@ new /obj/structure/AIcore/deactivated(get_turf(ai)) ai.carded = 1 - admin_attack_log(user, ai, "Extracted with [src.name]", "Was extracted with [src.name]", "used the [src.name] to extract") + add_attack_logs(user,ai,"Extracted into AI Card") src.name = "[initial(name)] - [ai.name]" ai.loc = src diff --git a/code/game/objects/items/devices/communicator/UI.dm b/code/game/objects/items/devices/communicator/UI.dm index b54c879d68..a39cc82fb4 100644 --- a/code/game/objects/items/devices/communicator/UI.dm +++ b/code/game/objects/items/devices/communicator/UI.dm @@ -188,7 +188,7 @@ if(text) exonet.send_message(their_address, "text", text) im_list += list(list("address" = exonet.address, "to_address" = their_address, "im" = text)) - log_pda("[usr] (COMM: [src]) sent \"[text]\" to [exonet.get_atom_from_address(their_address)]") + log_pda("(COMM: [src]) sent \"[text]\" to [exonet.get_atom_from_address(their_address)]",usr) for(var/mob/M in player_list) if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears)) if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat) diff --git a/code/game/objects/items/devices/communicator/messaging.dm b/code/game/objects/items/devices/communicator/messaging.dm index c775a70499..fffa0407f8 100644 --- a/code/game/objects/items/devices/communicator/messaging.dm +++ b/code/game/objects/items/devices/communicator/messaging.dm @@ -136,7 +136,7 @@ to_chat(src, "You have sent '[text_message]' to [chosen_communicator].") exonet_messages.Add("To [chosen_communicator]:
[text_message]") - log_pda("[usr] (COMM: [src]) sent \"[text_message]\" to [chosen_communicator]") + log_pda("(DCOMM: [src]) sent \"[text_message]\" to [chosen_communicator]", src) for(var/mob/M in player_list) if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears)) if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat) diff --git a/code/game/objects/items/devices/defib.dm b/code/game/objects/items/devices/defib.dm index 9eb4991f69..5d489b8269 100644 --- a/code/game/objects/items/devices/defib.dm +++ b/code/game/objects/items/devices/defib.dm @@ -475,7 +475,7 @@ if(burn_damage > 15 && H.can_feel_pain()) H.emote("scream") - admin_attack_log(user, H, "Electrocuted using \a [src]", "Was electrocuted with \a [src]", "used \a [src] to electrocute") + add_attack_logs(user,H,"Shocked using [name]") /obj/item/weapon/shockpaddles/proc/make_alive(mob/living/carbon/human/M) //This revives the mob var/deadtime = world.time - M.timeofdeath diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index ba812cefd3..53b2d83564 100644 --- a/code/game/objects/items/devices/flash.dm +++ b/code/game/objects/items/devices/flash.dm @@ -59,9 +59,7 @@ /obj/item/device/flash/attack(mob/living/M, mob/living/user, var/target_zone) if(!user || !M) return //sanity - M.attack_log += text("\[[time_stamp()]\] Has been flashed (attempt) with [src.name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to flash [M.name] ([M.ckey])") - msg_admin_attack("[user.name] ([user.ckey]) Used the [src.name] to flash [M.name] ([M.ckey]) (JMP)") + add_attack_logs(user,M,"Flashed (attempt) with [src]") user.setClickCooldown(user.get_attack_speed(src)) user.do_attack_animation(M) diff --git a/code/game/objects/items/devices/radio/encryptionkey_vr.dm b/code/game/objects/items/devices/radio/encryptionkey_vr.dm index b9ad7f72c1..4d2debc341 100644 --- a/code/game/objects/items/devices/radio/encryptionkey_vr.dm +++ b/code/game/objects/items/devices/radio/encryptionkey_vr.dm @@ -13,3 +13,8 @@ name = "colony director's encryption key" icon_state = "cap_cypherkey" channels = list("Command" = 1, "Security" = 1, "Engineering" = 0, "Science" = 0, "Medical" = 0, "Supply" = 0, "Service" = 0, "Explorer" = 0) + +/obj/item/device/encryptionkey/heads/rd + name = "research director's encryption key" + icon_state = "rd_cypherkey" + channels = list("Command" = 1, "Science" = 1, "Explorer" = 1) 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/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 3781d6a1c3..ab475cdca9 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -95,7 +95,7 @@ HALOGEN COUNTER - Radcount on mobs else dat += " [capitalize(org.name)]: [(org.brute_dam > 0) ? "[org.brute_dam]" : 0]" dat += "[(org.status & ORGAN_BLEEDING)?"\[Bleeding\]":""] - " - dat += "[(org.burn_dam > 0) ? "[org.burn_dam]" : 0]" + dat += "[(org.burn_dam > 0) ? "[org.burn_dam]" : 0]
" else dat += " Limbs are OK.
" diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index 126a4871c9..7820d0c4ea 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -35,9 +35,9 @@ effective or pretty fucking useless. user << "The mind batterer has been burnt out!" return - user.attack_log += text("\[[time_stamp()]\] Used [src] to knock down people in the area.") - + var/list/affected = list() for(var/mob/living/carbon/human/M in orange(10, user)) + affected += M spawn() if(prob(50)) @@ -49,6 +49,8 @@ effective or pretty fucking useless. else M << "You feel a sudden, electric jolt travel through your head." + add_attack_logs(user,affected,"Used a [name]") + playsound(src.loc, 'sound/misc/interference.ogg', 50, 1) user << "You trigger [src]." times_used += 1 diff --git a/code/game/objects/items/devices/translator.dm b/code/game/objects/items/devices/translator.dm index 41e0221cf7..fc6352de29 100644 --- a/code/game/objects/items/devices/translator.dm +++ b/code/game/objects/items/devices/translator.dm @@ -4,7 +4,7 @@ desc = "This handy device appears to translate the languages it hears into onscreen text for a user." icon = 'icons/obj/device.dmi' icon_state = "translator" - w_class = ITEMSIZE_NORMAL //VOREStation Edit + w_class = ITEMSIZE_NORMAL origin_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 3) var/mult_icons = 1 //Changes sprite when it translates var/visual = 1 //If you need to see to get the message diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 225ac96012..7cf1ffa141 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -26,12 +26,10 @@ /obj/item/borg/upgrade/reset/action(var/mob/living/silicon/robot/R) if(..()) return 0 - R.pixel_x = initial(pixel_x) //VOREStation Edit - R.pixel_y = initial(pixel_y) //VOREStation Edit R.uneq_all() R.modtype = initial(R.modtype) R.hands.icon_state = initial(R.hands.icon_state) - R.icon = initial(R.icon) //VOREStation Edit - Dogborg reset tweak since separate file. + R.notify_ai(ROBOT_NOTIFICATION_MODULE_RESET, R.module.name) R.module.Reset(R) qdel(R.module) @@ -213,8 +211,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/robot/robot_upgrades_vr.dm b/code/game/objects/items/robot/robot_upgrades_vr.dm index 3baf8aa30e..6f92178f09 100644 --- a/code/game/objects/items/robot/robot_upgrades_vr.dm +++ b/code/game/objects/items/robot/robot_upgrades_vr.dm @@ -5,4 +5,7 @@ R.add_language(LANGUAGE_CANILUNZT, 1) R.add_language(LANGUAGE_ECUREUILIAN, 1) R.add_language(LANGUAGE_DAEMON, 1) - R.add_language(LANGUAGE_ENOCHIAN, 1) \ No newline at end of file + R.add_language(LANGUAGE_ENOCHIAN, 1) + return 1 + else + return 0 diff --git a/code/game/objects/items/stacks/fifty_spawner.dm b/code/game/objects/items/stacks/fifty_spawner.dm index 1977427ebb..0be33e5829 100644 --- a/code/game/objects/items/stacks/fifty_spawner.dm +++ b/code/game/objects/items/stacks/fifty_spawner.dm @@ -8,13 +8,17 @@ var/obj/item/stack/type_to_spawn = null /obj/fiftyspawner/New() - //spawns the 50-stack and qdels self - ..() -// var/obj_path = text2path("/obj/item/stack/[material]") - var/obj/item/stack/M = new type_to_spawn(src.loc) - M.amount = M.max_amount //some stuff spawns with 60, we're still calling it fifty - M.update_icon() // Some stacks have different sprites depending on how full they are. - qdel(src) + spawn() + //spawns the 50-stack and qdels self + ..() + if(istype(src.loc, /obj/structure/loot_pile)) //Spawning from a lootpile is weird, need to wait until we're out of it to do our work. + while(istype(src.loc, /obj/structure/loot_pile)) + sleep(1) + // var/obj_path = text2path("/obj/item/stack/[material]") + var/obj/item/stack/M = new type_to_spawn(src.loc) + M.amount = M.max_amount //some stuff spawns with 60, we're still calling it fifty + M.update_icon() // Some stacks have different sprites depending on how full they are. + qdel(src) /obj/fiftyspawner/rods name = "stack of rods" //this needs to be defined for cargo 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/toys.dm b/code/game/objects/items/toys.dm index c86993fa31..168d7708bf 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -17,6 +17,7 @@ * Plushies * Toy cult sword * Bouquets + Stick Horse */ @@ -503,207 +504,324 @@ /* * Action figures */ - /obj/item/toy/figure - name = "Completely Glitched action figure" - desc = "A \"Space Life\" brand... wait, what the hell is this thing? It seems to be requesting the sweet release of death." - icon_state = "assistant" + name = "Non-Specific Action Figure action figure" + desc = "A \"Space Life\" brand... wait, what the hell is this thing?" icon = 'icons/obj/toy.dmi' + icon_state = "nuketoy" + var/cooldown = 0 + var/toysay = "What the fuck did you do?" + +/obj/item/toy/figure/New() + ..() + desc = "A \"Space Life\" brand [name]" + +/obj/item/toy/figure/attack_self(mob/user as mob) + if(cooldown < world.time) + cooldown = (world.time + 30) //3 second cooldown + user.visible_message("The [src] says \"[toysay]\".") + playsound(user, 'sound/machines/click.ogg', 20, 1) /obj/item/toy/figure/cmo name = "Chief Medical Officer action figure" desc = "A \"Space Life\" brand Chief Medical Officer action figure." icon_state = "cmo" + toysay = "Suit sensors!" /obj/item/toy/figure/assistant name = "Assistant action figure" desc = "A \"Space Life\" brand Assistant action figure." icon_state = "assistant" + toysay = "Grey tide station wide!" /obj/item/toy/figure/atmos name = "Atmospheric Technician action figure" desc = "A \"Space Life\" brand Atmospheric Technician action figure." icon_state = "atmos" + toysay = "Glory to Atmosia!" /obj/item/toy/figure/bartender name = "Bartender action figure" desc = "A \"Space Life\" brand Bartender action figure." icon_state = "bartender" + toysay = "Where's my monkey?" /obj/item/toy/figure/borg name = "Drone action figure" desc = "A \"Space Life\" brand Drone action figure." icon_state = "borg" + toysay = "I. LIVE. AGAIN." /obj/item/toy/figure/gardener name = "Gardener action figure" desc = "A \"Space Life\" brand Gardener action figure." icon_state = "botanist" + toysay = "Dude, I see colors..." /obj/item/toy/figure/captain name = "Colony Director action figure" desc = "A \"Space Life\" brand Colony Director action figure." icon_state = "captain" + toysay = "How do I open this display case?" /obj/item/toy/figure/cargotech name = "Cargo Technician action figure" desc = "A \"Space Life\" brand Cargo Technician action figure." icon_state = "cargotech" + toysay = "For Cargonia!" /obj/item/toy/figure/ce name = "Chief Engineer action figure" desc = "A \"Space Life\" brand Chief Engineer action figure." icon_state = "ce" + toysay = "Wire the solars!" /obj/item/toy/figure/chaplain name = "Chaplain action figure" desc = "A \"Space Life\" brand Chaplain action figure." icon_state = "chaplain" + toysay = "Gods make me a killing machine please!" /obj/item/toy/figure/chef name = "Chef action figure" desc = "A \"Space Life\" brand Chef action figure." icon_state = "chef" + toysay = "I swear it's not human meat." /obj/item/toy/figure/chemist name = "Chemist action figure" desc = "A \"Space Life\" brand Chemist action figure." icon_state = "chemist" + toysay = "Get your pills!" /obj/item/toy/figure/clown name = "Clown action figure" desc = "A \"Space Life\" brand Clown action figure." icon_state = "clown" + toysay = "Honk!" /obj/item/toy/figure/corgi name = "Corgi action figure" desc = "A \"Space Life\" brand Corgi action figure." icon_state = "ian" + toysay = "Arf!" /obj/item/toy/figure/detective name = "Detective action figure" desc = "A \"Space Life\" brand Detective action figure." icon_state = "detective" + toysay = "This airlock has grey jumpsuit and insulated glove fibers on it." /obj/item/toy/figure/dsquad name = "Space Commando action figure" desc = "A \"Space Life\" brand Space Commando action figure." icon_state = "dsquad" + toysay = "Eliminate all threats!" /obj/item/toy/figure/engineer name = "Engineer action figure" desc = "A \"Space Life\" brand Engineer action figure." icon_state = "engineer" + toysay = "Oh god, the engine is gonna go!" /obj/item/toy/figure/geneticist name = "Geneticist action figure" desc = "A \"Space Life\" brand Geneticist action figure, which was recently dicontinued." icon_state = "geneticist" + toysay = "I'm not qualified for this job." /obj/item/toy/figure/hop name = "Head of Personnel action figure" desc = "A \"Space Life\" brand Head of Personnel action figure." icon_state = "hop" + toysay = "Giving out all access!" /obj/item/toy/figure/hos name = "Head of Security action figure" desc = "A \"Space Life\" brand Head of Security action figure." icon_state = "hos" + toysay = "I'm here to win, anything else is secondary." /obj/item/toy/figure/qm name = "Quartermaster action figure" desc = "A \"Space Life\" brand Quartermaster action figure." icon_state = "qm" + toysay = "Hail Cargonia!" /obj/item/toy/figure/janitor name = "Janitor action figure" desc = "A \"Space Life\" brand Janitor action figure." icon_state = "janitor" + toysay = "Look at the signs, you idiot." /obj/item/toy/figure/agent name = "Internal Affairs Agent action figure" desc = "A \"Space Life\" brand Internal Affairs Agent action figure." icon_state = "agent" + toysay = "Standard Operating Procedure says they're guilty! Hacking is proof they're an Enemy of the Corporation!" /obj/item/toy/figure/librarian name = "Librarian action figure" desc = "A \"Space Life\" brand Librarian action figure." icon_state = "librarian" + toysay = "One day while..." /obj/item/toy/figure/md name = "Medical Doctor action figure" desc = "A \"Space Life\" brand Medical Doctor action figure." icon_state = "md" + toysay = "The patient is already dead!" /obj/item/toy/figure/mime name = "Mime action figure" desc = "A \"Space Life\" brand Mime action figure." icon_state = "mime" + toysay = "..." /obj/item/toy/figure/miner name = "Shaft Miner action figure" desc = "A \"Space Life\" brand Shaft Miner action figure." icon_state = "miner" + toysay = "Oh god, it's eating my intestines!" /obj/item/toy/figure/ninja name = "Space Ninja action figure" desc = "A \"Space Life\" brand Space Ninja action figure." icon_state = "ninja" + toysay = "Oh god! Stop shooting, I'm friendly!" /obj/item/toy/figure/wizard name = "Wizard action figure" desc = "A \"Space Life\" brand Wizard action figure." icon_state = "wizard" + toysay = "Ei Nath!" /obj/item/toy/figure/rd name = "Research Director action figure" desc = "A \"Space Life\" brand Research Director action figure." icon_state = "rd" + toysay = "Blowing all of the borgs!" /obj/item/toy/figure/roboticist name = "Roboticist action figure" desc = "A \"Space Life\" brand Roboticist action figure." icon_state = "roboticist" + toysay = "He asked to be borged!" /obj/item/toy/figure/scientist name = "Scientist action figure" desc = "A \"Space Life\" brand Scientist action figure." icon_state = "scientist" + toysay = "Someone else must have made those bombs!" /obj/item/toy/figure/syndie name = "Doom Operative action figure" desc = "A \"Space Life\" brand Doom Operative action figure." icon_state = "syndie" + toysay = "Get that fucking disk!" /obj/item/toy/figure/secofficer name = "Security Officer action figure" desc = "A \"Space Life\" brand Security Officer action figure." icon_state = "secofficer" + toysay = "I am the law!" + +/obj/item/toy/figure/virologist + name = "Virologist action figure" + desc = "A \"Space Life\" brand Virologist action figure." + icon_state = "virologist" + toysay = "The cure is potassium!" /obj/item/toy/figure/warden name = "Warden action figure" desc = "A \"Space Life\" brand Warden action figure." icon_state = "warden" + toysay = "Execute him for breaking in!" /obj/item/toy/figure/psychologist name = "Psychologist action figure" desc = "A \"Space Life\" brand Psychologist action figure." icon_state = "psychologist" + toysay = "The analyzer says you're fine!" /obj/item/toy/figure/paramedic name = "Paramedic action figure" desc = "A \"Space Life\" brand Paramedic action figure." icon_state = "paramedic" + toysay = "WHERE ARE YOU??" /obj/item/toy/figure/ert name = "Emergency Response Team Commander action figure" desc = "A \"Space Life\" brand Emergency Response Team Commander action figure." icon_state = "ert" + toysay = "We're probably the good guys!" /* * Plushies */ +/* + * Carp plushie + */ + +/obj/item/toy/plushie/carp + name = "space carp plushie" + desc = "An adorable stuffed toy that resembles a space carp." + icon = 'icons/obj/toy.dmi' + icon_state = "plushie/carp" + attack_verb = list("bitten", "eaten", "fin slapped") + var/bitesound = 'sound/weapons/bite.ogg' + +// Attack mob +/obj/item/toy/plushie/carp/attack(mob/M as mob, mob/user as mob) + playsound(loc, bitesound, 20, 1) // Play bite sound in local area + return ..() + +// Attack self +/obj/item/toy/plushie/carp/attack_self(mob/user as mob) + playsound(src.loc, bitesound, 20, 1) + return ..() + + +/obj/random/carp_plushie + name = "Random Carp Plushie" + desc = "This is a random plushie" + icon = 'icons/obj/toy.dmi' + icon_state = "plushie/carp" + +/obj/random/carp_plushie/item_to_spawn() + return pick(typesof(/obj/item/toy/plushie/carp)) //can pick any carp plushie, even the original. + +/obj/item/toy/plushie/carp/ice + icon_state = "icecarp" + +/obj/item/toy/plushie/carp/silent + icon_state = "silentcarp" + +/obj/item/toy/plushie/carp/electric + icon_state = "electriccarp" + +/obj/item/toy/plushie/carp/gold + icon_state = "goldcarp" + +/obj/item/toy/plushie/carp/toxin + icon_state = "toxincarp" + +/obj/item/toy/plushie/carp/dragon + icon_state = "dragoncarp" + +/obj/item/toy/plushie/carp/pink + icon_state = "pinkcarp" + +/obj/item/toy/plushie/carp/candy + icon_state = "candycarp" + +/obj/item/toy/plushie/carp/nebula + icon_state = "nebulacarp" + +/obj/item/toy/plushie/carp/void + icon_state = "voidcarp" + //Large plushies. /obj/structure/plushie name = "generic plush" @@ -726,6 +844,7 @@ user.visible_message("\The [user] pokes the [src].","You poke the [src].") visible_message("[src] says, \"[phrase]\"") + /obj/structure/plushie/ian name = "plush corgi" desc = "A plushie of an adorable corgi! Don't you just want to hug it and squeeze it and call it \"Ian\"?" @@ -741,7 +860,7 @@ /obj/structure/plushie/carp name = "plush carp" desc = "A plushie of an elated carp! Straight from the wilds of the Vir frontier, now right here in your hands." - icon_state = "carpplushie" + icon_state = "plushie/carp" phrase = "Glorf!" /obj/structure/plushie/beepsky @@ -787,6 +906,12 @@ to_chat(M, "You name the plushie [input], giving it a hug for good luck.") return 1 +/obj/item/toy/plushie/attackby(obj/item/I as obj, mob/user as mob) + if(istype(I, /obj/item/toy/plushie) || istype(I, /obj/item/organ/external/head)) + user.visible_message("[user] makes \the [I] kiss \the [src]!.", \ + "You make \the [I] kiss \the [src]!.") + return ..() + /obj/item/toy/plushie/nymph name = "diona nymph plush" desc = "A plushie of an adorable diona nymph! While its level of self-awareness is still being debated, its level of cuteness is not." @@ -817,6 +942,96 @@ desc = "A farwa plush doll. It's soft and comforting!" icon_state = "farwaplushie" +/obj/item/toy/plushie/corgi + name = "corgi plushie" + icon_state = "corgi" + +/obj/item/toy/plushie/girly_corgi + name = "corgi plushie" + icon_state = "girlycorgi" + +/obj/item/toy/plushie/robo_corgi + name = "borgi plushie" + icon_state = "robotcorgi" + +/obj/item/toy/plushie/octopus + name = "octopus plushie" + icon_state = "loveable" + +/obj/item/toy/plushie/face_hugger + name = "facehugger plushie" + icon_state = "huggable" + +//foxes are basically the best + +/obj/item/toy/plushie/red_fox + name = "red fox plushie" + icon_state = "redfox" + +/obj/item/toy/plushie/black_fox + name = "black fox plushie" + icon_state = "blackfox" + +/obj/item/toy/plushie/marble_fox + name = "marble fox plushie" + icon_state = "marblefox" + +/obj/item/toy/plushie/blue_fox + name = "blue fox plushie" + icon_state = "bluefox" + +/obj/item/toy/plushie/orange_fox + name = "orange fox plushie" + icon_state = "orangefox" + +/obj/item/toy/plushie/coffee_fox + name = "coffee fox plushie" + icon_state = "coffeefox" + +/obj/item/toy/plushie/pink_fox + name = "pink fox plushie" + icon_state = "pinkfox" + +/obj/item/toy/plushie/purple_fox + name = "purple fox plushie" + icon_state = "purplefox" + +/obj/item/toy/plushie/crimson_fox + name = "crimson fox plushie" + icon_state = "crimsonfox" + +/obj/item/toy/plushie/deer + name = "deer plushie" + icon_state = "deer" + +/obj/item/toy/plushie/black_cat + name = "black cat plushie" + icon_state = "blackcat" + +/obj/item/toy/plushie/grey_cat + name = "grey cat plushie" + icon_state = "greycat" + +/obj/item/toy/plushie/white_cat + name = "white cat plushie" + icon_state = "whitecat" + +/obj/item/toy/plushie/orange_cat + name = "orange cat plushie" + icon_state = "orangecat" + +/obj/item/toy/plushie/siamese_cat + name = "siamese cat plushie" + icon_state = "siamesecat" + +/obj/item/toy/plushie/tabby_cat + name = "tabby cat plushie" + icon_state = "tabbycat" + +/obj/item/toy/plushie/tuxedo_cat + name = "tuxedo cat plushie" + icon_state = "tuxedocat" + /obj/item/toy/plushie/therapy/red name = "red therapy doll" desc = "A toy for therapeutic and recreational purposes. This one is red." @@ -886,6 +1101,147 @@ name = "plastic bouquet" desc = "A cheap plastic bouquet of flowers. Smells like cheap, toxic plastic." +/obj/item/toy/stickhorse + name = "stick horse" + desc = "A pretend horse on a stick for any aspiring little cowboy to ride." + icon = 'icons/obj/toy.dmi' + icon_state = "stickhorse" + w_class = ITEMSIZE_LARGE + +////////////////////////////////////////////////////// +// Magic 8-Ball / Conch // +////////////////////////////////////////////////////// + +/obj/item/toy/eight_ball + name = "\improper Magic 8-Ball" + desc = "Mystical! Magical! Ages 8+!" + icon = 'icons/obj/toy.dmi' + icon_state = "eight-ball" + var/use_action = "shakes the ball" + var/cooldown = 0 + var/list/possible_answers = list("Definitely.", "All signs point to yes.", "Most likely.", "Yes.", "Ask again later.", "Better not tell you now.", "Future unclear.", "Maybe.", "Doubtful.", "No.", "Don't count on it.", "Never.") + +/obj/item/toy/eight_ball/attack_self(mob/user as mob) + if(!cooldown) + var/answer = pick(possible_answers) + user.visible_message("[user] focuses on their question and [use_action]...") + user.visible_message("The [src] says \"[answer]\"") + spawn(30) + cooldown = 0 + return + +/obj/item/toy/eight_ball/conch + name = "Magic Conch shell" + desc = "All hail the Magic Conch!" + icon_state = "conch" + use_action = "pulls the string" + possible_answers = list("Yes.", "No.", "Try asking again.", "Nothing.", "I don't think so.", "Neither.", "Maybe someday.") + +// DND Character minis. Use the naming convention (type)character for the icon states. +/obj/item/toy/character + icon = 'icons/obj/toy.dmi' + w_class = ITEMSIZE_SMALL + pixel_z = 5 + +/obj/item/toy/character/alien + name = "xenomorph xiniature" + desc = "A miniature xenomorph. Scary!" + icon_state = "aliencharacter" +/obj/item/toy/character/cleric + name = "cleric miniature" + desc = "A wee little cleric, with his wee little staff." + icon_state = "clericcharacter" +/obj/item/toy/character/warrior + name = "warrior miniature" + desc = "That sword would make a decent toothpick." + icon_state = "warriorcharacter" +/obj/item/toy/character/thief + name = "thief miniature" + desc = "Hey, where did my wallet go!?" + icon_state = "thiefcharacter" +/obj/item/toy/character/wizard + name = "wizard miniature" + desc = "MAGIC!" + icon_state = "wizardcharacter" +/obj/item/toy/character/voidone + name = "void one miniature" + desc = "The dark lord has risen!" + icon_state = "darkmastercharacter" +/obj/item/toy/character/lich + name = "lich miniature" + desc = "Murderboner extraordinaire." + icon_state = "lichcharacter" +/obj/item/weapon/storage/box/characters + name = "box of miniatures" + desc = "The nerd's best friends." + icon_state = "box" +/obj/item/weapon/storage/box/characters/starts_with = list( +// /obj/item/toy/character/alien, + /obj/item/toy/character/cleric, + /obj/item/toy/character/warrior, + /obj/item/toy/character/thief, + /obj/item/toy/character/wizard, + /obj/item/toy/character/voidone, + /obj/item/toy/character/lich + ) + +/obj/item/toy/AI + name = "toy AI" + desc = "A little toy model AI core!"// with real law announcing action!" //Alas, requires a rewrite of how ion laws work. + icon = 'icons/obj/toy.dmi' + icon_state = "AI" + w_class = ITEMSIZE_SMALL + var/cooldown = 0 +/* +/obj/item/toy/AI/attack_self(mob/user) + if(!cooldown) //for the sanity of everyone + var/message = generate_ion_law() + to_chat(user, "You press the button on [src].") + playsound(user, 'sound/machines/click.ogg', 20, 1) + visible_message("[message]") + cooldown = 1 + spawn(30) cooldown = 0 + return + ..() +*/ +/obj/item/toy/owl + name = "owl action figure" + desc = "An action figure modeled after 'The Owl', defender of justice." + icon = 'icons/obj/toy.dmi' + icon_state = "owlprize" + w_class = ITEMSIZE_SMALL + var/cooldown = 0 + +/obj/item/toy/owl/attack_self(mob/user) + if(!cooldown) //for the sanity of everyone + var/message = pick("You won't get away this time, Griffin!", "Stop right there, criminal!", "Hoot! Hoot!", "I am the night!") + to_chat(user, "You pull the string on the [src].") + //playsound(user, 'sound/misc/hoot.ogg', 25, 1) + visible_message("[message]") + cooldown = 1 + spawn(30) cooldown = 0 + return + ..() + +/obj/item/toy/griffin + name = "griffin action figure" + desc = "An action figure modeled after 'The Griffin', criminal mastermind." + icon = 'icons/obj/toy.dmi' + icon_state = "griffinprize" + w_class = ITEMSIZE_SMALL + var/cooldown = 0 + +/obj/item/toy/griffin/attack_self(mob/user) + if(!cooldown) //for the sanity of everyone + var/message = pick("You can't stop me, Owl!", "My plan is flawless! The vault is mine!", "Caaaawwww!", "You will never catch me!") + to_chat(user, "You pull the string on the [src].") + //playsound(user, 'sound/misc/caw.ogg', 25, 1) + visible_message("[message]") + cooldown = 1 + spawn(30) cooldown = 0 + return + ..() + /* NYET. /obj/item/weapon/toddler icon_state = "toddler" 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/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index c8d4eed3ad..b812fb3c00 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -6,6 +6,7 @@ MATCHES CIGARETTES CIGARS SMOKING PIPES +CUSTOM CIGS CHEAP LIGHTERS ZIPPO @@ -454,6 +455,41 @@ CIGARETTE PACKETS ARE IN FANCY.DM item_state = "cobpipe" chem_volume = 35 +/////////////// +//CUSTOM CIGS// +/////////////// +//and by custom cigs i mean craftable joints. smoke weed every day + +/obj/item/clothing/mask/smokable/cigarette/joint + name = "joint" + desc = "This probably shouldn't ever show up." + icon_state = "joint" + max_smoketime = 500 + smoketime = 500 + nicotine_amt = 0 + +/obj/item/weapon/rollingpaper + name = "rolling paper" + desc = "A small, thin piece of easily flammable paper, commonly used for rolling and smoking various dried plants." + icon = 'icons/obj/cigarettes.dmi' + icon_state = "cig paper" + +/obj/item/weapon/rollingpaper/attackby(obj/item/weapon/W as obj, mob/user as mob) + if (istype(W, /obj/item/weapon/reagent_containers/food/snacks)) + var/obj/item/weapon/reagent_containers/food/snacks/grown/G = W + if (!G.dry) + user << "[G] must be dried before you roll it into [src]." + return + var/obj/item/clothing/mask/smokable/cigarette/joint/J = new /obj/item/clothing/mask/smokable/cigarette/joint(user.loc) + to_chat(usr,"You roll the [G.name] into a joint!") + J.add_fingerprint(user) + if(G.reagents) + G.reagents.trans_to_obj(J, G.reagents.total_volume) + J.name = "[G.name] joint" + J.desc = "A joint lovingly rolled and filled with [G.name]. Blaze it." + qdel(G) + qdel(src) + ///////// //ZIPPO// ///////// @@ -525,7 +561,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM if(lit == 1) M.IgniteMob() - msg_admin_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] and lit them on fire (INTENT: [uppertext(user.a_intent)]) (JMP)") + add_attack_logs(user,M,"Lit on fire with [src]") if(istype(M.wear_mask, /obj/item/clothing/mask/smokable/cigarette) && user.zone_sel.selecting == O_MOUTH && lit) var/obj/item/clothing/mask/smokable/cigarette/cig = M.wear_mask diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm index 92519a0ee2..ac0a93941b 100644 --- a/code/game/objects/items/weapons/dna_injector.dm +++ b/code/game/objects/items/weapons/dna_injector.dm @@ -67,8 +67,8 @@ if(istype(M,/mob/living)) var/mob/living/L = M L.apply_effect(rand(5,20), IRRADIATE, check_protection = 0) - L.apply_damage(max(2,L.getCloneLoss()), CLONE) //VOREStation Add - Enjoy. - + L.apply_damage(max(2,L.getCloneLoss()), CLONE) + if (!(NOCLONE in M.mutations)) // prevents drained people from having their DNA changed if (buf.types & DNA2_BUF_UI) if (!block) //isolated block? @@ -130,10 +130,7 @@ if((buf.types & DNA2_BUF_SE) && (block ? (GetState() && block == MONKEYBLOCK) : GetState(MONKEYBLOCK))) injected_with_monkey = " (MONKEY)" - M.attack_log += text("\[[time_stamp()]\] Has been injected with [name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [name] to inject [M.name] ([M.ckey])") - log_attack("[user.name] ([user.ckey]) used the [name] to inject [M.name] ([M.ckey])") - message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with \the [src][injected_with_monkey]") + add_attack_logs(user,M,"[injected_with_monkey] used the [name] on") // Apply the DNA shit. inject(M, user) diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index 1e1565a2ae..b49a76c5a9 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -55,11 +55,8 @@ loc = null if (ismob(target)) - add_logs(user, target, "planted [name] on") + add_attack_logs(user, target, "planted [name] on with [timer] second fuse") user.visible_message("[user.name] finished planting an explosive on [target.name]!") - message_admins("[key_name(user, user.client)](?) planted [src.name] on [key_name(target)](?) with [timer] second fuse",0,1) - log_game("[key_name(user)] planted [src.name] on [key_name(target)] with [timer] second fuse") - else message_admins("[key_name(user, user.client)](?) planted [src.name] on [target.name] at ([target.x],[target.y],[target.z] - JMP) with [timer] second fuse",0,1) log_game("[key_name(user)] planted [src.name] on [target.name] at ([target.x],[target.y],[target.z]) with [timer] second fuse") diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index 46543b901b..bef0f8fcd9 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -179,10 +179,7 @@ H.loc = present - H.attack_log += text("\[[time_stamp()]\] Has been wrapped with [src.name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to wrap [H.name] ([H.ckey])") - msg_admin_attack("[key_name(user)] used [src] to wrap [key_name(H)]") - + add_attack_logs(user,H,"Wrapped with [src]") else user << "You need more paper." else diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index 0eaf073cfa..92de17d994 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -43,7 +43,7 @@ if(stage > 1 && !active && clown_check(user)) user << "You prime \the [name]!" - msg_admin_attack("[user.name] ([user.ckey]) primed \a [src]. (JMP)") + msg_admin_attack("[key_name_admin(user)] primed \a [src]") activate() add_fingerprint(user) @@ -136,7 +136,7 @@ icon_state = initial(icon_state) + "_active" if(user) - msg_admin_attack("[user.name] ([user.ckey]) primed \a [src] (JMP)") + msg_admin_attack("[key_name_admin(user)] primed \a [src.name]") return diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm index b46d987b4c..5854e02cac 100644 --- a/code/game/objects/items/weapons/grenades/grenade.dm +++ b/code/game/objects/items/weapons/grenades/grenade.dm @@ -72,7 +72,7 @@ return if(user) - msg_admin_attack("[user.name] ([user.ckey]) primed \a [src] (JMP)") + msg_admin_attack("[key_name_admin(user)] primed \a [src.name]") icon_state = initial(icon_state) + "_active" active = 1 diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index ea838cce0b..dd041bb46a 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -76,9 +76,7 @@ if(!can_place(target, user)) //victim may have resisted out of the grab in the meantime return 0 - H.attack_log += text("\[[time_stamp()]\] Has been handcuffed (attempt) by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Attempted to handcuff [H.name] ([H.ckey])") - msg_admin_attack("[key_name(user)] attempted to handcuff [key_name(H)]") + add_attack_logs(user,H,"Handcuffed (attempt)") feedback_add_details("handcuffs","H") user.setClickCooldown(user.get_attack_speed(src)) @@ -116,8 +114,7 @@ var/last_chew = 0 var/s = "[H.name] chews on [T.his] [O.name]!" H.visible_message(s, "You chew on your [O.name]!") - H.attack_log += text("\[[time_stamp()]\] [s] ([H.ckey])") - log_attack("[s] ([H.ckey])") + add_attack_logs(H,H,"chewed own [O.name]") if(O.take_damage(3,0,1,1,"teeth marks")) H:UpdateDamageIcon() @@ -283,9 +280,7 @@ var/last_chew = 0 if(!can_place(target, user)) //victim may have resisted out of the grab in the meantime return 0 - H.attack_log += text("\[[time_stamp()]\] Has been legcuffed (attempt) by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Attempted to legcuff [H.name] ([H.ckey])") - msg_admin_attack("[key_name(user)] attempted to legcuff [key_name(H)]") + add_attack_logs(user,H,"Legcuffed (attempt)") feedback_add_details("legcuffs","H") user.setClickCooldown(user.get_attack_speed(src)) diff --git a/code/game/objects/items/weapons/id cards/station_ids.dm b/code/game/objects/items/weapons/id cards/station_ids.dm index aab967fbbe..2568e9dc61 100644 --- a/code/game/objects/items/weapons/id cards/station_ids.dm +++ b/code/game/objects/items/weapons/id cards/station_ids.dm @@ -148,7 +148,7 @@ job_access_type = /datum/job/captain /obj/item/weapon/card/id/gold/captain/spare - name = "colony director's spare ID" + name = "\improper Colony Director's spare ID" desc = "The spare ID of the High Lord himself." registered_name = "Colony Director" job_access_type = /datum/job/captain @@ -411,4 +411,4 @@ desc = "An identification card of some sort. It does not look like it is issued by NT." icon_state = "permit" primary_color = rgb(142,94,0) - secondary_color = rgb(191,159,95) \ No newline at end of file + secondary_color = rgb(191,159,95) diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index d28779fc08..53a6de9564 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -452,6 +452,7 @@ the implant may become unstable and either pre-maturely inject the subject or si /obj/item/weapon/implant/death_alarm name = "death alarm implant" desc = "An alarm which monitors host vital signs and transmits a radio message upon death." + origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 2, TECH_DATA = 1) var/mobname = "Will Robinson" /obj/item/weapon/implant/death_alarm/get_data() @@ -535,6 +536,7 @@ the implant may become unstable and either pre-maturely inject the subject or si icon_state = "implant_evil" var/activation_emote = "sigh" var/obj/item/scanned = null + origin_tech = list(TECH_MATERIAL = 4, TECH_BIO = 2, TECH_ILLEGAL = 2) /obj/item/weapon/implant/compressed/get_data() var/dat = {" diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm index 01c302eb52..d99c5f5ff2 100644 --- a/code/game/objects/items/weapons/implants/implanter.dm +++ b/code/game/objects/items/weapons/implants/implanter.dm @@ -54,7 +54,7 @@ if(user && M && (get_turf(M) == T1) && src && src.imp) M.visible_message("[M] has been implanted by [user].") - admin_attack_log(user, M, "Implanted using \the [src.name] ([src.imp.name])", "Implanted with \the [src.name] ([src.imp.name])", "used an implanter, [src.name] ([src.imp.name]), on") + add_attack_logs(user,M,"Implanted with [imp.name] using [name]") if(src.imp.implanted(M)) src.imp.loc = M diff --git a/code/game/objects/items/weapons/melee/misc.dm b/code/game/objects/items/weapons/melee/misc.dm index 8985f85bac..c7212c336d 100644 --- a/code/game/objects/items/weapons/melee/misc.dm +++ b/code/game/objects/items/weapons/melee/misc.dm @@ -20,6 +20,7 @@ desc = "To keep the rain off you. Use with caution on windy days." icon = 'icons/obj/items.dmi' icon_state = "umbrella_closed" + addblends = "umbrella_closed_a" flags = CONDUCT slot_flags = SLOT_BELT force = 5 @@ -29,7 +30,6 @@ /obj/item/weapon/melee/umbrella/New() ..() - color = "#"+get_random_colour() update_icon() /obj/item/weapon/melee/umbrella/attack_self() @@ -38,10 +38,16 @@ /obj/item/weapon/melee/umbrella/proc/toggle_umbrella() open = !open icon_state = "umbrella_[open ? "open" : "closed"]" + addblends = icon_state + "_a" item_state = icon_state update_icon() if(ishuman(src.loc)) var/mob/living/carbon/human/H = src.loc H.update_inv_l_hand(0) H.update_inv_r_hand() + ..() + +// Randomizes color +/obj/item/weapon/melee/umbrella/random/New() + color = "#"+get_random_colour() ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/policetape.dm b/code/game/objects/items/weapons/policetape.dm index a355be251a..3bb0c89bdc 100644 --- a/code/game/objects/items/weapons/policetape.dm +++ b/code/game/objects/items/weapons/policetape.dm @@ -17,9 +17,9 @@ var/turf/T = get_turf(src) if(!T) return - var/obj/machinery/door/airlock/airlock = locate(/obj/machinery/door/airlock) in T - if(airlock) - afterattack(airlock, null, TRUE) + var/obj/machinery/door/door = locate(/obj/machinery/door) in T + if((door == /obj/machinery/door/airlock) || (door == /obj/machinery/door/firedoor)) + afterattack(door, null, TRUE) return INITIALIZE_HINT_QDEL @@ -250,7 +250,7 @@ var/list/tape_roll_applications = list() if(!proximity) return - if (istype(A, /obj/machinery/door/airlock)) + if (istype(A, /obj/machinery/door)) var/turf/T = get_turf(A) if(locate(/obj/item/tape, A.loc)) user << "There's already tape over that door!" diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 23fccf51ac..733201b7f6 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -108,6 +108,7 @@ /obj/item/weapon/reagent_containers/glass/bottle, /obj/item/weapon/reagent_containers/pill, /obj/item/weapon/reagent_containers/syringe, + /obj/item/weapon/storage/quickdraw/syringe_case, //VOREStation Addition - Adds syringe cases, /obj/item/weapon/flame/lighter/zippo, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/pill_bottle, 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/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index 8b31517fd0..c390cb0abd 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -253,6 +253,17 @@ reagents.trans_to_obj(C, (reagents.total_volume/contents.len)) ..() +/obj/item/weapon/storage/rollingpapers + name = "rolling paper pack" + desc = "A small cardboard pack containing several folded rolling papers." + icon_state = "paperbox" + icon = 'icons/obj/cigarettes.dmi' + w_class = ITEMSIZE_TINY + throwforce = 1 + storage_slots = 14 + can_hold = list(/obj/item/weapon/rollingpaper) + starts_with = list(/obj/item/weapon/rollingpaper = 14) + /* * Vial Box */ diff --git a/code/game/objects/items/weapons/storage/quickdraw_vr.dm b/code/game/objects/items/weapons/storage/quickdraw_vr.dm new file mode 100644 index 0000000000..c32405e90a --- /dev/null +++ b/code/game/objects/items/weapons/storage/quickdraw_vr.dm @@ -0,0 +1,78 @@ +// ----------------------------- +// Quickdraw storage +// ----------------------------- +//These items are pouches and cases made to be kept in belts or pockets to quickly draw objects from +//Largely inspired by the vest pouches on Colonial Marines + +/obj/item/weapon/storage/quickdraw + name = "quickdraw" + desc = "This object should not appear" + icon = 'icons/obj/storage_vr.dmi' + + //Quickmode + //When set to 0, this storage will operate as a regular storage, and clicking on it while equipped will open it as a storage + //When set to 1, a click while it is equipped will instead move the first item inside it to your hand + var/quickmode = 0 + +/obj/item/weapon/storage/quickdraw/attack_hand(mob/user as mob) + if(src.loc == user) //If they aren't holding us, we do nothing special + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(quickmode) + var/first_item = contents[1] + if(first_item && !H.get_active_hand()) //Do we have anything to give you? + H.put_in_hands(first_item) + return + + if(H.l_store == src && !H.get_active_hand()) //overrides + src.open(user) + return + if(H.r_store == src && !H.get_active_hand()) + src.open(user) + return + ..() //Nothing special happened, go call the other proc + + +/obj/item/weapon/storage/quickdraw/verb/toggle_quickdraw() + set name = "Switch Quickdraw Mode" + set category = "Object" + + quickmode = !quickmode + switch (quickmode) + if(1) + to_chat(usr, "[src] now draws the first object inside.") + if(0) + to_chat(usr, "[src] now opens as a container.") + +/obj/item/weapon/storage/quickdraw/AltClick(mob/user) + ..() + if(src.loc == user) //Are they carrying us? + toggle_quickdraw() + +// ----------------------------- +// Syringe case +// ----------------------------- + +/obj/item/weapon/storage/quickdraw/syringe_case + name = "syringe case" + desc = "A small case for safely carrying sharps around." + icon_state = "syringe_case" + + w_class = ITEMSIZE_SMALL + max_w_class = ITEMSIZE_TINY + max_storage_space = ITEMSIZE_TINY * 6 //Capable of holding six syringes + + //Can hold syringes and autoinjectors, but also pills if you really wanted. Syringe-shaped objects like pens and cigarettes also fit, but why would you do that? + can_hold = list(/obj/item/weapon/reagent_containers/syringe, /obj/item/weapon/reagent_containers/hypospray/autoinjector, + /obj/item/weapon/reagent_containers/pill, /obj/item/weapon/pen, /obj/item/device/flashlight/pen, /obj/item/clothing/mask/smokable/cigarette) + + quickmode = 1 //Starts in quickdraw mode + //Preloaded for your convenience! + starts_with = list( + /obj/item/weapon/reagent_containers/syringe, + /obj/item/weapon/reagent_containers/syringe, + /obj/item/weapon/reagent_containers/syringe, + /obj/item/weapon/reagent_containers/syringe, + /obj/item/weapon/reagent_containers/syringe, + /obj/item/weapon/reagent_containers/syringe + ) \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index 6bddb28769..e85982ea80 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." @@ -725,4 +724,6 @@ if(open && contents.len) var/display_item = contents[1] to_chat(user, "\The [src] contains \the [display_item]!") - */ \ No newline at end of file + +/obj/item/weapon/storage/AllowDrop() + return TRUE 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/items/weapons/trays.dm b/code/game/objects/items/weapons/trays.dm index c2ea991d98..68a2c3a774 100644 --- a/code/game/objects/items/weapons/trays.dm +++ b/code/game/objects/items/weapons/trays.dm @@ -52,9 +52,7 @@ if (istype(location, /turf/simulated)) location.add_blood(H) ///Plik plik, the sound of blood - M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])") - msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] to attack [M.name] ([M.ckey]) (JMP)") + add_attack_logs(user,M,"Hit with [src]") if(prob(15)) M.Weaken(3) diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index 8938e611c0..b5ae0912e9 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -17,10 +17,7 @@ /obj/item/weapon/nullrod/attack(mob/M as mob, mob/living/user as mob) //Paste from old-code to decult with a null rod. - M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])") - - msg_admin_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (JMP)") + add_attack_logs(user,M,"Hit with [src] (nullrod)") user.setClickCooldown(user.get_attack_speed(src)) user.do_attack_animation(M) diff --git a/code/game/objects/random/random.dm b/code/game/objects/random/random.dm index 86923e21e6..c83e96ad04 100644 --- a/code/game/objects/random/random.dm +++ b/code/game/objects/random/random.dm @@ -9,9 +9,13 @@ // creates a new object and deletes itself /obj/random/New() ..() - if (!prob(spawn_nothing_percentage)) - spawn_item() - qdel(src) + spawn() + if(istype(src.loc, /obj/structure/loot_pile)) //Spawning from a lootpile is weird, need to wait until we're out of it to do our work. + while(istype(src.loc, /obj/structure/loot_pile)) + sleep(1) + if (!prob(spawn_nothing_percentage)) + spawn_item() + qdel(src) // this function should return a specific item to spawn @@ -42,7 +46,7 @@ /obj/random/tool name = "random tool" desc = "This is a random tool" - icon = 'icons/obj/items.dmi' + icon = 'icons/obj/tools.dmi' icon_state = "welder" /obj/random/tool/item_to_spawn() @@ -55,6 +59,32 @@ /obj/item/device/flashlight, /obj/item/device/multitool) +/obj/random/tool/power + name = "random powertool" + desc = "This is a random powertool" + icon_state = "jaws_pry" + +/obj/random/tool/power/item_to_spawn() + return pick(/obj/item/weapon/screwdriver/power, + /obj/item/weapon/wirecutters/power, + /obj/item/weapon/weldingtool/electric, + /obj/item/weapon/weldingtool/experimental) + +/obj/random/tool/alien + name = "random alien tool" + desc = "This is a random tool" + icon = 'icons/obj/abductor.dmi' + icon_state = "welder" + +/obj/random/tool/alien/item_to_spawn() + return pick(/obj/item/weapon/screwdriver/alien, + /obj/item/weapon/wirecutters/alien, + /obj/item/weapon/weldingtool/alien, + /obj/item/weapon/crowbar/alien, + /obj/item/weapon/wrench/alien, + /obj/item/stack/cable_coil/alien, + /obj/item/device/multitool/alien) + /obj/random/technology_scanner name = "random scanner" desc = "This is a random technology scanner." @@ -131,6 +161,29 @@ prob(1);/obj/item/taperoll/atmos, prob(1);/obj/item/device/flashlight/maglight) +/obj/random/tech_supply/component + name = "random tech component" + desc = "This is a random machine component." + icon = 'icons/obj/items.dmi' + icon_state = "portable_analyzer" + +/obj/random/tech_supply/component/item_to_spawn() + return pick(prob(3);/obj/item/weapon/stock_parts/gear, + prob(2);/obj/item/weapon/stock_parts/console_screen, + prob(1);/obj/item/weapon/stock_parts/spring, + prob(3);/obj/item/weapon/stock_parts/capacitor, + prob(2);/obj/item/weapon/stock_parts/capacitor/adv, + prob(1);/obj/item/weapon/stock_parts/capacitor/super, + prob(3);/obj/item/weapon/stock_parts/manipulator, + prob(2);/obj/item/weapon/stock_parts/manipulator/nano, + prob(1);/obj/item/weapon/stock_parts/manipulator/pico, + prob(3);/obj/item/weapon/stock_parts/matter_bin, + prob(2);/obj/item/weapon/stock_parts/matter_bin/adv, + prob(1);/obj/item/weapon/stock_parts/matter_bin/super, + prob(3);/obj/item/weapon/stock_parts/scanning_module, + prob(2);/obj/item/weapon/stock_parts/scanning_module/adv, + prob(1);/obj/item/weapon/stock_parts/scanning_module/phasic) + /obj/random/medical name = "Random Medicine" desc = "This is a random medical item." @@ -1538,8 +1591,7 @@ var/list/multi_point_spawns icon_state = "phoron" /obj/random/mob/spider/mutant/item_to_spawn() - return pick(prob(1);/obj/random/mob/spider, - prob(5);/mob/living/simple_animal/hostile/giant_spider/nurse/medical, + return pick(prob(5);/obj/random/mob/spider, prob(10);/mob/living/simple_animal/hostile/giant_spider/webslinger, prob(10);/mob/living/simple_animal/hostile/giant_spider/carrier, prob(33);/mob/living/simple_animal/hostile/giant_spider/lurker, 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.dm b/code/game/objects/structures/crates_lockers/closets.dm index a9fc515e3b..c0303d8753 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -416,3 +416,6 @@ /obj/structure/closet/onDropInto(var/atom/movable/AM) return + +/obj/structure/closet/AllowDrop() + return TRUE 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/objects/structures/loot_piles.dm b/code/game/objects/structures/loot_piles.dm index 43369fb2fa..353dbe31a7 100644 --- a/code/game/objects/structures/loot_piles.dm +++ b/code/game/objects/structures/loot_piles.dm @@ -22,6 +22,8 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh density = FALSE anchored = TRUE + var/list/icon_states_to_use = list() // List of icon states the pile can choose from on initialization. If empty or null, it will stay the initial icon_state. + var/list/searched_by = list() // Keys that have searched this loot pile, with values of searched time. var/allow_multiple_looting = FALSE // If true, the same person can loot multiple times. Mostly for debugging. var/busy = FALSE // Used so you can't spamclick to loot. @@ -113,12 +115,9 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh var/path = pick(rare_loot) return new path(src) - -/obj/structure/loot_pile/maint - var/list/icon_states_to_use = list() - -/obj/structure/loot_pile/maint/initialize() - icon_state = pick(icon_states_to_use) +/obj/structure/loot_pile/initialize() + if(icon_states_to_use && icon_states_to_use.len) + icon_state = pick(icon_states_to_use) . = ..() // Has large amounts of possible items, most of which may or may not be useful. @@ -438,7 +437,7 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh // Base type for alien piles. /obj/structure/loot_pile/surface/alien name = "alien pod" - desc = "A pod which looks bigger on the inside. Something quiet shiny might be inside?" + desc = "A pod which looks bigger on the inside. Something quite shiny might be inside?" icon_state = "alien_pile1" /obj/structure/loot_pile/surface/alien @@ -568,3 +567,266 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh /obj/item/weapon/gun/launcher/crossbow ) +// Subtype for mecha and mecha accessories. These might not always be on the surface. +/obj/structure/loot_pile/mecha + name = "pod wreckage" + desc = "The ruins of some unfortunate pod. Perhaps something is salvageable." + icon = 'icons/mecha/mecha.dmi' + icon_state = "engineering_pod-broken" + density = TRUE + + chance_uncommon = 20 + chance_rare = 10 + + loot_depletion = TRUE + loot_left = 9 + + common_loot = list( + /obj/random/tool, + /obj/random/tool, + /obj/random/tool, + /obj/random/tool, + /obj/item/stack/cable_coil/random, + /obj/random/tank, + /obj/random/tech_supply/component, + /obj/random/tech_supply/component, + /obj/random/tech_supply/component, + /obj/effect/decal/remains/lizard, + /obj/effect/decal/remains/mouse, + /obj/effect/decal/remains/robot, + /obj/item/stack/material/steel{amount = 40} + ) + + uncommon_loot = list( + /obj/item/mecha_parts/mecha_equipment/weapon/energy/taser, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/riggedlaser, + /obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp, + /obj/item/mecha_parts/mecha_equipment/tool/drill, + /obj/item/mecha_parts/mecha_equipment/generator + ) + + rare_loot = list( + /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser, + /obj/item/mecha_parts/mecha_equipment/generator/nuclear, + /obj/item/mecha_parts/mecha_equipment/tool/jetpack + ) + +//Stuff you may find attached to a ripley. +/obj/structure/loot_pile/mecha/ripley + name = "ripley wreckage" + desc = "The ruins of some unfortunate ripley. Perhaps something is salvageable." + icon_states_to_use = list("ripley-broken", "firefighter-broken", "ripley-broken-old") + + common_loot = list( + /obj/random/tool, + /obj/item/stack/cable_coil/random, + /obj/random/tank, + /obj/random/tech_supply/component, + /obj/item/stack/material/steel{amount = 25}, + /obj/item/stack/material/glass{amount = 10}, + /obj/item/stack/material/plasteel{amount = 5}, + /obj/item/mecha_parts/chassis/ripley, + /obj/item/mecha_parts/part/ripley_torso, + /obj/item/mecha_parts/part/ripley_left_arm, + /obj/item/mecha_parts/part/ripley_right_arm, + /obj/item/mecha_parts/part/ripley_left_leg, + /obj/item/mecha_parts/part/ripley_right_leg, + /obj/item/device/kit/paint/ripley, + /obj/item/device/kit/paint/ripley/flames_red, + /obj/item/device/kit/paint/ripley/flames_blue + ) + + uncommon_loot = list( + /obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp, + /obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill, + /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster, + /obj/item/mecha_parts/mecha_equipment/tool/extinguisher, + ) + + rare_loot = list( + /obj/item/mecha_parts/mecha_equipment/gravcatapult, + /obj/item/mecha_parts/mecha_equipment/tool/rcd, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/flamer/rigged + ) + +//Death-Ripley, same common, but more combat-exosuit-based +/obj/structure/loot_pile/mecha/deathripley + name = "strange ripley wreckage" + icon_state = "deathripley-broken" + + common_loot = list( + /obj/random/tool, + /obj/item/stack/cable_coil/random, + /obj/random/tank, + /obj/random/tech_supply/component, + /obj/item/stack/material/steel{amount = 40}, + /obj/item/stack/material/glass{amount = 20}, + /obj/item/stack/material/plasteel{amount = 10}, + /obj/item/mecha_parts/chassis/ripley, + /obj/item/mecha_parts/part/ripley_torso, + /obj/item/mecha_parts/part/ripley_left_arm, + /obj/item/mecha_parts/part/ripley_right_arm, + /obj/item/mecha_parts/part/ripley_left_leg, + /obj/item/mecha_parts/part/ripley_right_leg, + /obj/item/device/kit/paint/ripley/death + ) + + uncommon_loot = list( + /obj/item/mecha_parts/mecha_equipment/tool/safety_clamp, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/riggedlaser, + /obj/item/mecha_parts/mecha_equipment/repair_droid, + /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay + ) + + rare_loot = list( + /obj/item/mecha_parts/mecha_equipment/tool/rcd, + /obj/item/mecha_parts/mecha_equipment/wormhole_generator, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/flamer/rigged + ) + +/obj/structure/loot_pile/mecha/odysseus + name = "odysseus wreckage" + desc = "The ruins of some unfortunate odysseus. Perhaps something is salvageable." + icon_state = "odysseus-broken" + + common_loot = list( + /obj/random/tool, + /obj/item/stack/cable_coil/random, + /obj/random/tank, + /obj/random/tech_supply/component, + /obj/item/stack/material/steel{amount = 25}, + /obj/item/stack/material/glass{amount = 10}, + /obj/item/stack/material/plasteel{amount = 5}, + /obj/item/mecha_parts/chassis/odysseus, + /obj/item/mecha_parts/part/odysseus_head, + /obj/item/mecha_parts/part/odysseus_torso, + /obj/item/mecha_parts/part/odysseus_left_arm, + /obj/item/mecha_parts/part/odysseus_right_arm, + /obj/item/mecha_parts/part/odysseus_left_leg, + /obj/item/mecha_parts/part/odysseus_right_leg + ) + + uncommon_loot = list( + /obj/item/mecha_parts/mecha_equipment/tool/sleeper, + /obj/item/mecha_parts/mecha_equipment/tool/syringe_gun, + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flare, + /obj/item/mecha_parts/mecha_equipment/tool/extinguisher, + ) + + rare_loot = list( + /obj/item/mecha_parts/mecha_equipment/gravcatapult, + /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster, + /obj/item/mecha_parts/mecha_equipment/shocker + ) + +/obj/structure/loot_pile/mecha/gygax + name = "gygax wreckage" + desc = "The ruins of some unfortunate gygax. Perhaps something is salvageable." + icon_state = "gygax-broken" + + common_loot = list( + /obj/random/tool, + /obj/item/stack/cable_coil/random, + /obj/random/tank, + /obj/random/tech_supply/component, + /obj/item/stack/material/steel{amount = 25}, + /obj/item/stack/material/glass{amount = 10}, + /obj/item/stack/material/plasteel{amount = 5}, + /obj/item/mecha_parts/chassis/gygax, + /obj/item/mecha_parts/part/gygax_head, + /obj/item/mecha_parts/part/gygax_torso, + /obj/item/mecha_parts/part/gygax_left_arm, + /obj/item/mecha_parts/part/gygax_right_arm, + /obj/item/mecha_parts/part/gygax_left_leg, + /obj/item/mecha_parts/part/gygax_right_leg, + /obj/item/mecha_parts/part/gygax_armour + ) + + uncommon_loot = list( + /obj/item/mecha_parts/mecha_equipment/shocker, + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/taser, + /obj/item/device/kit/paint/gygax, + /obj/item/device/kit/paint/gygax/darkgygax, + /obj/item/device/kit/paint/gygax/recitence + ) + + rare_loot = list( + /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay, + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg, + /obj/item/mecha_parts/mecha_equipment/repair_droid, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy + ) + +/obj/structure/loot_pile/mecha/durand + name = "durand wreckage" + desc = "The ruins of some unfortunate durand. Perhaps something is salvageable." + icon_state = "durand-broken" + + common_loot = list( + /obj/random/tool, + /obj/item/stack/cable_coil/random, + /obj/random/tank, + /obj/random/tech_supply/component, + /obj/item/stack/material/steel{amount = 25}, + /obj/item/stack/material/glass{amount = 10}, + /obj/item/stack/material/plasteel{amount = 5}, + /obj/item/mecha_parts/chassis/durand, + /obj/item/mecha_parts/part/durand_head, + /obj/item/mecha_parts/part/durand_torso, + /obj/item/mecha_parts/part/durand_left_arm, + /obj/item/mecha_parts/part/durand_right_arm, + /obj/item/mecha_parts/part/durand_left_leg, + /obj/item/mecha_parts/part/durand_right_leg, + /obj/item/mecha_parts/part/durand_armour + ) + + uncommon_loot = list( + /obj/item/mecha_parts/mecha_equipment/shocker, + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser, + /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster, + /obj/item/device/kit/paint/durand, + /obj/item/device/kit/paint/durand/seraph, + /obj/item/device/kit/paint/durand/phazon + ) + + rare_loot = list( + /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay, + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot, + /obj/item/mecha_parts/mecha_equipment/repair_droid, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy + ) + +/obj/structure/loot_pile/mecha/phazon + name = "phazon wreckage" + desc = "The ruins of some unfortunate phazon. Perhaps something is salvageable." + icon_state = "phazon-broken" + + common_loot = list( + /obj/item/weapon/storage/toolbox/syndicate/powertools, + /obj/item/stack/material/plasteel{amount = 20}, + /obj/item/stack/material/durasteel{amount = 10}, + /obj/item/mecha_parts/chassis/phazon, + /obj/item/mecha_parts/part/phazon_head, + /obj/item/mecha_parts/part/phazon_torso, + /obj/item/mecha_parts/part/phazon_left_arm, + /obj/item/mecha_parts/part/phazon_right_arm, + /obj/item/mecha_parts/part/phazon_left_leg, + /obj/item/mecha_parts/part/phazon_right_leg + ) + + uncommon_loot = list( + /obj/item/mecha_parts/mecha_equipment/shocker, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/flamer/rigged, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy, + /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster + ) + + rare_loot = list( + /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/ion, + /obj/item/mecha_parts/mecha_equipment/repair_droid, + /obj/item/mecha_parts/mecha_equipment/teleporter + ) diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 82a6d7fdfd..4954553a00 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -306,10 +306,6 @@ if (C.can_feel_pain()) C.emote("scream") - //Logging for this causes runtimes resulting in the cremator locking up. Commenting it out until that's figured out. - //M.attack_log += "\[[time_stamp()]\] Has been cremated by [user]/[user.ckey]" //No point in this when the mob's about to be deleted - //user.attack_log +="\[[time_stamp()]\] Cremated [M]/[M.ckey]" - //log_attack("\[[time_stamp()]\] [user]/[user.ckey] cremated [M]/[M.ckey]") M.death(1) M.ghostize() qdel(M) diff --git a/code/game/objects/structures/morgue_vr.dm b/code/game/objects/structures/morgue_vr.dm index abe82bdbac..eaf27b5ad0 100644 --- a/code/game/objects/structures/morgue_vr.dm +++ b/code/game/objects/structures/morgue_vr.dm @@ -44,10 +44,6 @@ if (C.can_feel_pain()) C.emote("scream") - //Logging for this causes runtimes resulting in the cremator locking up. Commenting it out until that's figured out. - //M.attack_log += "\[[time_stamp()]\] Has been cremated by [user]/[user.ckey]" //No point in this when the mob's about to be deleted - //user.attack_log +="\[[time_stamp()]\] Cremated [M]/[M.ckey]" - //log_attack("\[[time_stamp()]\] [user]/[user.ckey] cremated [M]/[M.ckey]") M.death(1) M.ghostize() qdel(M) diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm index 550b59d112..bb1a62e40b 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm @@ -176,9 +176,7 @@ if(pulling) occupant.visible_message("[pulling] has thrusted \the [name] into \the [A], throwing \the [occupant] out of it!") - pulling.attack_log += "\[[time_stamp()]\] Crashed [occupant.name]'s ([occupant.ckey]) [name] into \a [A]" - occupant.attack_log += "\[[time_stamp()]\] Thrusted into \a [A] by [pulling.name] ([pulling.ckey]) with \the [name]" - msg_admin_attack("[pulling.name] ([pulling.ckey]) has thrusted [occupant.name]'s ([occupant.ckey]) [name] into \a [A] (JMP)") + add_attack_logs(pulling,occupant,"Crashed their [name] into [A]") else occupant.visible_message("[occupant] crashed into \the [A]!") 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/supplyshuttle.dm b/code/game/supplyshuttle.dm index 03875e0168..c873ecf61d 100644 --- a/code/game/supplyshuttle.dm +++ b/code/game/supplyshuttle.dm @@ -264,6 +264,8 @@ var/list/mechtoys = list( proc/buy() if(!shoppinglist.len) return + var/orderedamount = shoppinglist.len + var/area/area_shuttle = shuttle.get_location_area() if(!area_shuttle) return @@ -302,7 +304,7 @@ var/list/mechtoys = list( slip.info = "

[command_name()] Shipping Manifest



" slip.info +="Order #[SO.ordernum]
" slip.info +="Destination: [station_name()]
" - slip.info +="[shoppinglist.len] PACKAGES IN THIS SHIPMENT
" + slip.info +="[orderedamount] PACKAGES IN THIS SHIPMENT
" slip.info +="CONTENTS: