From 63a1dd01437dba7cc5f91a91ea9c468948a6b87f Mon Sep 17 00:00:00 2001 From: Leshana Date: Sun, 4 Mar 2018 14:40:16 -0500 Subject: [PATCH 01/21] - Moved pipe construction defines into __defines/construction.dm - Unified pipe *unwrenching* by creating a standard proc along with the `construction_type` var. - Eliminated the pipe fitting name & icon_state lookup tables by adding `pipe_state` var on atmos machinery and referencing that. - Each pipe which can be made from a fitting object should override `pipe_state` with the icon state to be used on the pipe fitting object. - Eliminated the giant switch statement of doom in pipe construction by delegating that work to `on_construction` proc. - To make this work, every pipe must implement `get_neighbor_nodes_for_init` which returns a list of nodes which should be re-initialized on that pipe's construction. - Combined the SCRUBBERS, SUPPLY and REGULAR pipe fitting classes together by storing the `piping_layer` variable and using the `setPipingLayer` procs - Standardized the code for searching for node neighbors into the `can_be_node` proc. - This proc is also improved in that is a mutual check, `check_connectable` is called on BOTH objects, so they have to mutually agree to connect as nodes. Eliminates lots of special edge case logic. - Updated all the `amos_init` procs to use `can_be_node`. In the most common cases, even that boilerplate code is consolidated into the `STANDARD_ATMOS_CHOOSE_NODE` macro. - Implemented `pipe_flags` which lets pipes declare (or override) certain requirements. - Adds a "pipe_recipe" datum to help out things that construct pipes. By taking it out of the dispenser, we open the road for multiple dispenser types. No, no RPD yet. Soon. - Enhances the pipe dispenser to operate on pipe recipe datums instead of hard coded lists of pipes it can construct. These datums are also (partially) initialized from the pipe machine types themselves, reducing having to define stuff in multiple places. - Switched pipe dispenser UI to use browse(). Not a NanoUI, but makes it a bit prettier with low effort. - Changed pipe dispenser to use a button selector to switch between Regular/Scrubbers/Supply instead of having separate list items. - Added icon states to HE pipes to support the "connected on neither side" state. --- code/ATMOSPHERICS/_atmos_setup.dm | 5 - code/ATMOSPHERICS/atmospherics.dm | 80 +- .../binary_devices/algae_generator_vr.dm | 1 + .../binary_devices/binary_atmos_base.dm | 16 +- .../components/binary_devices/circulator.dm | 1 + .../components/binary_devices/dp_vent_pump.dm | 1 + .../components/binary_devices/passive_gate.dm | 5 +- .../components/binary_devices/pipeturbine.dm | 3 + .../components/binary_devices/pump.dm | 5 +- .../components/binary_devices/volume_pump.dm | 2 + .../components/omni_devices/filter.dm | 1 + .../components/omni_devices/mixer.dm | 1 + .../components/omni_devices/omni_base.dm | 16 +- .../components/portables_connector.dm | 16 +- .../components/trinary_devices/filter.dm | 2 + .../components/trinary_devices/mixer.dm | 4 + .../trinary_devices/trinary_base.dm | 25 +- code/ATMOSPHERICS/components/tvalve.dm | 28 +- .../components/unary/cold_sink.dm | 13 +- .../components/unary/heat_exchanger.dm | 4 +- .../components/unary/heat_source.dm | 13 +- .../components/unary/outlet_injector.dm | 1 + .../components/unary/unary_base.dm | 29 +- .../components/unary/vent_pump.dm | 4 +- .../components/unary/vent_scrubber.dm | 4 +- code/ATMOSPHERICS/components/valve.dm | 21 +- code/ATMOSPHERICS/mainspipe.dm | 3 + code/ATMOSPHERICS/pipes/cap.dm | 10 +- code/ATMOSPHERICS/pipes/he_pipes.dm | 32 +- code/ATMOSPHERICS/pipes/manifold.dm | 30 +- code/ATMOSPHERICS/pipes/manifold4w.dm | 39 +- code/ATMOSPHERICS/pipes/pipe_base.dm | 19 +- code/ATMOSPHERICS/pipes/simple.dm | 29 +- code/ATMOSPHERICS/pipes/tank.dm | 8 +- code/ATMOSPHERICS/pipes/universal.dm | 8 +- code/ATMOSPHERICS/pipes/vent.dm | 10 +- code/__defines/construction.dm | 45 +- code/game/machinery/pipe/construction.dm | 1472 +++-------------- code/game/machinery/pipe/pipe_dispenser.dm | 103 +- code/game/machinery/pipe/pipe_recipes.dm | 102 ++ code/modules/multiz/pipes.dm | 25 +- icons/atmos/heat.dmi | Bin 4827 -> 1605 bytes icons/atmos/junction.dmi | Bin 2799 -> 914 bytes icons/obj/pipe-item.dmi | Bin 28539 -> 29575 bytes vorestation.dme | 1 + 45 files changed, 718 insertions(+), 1519 deletions(-) create mode 100644 code/game/machinery/pipe/pipe_recipes.dm diff --git a/code/ATMOSPHERICS/_atmos_setup.dm b/code/ATMOSPHERICS/_atmos_setup.dm index f1f560a00d..6af102cf38 100644 --- a/code/ATMOSPHERICS/_atmos_setup.dm +++ b/code/ATMOSPHERICS/_atmos_setup.dm @@ -15,11 +15,6 @@ #define PIPE_COLOR_BLACK "#444444" #define PIPE_COLOR_PURPLE "#5c1ec0" -#define CONNECT_TYPE_REGULAR 1 -#define CONNECT_TYPE_SUPPLY 2 -#define CONNECT_TYPE_SCRUBBER 4 -#define CONNECT_TYPE_HE 8 - var/global/list/pipe_colors = list("grey" = PIPE_COLOR_GREY, "red" = PIPE_COLOR_RED, "blue" = PIPE_COLOR_BLUE, "cyan" = PIPE_COLOR_CYAN, "green" = PIPE_COLOR_GREEN, "yellow" = PIPE_COLOR_YELLOW, "black" = PIPE_COLOR_BLACK, "purple" = PIPE_COLOR_PURPLE) /proc/pipe_color_lookup(var/color) diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index 59163e1b82..940c5edf1c 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -19,8 +19,12 @@ Pipelines + Other Objects -> Pipe network layer = 2.4 //under wires with their 2.44 + var/pipe_flags = PIPING_DEFAULT_LAYER_ONLY // Allow other layers by exception basis. var/connect_types = CONNECT_TYPE_REGULAR + var/piping_layer = PIPING_LAYER_DEFAULT // This will replace icon_connect_type at some point ~Leshana var/icon_connect_type = "" //"-supply" or "-scrubbers" + var/construction_type = null // Type path of the pipe item when this is deconstructed. + var/pipe_state // icon_state as a pipe item var/initialize_directions = 0 var/pipe_color @@ -46,6 +50,10 @@ Pipelines + Other Objects -> Pipe network /obj/machinery/atmospherics/proc/init_dir() return +// Get ALL initialize_directions - Some types (HE pipes etc) combine two vars together for this. +/obj/machinery/atmospherics/proc/get_init_dirs() + return initialize_directions + // Get the direction each node is facing to connect. // It now returns as a list so it can be fetched nicely, each entry corresponds to node of same number. /obj/machinery/atmospherics/proc/get_node_connect_dirs() @@ -59,6 +67,14 @@ Pipelines + Other Objects -> Pipe network /obj/machinery/atmospherics/proc/atmos_init() return +/** Check if target is an acceptable target to connect as a node from this machine. */ +/obj/machinery/atmospherics/proc/can_be_node(obj/machinery/atmospherics/target, node_num) + return (target.initialize_directions & get_dir(target,src)) && check_connectable(target) && target.check_connectable(src) + +/** Check if this machine is willing to connect with the target machine. */ +/obj/machinery/atmospherics/proc/check_connectable(obj/machinery/atmospherics/target) + return (src.connect_types & target.connect_types) + /obj/machinery/atmospherics/attackby(atom/A, mob/user as mob) if(istype(A, /obj/item/device/pipe_painter)) return @@ -82,12 +98,6 @@ Pipelines + Other Objects -> Pipe network else return 0 -obj/machinery/atmospherics/proc/check_connect_types(obj/machinery/atmospherics/atmos1, obj/machinery/atmospherics/atmos2) - return (atmos1.connect_types & atmos2.connect_types) - -/obj/machinery/atmospherics/proc/check_connect_types_construction(obj/machinery/atmospherics/atmos1, obj/item/pipe/pipe2) - return (atmos1.connect_types & pipe2.connect_types) - /obj/machinery/atmospherics/proc/check_icon_cache(var/safety = 0) if(!istype(icon_manager)) if(!safety) //to prevent infinite loops @@ -146,4 +156,60 @@ obj/machinery/atmospherics/proc/check_connect_types(obj/machinery/atmospherics/a var/datum/gas_mixture/env_air = loc.return_air() if((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE) return 0 - return 1 \ No newline at end of file + return 1 + +// Deconstruct into a pipe item. +/obj/machinery/atmospherics/proc/deconstruct() + if(QDELETED(src)) + return + if(construction_type) + var/obj/item/pipe/I = new construction_type(loc, null, null, src) + I.setPipingLayer(piping_layer) + transfer_fingerprints_to(I) + qdel(src) + +// Return a list of nodes which we should call atmos_init() and build_network() during on_construction() +/obj/machinery/atmospherics/proc/get_neighbor_nodes_for_init() + return null + +// Called on construction (i.e from pipe item) but not on initialization +/obj/machinery/atmospherics/proc/on_construction(obj_color, set_layer) + pipe_color = obj_color + setPipingLayer(set_layer) + // TODO - M.connect_types = src.connect_types - Or otherwise copy from item? Or figure it out from piping layer? + var/turf/T = get_turf(src) + level = !T.is_plating() ? 2 : 1 + atmos_init() + if(QDELETED(src)) + return // TODO - Eventually should get rid of the need for this. + build_network() + var/list/nodes = get_neighbor_nodes_for_init() + for(var/obj/machinery/atmospherics/A in nodes) + A.atmos_init() + A.build_network() + // TODO - Should we do src.build_network() before or after the nodes? + // We've historically done before, but /tg does after. TODO research if there is a difference. + +// This sets our piping layer. Hopefully its cool. +/obj/machinery/atmospherics/proc/setPipingLayer(new_layer) + if(pipe_flags & (PIPING_DEFAULT_LAYER_ONLY|PIPING_ALL_LAYER)) + new_layer = PIPING_LAYER_DEFAULT + piping_layer = new_layer + // Do it the Polaris way + switch(piping_layer) + if(PIPING_LAYER_SCRUBBER) + icon_state = "[icon_state]-scrubbers" + connect_types = CONNECT_TYPE_SCRUBBER + layer = 2.38 + icon_connect_type = "-scrubbers" + if(PIPING_LAYER_SUPPLY) + icon_state = "[icon_state]-supply" + connect_types = CONNECT_TYPE_SUPPLY + layer = 2.39 + icon_connect_type = "-supply" + if(pipe_flags & PIPING_ALL_LAYER) + connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER + // Or if we were to do it the TG way... + // pixel_x = PIPE_PIXEL_OFFSET_X(piping_layer) + // pixel_y = PIPE_PIXEL_OFFSET_Y(piping_layer) + // layer = initial(layer) + PIPE_LAYER_OFFSET(piping_layer) diff --git a/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm b/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm index 1429b9b30a..adafb2ed17 100644 --- a/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm +++ b/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm @@ -14,6 +14,7 @@ idle_power_usage = 100 // Minimal lights to keep algae alive active_power_usage = 5000 // Powerful grow lights to stimulate oxygen production //power_rating = 7500 //7500 W ~ 10 HP + pipe_flags = PIPING_DEFAULT_LAYER_ONLY|PIPING_ONE_PER_TURF var/list/stored_material = list(MATERIAL_ALGAE = 0, MATERIAL_CARBON = 0) // Capacity increases with matter bin quality diff --git a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm index 6e6662f39c..4698c613a9 100644 --- a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm +++ b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm @@ -30,6 +30,9 @@ initialize_directions = EAST|WEST // Housekeeping and pipe network stuff below +/obj/machinery/atmospherics/binary/get_neighbor_nodes_for_init() + return list(node1, node2) + /obj/machinery/atmospherics/binary/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) if(reference == node1) network1 = new_network @@ -64,17 +67,8 @@ var/node2_connect = dir var/node1_connect = turn(dir, 180) - for(var/obj/machinery/atmospherics/target in get_step(src,node1_connect)) - 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_connect)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node2 = target - break + STANDARD_ATMOS_CHOOSE_NODE(1, node1_connect) + STANDARD_ATMOS_CHOOSE_NODE(2, node2_connect) update_icon() update_underlays() diff --git a/code/ATMOSPHERICS/components/binary_devices/circulator.dm b/code/ATMOSPHERICS/components/binary_devices/circulator.dm index 68ce37d088..ff1089e6f8 100644 --- a/code/ATMOSPHERICS/components/binary_devices/circulator.dm +++ b/code/ATMOSPHERICS/components/binary_devices/circulator.dm @@ -9,6 +9,7 @@ icon = 'icons/obj/pipes.dmi' icon_state = "circ-off" anchored = 0 + pipe_flags = PIPING_DEFAULT_LAYER_ONLY|PIPING_ONE_PER_TURF var/kinetic_efficiency = 0.04 //combined kinetic and kinetic-to-electric efficiency var/volume_ratio = 0.2 diff --git a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm index 840d2bdf8b..d696aad039 100644 --- a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm @@ -24,6 +24,7 @@ idle_power_usage = 150 //internal circuitry, friction losses and stuff power_rating = 7500 //7500 W ~ 10 HP + pipe_flags = PIPING_ALL_LAYER connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER //connects to regular, supply and scrubbers pipes var/pump_direction = 1 //0 = siphoning, 1 = releasing diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index b4f25459c1..c08c82f6b9 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -5,6 +5,8 @@ /obj/machinery/atmospherics/binary/passive_gate icon = 'icons/atmos/passive_gate.dmi' icon_state = "map" + construction_type = /obj/item/pipe/directional + pipe_state = "passivegate" level = 1 name = "pressure regulator" @@ -257,8 +259,7 @@ "\The [user] unfastens \the [src].", \ "You have unfastened \the [src].", \ "You hear ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) + deconstruct() #undef REGULATE_NONE #undef REGULATE_INPUT diff --git a/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm b/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm index b8c7883796..a7127a4dc6 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm @@ -139,6 +139,9 @@ src.set_dir(turn(src.dir, 90)) //Goddamn copypaste from binary base class because atmospherics machinery API is not damn flexible + get_neighbor_nodes_for_init() + return list(node1, node2) + network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) if(reference == node1) network1 = new_network diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index 6320ddf8a3..a89b1c5659 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -15,6 +15,8 @@ Thus, the two variables affect pump operation are set in New(): /obj/machinery/atmospherics/binary/pump icon = 'icons/atmos/pump.dmi' icon_state = "map_off" + construction_type = /obj/item/pipe/directional + pipe_state = "pump" level = 1 name = "gas pump" @@ -236,5 +238,4 @@ Thus, the two variables affect pump operation are set in New(): "\The [user] unfastens \the [src].", \ "You have unfastened \the [src].", \ "You hear ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) + deconstruct() diff --git a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm index 42b02282cc..b4493a1566 100644 --- a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm @@ -1,6 +1,8 @@ /obj/machinery/atmospherics/binary/pump/high_power icon = 'icons/atmos/volume_pump.dmi' icon_state = "map_off" + construction_type = /obj/item/pipe/directional + pipe_state = "volumepump" level = 1 name = "high power gas pump" diff --git a/code/ATMOSPHERICS/components/omni_devices/filter.dm b/code/ATMOSPHERICS/components/omni_devices/filter.dm index 8710623dfd..57889c463e 100644 --- a/code/ATMOSPHERICS/components/omni_devices/filter.dm +++ b/code/ATMOSPHERICS/components/omni_devices/filter.dm @@ -4,6 +4,7 @@ /obj/machinery/atmospherics/omni/atmos_filter name = "omni gas filter" icon_state = "map_filter" + pipe_state = "omni_filter" var/list/atmos_filters = new() var/datum/omni_port/input diff --git a/code/ATMOSPHERICS/components/omni_devices/mixer.dm b/code/ATMOSPHERICS/components/omni_devices/mixer.dm index 6340397870..c833b5bb2a 100644 --- a/code/ATMOSPHERICS/components/omni_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/omni_devices/mixer.dm @@ -4,6 +4,7 @@ /obj/machinery/atmospherics/omni/mixer name = "omni gas mixer" icon_state = "map_mixer" + pipe_state = "omni_mixer" use_power = 1 idle_power_usage = 150 //internal circuitry, friction losses and stuff diff --git a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm index a469b4e9ee..0981ff6b44 100644 --- a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm +++ b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm @@ -7,6 +7,7 @@ icon_state = "base" use_power = 1 initialize_directions = 0 + construction_type = /obj/item/pipe/quaternary level = 1 var/configuring = 0 @@ -93,8 +94,7 @@ "\The [user] unfastens \the [src].", \ "You have unfastened \the [src].", \ "You hear a ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) + deconstruct() /obj/machinery/atmospherics/omni/can_unwrench() var/int_pressure = 0 @@ -222,6 +222,11 @@ // Housekeeping and pipe network stuff below +/obj/machinery/atmospherics/omni/get_neighbor_nodes_for_init() + var/list/neighbor_nodes = list() + for(var/datum/omni_port/P in ports) + neighbor_nodes += P.node + return neighbor_nodes /obj/machinery/atmospherics/omni/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) for(var/datum/omni_port/P in ports) @@ -252,10 +257,9 @@ if(P.node || P.mode == 0) continue for(var/obj/machinery/atmospherics/target in get_step(src, P.dir)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - P.node = target - break + if(can_be_node(target, 1)) + P.node = target + break for(var/datum/omni_port/P in ports) P.update = 1 diff --git a/code/ATMOSPHERICS/components/portables_connector.dm b/code/ATMOSPHERICS/components/portables_connector.dm index 6911288c93..7dca3f52d4 100644 --- a/code/ATMOSPHERICS/components/portables_connector.dm +++ b/code/ATMOSPHERICS/components/portables_connector.dm @@ -7,6 +7,9 @@ dir = SOUTH initialize_directions = SOUTH + construction_type = /obj/item/pipe/directional + pipe_state = "connector" + pipe_flags = PIPING_DEFAULT_LAYER_ONLY|PIPING_ONE_PER_TURF var/obj/machinery/portable_atmospherics/connected_device @@ -47,6 +50,9 @@ return 1 // Housekeeping and pipe network stuff below +/obj/machinery/atmospherics/portables_connector/get_neighbor_nodes_for_init() + return list(node) + /obj/machinery/atmospherics/portables_connector/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) if(reference == node) network = new_network @@ -77,10 +83,9 @@ var/node_connect = dir for(var/obj/machinery/atmospherics/target in get_step(src,node_connect)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node = target - break + if(can_be_node(target, 1)) + node = target + break update_icon() update_underlays() @@ -146,5 +151,4 @@ "\The [user] unfastens \the [src].", \ "You have unfastened \the [src].", \ "You hear a ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) + deconstruct() diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index 94924baedc..49cb05e9af 100755 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -1,6 +1,8 @@ /obj/machinery/atmospherics/trinary/atmos_filter icon = 'icons/atmos/filter.dmi' icon_state = "map" + construction_type = /obj/item/pipe/trinary/flippable + pipe_state = "filter" density = 0 level = 1 diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm index 2a70fe1591..84c5d49daa 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm @@ -1,6 +1,8 @@ /obj/machinery/atmospherics/trinary/mixer icon = 'icons/atmos/mixer.dmi' icon_state = "map" + construction_type = /obj/item/pipe/trinary/flippable + pipe_state = "mixer" density = 0 level = 1 @@ -133,6 +135,8 @@ // obj/machinery/atmospherics/trinary/mixer/t_mixer icon_state = "tmap" + construction_type = /obj/item/pipe/trinary // Can't flip a "T", its symmetrical + pipe_state = "t_mixer" dir = SOUTH initialize_directions = SOUTH|EAST|WEST tee = TRUE diff --git a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm index 79aa77dc6f..0a68f74c71 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm @@ -2,6 +2,7 @@ dir = SOUTH initialize_directions = SOUTH|NORTH|WEST use_power = 0 + pipe_flags = PIPING_DEFAULT_LAYER_ONLY|PIPING_ONE_PER_TURF var/mirrored = FALSE var/tee = FALSE @@ -64,10 +65,12 @@ "\The [user] unfastens \the [src].", \ "You have unfastened \the [src].", \ "You hear a ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) + deconstruct() // Housekeeping and pipe network stuff below +/obj/machinery/atmospherics/trinary/get_neighbor_nodes_for_init() + return list(node1, node2, node3) + /obj/machinery/atmospherics/trinary/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) if(reference == node1) network1 = new_network @@ -113,21 +116,9 @@ var/list/node_connects = get_node_connect_dirs() - for(var/obj/machinery/atmospherics/target in get_step(src,node_connects[1])) - 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,node_connects[2])) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node2 = target - break - for(var/obj/machinery/atmospherics/target in get_step(src,node_connects[3])) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node3 = target - break + STANDARD_ATMOS_CHOOSE_NODE(1, node_connects[1]) + STANDARD_ATMOS_CHOOSE_NODE(2, node_connects[2]) + STANDARD_ATMOS_CHOOSE_NODE(3, node_connects[3]) update_icon() update_underlays() diff --git a/code/ATMOSPHERICS/components/tvalve.dm b/code/ATMOSPHERICS/components/tvalve.dm index 2b64d6f5bb..b65c615174 100644 --- a/code/ATMOSPHERICS/components/tvalve.dm +++ b/code/ATMOSPHERICS/components/tvalve.dm @@ -1,6 +1,8 @@ /obj/machinery/atmospherics/tvalve icon = 'icons/atmos/tvalve.dmi' icon_state = "map_tvalve0" + construction_type = /obj/item/pipe/trinary/flippable + pipe_state = "mtvalve" name = "manual switching valve" desc = "A pipe valve" @@ -12,6 +14,7 @@ var/state = 0 // 0 = go straight, 1 = go to side var/mirrored = FALSE + var/tee = FALSE // Note: Tee not actually supported for T-valves: no sprites // like a trinary component, node1 is input, node2 is side output, node3 is straight output var/obj/machinery/atmospherics/node3 @@ -47,6 +50,9 @@ /obj/machinery/atmospherics/tvalve/init_dir() initialize_directions = get_initialize_directions_trinary(dir, mirrored) +/obj/machinery/atmospherics/tvalve/get_neighbor_nodes_for_init() + return list(node1, node2, node3) + /obj/machinery/atmospherics/tvalve/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) if(reference == node1) network_node1 = new_network @@ -178,21 +184,9 @@ var/list/node_connects = get_node_connect_dirs() - for(var/obj/machinery/atmospherics/target in get_step(src,node_connects[1])) - 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,node_connects[2])) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node2 = target - break - for(var/obj/machinery/atmospherics/target in get_step(src,node_connects[3])) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node3 = target - break + STANDARD_ATMOS_CHOOSE_NODE(1, node_connects[1]) + STANDARD_ATMOS_CHOOSE_NODE(2, node_connects[2]) + STANDARD_ATMOS_CHOOSE_NODE(3, node_connects[3]) update_icon() update_underlays() @@ -262,6 +256,7 @@ name = "digital switching valve" desc = "A digitally controlled valve." icon = 'icons/atmos/digital_tvalve.dmi' + pipe_state = "dtvalve" var/frequency = 0 var/id = null @@ -348,8 +343,7 @@ "\The [user] unfastens \the [src].", \ "You have unfastened \the [src].", \ "You hear a ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) + deconstruct() /obj/machinery/atmospherics/tvalve/mirrored icon_state = "map_tvalvem0" diff --git a/code/ATMOSPHERICS/components/unary/cold_sink.dm b/code/ATMOSPHERICS/components/unary/cold_sink.dm index 5759c39dcf..07b0052910 100644 --- a/code/ATMOSPHERICS/components/unary/cold_sink.dm +++ b/code/ATMOSPHERICS/components/unary/cold_sink.dm @@ -38,18 +38,15 @@ var/node_connect = dir for(var/obj/machinery/atmospherics/target in get_step(src, node_connect)) - if(target.initialize_directions & get_dir(target, src)) + if(can_be_node(target, 1)) node = target break - //copied from pipe construction code since heaters/freezers don't use fittings and weren't doing this check - this all really really needs to be refactored someday. - //check that there are no incompatible pipes/machinery in our own location - for(var/obj/machinery/atmospherics/M in src.loc) - if(M != src && (M.initialize_directions & node_connect) && M.check_connect_types(M,src)) // matches at least one direction on either type of pipe & same connection type - node = null - break + if(check_for_obstacles()) + node = null - update_icon() + if(node) + update_icon() /obj/machinery/atmospherics/unary/freezer/update_icon() if(node) diff --git a/code/ATMOSPHERICS/components/unary/heat_exchanger.dm b/code/ATMOSPHERICS/components/unary/heat_exchanger.dm index 8a7fba153a..ed4010f81e 100644 --- a/code/ATMOSPHERICS/components/unary/heat_exchanger.dm +++ b/code/ATMOSPHERICS/components/unary/heat_exchanger.dm @@ -2,6 +2,7 @@ icon = 'icons/obj/atmospherics/heat_exchanger.dmi' icon_state = "intact" + pipe_state = "heunary" density = 1 name = "Heat Exchanger" @@ -83,5 +84,4 @@ "\The [user] unfastens \the [src].", \ "You have unfastened \the [src].", \ "You hear a ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) + deconstruct() diff --git a/code/ATMOSPHERICS/components/unary/heat_source.dm b/code/ATMOSPHERICS/components/unary/heat_source.dm index a1e933b96a..bc1aaae118 100644 --- a/code/ATMOSPHERICS/components/unary/heat_source.dm +++ b/code/ATMOSPHERICS/components/unary/heat_source.dm @@ -39,18 +39,15 @@ //check that there is something to connect to for(var/obj/machinery/atmospherics/target in get_step(src, node_connect)) - if(target.initialize_directions & get_dir(target, src)) + if(can_be_node(target, 1)) node = target break - //copied from pipe construction code since heaters/freezers don't use fittings and weren't doing this check - this all really really needs to be refactored someday. - //check that there are no incompatible pipes/machinery in our own location - for(var/obj/machinery/atmospherics/M in src.loc) - if(M != src && (M.initialize_directions & node_connect) && M.check_connect_types(M,src)) // matches at least one direction on either type of pipe & same connection type - node = null - break + if(check_for_obstacles()) + node = null - update_icon() + if(node) + update_icon() /obj/machinery/atmospherics/unary/heater/update_icon() diff --git a/code/ATMOSPHERICS/components/unary/outlet_injector.dm b/code/ATMOSPHERICS/components/unary/outlet_injector.dm index 7c52cea895..9d980647a8 100644 --- a/code/ATMOSPHERICS/components/unary/outlet_injector.dm +++ b/code/ATMOSPHERICS/components/unary/outlet_injector.dm @@ -5,6 +5,7 @@ /obj/machinery/atmospherics/unary/outlet_injector icon = 'icons/atmos/injector.dmi' icon_state = "map_injector" + pipe_state = "injector" layer = 3 name = "air injector" diff --git a/code/ATMOSPHERICS/components/unary/unary_base.dm b/code/ATMOSPHERICS/components/unary/unary_base.dm index 77b135cdc5..db395ad6fc 100644 --- a/code/ATMOSPHERICS/components/unary/unary_base.dm +++ b/code/ATMOSPHERICS/components/unary/unary_base.dm @@ -1,6 +1,8 @@ /obj/machinery/atmospherics/unary dir = SOUTH initialize_directions = SOUTH + construction_type = /obj/item/pipe/directional + pipe_flags = PIPING_DEFAULT_LAYER_ONLY|PIPING_ONE_PER_TURF //layer = TURF_LAYER+0.1 var/datum/gas_mixture/air_contents @@ -21,6 +23,9 @@ initialize_directions = dir // Housekeeping and pipe network stuff below +/obj/machinery/atmospherics/unary/get_neighbor_nodes_for_init() + return list(node) + /obj/machinery/atmospherics/unary/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) if(reference == node) network = new_network @@ -48,10 +53,9 @@ var/node_connect = dir for(var/obj/machinery/atmospherics/target in get_step(src,node_connect)) - if(target.initialize_directions & get_dir(target,src)) - if (check_connect_types(target,src)) - node = target - break + if(can_be_node(target, 1)) + node = target + break update_icon() update_underlays() @@ -93,4 +97,19 @@ update_icon() update_underlays() - return null \ No newline at end of file + return null + +// Check if there are any other atmos machines in the same turf that will block this machine from initializing. +// Intended for use when a frame-constructable machine (i.e. not made from pipe fittings) wants to wrench down and connect. +// Returns TRUE if something is blocking, FALSE if its okay to continue. +/obj/machinery/atmospherics/unary/proc/check_for_obstacles() + for(var/obj/machinery/atmospherics/M in loc) + if((M.pipe_flags & pipe_flags & PIPING_ONE_PER_TURF)) //Only one dense/requires density object per tile, eg connectors/cryo/heater/coolers. + visible_message("\The [src]'s cannot be connected, something is hogging the tile!") + return TRUE + if((M.piping_layer != piping_layer) && !((M.pipe_flags | flags) & PIPING_ALL_LAYER)) // Pipes on different layers can't block each other unless they are ALL_LAYER + continue + if(M.get_init_dirs() & get_init_dirs()) // matches at least one direction on either type of pipe + visible_message("\The [src]'s connector can't be connected, there is already a pipe at that location!") + return TRUE + return FALSE diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm index 17da4afcf7..9338516343 100644 --- a/code/ATMOSPHERICS/components/unary/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm @@ -10,6 +10,7 @@ /obj/machinery/atmospherics/unary/vent_pump icon = 'icons/atmos/vent_pump.dmi' icon_state = "map_vent" + pipe_state = "uvent" name = "Air Vent" desc = "Has a valve and pump attached to it" @@ -426,8 +427,7 @@ "\The [user] unfastens \the [src].", \ "You have unfastened \the [src].", \ "You hear a ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) + deconstruct() #undef DEFAULT_PRESSURE_DELTA diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm index ad78f5a1f4..09b5fde7c1 100644 --- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm @@ -1,6 +1,7 @@ /obj/machinery/atmospherics/unary/vent_scrubber icon = 'icons/atmos/vent_scrubber.dmi' icon_state = "map_scrubber_off" + pipe_state = "scrubber" name = "Air Scrubber" desc = "Has a valve and pump attached to it" @@ -283,8 +284,7 @@ "\The [user] unfastens \the [src].", \ "You have unfastened \the [src].", \ "You hear a ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) + deconstruct() /obj/machinery/atmospherics/unary/vent_scrubber/examine(mob/user) if(..(user, 1)) diff --git a/code/ATMOSPHERICS/components/valve.dm b/code/ATMOSPHERICS/components/valve.dm index 77aedf94e0..93e5da7c32 100644 --- a/code/ATMOSPHERICS/components/valve.dm +++ b/code/ATMOSPHERICS/components/valve.dm @@ -1,6 +1,8 @@ /obj/machinery/atmospherics/valve icon = 'icons/atmos/valve.dmi' icon_state = "map_valve0" + construction_type = /obj/item/pipe/binary + pipe_state = "mvalve" name = "manual valve" desc = "A pipe valve" @@ -45,6 +47,9 @@ if(EAST || WEST) initialize_directions = EAST|WEST +/obj/machinery/atmospherics/valve/get_neighbor_nodes_for_init() + return list(node1, node2) + /obj/machinery/atmospherics/valve/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) if(reference == node1) network_node1 = new_network @@ -153,16 +158,8 @@ 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 + STANDARD_ATMOS_CHOOSE_NODE(1, node1_dir) + STANDARD_ATMOS_CHOOSE_NODE(2, node2_dir) build_network() @@ -224,6 +221,7 @@ name = "digital valve" desc = "A digitally controlled valve." icon = 'icons/atmos/digital_valve.dmi' + pipe_state = "dvalve" var/frequency = 0 var/id = null @@ -306,8 +304,7 @@ "\The [user] unfastens \the [src].", \ "You have unfastened \the [src].", \ "You hear a ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) + deconstruct() /obj/machinery/atmospherics/valve/examine(mob/user) ..() diff --git a/code/ATMOSPHERICS/mainspipe.dm b/code/ATMOSPHERICS/mainspipe.dm index 1b0c617564..a38587baf5 100644 --- a/code/ATMOSPHERICS/mainspipe.dm +++ b/code/ATMOSPHERICS/mainspipe.dm @@ -92,6 +92,9 @@ obj/machinery/atmospherics/mains_pipe else return 1 + get_neighbor_nodes_for_init() + return nodes + disconnect() ..() for(var/obj/machinery/atmospherics/pipe/mains_component/node in nodes) diff --git a/code/ATMOSPHERICS/pipes/cap.dm b/code/ATMOSPHERICS/pipes/cap.dm index de81c60200..8e56319d69 100644 --- a/code/ATMOSPHERICS/pipes/cap.dm +++ b/code/ATMOSPHERICS/pipes/cap.dm @@ -14,6 +14,9 @@ dir = SOUTH initialize_directions = SOUTH + construction_type = /obj/item/pipe/directional + pipe_state = "cap" + var/obj/machinery/atmospherics/node /obj/machinery/atmospherics/pipe/cap/init_dir() @@ -56,10 +59,9 @@ /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 + if (can_be_node(target, 1)) + node = target + break var/turf/T = src.loc // hide if turf is not intact if(level == 1 && !T.is_plating()) hide(1) diff --git a/code/ATMOSPHERICS/pipes/he_pipes.dm b/code/ATMOSPHERICS/pipes/he_pipes.dm index 8953739a9c..fe6580b1ce 100644 --- a/code/ATMOSPHERICS/pipes/he_pipes.dm +++ b/code/ATMOSPHERICS/pipes/he_pipes.dm @@ -8,6 +8,10 @@ color = "#404040" level = 2 connect_types = CONNECT_TYPE_HE + pipe_flags = PIPING_DEFAULT_LAYER_ONLY + construction_type = /obj/item/pipe/binary/bendable + pipe_state = "he" + layer = 2.41 var/initialize_directions_he var/surface = 2 //surface area in m^2 @@ -27,6 +31,16 @@ /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 + initialize_directions = 0 + +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/get_init_dirs() + return ..() | initialize_directions_he + +// Use initialize_directions_he to connect to neighbors instead. +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/can_be_node(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target) + if(!istype(target)) + return FALSE + return (target.initialize_directions_he & get_dir(target,src)) && check_connectable(target) && target.check_connectable(src) /obj/machinery/atmospherics/pipe/simple/heat_exchanging/atmos_init() normalize_dir() @@ -41,11 +55,11 @@ 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)) + if(can_be_node(target, 1)) 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)) + if(can_be_node(target, 2)) node2 = target break if(!node1 && !node2) @@ -117,6 +131,8 @@ pipe_icon = "hejunction" level = 2 connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_HE + construction_type = /obj/item/pipe/directional + pipe_state = "junction" minimum_temperature_difference = 300 thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT @@ -136,6 +152,18 @@ initialize_directions = EAST initialize_directions_he = WEST + // Allow ourselves to make connections to either HE or normal pipes depending on which node we are doing. +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/can_be_node(obj/machinery/atmospherics/target, node_num) + var/target_initialize_directions + switch(node_num) + if(1) + target_initialize_directions = target.initialize_directions // Node1 is towards normal pipes + if(2) + var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/H = target + if(!istype(H)) + return FALSE + target_initialize_directions = H.initialize_directions_he // Node2 is towards HE pies. + return (target_initialize_directions & get_dir(target,src)) && check_connectable(target) && target.check_connectable(src) /obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/atmos_init() for(var/obj/machinery/atmospherics/target in get_step(src,initialize_directions)) diff --git a/code/ATMOSPHERICS/pipes/manifold.dm b/code/ATMOSPHERICS/pipes/manifold.dm index 1b9afd9c63..8df3b4326a 100644 --- a/code/ATMOSPHERICS/pipes/manifold.dm +++ b/code/ATMOSPHERICS/pipes/manifold.dm @@ -12,6 +12,9 @@ dir = SOUTH initialize_directions = EAST|NORTH|WEST + construction_type = /obj/item/pipe/trinary + pipe_state = "manifold" + var/obj/machinery/atmospherics/node3 level = 1 @@ -116,11 +119,10 @@ 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 (can_be_node(target, 1)) + node1 = target + connect_directions &= ~direction + break if (node1) break @@ -128,11 +130,10 @@ 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 (can_be_node(target, 2)) + node2 = target + connect_directions &= ~direction + break if (node2) break @@ -140,11 +141,10 @@ 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 (can_be_node(target, 3)) + node3 = target + connect_directions &= ~direction + break if (node3) break diff --git a/code/ATMOSPHERICS/pipes/manifold4w.dm b/code/ATMOSPHERICS/pipes/manifold4w.dm index ba360eefd8..1bd556b3fb 100644 --- a/code/ATMOSPHERICS/pipes/manifold4w.dm +++ b/code/ATMOSPHERICS/pipes/manifold4w.dm @@ -12,6 +12,9 @@ dir = SOUTH initialize_directions = NORTH|SOUTH|EAST|WEST + construction_type = /obj/item/pipe/quaternary + pipe_state = "manifold4w" + var/obj/machinery/atmospherics/node3 var/obj/machinery/atmospherics/node4 @@ -127,29 +130,25 @@ /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, NORTH)) + if (can_be_node(target, 1)) + 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, SOUTH)) + if (can_be_node(target, 2)) + 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, EAST)) + if (can_be_node(target, 3)) + 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 + for(var/obj/machinery/atmospherics/target in get_step(src, WEST)) + if (can_be_node(target, 4)) + node4 = target + break if(!node1 && !node2 && !node3 && !node4) qdel(src) diff --git a/code/ATMOSPHERICS/pipes/pipe_base.dm b/code/ATMOSPHERICS/pipes/pipe_base.dm index 94167e01f6..4e852ed0c8 100644 --- a/code/ATMOSPHERICS/pipes/pipe_base.dm +++ b/code/ATMOSPHERICS/pipes/pipe_base.dm @@ -10,6 +10,8 @@ layer = 2.4 //under wires with their 2.44 use_power = 0 + pipe_flags = 0 // Does not have PIPING_DEFAULT_LAYER_ONLY flag. + var/alert_pressure = 80*ONE_ATMOSPHERE //minimum pressure before check_pressure(...) should be called @@ -31,6 +33,10 @@ /obj/machinery/atmospherics/pipe/proc/pipeline_expansion() return null +// For pipes this is the same as pipeline_expansion() +/obj/machinery/atmospherics/pipe/get_neighbor_nodes_for_init() + return pipeline_expansion() + /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 @@ -69,7 +75,11 @@ qdel_null(parent) if(air_temporary) loc.assume_air(air_temporary) - + for(var/obj/machinery/meter/meter in loc) + if(meter.target == src) + var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(loc) + meter.transfer_fingerprints_to(PM) + qdel(meter) . = ..() /obj/machinery/atmospherics/pipe/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) @@ -96,12 +106,7 @@ "\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) + deconstruct() /obj/machinery/atmospherics/pipe/proc/change_color(var/new_color) //only pass valid pipe colors please ~otherwise your pipe will turn invisible diff --git a/code/ATMOSPHERICS/pipes/simple.dm b/code/ATMOSPHERICS/pipes/simple.dm index f676c1ac38..289e8b4274 100644 --- a/code/ATMOSPHERICS/pipes/simple.dm +++ b/code/ATMOSPHERICS/pipes/simple.dm @@ -13,6 +13,10 @@ dir = SOUTH initialize_directions = SOUTH|NORTH + pipe_flags = PIPING_CARDINAL_AUTONORMALIZE + construction_type = /obj/item/pipe/binary/bendable + pipe_state = "simple" + var/minimum_temperature_difference = 300 var/thermal_conductivity = 0 //WALL_HEAT_TRANSFER_COEFFICIENT No @@ -47,9 +51,13 @@ /obj/machinery/atmospherics/pipe/simple/init_dir() switch(dir) - if(SOUTH || NORTH) + if(SOUTH) initialize_directions = SOUTH|NORTH - if(EAST || WEST) + if(NORTH) + initialize_directions = SOUTH|NORTH + if(EAST) + initialize_directions = EAST|WEST + if(WEST) initialize_directions = EAST|WEST if(NORTHEAST) initialize_directions = NORTH|EAST @@ -124,15 +132,13 @@ 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 + if(can_be_node(target, 1)) + 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(can_be_node(target, 2)) + node2 = target + break if(!node1 && !node2) qdel(src) @@ -248,6 +254,9 @@ icon = 'icons/obj/atmospherics/red_pipe.dmi' icon_state = "intact" + construction_type = /obj/item/pipe/binary/bendable + pipe_state = "insulated" + minimum_temperature_difference = 10000 thermal_conductivity = 0 maximum_pressure = 1000*ONE_ATMOSPHERE diff --git a/code/ATMOSPHERICS/pipes/tank.dm b/code/ATMOSPHERICS/pipes/tank.dm index 07ce8d5b71..c96f4ddf1d 100644 --- a/code/ATMOSPHERICS/pipes/tank.dm +++ b/code/ATMOSPHERICS/pipes/tank.dm @@ -14,6 +14,7 @@ level = 1 dir = SOUTH initialize_directions = SOUTH + pipe_flags = PIPING_DEFAULT_LAYER_ONLY density = 1 /obj/machinery/atmospherics/pipe/tank/New() @@ -48,10 +49,9 @@ 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 + if (can_be_node(target, 1)) + node1 = target + break update_underlays() diff --git a/code/ATMOSPHERICS/pipes/universal.dm b/code/ATMOSPHERICS/pipes/universal.dm index 1017751aa1..2d8bd09dff 100644 --- a/code/ATMOSPHERICS/pipes/universal.dm +++ b/code/ATMOSPHERICS/pipes/universal.dm @@ -6,6 +6,9 @@ desc = "An adapter for regular, supply and scrubbers pipes" connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER icon_state = "map_universal" + pipe_flags = PIPING_ALL_LAYER|PIPING_CARDINAL_AUTONORMALIZE + construction_type = /obj/item/pipe/binary + pipe_state = "universal" /obj/machinery/atmospherics/pipe/simple/visible/universal/update_icon(var/safety = 0) if(!check_icon_cache()) @@ -28,7 +31,7 @@ universal_underlays(node2) else universal_underlays(,dir) - universal_underlays(dir, -180) + universal_underlays(,turn(dir, -180)) /obj/machinery/atmospherics/pipe/simple/visible/universal/update_underlays() ..() @@ -41,6 +44,9 @@ desc = "An adapter for regular, supply and scrubbers pipes" connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER icon_state = "map_universal" + pipe_flags = PIPING_ALL_LAYER|PIPING_CARDINAL_AUTONORMALIZE + construction_type = /obj/item/pipe/binary + pipe_state = "universal" /obj/machinery/atmospherics/pipe/simple/hidden/universal/update_icon(var/safety = 0) if(!check_icon_cache()) diff --git a/code/ATMOSPHERICS/pipes/vent.dm b/code/ATMOSPHERICS/pipes/vent.dm index 74eebb29a1..4a1dc5696d 100644 --- a/code/ATMOSPHERICS/pipes/vent.dm +++ b/code/ATMOSPHERICS/pipes/vent.dm @@ -14,6 +14,9 @@ dir = SOUTH initialize_directions = SOUTH + pipe_flags = PIPING_DEFAULT_LAYER_ONLY + construction_type = /obj/item/pipe/directional + pipe_state = "passive vent" var/build_killswitch = 1 @@ -58,10 +61,9 @@ 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 + if (can_be_node(target, 1)) + node1 = target + break update_icon() diff --git a/code/__defines/construction.dm b/code/__defines/construction.dm index 7aceb1ffc4..837ad7ed38 100644 --- a/code/__defines/construction.dm +++ b/code/__defines/construction.dm @@ -1,4 +1,6 @@ - +// +// Frame construction +// // Frame construction states #define FRAME_PLACED 0 // Has been placed (can be anchored or not). @@ -16,3 +18,44 @@ // Does the frame get built on the floor or a wall? #define FRAME_STYLE_FLOOR "floor" #define FRAME_STYLE_WALL "wall" + +// +// Pipe Construction +// + +//Construction Orientation Types - Each of these categories has a different selection of how pipes can rotate and flip. Used for RPD. +#define PIPE_STRAIGHT 0 //2 directions: N/S, E/W +#define PIPE_BENDABLE 1 //6 directions: N/S, E/W, N/E, N/W, S/E, S/W +#define PIPE_TRINARY 2 //4 directions: N/E/S, E/S/W, S/W/N, W/N/E +#define PIPE_TRIN_M 3 //8 directions: N->S+E, S->N+E, N->S+W, S->N+W, E->W+S, W->E+S, E->W+N, W->E+N +#define PIPE_DIRECTIONAL 4 //4 directions: N, S, E, W +#define PIPE_ONEDIR 5 //1 direction: N/S/E/W +#define PIPE_UNARY_FLIPPABLE 6 //8 directions: N, S, E, W, N-flipped, S-flipped, E-flipped, W-flipped +#define PIPE_TRIN_T 7 //8 directions: N->S+E, S->N+E, N->S+W, S->N+W, E->W+S, W->E+S, E->W+N, W->E+N + +// Pipe connectivity bit flags +#define CONNECT_TYPE_REGULAR 1 +#define CONNECT_TYPE_SUPPLY 2 +#define CONNECT_TYPE_SCRUBBER 4 +#define CONNECT_TYPE_HE 8 + +// We are based on the three named layers of supply, regular, and scrubber. +#define PIPING_LAYER_SUPPLY 1 +#define PIPING_LAYER_REGULAR 2 +#define PIPING_LAYER_SCRUBBER 3 +#define PIPING_LAYER_DEFAULT PIPING_LAYER_REGULAR + +// Pipe flags +#define PIPING_ALL_LAYER 1 //intended to connect with all layers, check for all instead of just one. +#define PIPING_ONE_PER_TURF 2 //can only be built if nothing else with this flag is on the tile already. +#define PIPING_DEFAULT_LAYER_ONLY 4 //can only exist at PIPING_LAYER_DEFAULT +#define PIPING_CARDINAL_AUTONORMALIZE 8 //north/south east/west doesn't matter, auto normalize on build. + +// Macro for easy use of boilerplate code for searching for a valid node connection. +#define STANDARD_ATMOS_CHOOSE_NODE(node_num, direction) \ + for(var/obj/machinery/atmospherics/target in get_step(src, direction)) { \ + if(can_be_node(target, node_num)) { \ + node##node_num = target; \ + break; \ + } \ + } diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index f03e56e642..9c67a9bc5d 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -2,1317 +2,273 @@ Buildable pipes Buildable meters */ -#define PIPE_SIMPLE_STRAIGHT 0 -#define PIPE_SIMPLE_BENT 1 -#define PIPE_HE_STRAIGHT 2 -#define PIPE_HE_BENT 3 -#define PIPE_CONNECTOR 4 -#define PIPE_MANIFOLD 5 -#define PIPE_JUNCTION 6 -#define PIPE_UVENT 7 -#define PIPE_MVALVE 8 -#define PIPE_PUMP 9 -#define PIPE_SCRUBBER 10 -#define PIPE_INSULATED_STRAIGHT 11 -#define PIPE_INSULATED_BENT 12 -#define PIPE_GAS_FILTER 13 -#define PIPE_GAS_MIXER 14 -#define PIPE_PASSIVE_GATE 15 -#define PIPE_VOLUME_PUMP 16 -#define PIPE_HEAT_EXCHANGE 17 -#define PIPE_MTVALVE 18 -#define PIPE_MANIFOLD4W 19 -#define PIPE_CAP 20 -///// Z-Level stuff -#define PIPE_UP 21 -#define PIPE_DOWN 22 -///// Z-Level stuff -#define PIPE_GAS_FILTER_M 23 -#define PIPE_GAS_MIXER_T 24 -#define PIPE_GAS_MIXER_M 25 -#define PIPE_OMNI_MIXER 26 -#define PIPE_OMNI_FILTER 27 -///// Supply, scrubbers and universal pipes -#define PIPE_UNIVERSAL 28 -#define PIPE_SUPPLY_STRAIGHT 29 -#define PIPE_SUPPLY_BENT 30 -#define PIPE_SCRUBBERS_STRAIGHT 31 -#define PIPE_SCRUBBERS_BENT 32 -#define PIPE_SUPPLY_MANIFOLD 33 -#define PIPE_SCRUBBERS_MANIFOLD 34 -#define PIPE_SUPPLY_MANIFOLD4W 35 -#define PIPE_SCRUBBERS_MANIFOLD4W 36 -#define PIPE_SUPPLY_UP 37 -#define PIPE_SCRUBBERS_UP 38 -#define PIPE_SUPPLY_DOWN 39 -#define PIPE_SCRUBBERS_DOWN 40 -#define PIPE_SUPPLY_CAP 41 -#define PIPE_SCRUBBERS_CAP 42 -///// Mirrored T-valve ~ because I couldn't be bothered re-sorting all of the defines -#define PIPE_MTVALVEM 43 -///// Digital Valves sit here because otherwise we're resorting every define. -#define PIPE_DVALVE 44 -#define PIPE_DTVALVE 45 -#define PIPE_DTVALVEM 46 - -#define PIPE_PASSIVE_VENT 47 /obj/item/pipe name = "pipe" - desc = "A pipe" - var/pipe_type = 0 - //var/pipe_dir = 0 + desc = "A pipe." + var/pipe_type var/pipename - var/connect_types = CONNECT_TYPE_REGULAR force = 7 + throwforce = 7 icon = 'icons/obj/pipe-item.dmi' icon_state = "simple" item_state = "buildpipe" w_class = ITEMSIZE_NORMAL level = 2 + var/piping_layer = PIPING_LAYER_DEFAULT + var/dispenser_class // Tells the dispenser what orientations we support, so RPD can show previews. -/obj/item/pipe/New(var/loc, var/pipe_type as num, var/dir as num, var/obj/machinery/atmospherics/make_from = null) - ..() - if (make_from) - src.set_dir(make_from.dir) - src.pipename = make_from.name - if(make_from.req_access) - src.req_access = make_from.req_access - if(make_from.req_one_access) - src.req_one_access = make_from.req_one_access - color = make_from.pipe_color - var/is_bent - if (make_from.initialize_directions in list(NORTH|SOUTH, WEST|EAST)) - is_bent = 0 - else - is_bent = 1 - if (istype(make_from, /obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction)) - src.pipe_type = PIPE_JUNCTION - connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_HE - else if(istype(make_from, /obj/machinery/atmospherics/pipe/simple/heat_exchanging)) - src.pipe_type = PIPE_HE_STRAIGHT + is_bent - connect_types = CONNECT_TYPE_HE - else if(istype(make_from, /obj/machinery/atmospherics/pipe/simple/insulated)) - src.pipe_type = PIPE_INSULATED_STRAIGHT + is_bent - else if(istype(make_from, /obj/machinery/atmospherics/pipe/simple/visible/supply) || istype(make_from, /obj/machinery/atmospherics/pipe/simple/hidden/supply)) - src.pipe_type = PIPE_SUPPLY_STRAIGHT + is_bent - connect_types = CONNECT_TYPE_SUPPLY - src.color = PIPE_COLOR_BLUE - else if(istype(make_from, /obj/machinery/atmospherics/pipe/simple/visible/scrubbers) || istype(make_from, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers)) - src.pipe_type = PIPE_SCRUBBERS_STRAIGHT + is_bent - connect_types = CONNECT_TYPE_SCRUBBER - src.color = PIPE_COLOR_RED - else if(istype(make_from, /obj/machinery/atmospherics/pipe/simple/visible/universal) || istype(make_from, /obj/machinery/atmospherics/pipe/simple/hidden/universal)) - src.pipe_type = PIPE_UNIVERSAL - connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER - else if(istype(make_from, /obj/machinery/atmospherics/pipe/simple)) - src.pipe_type = PIPE_SIMPLE_STRAIGHT + is_bent - else if(istype(make_from, /obj/machinery/atmospherics/portables_connector)) - src.pipe_type = PIPE_CONNECTOR - else if(istype(make_from, /obj/machinery/atmospherics/pipe/manifold/visible/supply) || istype(make_from, /obj/machinery/atmospherics/pipe/manifold/hidden/supply)) - src.pipe_type = PIPE_SUPPLY_MANIFOLD - connect_types = CONNECT_TYPE_SUPPLY - src.color = PIPE_COLOR_BLUE - else if(istype(make_from, /obj/machinery/atmospherics/pipe/manifold/visible/scrubbers) || istype(make_from, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers)) - src.pipe_type = PIPE_SCRUBBERS_MANIFOLD - connect_types = CONNECT_TYPE_SCRUBBER - src.color = PIPE_COLOR_RED - else if(istype(make_from, /obj/machinery/atmospherics/pipe/manifold)) - src.pipe_type = PIPE_MANIFOLD - else if(istype(make_from, /obj/machinery/atmospherics/unary/vent_pump)) - src.pipe_type = PIPE_UVENT - else if(istype(make_from, /obj/machinery/atmospherics/valve/digital)) - src.pipe_type = PIPE_DVALVE - else if(istype(make_from, /obj/machinery/atmospherics/valve)) - src.pipe_type = PIPE_MVALVE - else if(istype(make_from, /obj/machinery/atmospherics/binary/pump/high_power)) - src.pipe_type = PIPE_VOLUME_PUMP - else if(istype(make_from, /obj/machinery/atmospherics/binary/pump)) - src.pipe_type = PIPE_PUMP - else if(istype(make_from, /obj/machinery/atmospherics/trinary/atmos_filter/m_filter)) - src.pipe_type = PIPE_GAS_FILTER_M - else if(istype(make_from, /obj/machinery/atmospherics/trinary/mixer/t_mixer)) - src.pipe_type = PIPE_GAS_MIXER_T - else if(istype(make_from, /obj/machinery/atmospherics/trinary/mixer/m_mixer)) - src.pipe_type = PIPE_GAS_MIXER_M - else if(istype(make_from, /obj/machinery/atmospherics/trinary/atmos_filter)) - src.pipe_type = PIPE_GAS_FILTER - else if(istype(make_from, /obj/machinery/atmospherics/trinary/mixer)) - src.pipe_type = PIPE_GAS_MIXER - else if(istype(make_from, /obj/machinery/atmospherics/unary/vent_scrubber)) - src.pipe_type = PIPE_SCRUBBER - else if(istype(make_from, /obj/machinery/atmospherics/binary/passive_gate)) - src.pipe_type = PIPE_PASSIVE_GATE - else if(istype(make_from, /obj/machinery/atmospherics/unary/heat_exchanger)) - src.pipe_type = PIPE_HEAT_EXCHANGE - else if(istype(make_from, /obj/machinery/atmospherics/tvalve/digital/mirrored)) - src.pipe_type = PIPE_DTVALVEM - else if(istype(make_from, /obj/machinery/atmospherics/tvalve/mirrored)) - src.pipe_type = PIPE_MTVALVEM - else if(istype(make_from, /obj/machinery/atmospherics/tvalve/digital)) - src.pipe_type = PIPE_DTVALVE - else if(istype(make_from, /obj/machinery/atmospherics/tvalve)) - src.pipe_type = PIPE_MTVALVE - else if(istype(make_from, /obj/machinery/atmospherics/pipe/manifold4w/visible/supply) || istype(make_from, /obj/machinery/atmospherics/pipe/manifold4w/hidden/supply)) - src.pipe_type = PIPE_SUPPLY_MANIFOLD4W - connect_types = CONNECT_TYPE_SUPPLY - src.color = PIPE_COLOR_BLUE - else if(istype(make_from, /obj/machinery/atmospherics/pipe/manifold4w/visible/scrubbers) || istype(make_from, /obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers)) - src.pipe_type = PIPE_SCRUBBERS_MANIFOLD4W - connect_types = CONNECT_TYPE_SCRUBBER - src.color = PIPE_COLOR_RED - else if(istype(make_from, /obj/machinery/atmospherics/pipe/manifold4w)) - src.pipe_type = PIPE_MANIFOLD4W - else if(istype(make_from, /obj/machinery/atmospherics/pipe/cap/visible/supply) || istype(make_from, /obj/machinery/atmospherics/pipe/cap/hidden/supply)) - src.pipe_type = PIPE_SUPPLY_CAP - connect_types = CONNECT_TYPE_SUPPLY - src.color = PIPE_COLOR_BLUE - else if(istype(make_from, /obj/machinery/atmospherics/pipe/cap/visible/scrubbers) || istype(make_from, /obj/machinery/atmospherics/pipe/cap/hidden/scrubbers)) - src.pipe_type = PIPE_SCRUBBERS_CAP - connect_types = CONNECT_TYPE_SCRUBBER - src.color = PIPE_COLOR_RED - else if(istype(make_from, /obj/machinery/atmospherics/pipe/cap)) - src.pipe_type = PIPE_CAP - else if(istype(make_from, /obj/machinery/atmospherics/omni/mixer)) - src.pipe_type = PIPE_OMNI_MIXER - else if(istype(make_from, /obj/machinery/atmospherics/omni/atmos_filter)) - src.pipe_type = PIPE_OMNI_FILTER -///// Z-Level stuff - else if(istype(make_from, /obj/machinery/atmospherics/pipe/zpipe/up/supply)) - src.pipe_type = PIPE_SUPPLY_UP - connect_types = CONNECT_TYPE_SUPPLY - src.color = PIPE_COLOR_BLUE - else if(istype(make_from, /obj/machinery/atmospherics/pipe/zpipe/up/scrubbers)) - src.pipe_type = PIPE_SCRUBBERS_UP - connect_types = CONNECT_TYPE_SCRUBBER - src.color = PIPE_COLOR_RED - else if(istype(make_from, /obj/machinery/atmospherics/pipe/zpipe/up)) - src.pipe_type = PIPE_UP - else if(istype(make_from, /obj/machinery/atmospherics/pipe/zpipe/down/supply)) - src.pipe_type = PIPE_SUPPLY_DOWN - connect_types = CONNECT_TYPE_SUPPLY - src.color = PIPE_COLOR_BLUE - else if(istype(make_from, /obj/machinery/atmospherics/pipe/zpipe/down/scrubbers)) - src.pipe_type = PIPE_SCRUBBERS_DOWN - connect_types = CONNECT_TYPE_SCRUBBER - src.color = PIPE_COLOR_RED - else if(istype(make_from, /obj/machinery/atmospherics/pipe/zpipe/down)) - src.pipe_type = PIPE_DOWN -///// Z-Level stuff - else if(istype(make_from, /obj/machinery/atmospherics/pipe/vent)) - src.pipe_type = PIPE_PASSIVE_VENT +// One subtype for each way components connect to neighbors +/obj/item/pipe/directional + dispenser_class = PIPE_DIRECTIONAL +/obj/item/pipe/binary + dispenser_class = PIPE_STRAIGHT +/obj/item/pipe/binary/bendable + dispenser_class = PIPE_BENDABLE +/obj/item/pipe/trinary + dispenser_class = PIPE_TRINARY +/obj/item/pipe/trinary/flippable + dispenser_class = PIPE_TRIN_M + var/mirrored = FALSE +/obj/item/pipe/quaternary + dispenser_class = PIPE_ONEDIR + +/** + * Call constructor with: + * @param loc Location + * @pipe_type + */ +/obj/item/pipe/initialize(var/mapload, var/_pipe_type, var/_dir, var/obj/machinery/atmospherics/make_from) + if(make_from) + make_from_existing(make_from) else - src.pipe_type = pipe_type - src.set_dir(dir) - if (pipe_type == 29 || pipe_type == 30 || pipe_type == 33 || pipe_type == 35 || pipe_type == 37 || pipe_type == 39 || pipe_type == 41) - connect_types = CONNECT_TYPE_SUPPLY - src.color = PIPE_COLOR_BLUE - else if (pipe_type == 31 || pipe_type == 32 || pipe_type == 34 || pipe_type == 36 || pipe_type == 38 || pipe_type == 40 || pipe_type == 42) - connect_types = CONNECT_TYPE_SCRUBBER - src.color = PIPE_COLOR_RED - else if (pipe_type == 2 || pipe_type == 3) - connect_types = CONNECT_TYPE_HE - else if (pipe_type == 6) - connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_HE - else if (pipe_type == 28) - connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER - //src.pipe_dir = get_pipe_dir() - update() - src.pixel_x = rand(-5, 5) - src.pixel_y = rand(-5, 5) + pipe_type = _pipe_type + set_dir(_dir) -//update the name and icon of the pipe item depending on the type + update() + pixel_x += rand(-5, 5) + pixel_y += rand(-5, 5) + return ..() + +/obj/item/pipe/proc/make_from_existing(obj/machinery/atmospherics/make_from) + set_dir(make_from.dir) + pipename = make_from.name + if(make_from.req_access) + src.req_access = make_from.req_access + if(make_from.req_one_access) + src.req_one_access = make_from.req_one_access + color = make_from.pipe_color + pipe_type = make_from.type + +/obj/item/pipe/trinary/flippable/make_from_existing(obj/machinery/atmospherics/trinary/make_from) + ..() + if(make_from.mirrored) + do_a_flip() + +/obj/item/pipe/dropped() + if(loc) + setPipingLayer(piping_layer) + return ..() + +/obj/item/pipe/proc/setPipingLayer(new_layer = PIPING_LAYER_DEFAULT) + var/obj/machinery/atmospherics/fakeA = pipe_type + if(initial(fakeA.pipe_flags) & (PIPING_ALL_LAYER|PIPING_DEFAULT_LAYER_ONLY)) + new_layer = PIPING_LAYER_DEFAULT + piping_layer = new_layer + // Do it the Polaris way + switch(piping_layer) + if(PIPING_LAYER_SCRUBBER) + color = PIPE_COLOR_RED + name = "[initial(fakeA.name)] scrubber fitting" + if(PIPING_LAYER_SUPPLY) + color = PIPE_COLOR_BLUE + name = "[initial(fakeA.name)] supply fitting" + // Or if we were to do it the TG way... + // pixel_x = PIPE_PIXEL_OFFSET_X(piping_layer) + // pixel_y = PIPE_PIXEL_OFFSET_Y(piping_layer) + // layer = initial(layer) + PIPE_LAYER_OFFSET(piping_layer) /obj/item/pipe/proc/update() - var/list/nlist = list( \ - "pipe", \ - "bent pipe", \ - "h/e pipe", \ - "bent h/e pipe", \ - "connector", \ - "manifold", \ - "junction", \ - "uvent", \ - "mvalve", \ - "pump", \ - "scrubber", \ - "insulated pipe", \ - "bent insulated pipe", \ - "gas filter", \ - "gas mixer", \ - "pressure regulator", \ - "high power pump", \ - "heat exchanger", \ - "t-valve", \ - "4-way manifold", \ - "pipe cap", \ -///// Z-Level stuff - "pipe up", \ - "pipe down", \ -///// Z-Level stuff - "gas filter m", \ - "gas mixer t", \ - "gas mixer m", \ - "omni mixer", \ - "omni filter", \ -///// Supply and scrubbers pipes - "universal pipe adapter", \ - "supply pipe", \ - "bent supply pipe", \ - "scrubbers pipe", \ - "bent scrubbers pipe", \ - "supply manifold", \ - "scrubbers manifold", \ - "supply 4-way manifold", \ - "scrubbers 4-way manifold", \ - "supply pipe up", \ - "scrubbers pipe up", \ - "supply pipe down", \ - "scrubbers pipe down", \ - "supply pipe cap", \ - "scrubbers pipe cap", \ - "t-valve m", \ - "dvalve", \ - "dt-valve", \ - "dt-valve m", \ - "passive vent", \ - ) - name = nlist[pipe_type+1] + " fitting" - var/list/islist = list( \ - "simple", \ - "simple", \ - "he", \ - "he", \ - "connector", \ - "manifold", \ - "junction", \ - "uvent", \ - "mvalve", \ - "pump", \ - "scrubber", \ - "insulated", \ - "insulated", \ - "filter", \ - "mixer", \ - "passivegate", \ - "volumepump", \ - "heunary", \ - "mtvalve", \ - "manifold4w", \ - "cap", \ -///// Z-Level stuff - "cap", \ - "cap", \ -///// Z-Level stuff - "m_filter", \ - "t_mixer", \ - "m_mixer", \ - "omni_mixer", \ - "omni_filter", \ -///// Supply and scrubbers pipes - "universal", \ - "simple", \ - "simple", \ - "simple", \ - "simple", \ - "manifold", \ - "manifold", \ - "manifold4w", \ - "manifold4w", \ - "cap", \ - "cap", \ - "cap", \ - "cap", \ - "cap", \ - "cap", \ - "mtvalvem", \ - "dvalve", \ - "dtvalve", \ - "dtvalvem", \ - "passive vent", \ - ) - icon_state = islist[pipe_type + 1] + var/obj/machinery/atmospherics/fakeA = pipe_type + name = "[initial(fakeA.name)] fitting" + icon_state = initial(fakeA.pipe_state) -//called when a turf is attacked with a pipe item -/obj/item/pipe/afterattack(turf/simulated/floor/target, mob/user, proximity) - if(!proximity) return - if(istype(target)) - user.drop_from_inventory(src, target) - else - return ..() +/obj/item/pipe/verb/flip() + set category = "Object" + set name = "Flip Pipe" + set src in view(1) -// rotate the pipe item clockwise + if ( usr.stat || usr.restrained() || !usr.canmove ) + return + + do_a_flip() + +/obj/item/pipe/proc/do_a_flip() + set_dir(turn(dir, -180)) + fixdir() + +/obj/item/pipe/trinary/flippable/do_a_flip() + // set_dir(turn(dir, flipped ? 45 : -45)) + // TG has a magic icon set with the flipped versions in the diagonals. + // We may switch to this later, but for now gotta do some magic. + mirrored = !mirrored + var/obj/machinery/atmospherics/fakeA = pipe_type + icon_state = "[initial(fakeA.pipe_state)][mirrored ? "m" : ""]" /obj/item/pipe/verb/rotate() set category = "Object" set name = "Rotate Pipe" set src in view(1) - if ( usr.stat || usr.restrained() ) + if ( usr.stat || usr.restrained() || !usr.canmove ) return - src.set_dir(turn(src.dir, -90)) - - if (pipe_type in list (PIPE_SIMPLE_STRAIGHT, PIPE_SUPPLY_STRAIGHT, PIPE_SCRUBBERS_STRAIGHT, PIPE_UNIVERSAL, PIPE_HE_STRAIGHT, PIPE_INSULATED_STRAIGHT, PIPE_MVALVE)) - if(dir==2) - set_dir(1) - else if(dir==8) - set_dir(4) - else if (pipe_type in list (PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W)) - set_dir(2) - //src.pipe_set_dir(get_pipe_dir()) - return + set_dir(turn(src.dir, -90)) // Rotate clockwise + fixdir() /obj/item/pipe/Move() - ..() - if ((pipe_type in list (PIPE_SIMPLE_BENT, PIPE_SUPPLY_BENT, PIPE_SCRUBBERS_BENT, PIPE_HE_BENT, PIPE_INSULATED_BENT)) \ - && (src.dir in cardinal)) - src.set_dir(src.dir|turn(src.dir, 90)) - else if (pipe_type in list (PIPE_SIMPLE_STRAIGHT, PIPE_SUPPLY_STRAIGHT, PIPE_SCRUBBERS_STRAIGHT, PIPE_UNIVERSAL, PIPE_HE_STRAIGHT, PIPE_INSULATED_STRAIGHT, PIPE_MVALVE)) - if(dir==2) - set_dir(1) - else if(dir==8) - set_dir(4) + var/old_dir = dir + . = ..() + set_dir(old_dir) //pipes changing direction when moved is just annoying and buggy + +//Helper to clean up dir +/obj/item/pipe/proc/fixdir() return -// returns all pipe's endpoints +/obj/item/pipe/binary/fixdir() + if(dir == SOUTH) + set_dir(NORTH) + else if(dir == WEST) + set_dir(EAST) -/obj/item/pipe/proc/get_pipe_dir() - if (!dir) - return 0 - var/flip = turn(dir, 180) - var/cw = turn(dir, -90) - var/acw = turn(dir, 90) +/obj/item/pipe/trinary/flippable/fixdir() + if(dir in cornerdirs) + set_dir(turn(dir, 45)) - switch(pipe_type) - if( PIPE_SIMPLE_STRAIGHT, \ - PIPE_INSULATED_STRAIGHT, \ - PIPE_HE_STRAIGHT, \ - PIPE_JUNCTION ,\ - PIPE_PUMP ,\ - PIPE_VOLUME_PUMP ,\ - PIPE_PASSIVE_GATE ,\ - PIPE_MVALVE, \ - PIPE_SUPPLY_STRAIGHT, \ - PIPE_SCRUBBERS_STRAIGHT, \ - PIPE_UNIVERSAL, \ - PIPE_DVALVE, \ - ) - return dir|flip - if(PIPE_SIMPLE_BENT, PIPE_INSULATED_BENT, PIPE_HE_BENT, PIPE_SUPPLY_BENT, PIPE_SCRUBBERS_BENT) - return dir //dir|acw - if(PIPE_CONNECTOR,PIPE_UVENT,PIPE_SCRUBBER,PIPE_HEAT_EXCHANGE) - return dir - if(PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W, PIPE_OMNI_MIXER, PIPE_OMNI_FILTER) - return dir|flip|cw|acw - if(PIPE_MANIFOLD, PIPE_SUPPLY_MANIFOLD, PIPE_SCRUBBERS_MANIFOLD) - return flip|cw|acw - if(PIPE_GAS_FILTER, PIPE_GAS_MIXER, PIPE_MTVALVE, PIPE_DTVALVE) - return dir|flip|cw - if(PIPE_GAS_FILTER_M, PIPE_GAS_MIXER_M, PIPE_MTVALVEM, PIPE_DTVALVEM) - return dir|flip|acw - if(PIPE_GAS_MIXER_T) - return dir|cw|acw - if(PIPE_CAP, PIPE_SUPPLY_CAP, PIPE_SCRUBBERS_CAP) - return dir -///// Z-Level stuff - if(PIPE_UP,PIPE_DOWN,PIPE_SUPPLY_UP,PIPE_SUPPLY_DOWN,PIPE_SCRUBBERS_UP,PIPE_SCRUBBERS_DOWN) - return dir -///// Z-Level stuff - if(PIPE_PASSIVE_VENT) - return dir - return 0 +/obj/item/pipe/attack_self(mob/user) + set_dir(turn(dir,-90)) + fixdir() -/obj/item/pipe/proc/get_pdir() //endpoints for regular pipes - - var/flip = turn(dir, 180) -// var/cw = turn(dir, -90) -// var/acw = turn(dir, 90) - - if (!(pipe_type in list(PIPE_HE_STRAIGHT, PIPE_HE_BENT, PIPE_JUNCTION))) - return get_pipe_dir() - switch(pipe_type) - if(PIPE_HE_STRAIGHT,PIPE_HE_BENT) - return 0 - if(PIPE_JUNCTION) - return flip - return 0 - -// return the h_dir (heat-exchange pipes) from the type and the dir - -/obj/item/pipe/proc/get_hdir() //endpoints for h/e pipes - -// var/flip = turn(dir, 180) -// var/cw = turn(dir, -90) - - switch(pipe_type) - if(PIPE_HE_STRAIGHT) - return get_pipe_dir() - if(PIPE_HE_BENT) - return get_pipe_dir() - if(PIPE_JUNCTION) - return dir - else - return 0 - -/obj/item/pipe/attack_self(mob/user as mob) - return rotate() +//called when a turf is attacked with a pipe item +/obj/item/pipe/afterattack(turf/simulated/floor/target, mob/user, proximity) + if(!proximity) return + if(istype(target) && user.canUnEquip(src)) + user.drop_from_inventory(src, target) + else + return ..() /obj/item/pipe/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) - ..() - //* - if (!istype(W, /obj/item/weapon/wrench)) - return ..() - if (!isturf(src.loc)) - return 1 - if (pipe_type in list (PIPE_SIMPLE_STRAIGHT, PIPE_SUPPLY_STRAIGHT, PIPE_SCRUBBERS_STRAIGHT, PIPE_HE_STRAIGHT, PIPE_INSULATED_STRAIGHT, PIPE_MVALVE)) - if(dir==2) - set_dir(1) - else if(dir==8) - set_dir(4) - else if (pipe_type in list(PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W, PIPE_OMNI_MIXER, PIPE_OMNI_FILTER)) - set_dir(2) - var/pipe_dir = get_pipe_dir() + if(iswrench(W)) + return wrench_act(user, W) + return ..() - for(var/obj/machinery/atmospherics/M in src.loc) - if((M.initialize_directions & pipe_dir) && M.check_connect_types_construction(M,src)) // matches at least one direction on either type of pipe & same connection type - user << "There is already a pipe of the same type at this location." - return 1 +/obj/item/pipe/proc/wrench_act(var/mob/living/user, var/obj/item/weapon/wrench/W) + if(!isturf(loc)) + return TRUE + + add_fingerprint(user) + fixdir() + + var/obj/machinery/atmospherics/fakeA = pipe_type + var/flags = initial(fakeA.pipe_flags) + for(var/obj/machinery/atmospherics/M in loc) + if((M.pipe_flags & flags & PIPING_ONE_PER_TURF)) //Only one dense/requires density object per tile, eg connectors/cryo/heater/coolers. + to_chat(user, "Something is hogging the tile!") + return TRUE + if((M.piping_layer != piping_layer) && !((M.pipe_flags | flags) & PIPING_ALL_LAYER)) // Pipes on different layers can't block each other unless they are ALL_LAYER + continue + if(M.get_init_dirs() & SSmachines.get_init_dirs(pipe_type, dir)) // matches at least one direction on either type of pipe + to_chat(user, "There is already a pipe at that location!") + return TRUE // no conflicts found - var/pipefailtext = "There's nothing to connect this pipe section to!" //(with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)" - - //TODO: Move all of this stuff into the various pipe constructors. - switch(pipe_type) - if(PIPE_SIMPLE_STRAIGHT, PIPE_SIMPLE_BENT) - var/obj/machinery/atmospherics/pipe/simple/P = new( src.loc ) - P.pipe_color = color - P.set_dir(src.dir) - P.initialize_directions = pipe_dir - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - if (QDELETED(P)) - usr << pipefailtext - return 1 - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - - if(PIPE_SUPPLY_STRAIGHT, PIPE_SUPPLY_BENT) - var/obj/machinery/atmospherics/pipe/simple/hidden/supply/P = new( src.loc ) - P.pipe_color = color - P.set_dir(src.dir) - P.initialize_directions = pipe_dir - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - if (QDELETED(P)) - usr << pipefailtext - return 1 - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - - if(PIPE_SCRUBBERS_STRAIGHT, PIPE_SCRUBBERS_BENT) - var/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers/P = new( src.loc ) - P.pipe_color = color - P.set_dir(src.dir) - P.initialize_directions = pipe_dir - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - if (QDELETED(P)) - usr << pipefailtext - return 1 - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - - if(PIPE_UNIVERSAL) - var/obj/machinery/atmospherics/pipe/simple/hidden/universal/P = new( src.loc ) - P.pipe_color = color - P.set_dir(src.dir) - P.initialize_directions = pipe_dir - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - if (QDELETED(P)) - usr << pipefailtext - return 1 - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - - if(PIPE_HE_STRAIGHT, PIPE_HE_BENT) - var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/P = new ( src.loc ) - P.set_dir(src.dir) - P.initialize_directions = pipe_dir //this var it's used to know if the pipe is bent or not - P.initialize_directions_he = pipe_dir - P.atmos_init() - if (QDELETED(P)) - usr << pipefailtext - return 1 - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - - if(PIPE_CONNECTOR) // connector - var/obj/machinery/atmospherics/portables_connector/C = new( src.loc ) - C.set_dir(dir) - C.initialize_directions = pipe_dir - if (pipename) - C.name = pipename - var/turf/T = C.loc - C.level = !T.is_plating() ? 2 : 1 - C.atmos_init() - C.build_network() - if (C.node) - C.node.atmos_init() - C.node.build_network() - - - if(PIPE_MANIFOLD) //manifold - var/obj/machinery/atmospherics/pipe/manifold/M = new( src.loc ) - M.pipe_color = color - M.set_dir(dir) - M.initialize_directions = pipe_dir - //M.New() - var/turf/T = M.loc - M.level = !T.is_plating() ? 2 : 1 - M.atmos_init() - if (QDELETED(M)) - usr << pipefailtext - return 1 - M.build_network() - if (M.node1) - M.node1.atmos_init() - M.node1.build_network() - if (M.node2) - M.node2.atmos_init() - M.node2.build_network() - if (M.node3) - M.node3.atmos_init() - M.node3.build_network() - - if(PIPE_SUPPLY_MANIFOLD) //manifold - var/obj/machinery/atmospherics/pipe/manifold/hidden/supply/M = new( src.loc ) - M.pipe_color = color - M.set_dir(dir) - M.initialize_directions = pipe_dir - //M.New() - var/turf/T = M.loc - M.level = !T.is_plating() ? 2 : 1 - M.atmos_init() - if (!M) - usr << "There's nothing to connect this manifold to! (with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)" - return 1 - M.build_network() - if (M.node1) - M.node1.atmos_init() - M.node1.build_network() - if (M.node2) - M.node2.atmos_init() - M.node2.build_network() - if (M.node3) - M.node3.atmos_init() - M.node3.build_network() - - if(PIPE_SCRUBBERS_MANIFOLD) //manifold - var/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers/M = new( src.loc ) - M.pipe_color = color - M.set_dir(dir) - M.initialize_directions = pipe_dir - //M.New() - var/turf/T = M.loc - M.level = !T.is_plating() ? 2 : 1 - M.atmos_init() - if (!M) - usr << "There's nothing to connect this manifold to! (with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)" - return 1 - M.build_network() - if (M.node1) - M.node1.atmos_init() - M.node1.build_network() - if (M.node2) - M.node2.atmos_init() - M.node2.build_network() - if (M.node3) - M.node3.atmos_init() - M.node3.build_network() - M.node3.build_network() - - if(PIPE_MANIFOLD4W) //4-way manifold - var/obj/machinery/atmospherics/pipe/manifold4w/M = new( src.loc ) - M.pipe_color = color - M.set_dir(dir) - M.initialize_directions = pipe_dir - //M.New() - var/turf/T = M.loc - M.level = !T.is_plating() ? 2 : 1 - M.atmos_init() - if (QDELETED(M)) - usr << pipefailtext - return 1 - M.build_network() - if (M.node1) - M.node1.atmos_init() - M.node1.build_network() - if (M.node2) - M.node2.atmos_init() - M.node2.build_network() - if (M.node3) - M.node3.atmos_init() - M.node3.build_network() - if (M.node4) - M.node4.atmos_init() - M.node4.build_network() - - if(PIPE_SUPPLY_MANIFOLD4W) //4-way manifold - var/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply/M = new( src.loc ) - M.pipe_color = color - M.set_dir(dir) - M.initialize_directions = pipe_dir - M.connect_types = src.connect_types - //M.New() - var/turf/T = M.loc - M.level = !T.is_plating() ? 2 : 1 - M.atmos_init() - if (!M) - usr << "There's nothing to connect this manifold to! (with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)" - return 1 - M.build_network() - if (M.node1) - M.node1.atmos_init() - M.node1.build_network() - if (M.node2) - M.node2.atmos_init() - M.node2.build_network() - if (M.node3) - M.node3.atmos_init() - M.node3.build_network() - if (M.node4) - M.node4.atmos_init() - M.node4.build_network() - - if(PIPE_SCRUBBERS_MANIFOLD4W) //4-way manifold - var/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers/M = new( src.loc ) - M.pipe_color = color - M.set_dir(dir) - M.initialize_directions = pipe_dir - M.connect_types = src.connect_types - //M.New() - var/turf/T = M.loc - M.level = !T.is_plating() ? 2 : 1 - M.atmos_init() - if (!M) - usr << "There's nothing to connect this manifold to! (with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)" - return 1 - M.build_network() - if (M.node1) - M.node1.atmos_init() - M.node1.build_network() - if (M.node2) - M.node2.atmos_init() - M.node2.build_network() - if (M.node3) - M.node3.atmos_init() - M.node3.build_network() - if (M.node4) - M.node4.atmos_init() - M.node4.build_network() - - if(PIPE_JUNCTION) - var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/P = new ( src.loc ) - P.set_dir(src.dir) - P.initialize_directions = src.get_pdir() - P.initialize_directions_he = src.get_hdir() - P.atmos_init() - if (QDELETED(P)) - usr << pipefailtext //"There's nothing to connect this pipe to! (with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)" - return 1 - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - - if(PIPE_UVENT) //unary vent - var/obj/machinery/atmospherics/unary/vent_pump/V = new( src.loc ) - V.set_dir(dir) - V.initialize_directions = pipe_dir - if (pipename) - V.name = pipename - var/turf/T = V.loc - V.level = !T.is_plating() ? 2 : 1 - V.atmos_init() - V.build_network() - if (V.node) - V.node.atmos_init() - V.node.build_network() - - if(PIPE_MVALVE) //manual valve - var/obj/machinery/atmospherics/valve/V = new( src.loc) - V.set_dir(dir) - V.initialize_directions = pipe_dir - if (pipename) - V.name = pipename - var/turf/T = V.loc - V.level = !T.is_plating() ? 2 : 1 - V.atmos_init() - V.build_network() - if (V.node1) -// world << "[V.node1.name] is connected to valve, forcing it to update its nodes." - V.node1.atmos_init() - V.node1.build_network() - if (V.node2) -// world << "[V.node2.name] is connected to valve, forcing it to update its nodes." - V.node2.atmos_init() - V.node2.build_network() - - if(PIPE_PUMP) //gas pump - var/obj/machinery/atmospherics/binary/pump/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - - if(PIPE_GAS_FILTER) //gas filter - var/obj/machinery/atmospherics/trinary/atmos_filter/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - if (P.node3) - P.node3.atmos_init() - P.node3.build_network() - - if(PIPE_GAS_MIXER) //gas mixer - var/obj/machinery/atmospherics/trinary/mixer/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - if (P.node3) - P.node3.atmos_init() - P.node3.build_network() - - if(PIPE_GAS_FILTER_M) //gas filter mirrored - var/obj/machinery/atmospherics/trinary/atmos_filter/m_filter/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - if (P.node3) - P.node3.atmos_init() - P.node3.build_network() - - if(PIPE_GAS_MIXER_T) //gas mixer-t - var/obj/machinery/atmospherics/trinary/mixer/t_mixer/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - if (P.node3) - P.node3.atmos_init() - P.node3.build_network() - - if(PIPE_GAS_MIXER_M) //gas mixer mirrored - var/obj/machinery/atmospherics/trinary/mixer/m_mixer/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - if (P.node3) - P.node3.atmos_init() - P.node3.build_network() - - if(PIPE_SCRUBBER) //scrubber - var/obj/machinery/atmospherics/unary/vent_scrubber/S = new(src.loc) - S.set_dir(dir) - S.initialize_directions = pipe_dir - if (pipename) - S.name = pipename - var/turf/T = S.loc - S.level = !T.is_plating() ? 2 : 1 - S.atmos_init() - S.build_network() - if (S.node) - S.node.atmos_init() - S.node.build_network() - - if(PIPE_INSULATED_STRAIGHT, PIPE_INSULATED_BENT) - var/obj/machinery/atmospherics/pipe/simple/insulated/P = new( src.loc ) - P.set_dir(src.dir) - P.initialize_directions = pipe_dir - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - if (QDELETED(P)) - usr << pipefailtext - return 1 - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - - if(PIPE_MTVALVE) //manual t-valve - var/obj/machinery/atmospherics/tvalve/V = new(src.loc) - V.set_dir(dir) - V.initialize_directions = pipe_dir - if (pipename) - V.name = pipename - var/turf/T = V.loc - V.level = !T.is_plating() ? 2 : 1 - V.atmos_init() - V.build_network() - if (V.node1) - V.node1.atmos_init() - V.node1.build_network() - if (V.node2) - V.node2.atmos_init() - V.node2.build_network() - if (V.node3) - V.node3.atmos_init() - V.node3.build_network() - - if(PIPE_MTVALVEM) //manual t-valve - var/obj/machinery/atmospherics/tvalve/mirrored/V = new(src.loc) - V.set_dir(dir) - V.initialize_directions = pipe_dir - if (pipename) - V.name = pipename - var/turf/T = V.loc - V.level = !T.is_plating() ? 2 : 1 - V.atmos_init() - V.build_network() - if (V.node1) - V.node1.atmos_init() - V.node1.build_network() - if (V.node2) - V.node2.atmos_init() - V.node2.build_network() - if (V.node3) - V.node3.atmos_init() - V.node3.build_network() - - if(PIPE_CAP) - var/obj/machinery/atmospherics/pipe/cap/C = new(src.loc) - C.set_dir(dir) - C.initialize_directions = pipe_dir - C.atmos_init() - C.build_network() - if(C.node) - C.node.atmos_init() - C.node.build_network() - - if(PIPE_SUPPLY_CAP) - var/obj/machinery/atmospherics/pipe/cap/hidden/supply/C = new(src.loc) - C.set_dir(dir) - C.initialize_directions = pipe_dir - C.atmos_init() - C.build_network() - if(C.node) - C.node.atmos_init() - C.node.build_network() - - if(PIPE_SCRUBBERS_CAP) - var/obj/machinery/atmospherics/pipe/cap/hidden/scrubbers/C = new(src.loc) - C.set_dir(dir) - C.initialize_directions = pipe_dir - C.atmos_init() - C.build_network() - if(C.node) - C.node.atmos_init() - C.node.build_network() - - if(PIPE_PASSIVE_GATE) //passive gate - var/obj/machinery/atmospherics/binary/passive_gate/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - - if(PIPE_VOLUME_PUMP) //volume pump - var/obj/machinery/atmospherics/binary/pump/high_power/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - - if(PIPE_HEAT_EXCHANGE) // heat exchanger - var/obj/machinery/atmospherics/unary/heat_exchanger/C = new( src.loc ) - C.set_dir(dir) - C.initialize_directions = pipe_dir - if (pipename) - C.name = pipename - var/turf/T = C.loc - C.level = !T.is_plating() ? 2 : 1 - C.atmos_init() - C.build_network() - if (C.node) - C.node.atmos_init() - C.node.build_network() - - if(PIPE_DVALVE) //digital valve - var/obj/machinery/atmospherics/valve/digital/V = new( src.loc) - if(src.req_access) - V.req_access = src.req_access - if(src.req_one_access) - V.req_one_access = src.req_one_access - V.set_dir(dir) - V.initialize_directions = pipe_dir - if (pipename) - V.name = pipename - var/turf/T = V.loc - V.level = !T.is_plating() ? 2 : 1 - V.atmos_init() - V.build_network() - if (V.node1) - V.node1.atmos_init() - V.node1.build_network() - if (V.node2) - V.node2.atmos_init() - V.node2.build_network() - - if(PIPE_DTVALVE) //digital t-valve - var/obj/machinery/atmospherics/tvalve/digital/V = new(src.loc) - if(src.req_access) - V.req_access = src.req_access - if(src.req_one_access) - V.req_one_access = src.req_one_access - V.set_dir(dir) - V.initialize_directions = pipe_dir - if (pipename) - V.name = pipename - var/turf/T = V.loc - V.level = !T.is_plating() ? 2 : 1 - V.atmos_init() - V.build_network() - if (V.node1) - V.node1.atmos_init() - V.node1.build_network() - if (V.node2) - V.node2.atmos_init() - V.node2.build_network() - if (V.node3) - V.node3.atmos_init() - V.node3.build_network() - - if(PIPE_DTVALVEM) //mirrored digital t-valve - var/obj/machinery/atmospherics/tvalve/digital/mirrored/V = new(src.loc) - if(src.req_access) - V.req_access = src.req_access - if(src.req_one_access) - V.req_one_access = src.req_one_access - V.set_dir(dir) - V.initialize_directions = pipe_dir - if (pipename) - V.name = pipename - var/turf/T = V.loc - V.level = !T.is_plating() ? 2 : 1 - V.atmos_init() - V.build_network() - if (V.node1) - V.node1.atmos_init() - V.node1.build_network() - if (V.node2) - V.node2.atmos_init() - V.node2.build_network() - if (V.node3) - V.node3.atmos_init() - V.node3.build_network() - -///// Z-Level stuff - if(PIPE_UP) - var/obj/machinery/atmospherics/pipe/zpipe/up/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - if(PIPE_DOWN) - var/obj/machinery/atmospherics/pipe/zpipe/down/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - if(PIPE_SUPPLY_UP) - var/obj/machinery/atmospherics/pipe/zpipe/up/supply/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - if(PIPE_SUPPLY_DOWN) - var/obj/machinery/atmospherics/pipe/zpipe/down/supply/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - if(PIPE_SCRUBBERS_UP) - var/obj/machinery/atmospherics/pipe/zpipe/up/scrubbers/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() - if(PIPE_SCRUBBERS_DOWN) - var/obj/machinery/atmospherics/pipe/zpipe/down/scrubbers/P = new(src.loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - if (pipename) - P.name = pipename - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() - if (P.node2) - P.node2.atmos_init() - P.node2.build_network() -///// Z-Level stuff - if(PIPE_OMNI_MIXER) - var/obj/machinery/atmospherics/omni/mixer/P = new(loc) - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if(PIPE_OMNI_FILTER) - var/obj/machinery/atmospherics/omni/atmos_filter/P = new(loc) - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if(PIPE_PASSIVE_VENT) - var/obj/machinery/atmospherics/pipe/vent/P = new(loc) - P.set_dir(dir) - P.initialize_directions = pipe_dir - var/turf/T = P.loc - P.level = !T.is_plating() ? 2 : 1 - P.atmos_init() - P.build_network() - if (P.node1) - P.node1.atmos_init() - P.node1.build_network() + var/obj/machinery/atmospherics/A = new pipe_type(loc) + build_pipe(A) + // TODO - Evaluate and remove the "need at least one thing to connect to" thing ~Leshana + // With how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment. + if (QDELETED(A)) + to_chat(user, "There's nothing to connect this pipe section to!") + return TRUE + transfer_fingerprints_to(A) playsound(src, W.usesound, 50, 1) user.visible_message( \ - "[user] fastens the [src].", \ - "You have fastened the [src].", \ - "You hear ratchet.") - qdel(src) // remove the pipe item + "[user] fastens \the [src].", \ + "You fasten \the [src].", \ + "You hear ratcheting.") - return - //TODO: DEFERRED + qdel(src) -// ensure that setterm() is called for a newly connected pipeline +/obj/item/pipe/proc/build_pipe(obj/machinery/atmospherics/A) + A.set_dir(dir) + A.init_dir() + if(pipename) + A.name = pipename + if(req_access) + A.req_access = req_access + if(req_one_access) + A.req_one_access = req_one_access + A.on_construction(color, piping_layer) + +/obj/item/pipe/trinary/flippable/build_pipe(obj/machinery/atmospherics/trinary/T) + T.mirrored = mirrored + . = ..() + +// Lookup the initialize_directions for a given atmos machinery instance facing dir. +// TODO - Right now this determines the answer by instantiating an instance and checking! +// There has to be a better way... ~Leshana +/datum/controller/subsystem/machines/proc/get_init_dirs(type, dir) + var/static/list/pipe_init_dirs_cache = list() + if(!pipe_init_dirs_cache[type]) + pipe_init_dirs_cache[type] = list() + + if(!pipe_init_dirs_cache[type]["[dir]"]) + var/obj/machinery/atmospherics/temp = new type(null, FALSE, dir) + pipe_init_dirs_cache[type]["[dir]"] = temp.get_init_dirs() + qdel(temp) + + return pipe_init_dirs_cache[type]["[dir]"] + + +// +// Meters are special - not like any other pipes or components +// + /obj/item/pipe_meter name = "meter" - desc = "A meter that can be laid on pipes" + desc = "A meter that can be laid on pipes." icon = 'icons/obj/pipe-item.dmi' icon_state = "meter" item_state = "buildpipe" w_class = ITEMSIZE_LARGE + var/piping_layer = PIPING_LAYER_DEFAULT /obj/item/pipe_meter/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) - ..() + if(iswrench(W)) + return wrench_act(user, W) + return ..() - if (!istype(W, /obj/item/weapon/wrench)) - return ..() - if(!locate(/obj/machinery/atmospherics/pipe, src.loc)) - user << "You need to fasten it to a pipe" - return 1 - new/obj/machinery/meter( src.loc ) +/obj/item/pipe_meter/proc/wrench_act(var/mob/living/user, var/obj/item/weapon/wrench/W) + var/obj/machinery/atmospherics/pipe/pipe + for(var/obj/machinery/atmospherics/pipe/P in loc) + if(P.piping_layer == piping_layer) + pipe = P + break + if(!pipe) + to_chat(user, "You need to fasten it to a pipe!") + return TRUE + new /obj/machinery/meter(loc, piping_layer) playsound(src, W.usesound, 50, 1) - user << "You have fastened the meter to the pipe" + to_chat(user, "You fasten the meter to the pipe.") qdel(src) -//not sure why these are necessary -#undef PIPE_SIMPLE_STRAIGHT -#undef PIPE_SIMPLE_BENT -#undef PIPE_HE_STRAIGHT -#undef PIPE_HE_BENT -#undef PIPE_CONNECTOR -#undef PIPE_MANIFOLD -#undef PIPE_JUNCTION -#undef PIPE_UVENT -#undef PIPE_MVALVE -#undef PIPE_PUMP -#undef PIPE_SCRUBBER -#undef PIPE_INSULATED_STRAIGHT -#undef PIPE_INSULATED_BENT -#undef PIPE_GAS_FILTER -#undef PIPE_GAS_MIXER -#undef PIPE_PASSIVE_GATE -#undef PIPE_VOLUME_PUMP -#undef PIPE_OUTLET_INJECT -#undef PIPE_MTVALVE -#undef PIPE_MTVALVEM -#undef PIPE_GAS_FILTER_M -#undef PIPE_GAS_MIXER_T -#undef PIPE_GAS_MIXER_M -#undef PIPE_SUPPLY_STRAIGHT -#undef PIPE_SUPPLY_BENT -#undef PIPE_SCRUBBERS_STRAIGHT -#undef PIPE_SCRUBBERS_BENT -#undef PIPE_SUPPLY_MANIFOLD -#undef PIPE_SCRUBBERS_MANIFOLD -#undef PIPE_UNIVERSAL -//#undef PIPE_MANIFOLD4W + +/obj/item/pipe_meter/dropped() + . = ..() + if(loc) + setAttachLayer(piping_layer) + +/obj/item/pipe_meter/proc/setAttachLayer(new_layer = PIPING_LAYER_DEFAULT) + piping_layer = new_layer diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm index 8bc779adf3..6675a5ca15 100644 --- a/code/game/machinery/pipe/pipe_dispenser.dm +++ b/code/game/machinery/pipe/pipe_dispenser.dm @@ -6,74 +6,32 @@ anchored = 1 var/unwrenched = 0 var/wait = 0 + var/p_layer = PIPING_LAYER_REGULAR -/obj/machinery/pipedispenser/attack_hand(user as mob) - if(..()) +// TODO - Its about time to make this NanoUI don't we think? +/obj/machinery/pipedispenser/attack_hand(var/mob/user as mob) + if((. = ..())) return -///// Z-Level stuff - var/dat = {" -Regular pipes:
-Pipe
-Bent Pipe
-Manifold
-Digital Valve
-Manual Valve
-Pipe Cap
-4-Way Manifold
-Digital T-Valve
-Digital T-Valve - Mirrored
-Manual T-Valve
-Manual T-Valve - Mirrored
-Upward Pipe
-Downward Pipe
-Supply pipes:
-Pipe
-Bent Pipe
-Manifold
-Pipe Cap
-4-Way Manifold
-Upward Pipe
-Downward Pipe
-Scrubbers pipes:
-Pipe
-Bent Pipe
-Manifold
-Pipe Cap
-4-Way Manifold
-Upward Pipe
-Downward Pipe
-Devices:
-Universal pipe adapter
-Connector
-Unary Vent
-Passive Vent
-Gas Pump
-Pressure Regulator
-High Power Gas Pump
-Scrubber
-Meter
-Gas Filter
-Gas Filter - Mirrored
-Gas Mixer
-Gas Mixer - Mirrored
-Gas Mixer - T
-Omni Gas Mixer
-Omni Gas Filter
-Heat exchange:
-Pipe
-Bent Pipe
-Junction
-Heat Exchanger
-Insulated pipes:
-Pipe
-Bent Pipe
+ src.interact(user) -"} -///// Z-Level stuff -//What number the make points to is in the define # at the top of construction.dm in same folder +/obj/machinery/pipedispenser/interact(mob/user) + user.set_machine(src) - user << browse("[src][dat]", "window=pipedispenser") - onclose(user, "pipedispenser") + var/list/lines = list() + for(var/category in atmos_pipe_recipes) + lines += "[category]:
" + if(category == "Pipes") + // Stupid hack. Fix someday. So tired right now. + lines += "Regular " + lines += "Supply " + lines += "Scrubber " + lines += "
" + for(var/datum/pipe_recipe/PI in atmos_pipe_recipes[category]) + lines += PI.Render(src) + var/dat = lines.Join() + var/datum/browser/popup = new(user, "pipedispenser", name, 300, 800, src) + popup.set_content("[dat]") + popup.open() return /obj/machinery/pipedispenser/Topic(href, href_list) @@ -81,20 +39,27 @@ return if(unwrenched || !usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) usr << browse(null, "window=pipedispenser") + usr.unset_machine(src) return usr.set_machine(src) src.add_fingerprint(usr) - if(href_list["make"]) + if(href_list["setlayer"]) + var/new_pipe_layer = text2num(href_list["setlayer"]) + if(isnum(new_pipe_layer)) + p_layer = new_pipe_layer + updateDialog() + else if(href_list["makepipe"]) if(!wait) - var/p_type = text2num(href_list["make"]) + var/obj/machinery/atmospherics/p_type = text2path(href_list["makepipe"]) var/p_dir = text2num(href_list["dir"]) - var/obj/item/pipe/P = new (/*usr.loc*/ src.loc, pipe_type=p_type, dir=p_dir) - P.update() + var/pi_type = initial(p_type.construction_type) + var/obj/item/pipe/P = new pi_type(src.loc, p_type, p_dir) + P.setPipingLayer(p_layer) P.add_fingerprint(usr) wait = 1 spawn(10) wait = 0 - if(href_list["makemeter"]) + else if(href_list["makemeter"]) if(!wait) new /obj/item/pipe_meter(/*usr.loc*/ src.loc) wait = 1 diff --git a/code/game/machinery/pipe/pipe_recipes.dm b/code/game/machinery/pipe/pipe_recipes.dm new file mode 100644 index 0000000000..f0ae483055 --- /dev/null +++ b/code/game/machinery/pipe/pipe_recipes.dm @@ -0,0 +1,102 @@ +// +// Recipies for Pipe Dispenser and (someday) the RPD +// + +var/global/list/atmos_pipe_recipes = null + +/hook/startup/proc/init_pipe_recipes() + global.atmos_pipe_recipes = list( + "Pipes" = list( + new /datum/pipe_recipe/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple), + new /datum/pipe_recipe/pipe("Manifold", /obj/machinery/atmospherics/pipe/manifold), + new /datum/pipe_recipe/pipe("Manual Valve", /obj/machinery/atmospherics/valve), + new /datum/pipe_recipe/pipe("Digital Valve", /obj/machinery/atmospherics/valve/digital), + new /datum/pipe_recipe/pipe("Pipe cap", /obj/machinery/atmospherics/pipe/cap), + new /datum/pipe_recipe/pipe("4-Way Manifold", /obj/machinery/atmospherics/pipe/manifold4w), + new /datum/pipe_recipe/pipe("Manual T-Valve", /obj/machinery/atmospherics/tvalve), + new /datum/pipe_recipe/pipe("Digital T-Valve", /obj/machinery/atmospherics/tvalve/digital), + new /datum/pipe_recipe/pipe("Upward Pipe", /obj/machinery/atmospherics/pipe/zpipe/up), + new /datum/pipe_recipe/pipe("Downward Pipe", /obj/machinery/atmospherics/pipe/zpipe/down), + new /datum/pipe_recipe/pipe("Universal Pipe Adaptor", /obj/machinery/atmospherics/pipe/simple/visible/universal), + ), + "Devices" = list( + new /datum/pipe_recipe/pipe("Connector", /obj/machinery/atmospherics/portables_connector), + new /datum/pipe_recipe/pipe("Unary Vent", /obj/machinery/atmospherics/unary/vent_pump), + new /datum/pipe_recipe/pipe("Passive Vent", /obj/machinery/atmospherics/pipe/vent), + new /datum/pipe_recipe/pipe("Injector", /obj/machinery/atmospherics/unary/outlet_injector), + new /datum/pipe_recipe/pipe("Gas Pump", /obj/machinery/atmospherics/binary/pump), + new /datum/pipe_recipe/pipe("Pressure Regulator", /obj/machinery/atmospherics/binary/passive_gate), + new /datum/pipe_recipe/pipe("High Power Gas Pump",/obj/machinery/atmospherics/binary/pump/high_power), + new /datum/pipe_recipe/pipe("Scrubber", /obj/machinery/atmospherics/unary/vent_scrubber), + new /datum/pipe_recipe/meter("Meter"), + new /datum/pipe_recipe/pipe("Gas Filter", /obj/machinery/atmospherics/trinary/atmos_filter), + new /datum/pipe_recipe/pipe("Gas Mixer", /obj/machinery/atmospherics/trinary/mixer), + new /datum/pipe_recipe/pipe("Gas Mixer 'T'", /obj/machinery/atmospherics/trinary/mixer/t_mixer), + new /datum/pipe_recipe/pipe("Omni Gas Mixer", /obj/machinery/atmospherics/omni/mixer), + new /datum/pipe_recipe/pipe("Omni Gas Filter", /obj/machinery/atmospherics/omni/atmos_filter), + ), + "Heat Exchange" = list( + new /datum/pipe_recipe/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple/heat_exchanging), + new /datum/pipe_recipe/pipe("Junction", /obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction), + new /datum/pipe_recipe/pipe("Heat Exchanger", /obj/machinery/atmospherics/unary/heat_exchanger), + ), + "Insulated pipes" = list( + new /datum/pipe_recipe/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple/insulated), + ) + ) + return TRUE + +// +// New method of handling pipe construction. Instead of numeric constants and a giant switch statement of doom +// every pipe type has a datum instance which describes its name, placement rules and construction method, dispensing etc. +// The advantages are obvious, mostly in simplifying the code of the dispenser, and the ability to add new pipes without hassle. +// +/datum/pipe_recipe + var/name = "Abstract Pipe (fixme)" // Recipe name + var/dirtype // If using an RPD, this tells more about what previews to show. + +// Render an HTML link to select this pipe type. Returns text. +/datum/pipe_recipe/proc/Render(dispenser) + return "[name]
" + +// Parameters for the Topic link returned by Render(). Returns text. +/datum/pipe_recipe/proc/Params() + return "" + +// +// Subtype for actual pipes +// +/datum/pipe_recipe/pipe + var/obj/item/pipe/construction_type // The type PATH to the type of pipe fitting object the recipe makes. + var/obj/machinery/atmospherics/pipe_type // The type PATH of what actual pipe the fitting becomes. + +/datum/pipe_recipe/pipe/New(var/label, var/obj/machinery/atmospherics/path) + name = label + pipe_type = path + construction_type = initial(path.construction_type) + dirtype = initial(construction_type.dispenser_class) + +// Render an HTML link to select this pipe type +/datum/pipe_recipe/pipe/Render(dispenser) + var/dat = ..(dispenser) + // Stationary pipe dispensers don't allow you to pre-select pipe directions. + // This makes it impossble to spawn bent versions of bendable pipes. + // We add a "Bent" pipe type with a preset diagonal direction to work around it. + if(istype(dispenser, /obj/machinery/pipedispenser) && (dirtype == PIPE_BENDABLE)) + dat += "Bent [name]
" + return dat + +/datum/pipe_recipe/pipe/Params() + return "makepipe=[pipe_type]" + +// +// Subtype for meters +// +/datum/pipe_recipe/meter + dirtype = PIPE_ONEDIR + +/datum/pipe_recipe/meter/New(label) + name = label + +/datum/pipe_recipe/meter/Params() + return "makemeter=1" diff --git a/code/modules/multiz/pipes.dm b/code/modules/multiz/pipes.dm index 62b62e3fca..2f6e1e8dde 100644 --- a/code/modules/multiz/pipes.dm +++ b/code/modules/multiz/pipes.dm @@ -13,6 +13,9 @@ obj/machinery/atmospherics/pipe/zpipe dir = SOUTH initialize_directions = SOUTH + construction_type = /obj/item/pipe/directional + pipe_state = "cap" + // node1 is the connection on the same Z // node2 is the connection on the other Z @@ -135,16 +138,15 @@ obj/machinery/atmospherics/pipe/zpipe/up/atmos_init() node1_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 + if(can_be_node(target, 1)) + node1 = target + break var/turf/above = GetAbove(src) if(above) for(var/obj/machinery/atmospherics/target in above) - if(target.initialize_directions && istype(target, /obj/machinery/atmospherics/pipe/zpipe/down)) - if (check_connect_types(target,src)) + if(istype(target, /obj/machinery/atmospherics/pipe/zpipe/down)) + if (check_connectable(target) && target.check_connectable(src)) node2 = target break @@ -173,16 +175,15 @@ obj/machinery/atmospherics/pipe/zpipe/down/atmos_init() node1_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 + if(can_be_node(target, 1)) + node1 = target + break var/turf/below = GetBelow(src) if(below) for(var/obj/machinery/atmospherics/target in below) - if(target.initialize_directions && istype(target, /obj/machinery/atmospherics/pipe/zpipe/up)) - if (check_connect_types(target,src)) + if(istype(target, /obj/machinery/atmospherics/pipe/zpipe/up)) + if (check_connectable(target) && target.check_connectable(src)) node2 = target break diff --git a/icons/atmos/heat.dmi b/icons/atmos/heat.dmi index 1014c2015b0530e63190c50fd363fdf51ae96873..8ac9682df1fc22724689d99290d1f2c2c81225eb 100644 GIT binary patch delta 1503 zcmV<51t9v{CB+O)iBL{Q4GJ0x0000DNk~Le0002s0002M1Oos70PnAINpnuNy>HH%&j&%lxf=rs-w=SpblESma@E{7ES6#ufpT za@e;CiKYYoaR%x2^P1G;{;9#C9$OugXa=-*V>-QffF&I2`SI=VdhOQ?s9pixkj{Yg zkd}DZ55`A$XX`GxA!PxUaM;i8KoW=ff_vWN$8vdT>Tqc8e;pzc$JxJwfF&HxQ%KJw zx@*7PpwR72IuA|f9_FQ7Db(WwUHs)7&OdskP!YRL1r8S<1BDL(V2Ppar^If+YXV|n zW)@Hwmwv&JUJ9_}25AS_J^BNH#56eH!`gcB3po5=0FfOU1N0kxy79vZ0NmGs2kgfn z7@&`2(#R&#e;RZ2A8QXh%A!3?#1bg`HahZ5w%W9SL%NnBZEO3r?3#pkf5bfj`Rbs`v_|A0DEmS5L+HnJ z|GNr+$d-%dVXMMCcTAvPj+$g1HXFUzCjPBu*TF|K*qc|xF(one2U$y>Dqc)M*|%us zyPI`hqF?_=4%H5U;H_+wy{Jk|z8^04mftT0Y?l_zd4TK@`8+^wSXo;yvKw4~NG}IS z0mv7EfA0gl_2TDq_)fsx9sbce;h*o@cu=JuHW83p^gaN?% zu*G?nUL-yAai{`uXn4iFUep4;nD@}!8%Nq2_SQ&|V!c?%VX7rGs9T6A){9LUhlyGm zK$RVUV!c?#VWJ216VxsBYNHor93~z>-(CGie=o}BVWR05gJe8a!m)H7CSNU52j^~< z>ct`sv-v$lFN!%_R+3~$gI=^tYNX%9^Kj;`jR7?zuwm%MA`a)3QY9S1PHKi;q&dty zfHLt0{0)HHuT5_SZ0(1T^8mLWeu%rJap~n>n$FxihdO)Z>VR*z3NJ}rz^?6*A?|oX zf6N7}J_5I1Jm15Q0Q3=z4v|a(X!DCp{ek=#qf3qgDqF%!e+P|wdV25SS}5PKL$ zX={FQspsbxQxA!}Mb-SGy(461oQIptjL$FHdS-rc>tP>qPmaTlUi7&mThGfcZaDnnN4=Ijlj+q=%Z(+e(%=C~t4@%8bHiyJY zLas#Ic}T65s%Wj{aft2)pr`x03GXeHZJ_M-H(-6hcOLJo(m>kbFW~TOz{?w@2j~Ak zkTTn-A*?>cw_ZHo!;b*W?$q!B2hXGK;w7=jo?f(-486FEhn)iJ1?N%o_D;Q+e>M6f z-{JG9JAl+##pCBuvqqlA6r4xR1HMx)=8W>7i2p)|i3TLFhsy~y@ZnqN$YE3#)6P?%rjdnn8=##X?gR4*R!P?TSc z0So3~!CHx~wMRS@?k&PDHLk FV1j%;-4y@; delta 4750 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 NT)Aw4BpYHQ{|BhE0IC20 diff --git a/icons/atmos/junction.dmi b/icons/atmos/junction.dmi index 892f5823f2e512291e3bb0a5c4a49afb33370d74..36704e0e4780669b0e37d20e0e8aef23d604795a 100644 GIT binary patch delta 808 zcmV+@1K0fT6_N*8iBL{Q4GJ0x0000DNk~Le0001>0001h1Oos70Det>C;$Ke8&FJC zMF0Q*s;a8n+uQ#B{{R2~{{R3~R8%oBF#rGn@x!$v00001bW%=J06^y0W&i*Hg^?wA ze?+UqX{NG*tDg(l+Wg0a0$;jg&JGs} z+)mOyX_OzXK*lG%YQVS0_h$mQuO5dAf85oh!GfzF36#L%z?zp;tyXm-p0e&s9o@4O zgW8bx>T3PE3NAaWp+&`@{x{o-p=N+oT+x0w-&;Io+WiQUl$zjFo;rw7x zH3(*9x~S1pDa~Oy`4yu!jcO18r{CQi0-!$46VPoAZ;ietSObvUhk0)(VYV7J@O&CmqEQpK1823pg#7!4C+^4 z0$^l51og=s!f+G`gi5|BkqQ7RyAMoRZ1hNQ$u?kQ9(1@5V;wFOX#NjAe+)?U809rC1KztAC1#=h8B;NJu7c`~^}&S{6iR=%Ci0lsrMu^UX0iyeZKB9YD{yau^-~64r m50med^m{q^(`MDGf241VZWdl7Swj2(0000zi-<}7RSGGoD1S22qIvcWQ&8K z9B!-d3AXc67qklp@HWO>d1_L|g?(KbU3o={HINjF3O50q0BM5&#+_2Ru%Le+ z01tr+dvi%NSJ=ahM*J}|oZ)cD`2d1Vf05!F&OAQ8d3<~X6c`K!WIP^|>2ylQ<1rZw z21I2)qOzvbX)Hr_*^|wJ?FM-4;uWCbcm-%UPALE(gvcy=@^MN5TCG+~X4#XEQwreG zk5_<(vuL{kb;D%*VPj)M`z6jRfJO#`0SUv<=>Bypfinsa1OWzv0SSUYXt`|If5D$j zCK!!I+V&j;0Xm%y!Z6gX1kNZxr_-7F3tV(e*7~ww6^{;n(jXB+NY+dxZ9ToLbUK|_ z(RC?-(oX0BcRHQS1J*^FX`M_ai32_y4vn^lZyW6kwp}JH0Kb17$LNFw*x1-;C3Q59 zO2-s++LGGT>2!=*BD!xK4yO|ee*k<}0wCGktDY4_eFlD@CzA;PXtw~oEL{rbi~<13 zN&plyiMl$H4m1kD^(K#3 zNQ0_254Y`uq_xR(BoHV!#sT1ak|lq}kH_QqleFG+qG**Y0EO)<6CV@DDeMEVT1~Za zG#Y^qfwJqH20KkPwSV3F6jlIgW(R`->2x}|%T2}hrAQW^5YlkG0yG@201d}0K*Nzz z0H2p%Kcp1E=jGQAe+g(fe_jDR?oriHu!}gA5o7~ax%g18$Z~ltRl{Eb1mN$4$}U$K zuK*3lD}V%bjDvUukf4rn5U&6Y$16a?$(;rgfB-;C@)-iv-+7856BF6k*k}pI0SG`u z2a^uIr(9&}6AXt#00I`E1+?gZiYNg)_;ot_>sp^c$O4EeL0tzQf2ePL0;TKvvZGm6U??vwLXEA4*<+tg7q-OWHP~j7-4lg^MQKSClK}lcvvNPdASpIo$UTxp|14_ zl`AhfJKH z2);hSJSz1GRDFP%f5BhB^o*%5U|I=$eS&$)s82v4g!zPFNP-|BVHlDy3}@D9mkeK@ zKu3F$ZdZ$1fW$K&+;^rdfoO=6PJdjq1VvyU%FQYvm*fM8?0@der)NL?u;1yn1in6j zI5PDKXq!du2FA1i1WfcRsXoA8f*=kI>9hpCK0!W4>Ju<$e>2@N3BxdVS(g>4;%noo zY5`QpO$ccr`I;~CyCwvOT*qewH5`#yKx;S~^Os%rR2Xjo8je#6P{+J{+c>2FbsTq0!UEDe>j9!fQI80py4b6;*Tf!=~nfToe{-x0Fk82rX^dthD?0`N~{1`@pF^! zuXlx7*9V{jYUBO&u2Adx0D0GqO1!y}!Pf_vZJTO+06@|Qpy+&my$hDaWPJdNYG10> z2cQW10CdN!kS1ZOJ^+A1zJr$f03tqssrT2rgo*k9f0UwqsahXE*at{zq>lI3ce`EX zGsf1tgLTWN{jXvLv{eX^oj;m-1UZko)dv8+TNc&+RH+X@k%|LQY|R4dSRa6*+HS4& z0c^a#UKC#+pm=+d##cHHQ2P7pQN4M%Z6749O)8PV_{X;1UoX=(UmqYFnfd_qBjf{6 zY-+i$e-Dt4N_~KtI6#%5W|o#h$y;tJvSaBJLK==&fQI80py7B0XgE$OKppe)ZR3;z z)G;sLHqJgAY7_qEjSJK0G`s>R;_{%gSU-p`3<(p(6KPKzhyTOUDSo*1)6B|#zmHz8 zH}|8o??3+c82>xF0f{zb%1@G&CR;>)uh*OLe{1^vKJw(tU|j(=w^j+;0enaG`+X^; z7~Yx>X>b0%is!$*!J}U<{;scwG6OC`zWn_NkG9%)z8_&d{G(C%%iPL8{l1D9`>(ON z^$T9?zeX6Y$MUT!Ko-5%e_!bT^3Q43Htlws^m;uU930^0&6{}q_%V)-j&k?Cva*7w ze@~y{)2B~ZTU$fF-$xWh(*2=R{=BA!-Me>2_FriWpvc@c`o@hLI6Xa8 zx!%X@?CjJs#$a6msFTAF&d$zG>Th;;e|HNxLcCL^s2HivV3yODhOOhT>@;w9cQa4Sv7hkGEm}=Q%z;PTfZshH?G| zd;FsNX1}v;0fHbPWqQLbs+R*%`8=BylrNP*Vj}o)cz8&tH+=8jJscbyD0|~;e`{;_ z@Zp29H%{eWyLJs%u3W*lZ{I+p%L@w&I6FJT($W&9(+l5}5E5_q`SWM!l3(WWFUmX* z;Bwk^QO?fJ5JgcdiXz;;eY^4!EP&yx;JNE<7JOu^X(R;3 z3OS>*uYk{aHqb;GG&`WWy>S)ze>UVfbS7n^gyWaC0D#^ngZMMrc5IxNpZB~T-KH!B z)E63$@aWezTGQ!N$)py2HZXo78Ox;1*!aIO+X2sii?F`#hJ4Y`c)Q)k{rmUP?RK%U zvXbcx3R?g`@6*B5g6!?>5dd*R$Kx^HzkiP?iU2^$Bc|bGnGT>N$yfEpe_fKl$eQso z>jT($vbYTBOyT6@gnlLDjX!zv1khl8WaV480GnH@PI~n(_TLD5<0|mJz~b5WT z-zfVbQgHwlT|PisW6SCQK-;|mWqBebDBKKLq46wvm74`n5(Xg`Q6&%=fIJ1v8<0zK zok14Uq2VO?*5d%|CBS%WfBatn{>I2w8~~X_mGOA2>0X^7i&N?Eu1dz{$zU(%rjv&qVjjcfj__Hje&r1pJu&yEOUiHg!r=k%|MD zD7-+YffQY5KmtY*MQqEzd~>@p*6#)uJ%HhGs5Lgu!w*iD(>xpwf2-h(N*({A?Ynz- z?%aw0H|>olgjJ;#B0=G1Q1!->5J^^X3uBLK6vmTS3WMXm4p;yG#W|W8%WFGP5WQ>@zeh+VF5(8Gw~3o z40-Z-3m`KHI^-uHbo|y8ATJJJ${QA??((fGz~SLxt_3jV4U1A|`TqwK-#>Lnuo(*g O00005|Nk9BKtV(WX+{aCv>;Lglu%-zw4`(i(kQZvfpm$$n;3{lNp}ewHM+YT z64KqHzSqyczsK)9_Sj=PyXSS!>visV#@WelSl}WoiXQZ*AOis4M{7A20ATmu>KJ$^ zTDx1i*}wL%cX0*)pXBhbz0QroRQTR?ZG+dpNsX@6?uowVq29Wp`^3cItDNpE>A`_C zuKAOBkH~;#DrU1(Hn4Yp)P_8FJ+p^_^9{LxSYc?5)U#f$vaNGHeXfC*^POBJ7N2g} zM6X%B)&uor11JRE4Gq(LZJ`k0cNyd3nvf1m^s9>Qwj8*t@=>CWf-PoH{dcf=$CAMh z9y%`TPn=^m)}kQ>V4$pst*Y0J^6%94Se0>kHxb5`u~1Ke9kaRxO9%EQ2B~#ca+fQv z;|fyrTBBOjA=ag(673ez@mxGvjg?c}@eA)3@?_L#0zUZV%xqSO@rp3yTUnMRnvzA= zDDq3RnizJ(_1t#*Ew!@Iy4r4A=jmZ~b~%y7n(A4?hi<8J-=@Dszw^z@r-$Th^J5ky z436AO4PXc(u=Mh))ro^6vyvZp$KK||G4C33`f}E4KK_TMB>f-2vwdo1T(1`*@amZ?MHshwbxEAn>Om&UX z>FRA?kR150LVmhg(=Ur~K~&|aR-r-2$0nt=Td7LbPoI}CeTxxNkR-;kXj+5!$a&Gc zlfBEUy$|0lMWwgivjz>-aCiLZ#-zUyr>sR86*;dDYCWwm**8`j_P)VO052xK2;Pir zRatklDr%S3(9qzcz0xOk6>4pZyQlYoyh5;0Uqd2(>`!SjEtPz z^O{^zmsOYbmnYo9;^GTWXv0_+ds9cJhP=O@>djr9^)5N<=#Ol%_%Ahe^y)!-Sa()a z)6t2(*`Eva1;$0%V~hPuywF_jW_`>`XsLm2r<{~jh=){oY%HC9we{%7OT7I2{Oq^D z(3cJlsy_?AD0Vw_HLayEIJV46DyBa}BgRe;;mX&;m5ZyZ@Aw^bIgHy7CnqOQON}^o zeo~KZ98bnj&ol;5rrY);H%M>(N>3`jyw+m^<<+*}W?*8XWNFFO_(#|ubFS+JudJv5 z){L_$=>>I^yyM46X%T?lt`(u(#s@U}<#Qdk@jR~Dm>TH&{kx~IGu{k+XPC~6#3m{^ z`}lBg?`z(*B{N{II-!ms?-aLjMxNJ+bs->4;%^R;&Er$od5!p$b+P5;bi2E|rw?;< zLJ*TabxL!7OEU^o;6Z}*vEjVdodpCdtCDC!GYB5vMw^+$vQ7HPD!wo>0tNQh`8>Nm zdQyg5cUxom{Q2|IgW^+MkCQdmf=6-C;;LQ^g)TWir|-q#4>;i8(}VhTb}%XP@;Ne9 zMVLX6oyI@Y9?IG7yveSjtZa*}UQFY0n$`@qeR22bcrkVRXxlPXtt_BV0BzQ>Gtr-1qj86d9S%Uv(s z3_sER?!q!jlkU>|3WtEl=ofO*P%NRnXPYmp?7`my=c_K@>C32?=3kxkT&d+L?qFkLHbKhtf%+i#VaTgCm$-nDMfQc!?r|SKfan7Be z12#hh*tu+k-fN>~Hl}M;iByJa^U%J_h)<10jMZKEdme92Rcm|j8?JXQeM4cStlysL z?rZ1J%0++%dWOfKi76gDUl2Mv?Vt;bh~T^x%8}H)!gE#kryOw<>*hBnE{u%)No_Q!Mch|N(?e3Yr+)VNCn;1F&|5mf=&F)`2P=*ch%E^he$Z}|0OnFQm0Ish-RaDR+ zwye1eGc@Pw7XrZHCZSU1HzGJrc^bL-Ji46Js(d~p<2Hcn>Y@^oE}GP5yb^H45L6{+ zetrY!DI;Z*Lp$a6KKiXFVA)MrS&)cBjJ0QHKS%4Kwrdji&l1a@s}4(8h!Y;o9}a`M zKL+i&W1gn);)8dm*S$BxCdAKMbXyw;QX1#*)9OzEb!B)Jc2 z>+HVhH|-bN8k7z0?1&;ktlK4WYL+dX3*3A7zvqu%NXYW2v{wh?pU%}NDy>C54>(XI zUS5;4;0_W|9HO+MZtGoj8ICt2V{!_!-r2GK@%)ZmBL1;X9e0Adg@*@iVkSqdD#x4S zk}M*s#I_YU5VdiK{c2oKz?B2;BDin7_?1m&$UO z`P;WI;=?p#5R@#{TKHogdFxntH$dEfoYF4#$^@k!aI{-&X(#?Pa5bQwe#``XFt(I| zq}0S^(IZoLLZi0 z_TdrrH`U^|unrSiU!f&mrSdq!tF!j@cK;}m(&RRfE~iP$gl77ikWvLVCwuRLc86rP zU3_lg3-ooNy8z5^K)BItjjizs_xGe=#&G2~HjnSCz5$+M>-Tdp=jZ7BtSs`gv$Ow_ zlA88cM@5jx4Z~xIA|0O{c}NNPk!4@f3NWb4+x9W0Bqdo|U2Up%Ulf**2xOLUrajxp zulx-<5EtUjOxMNzgkFC?EzdJsFWM$AjLC1`!=Q+n16LTCnPc>T4*T~}@N5wtUS2rV zn2KUF0~W-$R~8P92rj3B7xVL0?9or`jEsz=nzV&Ru@kQ?g{L~N02-vZ3LhHSD=I2{ zY8)6BM(Q0E2rfDunpJ^>Q9|}+i!lWrgvNeLOM{_wfi~C>d!cDvBatYTA_qno3))Uz z)Q;|*;Wu|q@;4;dQbFtyUhBQdnbiGuf>ahf|1~l= z*tCz3L+6#1u_(}x7ONRr0{wQh>+9=w_Vx-8Ehi=>CL@K^IHQA5Sa9g}9K{FryBrvl zNZx+ch8F=X+OMLA9D^-l8F{l{rE5S#Be-5~wL7_9in(aEV9DkVhN zre$Mq1)jMLOR_~eLU%cSm%@zJ7^I1870;@9uft=>KwqeL9Nux9!;;0qr}~lofGpq< z?9c1}^glQ<=D@W;kq;JK_S`p$&oDn>9*&%((iJ8_u|_%8YOYaeP0}4BGv%Ce{w!Xy z<9tn>Yl)fLo}P!va4iws!h9oNd4TzYt2Mc~YEpEyxw)O9-s*R9E+zLUXopll1$Obf z_pdhZ-@}Y+JT7n69kP*;k!{UI%FW`#nNOt;u*^sKnxGE7)2rzh_%h124xqQU*Ak7c zx2qj@>F8dyIDqCNPUj#=Hl1TEwjgyATZknPIW5*}wfMH^3!%4>tnG`228HgN7gYqJ zqGy_YqKjoJ%2JZd+}2+=yX?WMxKI=0sD=>Lk_Fww!1@7ozq{0Z&LUB&1^)t#7ML_` zfm_0C$aj2a=YN_4Po*mgW1u<-gOO{wGA@k@qYb)fh23GV(bmC+E9}@Gam^ zMZNZkNQWCRT*UX#oy2shete35xOigY0a{RXBmR75hJCHk1G0FPL6$h`8X57kpaTdC+SmYW#RaOmq-kT0O3#Qh`|)Dj2rUdZoBe%#||DEDRwK zy{hP5=?D-ZXjZz;^L;luU@BxX43%A4TAI0+U&N&ERy$d&w+A9*-~M>_tM7Psv0RJq z)1x%pU?|=~q^q}g64{3uI-T3D8W|db`u!z-`@kV?iGE`4;1IG}I+3Z`mQ^KpzmbxX z@(K4124?2R>@+wW&i@t_+4jmX3O{Qn7GfuMMc(Yd@8n=xkQ!gu*;&JcJn5<^Jv00| z0AamFF@p_gV*@NDjX63x4m2=X98C-OS*Y3h(aLKpK>lmj~?cd#(|%2nfvpFTtM%2me&^%-OWM%4w?K zgM-lfsN{$5M@IDW^7Atf9wnLlGYP7q!2zG`S*895mYs@gXqf6I$&MN!!b7T? zV0nOzN8udL;yZ;zre(To>vZ;oOn*_xBaI{>9BsD}r6JCIyw*1`@Zs}kGEx#424?fs z0#H>N5~95#b*6JSz<^(m*1nM{$pDn5uPoiPv9*ovw()$s*n@ctxe8=z>+WJN3=j|y z7*Jx}fTZ)h;@BHli;0GX+QLwdw$ILda6zUAWF(Nme5t+Z<2HHzl4AX7430$ng%Yyb z<1#NQxoAkMpFWaT*&K$;(3D$PwEhbO4@7x3Fud$hSuiNiEbJ(??R^c-w_P8NFk2-; zetKS3y1_h(F!&A`nWdRZ0zA5gKq~tB)()vFaw6&~U|i$px#ct8ew@U2Eza7Qp(X`ql46Q=NTUR#UtOV`m}P0 z`#sm>PH{#dHfjIi1Cp)8-5ziy44>+_j~?Z_sE8))c~apV{ajN%h9G?jY%)H$N|D+o z7J#z#Dx>~DNb6i8!=;kq;y(^msShbSI9*G|^8~N7sOx+Bs;H1ds$1eHLlKt1L4EYX zBp!^2ptcfaOp(>TeWlF+J!f7!J>z>fb~YcOcksMukiL?c+#l0d`RD<~ zCri%Rv9Q+zchpfRvf1q_n;~zK2lBR{jlWvI4IZJDL}8sJFlm-?`ZJ|~LDd;LO{;8(=nF7>X5E3r?7bXQ&`!rwFxizDgnZu*Tk>v$0aaIM% zmhmwOLoR-dT@*k6&bl)7Q!u+<*O1VpU*L4pCOBiCXA_O(QMO+_UQD*1zq*e~k;$Rd zwuU$1oU2yxc(U{Ka=OG!NigO6h>PF#O82v){9dv}=-fq|mscz2@65Ilfnqh0t};O> zF1Xw+tHiZq?>*+d;r&-ad%EbXlGHD7;gJt5Oq;2ZtaBHk&m>SYdk_7!Cm=Kiyey{1 zo5uS4|9mYY^C!sM=jE0%55zK_LDzN6z;9Pf#KG=O>A79IDad|80)!$EwVwj{6Odbmp=R90bu5);L@w!$+6wPvm2{RzZRDG=&GlqFltS4*Ik z^mh;ghRJf@7p>)><_^nuj0jW}8_vQEL-`H&&|qc!elRO!U@IysuTzlzxZ_0O`9lD> z2gfBphK_5t=UPQXL>jbN^>hEQJ0P%*L+I6;wN)mtTwYb@$0A&WzCK)%`Fr_q1z{j$ z*GEQf?HvEg<%lFzpnbfV>i%^)7%zAZ_3pP^hlFc_I!{r3eME5Z<#{(r2aK+~;Z3k% zWMm|&bD?i)Dh#5Q`VzgmqPn_p=%WmH&Qfh0!TXkrqLKMaJ2#^rIR(RD&D-#m#v7yx zG@nYf2v-$o6fuve{n;tLqd3UrX-J=CMZwuAK4fdR!DvVohVIM*khWf-bpxOQo*@H@ z!V>yFIH0c6h7nlvoU1^BI!K~rlopy19nm_+BnkV#9<-t)N%v{RVK<{dRTGMF^zjSa zTzR_cLDBFz6hzT8eI8(wecSA~ujfdbD+R@(XauX^MK5*)|ECO8ZD(4Bv11IdBJGpZ zloYR1#mmqowwGbJN&-3;I(STjn%(0@Fdq}HKP6>0^tz6Vq)5iG8URR1FCQ^0U5D|elzYXV+B41<)*`ueL3 zM9elXl)cF#T+fOW=q;YSFd$&OYoaI z4;QA4F0!@U=|QL>XWFD7lV3FCnOJ${;SEsEy5Y|m?DX~NFVxdgps&90+vI&CBbhSQ zp*AEpp(>Mg&RG@79e^=y+B=7(l jBo)8{{C`*S9Ff9vRsZ6h4-Wd@0eGr}QY?66{^9=sS($8+ delta 5244 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 Date: Fri, 9 Mar 2018 12:36:43 -0500 Subject: [PATCH 02/21] Fix pipe construction conflicting with existing pipes too much. Bug in the init_dirs_cache was not setting direction of pipes, making all cached dirs be for south. Because mapped in pipes didn't have piping layer set, mapped in pipes conflicted. The full-tile check for unary machines forgot to exclude *itself* --- code/ATMOSPHERICS/_atmospherics_helpers.dm | 37 +++++++++++++++++++ code/ATMOSPHERICS/atmospherics.dm | 5 ++- .../components/unary/unary_base.dm | 1 + code/ATMOSPHERICS/pipes/cap.dm | 4 ++ code/ATMOSPHERICS/pipes/manifold.dm | 4 ++ code/ATMOSPHERICS/pipes/manifold4w.dm | 4 ++ code/ATMOSPHERICS/pipes/simple.dm | 4 ++ code/game/machinery/pipe/construction.dm | 2 +- code/modules/multiz/pipes.dm | 4 ++ 9 files changed, 62 insertions(+), 3 deletions(-) diff --git a/code/ATMOSPHERICS/_atmospherics_helpers.dm b/code/ATMOSPHERICS/_atmospherics_helpers.dm index 6fc2b923dd..b5cd6486b9 100644 --- a/code/ATMOSPHERICS/_atmospherics_helpers.dm +++ b/code/ATMOSPHERICS/_atmospherics_helpers.dm @@ -455,3 +455,40 @@ var/sink_pressure = sink.return_pressure() return (source_pressure - sink_pressure)/(R_IDEAL_GAS_EQUATION * (source.temperature/source_volume + sink.temperature/sink_volume)) + +// +// Debugging helper procs +// + +/proc/atmos_piping_layer_str(piping_layer) + switch(piping_layer) + if(PIPING_LAYER_SUPPLY) + return "SUPPLY" + if(PIPING_LAYER_REGULAR) + return "REGULAR" + if(PIPING_LAYER_SCRUBBER) + return "SCRUBBER" + +/proc/atmos_pipe_flags_str(pipe_flags) + var/list/dat = list() + if(pipe_flags & PIPING_ALL_LAYER) + dat += "ALL_LAYER" + if(pipe_flags & PIPING_ONE_PER_TURF) + dat += "ONE_PER_TURF" + if(pipe_flags & PIPING_DEFAULT_LAYER_ONLY) + dat += "DEFAULT_LAYER_ONLY" + if(pipe_flags & PIPING_CARDINAL_AUTONORMALIZE) + dat += "CARDINAL_AUTONORMALIZE" + return dat.Join("|") + +/proc/atmos_connect_types_str(connect_types) + var/list/dat = list() + if(connect_types & CONNECT_TYPE_REGULAR) + dat += "REGULAR" + if(connect_types & CONNECT_TYPE_SUPPLY) + dat += "SUPPLY" + if(connect_types & CONNECT_TYPE_SCRUBBER) + dat += "SCRUBBER" + if(connect_types & CONNECT_TYPE_HE) + dat += "HE" + return dat.Join("|") diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index 940c5edf1c..fc074184d8 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -33,11 +33,12 @@ Pipelines + Other Objects -> Pipe network var/obj/machinery/atmospherics/node1 var/obj/machinery/atmospherics/node2 -/obj/machinery/atmospherics/New() +/obj/machinery/atmospherics/New(loc, newdir) ..() if(!icon_manager) icon_manager = new() - + if(!isnull(newdir)) + set_dir(newdir) if(!pipe_color) pipe_color = color color = null diff --git a/code/ATMOSPHERICS/components/unary/unary_base.dm b/code/ATMOSPHERICS/components/unary/unary_base.dm index db395ad6fc..12d6822ad4 100644 --- a/code/ATMOSPHERICS/components/unary/unary_base.dm +++ b/code/ATMOSPHERICS/components/unary/unary_base.dm @@ -104,6 +104,7 @@ // Returns TRUE if something is blocking, FALSE if its okay to continue. /obj/machinery/atmospherics/unary/proc/check_for_obstacles() for(var/obj/machinery/atmospherics/M in loc) + if(M == src) continue if((M.pipe_flags & pipe_flags & PIPING_ONE_PER_TURF)) //Only one dense/requires density object per tile, eg connectors/cryo/heater/coolers. visible_message("\The [src]'s cannot be connected, something is hogging the tile!") return TRUE diff --git a/code/ATMOSPHERICS/pipes/cap.dm b/code/ATMOSPHERICS/pipes/cap.dm index 8e56319d69..4bcf200140 100644 --- a/code/ATMOSPHERICS/pipes/cap.dm +++ b/code/ATMOSPHERICS/pipes/cap.dm @@ -79,6 +79,7 @@ desc = "An endcap for scrubbers pipes" icon_state = "cap-scrubbers" connect_types = CONNECT_TYPE_SCRUBBER + piping_layer = PIPING_LAYER_SCRUBBER layer = 2.38 icon_connect_type = "-scrubbers" color = PIPE_COLOR_RED @@ -88,6 +89,7 @@ desc = "An endcap for supply pipes" icon_state = "cap-supply" connect_types = CONNECT_TYPE_SUPPLY + piping_layer = PIPING_LAYER_SUPPLY layer = 2.39 icon_connect_type = "-supply" color = PIPE_COLOR_BLUE @@ -102,6 +104,7 @@ desc = "An endcap for scrubbers pipes" icon_state = "cap-f-scrubbers" connect_types = CONNECT_TYPE_SCRUBBER + piping_layer = PIPING_LAYER_SCRUBBER layer = 2.38 icon_connect_type = "-scrubbers" color = PIPE_COLOR_RED @@ -111,6 +114,7 @@ desc = "An endcap for supply pipes" icon_state = "cap-f-supply" connect_types = CONNECT_TYPE_SUPPLY + piping_layer = PIPING_LAYER_SUPPLY layer = 2.39 icon_connect_type = "-supply" color = PIPE_COLOR_BLUE diff --git a/code/ATMOSPHERICS/pipes/manifold.dm b/code/ATMOSPHERICS/pipes/manifold.dm index 8df3b4326a..bca6dd3379 100644 --- a/code/ATMOSPHERICS/pipes/manifold.dm +++ b/code/ATMOSPHERICS/pipes/manifold.dm @@ -165,6 +165,7 @@ desc = "A manifold composed of scrubbers pipes" icon_state = "map-scrubbers" connect_types = CONNECT_TYPE_SCRUBBER + piping_layer = PIPING_LAYER_SCRUBBER layer = 2.38 icon_connect_type = "-scrubbers" color = PIPE_COLOR_RED @@ -174,6 +175,7 @@ desc = "A manifold composed of supply pipes" icon_state = "map-supply" connect_types = CONNECT_TYPE_SUPPLY + piping_layer = PIPING_LAYER_SUPPLY layer = 2.39 icon_connect_type = "-supply" color = PIPE_COLOR_BLUE @@ -209,6 +211,7 @@ desc = "A manifold composed of scrubbers pipes" icon_state = "map-scrubbers" connect_types = CONNECT_TYPE_SCRUBBER + piping_layer = PIPING_LAYER_SCRUBBER layer = 2.38 icon_connect_type = "-scrubbers" color = PIPE_COLOR_RED @@ -218,6 +221,7 @@ desc = "A manifold composed of supply pipes" icon_state = "map-supply" connect_types = CONNECT_TYPE_SUPPLY + piping_layer = PIPING_LAYER_SUPPLY layer = 2.39 icon_connect_type = "-supply" color = PIPE_COLOR_BLUE diff --git a/code/ATMOSPHERICS/pipes/manifold4w.dm b/code/ATMOSPHERICS/pipes/manifold4w.dm index 1bd556b3fb..88adc47d62 100644 --- a/code/ATMOSPHERICS/pipes/manifold4w.dm +++ b/code/ATMOSPHERICS/pipes/manifold4w.dm @@ -167,6 +167,7 @@ desc = "A manifold composed of scrubbers pipes" icon_state = "map_4way-scrubbers" connect_types = CONNECT_TYPE_SCRUBBER + piping_layer = PIPING_LAYER_SCRUBBER layer = 2.38 icon_connect_type = "-scrubbers" color = PIPE_COLOR_RED @@ -176,6 +177,7 @@ desc = "A manifold composed of supply pipes" icon_state = "map_4way-supply" connect_types = CONNECT_TYPE_SUPPLY + piping_layer = PIPING_LAYER_SUPPLY layer = 2.39 icon_connect_type = "-supply" color = PIPE_COLOR_BLUE @@ -211,6 +213,7 @@ desc = "A manifold composed of scrubbers pipes" icon_state = "map_4way-scrubbers" connect_types = CONNECT_TYPE_SCRUBBER + piping_layer = PIPING_LAYER_SCRUBBER layer = 2.38 icon_connect_type = "-scrubbers" color = PIPE_COLOR_RED @@ -220,6 +223,7 @@ desc = "A manifold composed of supply pipes" icon_state = "map_4way-supply" connect_types = CONNECT_TYPE_SUPPLY + piping_layer = PIPING_LAYER_SUPPLY layer = 2.39 icon_connect_type = "-supply" color = PIPE_COLOR_BLUE diff --git a/code/ATMOSPHERICS/pipes/simple.dm b/code/ATMOSPHERICS/pipes/simple.dm index 289e8b4274..77290e5d8a 100644 --- a/code/ATMOSPHERICS/pipes/simple.dm +++ b/code/ATMOSPHERICS/pipes/simple.dm @@ -172,6 +172,7 @@ desc = "A one meter section of scrubbers pipe" icon_state = "intact-scrubbers" connect_types = CONNECT_TYPE_SCRUBBER + piping_layer = PIPING_LAYER_SCRUBBER layer = 2.38 icon_connect_type = "-scrubbers" color = PIPE_COLOR_RED @@ -181,6 +182,7 @@ desc = "A one meter section of supply pipe" icon_state = "intact-supply" connect_types = CONNECT_TYPE_SUPPLY + piping_layer = PIPING_LAYER_SUPPLY layer = 2.39 icon_connect_type = "-supply" color = PIPE_COLOR_BLUE @@ -216,6 +218,7 @@ desc = "A one meter section of scrubbers pipe" icon_state = "intact-scrubbers" connect_types = CONNECT_TYPE_SCRUBBER + piping_layer = PIPING_LAYER_SCRUBBER layer = 2.38 icon_connect_type = "-scrubbers" color = PIPE_COLOR_RED @@ -225,6 +228,7 @@ desc = "A one meter section of supply pipe" icon_state = "intact-supply" connect_types = CONNECT_TYPE_SUPPLY + piping_layer = PIPING_LAYER_SUPPLY layer = 2.39 icon_connect_type = "-supply" color = PIPE_COLOR_BLUE diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index 9c67a9bc5d..e4e42bbd7b 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -223,7 +223,7 @@ Buildable meters pipe_init_dirs_cache[type] = list() if(!pipe_init_dirs_cache[type]["[dir]"]) - var/obj/machinery/atmospherics/temp = new type(null, FALSE, dir) + var/obj/machinery/atmospherics/temp = new type(null, dir) pipe_init_dirs_cache[type]["[dir]"] = temp.get_init_dirs() qdel(temp) diff --git a/code/modules/multiz/pipes.dm b/code/modules/multiz/pipes.dm index 2f6e1e8dde..8d03c8f862 100644 --- a/code/modules/multiz/pipes.dm +++ b/code/modules/multiz/pipes.dm @@ -200,6 +200,7 @@ obj/machinery/atmospherics/pipe/zpipe/up/scrubbers name = "upwards scrubbers pipe" desc = "A scrubbers pipe segment to connect upwards." connect_types = CONNECT_TYPE_SCRUBBER + piping_layer = PIPING_LAYER_SCRUBBER layer = 2.38 icon_connect_type = "-scrubbers" color = PIPE_COLOR_RED @@ -209,6 +210,7 @@ obj/machinery/atmospherics/pipe/zpipe/up/supply name = "upwards supply pipe" desc = "A supply pipe segment to connect upwards." connect_types = CONNECT_TYPE_SUPPLY + piping_layer = PIPING_LAYER_SUPPLY layer = 2.39 icon_connect_type = "-supply" color = PIPE_COLOR_BLUE @@ -218,6 +220,7 @@ obj/machinery/atmospherics/pipe/zpipe/down/scrubbers name = "downwards scrubbers pipe" desc = "A scrubbers pipe segment to connect downwards." connect_types = CONNECT_TYPE_SCRUBBER + piping_layer = PIPING_LAYER_SCRUBBER layer = 2.38 icon_connect_type = "-scrubbers" color = PIPE_COLOR_RED @@ -227,6 +230,7 @@ obj/machinery/atmospherics/pipe/zpipe/down/supply name = "downwards supply pipe" desc = "A supply pipe segment to connect downwards." connect_types = CONNECT_TYPE_SUPPLY + piping_layer = PIPING_LAYER_SUPPLY layer = 2.39 icon_connect_type = "-supply" color = PIPE_COLOR_BLUE From e129f03b42dda16182e0ecdf93e70340f08fe244 Mon Sep 17 00:00:00 2001 From: Mewchild Date: Sat, 10 Mar 2018 16:52:52 -0600 Subject: [PATCH 03/21] Gives RD explorer comms --- code/game/objects/items/devices/radio/encryptionkey_vr.dm | 5 +++++ 1 file changed, 5 insertions(+) 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) From 119381e14b6e51ebcc21f0206f40a3b9897b9abb Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Sat, 10 Mar 2018 18:39:11 -0500 Subject: [PATCH 04/21] POLARIS: Prevent ghosts from ejecting borgs from rechargers --- code/game/machinery/rechargestation.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 From 11e4592a751e5dd24783c48a48768b4b07ce77b4 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Sat, 10 Mar 2018 20:52:12 -0500 Subject: [PATCH 05/21] POLARIS: Move Topic() log to debug_log --- code/world.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/world.dm b/code/world.dm index 635aa8d537..84b0bcdf95 100644 --- a/code/world.dm +++ b/code/world.dm @@ -145,7 +145,7 @@ var/world_topic_spam_protect_ip = "0.0.0.0" var/world_topic_spam_protect_time = world.timeofday /world/Topic(T, addr, master, key) - diary << "TOPIC: \"[T]\", from:[addr], master:[master], key:[key][log_end]" + debug_log << "TOPIC: \"[T]\", from:[addr], master:[master], key:[key][log_end]" if (T == "ping") var/x = 1 From ef37b4b307a77ee29743c2ad6a65fc67e35160b6 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Sat, 10 Mar 2018 21:26:45 -0500 Subject: [PATCH 06/21] VS: HTMLDecode vorestation log types --- code/_helpers/logging_vr.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/_helpers/logging_vr.dm b/code/_helpers/logging_vr.dm index b87da0a8b5..66a91e0c2e 100644 --- a/code/_helpers/logging_vr.dm +++ b/code/_helpers/logging_vr.dm @@ -1,11 +1,11 @@ /proc/log_nsay(text, inside, mob/speaker) if (config.log_say) - diary << "\[[time_stamp()]]NSAY (NIF:[inside]): [speaker.simple_info_line()]: [text][log_end]" + diary << "\[[time_stamp()]]NSAY (NIF:[inside]): [speaker.simple_info_line()]: [html_decode(text)][log_end]" /proc/log_nme(text, inside, mob/speaker) if (config.log_emote) - diary << "\[[time_stamp()]]NME (NIF:[inside]): [speaker.simple_info_line()]: [text][log_end]" + diary << "\[[time_stamp()]]NME (NIF:[inside]): [speaker.simple_info_line()]: [html_decode(text)][log_end]" /proc/log_subtle(text, mob/speaker) if (config.log_emote) - diary << "\[[time_stamp()]]SUBTLE: [speaker.simple_info_line()]: [text][log_end]" + diary << "\[[time_stamp()]]SUBTLE: [speaker.simple_info_line()]: [html_decode(text)][log_end]" From 3e92f000f77d38eb3a6fd8197e456c23ed6743ec Mon Sep 17 00:00:00 2001 From: Little-119 Date: Sun, 11 Mar 2018 04:29:07 -0400 Subject: [PATCH 07/21] Fixes the cancel button in ears/wings/tail selection clearing the respective selection --- .../client/preference_setup/vore/01_ears.dm | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/code/modules/client/preference_setup/vore/01_ears.dm b/code/modules/client/preference_setup/vore/01_ears.dm index 65dfc87c34..08e704511a 100644 --- a/code/modules/client/preference_setup/vore/01_ears.dm +++ b/code/modules/client/preference_setup/vore/01_ears.dm @@ -186,8 +186,9 @@ pretty_ear_styles[instance.name] = path // Present choice to user - var/selection = input(user, "Pick ears", "Character Preference") as null|anything in pretty_ear_styles - pref.ear_style = pretty_ear_styles[selection] + var/new_ear_style = input(user, "Pick ears", "Character Preference", pref.ear_style) as null|anything in pretty_ear_styles + if(new_ear_style) + pref.ear_style = pretty_ear_styles[new_ear_style] return TOPIC_REFRESH_UPDATE_PREVIEW @@ -218,8 +219,9 @@ pretty_tail_styles[instance.name] = path // Present choice to user - var/selection = input(user, "Pick tails", "Character Preference") as null|anything in pretty_tail_styles - pref.tail_style = pretty_tail_styles[selection] + var/new_tail_style = input(user, "Pick tails", "Character Preference", pref.tail_style) as null|anything in pretty_tail_styles + if(new_tail_style) + pref.tail_style = pretty_tail_styles[new_tail_style] return TOPIC_REFRESH_UPDATE_PREVIEW @@ -250,8 +252,9 @@ pretty_wing_styles[instance.name] = path // Present choice to user - var/selection = input(user, "Pick wings", "Character Preference") as null|anything in pretty_wing_styles - pref.wing_style = pretty_wing_styles[selection] + var/new_wing_style = input(user, "Pick wings", "Character Preference", pref.wing_style) as null|anything in pretty_wing_styles + if(new_wing_style) + pref.wing_style = pretty_wing_styles[new_wing_style] return TOPIC_REFRESH_UPDATE_PREVIEW From 509474fcd676fde987523139d9acf3c821ee4f07 Mon Sep 17 00:00:00 2001 From: Little-119 Date: Sun, 11 Mar 2018 04:31:19 -0400 Subject: [PATCH 08/21] Changes the shadekin empathy key from s to m, to fix sign language --- code/modules/mob/living/simple_animal/vore/shadekin/shadekin.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/vore/shadekin/shadekin.dm b/code/modules/mob/living/simple_animal/vore/shadekin/shadekin.dm index 2a2085d8e4..73027e0a37 100644 --- a/code/modules/mob/living/simple_animal/vore/shadekin/shadekin.dm +++ b/code/modules/mob/living/simple_animal/vore/shadekin/shadekin.dm @@ -447,6 +447,6 @@ speech_verb = "mars" ask_verb = "mars" exclaim_verb = "mars" - key = "s" + key = "m" machine_understands = 0 flags = RESTRICTED | HIVEMIND From cb4ac918a212c083d0d1ee1692aaf91bd829889a Mon Sep 17 00:00:00 2001 From: Mewchild Date: Sun, 11 Mar 2018 15:53:37 -0500 Subject: [PATCH 09/21] Meeting Room fixes --- maps/tether/tether-05-station1.dmm | 529 +++++++++++++---------------- 1 file changed, 239 insertions(+), 290 deletions(-) diff --git a/maps/tether/tether-05-station1.dmm b/maps/tether/tether-05-station1.dmm index b87878dc5a..e300fd1795 100644 --- a/maps/tether/tether-05-station1.dmm +++ b/maps/tether/tether-05-station1.dmm @@ -583,10 +583,10 @@ /area/engineering/hallway) "aby" = ( /obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 + dir = 9 }, /obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 + dir = 10 }, /obj/structure/cable{ d1 = 2; @@ -770,6 +770,9 @@ /turf/simulated/floor/tiled, /area/engineering/hallway) "abO" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -779,9 +782,6 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/structure/cable{ d1 = 1; d2 = 2; @@ -957,10 +957,10 @@ /area/hallway/station/atrium) "acu" = ( /obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 + dir = 9 }, /obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 + dir = 10 }, /obj/structure/cable{ d1 = 1; @@ -1270,15 +1270,15 @@ /turf/simulated/floor/tiled, /area/engineering/hallway) "ads" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 4 }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/structure/cable{ d1 = 1; d2 = 2; @@ -1311,10 +1311,10 @@ /area/engineering/hallway) "adv" = ( /obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 + dir = 9 }, /obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 + dir = 10 }, /turf/simulated/floor/tiled, /area/engineering/hallway) @@ -1518,15 +1518,15 @@ /turf/simulated/floor/tiled, /area/engineering/hallway) "adV" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 6 }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/structure/cable{ d1 = 1; d2 = 2; @@ -1771,6 +1771,9 @@ /turf/simulated/floor/tiled, /area/engineering/hallway) "aeE" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 4; d2 = 8; @@ -1783,9 +1786,6 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals4{ dir = 6 }, @@ -2783,6 +2783,9 @@ /turf/simulated/floor/tiled, /area/engineering/hallway) "ahO" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 4; d2 = 8; @@ -2791,9 +2794,6 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals4{ dir = 6 }, @@ -3268,15 +3268,15 @@ /turf/simulated/floor/tiled, /area/engineering/hallway) "ajC" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 5 }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/structure/extinguisher_cabinet{ dir = 4; icon_state = "extinguisher_closed"; @@ -3468,15 +3468,21 @@ /turf/simulated/floor/tiled, /area/tether/station/explorer_prep) "aka" = ( +/obj/effect/floor_decal/steeldecal/steel_decals10, +/obj/effect/floor_decal/steeldecal/steel_decals10{ + dir = 4 + }, +/obj/structure/table/standard, +/obj/item/device/multitool/tether_buffered, +/obj/structure/cable/green{ + d2 = 8; + icon_state = "0-8" + }, /obj/machinery/power/apc{ dir = 4; name = "east bump"; pixel_x = 28 }, -/obj/structure/cable/green{ - d2 = 8; - icon_state = "0-8" - }, /turf/simulated/floor/tiled, /area/tether/station/explorer_prep) "ake" = ( @@ -3696,10 +3702,10 @@ /area/engineering/hallway) "akX" = ( /obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 + dir = 9 }, /obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 + dir = 10 }, /obj/machinery/door/firedoor/glass, /obj/structure/cable{ @@ -4953,6 +4959,9 @@ /turf/simulated/wall/r_wall, /area/engineering/hallway) "aoB" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -4970,9 +4979,6 @@ /obj/effect/floor_decal/corner/yellow/bordercorner2{ dir = 6 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -5513,6 +5519,9 @@ /turf/simulated/floor/tiled, /area/engineering/hallway) "apL" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -5524,9 +5533,6 @@ /obj/effect/floor_decal/corner/yellow/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -5606,13 +5612,13 @@ /turf/simulated/floor/tiled, /area/engineering/atmos/backup) "aqd" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/structure/cable/green{ d1 = 1; d2 = 2; icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 8 }, /turf/simulated/floor/tiled/monotile, @@ -6059,6 +6065,9 @@ /turf/simulated/floor/tiled, /area/engineering/hallway) "aqR" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -6076,9 +6085,6 @@ /obj/effect/floor_decal/corner/yellow/bordercorner2{ dir = 5 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -6132,15 +6138,15 @@ /turf/simulated/floor/tiled, /area/hallway/station/atrium) "arf" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/effect/floor_decal/borderfloor{ dir = 4 }, /obj/effect/floor_decal/corner/lightgrey/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -6945,6 +6951,9 @@ /turf/simulated/floor/tiled/monotile, /area/engineering/workshop) "atF" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -6962,9 +6971,6 @@ /obj/effect/floor_decal/corner/yellow/bordercorner2{ dir = 6 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -7329,12 +7335,6 @@ }, /turf/simulated/floor/tiled/monotile, /area/tether/station/excursion_dock) -"auR" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/tether/station/excursion_dock) "auS" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ @@ -7347,20 +7347,21 @@ /turf/simulated/shuttle/floor/black, /area/shuttle/excursion/tether) "auU" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 9 - }, /obj/machinery/light, /obj/structure/cable/green{ d1 = 1; d2 = 8; icon_state = "1-8" }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply, /obj/structure/disposalpipe/segment{ dir = 8; icon_state = "pipe-c" }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9; + pixel_y = 0 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, /turf/simulated/floor/tiled/monotile, /area/tether/station/excursion_dock) "auV" = ( @@ -7853,6 +7854,9 @@ }, /area/engineering/hallway) "awO" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -7870,9 +7874,6 @@ /obj/effect/floor_decal/corner/yellow/bordercorner2{ dir = 6 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -7919,15 +7920,15 @@ /turf/simulated/floor/tiled, /area/storage/tools) "awZ" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/effect/floor_decal/borderfloor{ dir = 4 }, /obj/effect/floor_decal/corner/lightgrey/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -7973,6 +7974,9 @@ /turf/simulated/floor/tiled/monotile, /area/bridge_hallway) "axg" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/effect/floor_decal/borderfloor{ dir = 4 }, @@ -7985,9 +7989,6 @@ /obj/effect/floor_decal/corner/blue/bordercorner2{ dir = 6 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -8259,6 +8260,9 @@ /turf/simulated/floor, /area/hallway/station/docks) "ayb" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -8270,9 +8274,6 @@ /obj/effect/floor_decal/corner/yellow/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -8429,6 +8430,9 @@ /turf/simulated/floor/tiled, /area/hallway/station/docks) "ayF" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 4 }, @@ -8441,9 +8445,6 @@ /obj/effect/floor_decal/corner/lightgrey/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -8496,15 +8497,15 @@ /turf/simulated/floor/tiled/monotile, /area/bridge_hallway) "ayU" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/effect/floor_decal/borderfloor{ dir = 4 }, /obj/effect/floor_decal/corner/blue/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -8551,6 +8552,9 @@ /turf/simulated/floor/tiled/monotile, /area/engineering/workshop) "azf" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -8565,9 +8569,6 @@ /obj/effect/floor_decal/corner/yellow/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -8683,15 +8684,15 @@ /turf/simulated/floor/tiled/dark, /area/bridge) "azv" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/effect/floor_decal/borderfloor{ dir = 4 }, /obj/effect/floor_decal/corner/blue/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -8829,15 +8830,15 @@ /turf/simulated/floor/tiled, /area/hallway/station/docks) "azR" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/effect/floor_decal/borderfloor{ dir = 4 }, /obj/effect/floor_decal/corner/lightgrey/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /turf/simulated/floor/tiled, /area/hallway/station/docks) "azU" = ( @@ -8898,6 +8899,9 @@ /turf/simulated/floor/tiled, /area/bridge_hallway) "azZ" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/effect/floor_decal/borderfloor{ dir = 4 }, @@ -8910,9 +8914,6 @@ /obj/effect/floor_decal/corner/blue/bordercorner2{ dir = 5 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -9154,6 +9155,9 @@ /turf/simulated/floor/tiled, /area/hallway/station/atrium) "aAo" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/effect/floor_decal/borderfloor{ dir = 4 }, @@ -9163,9 +9167,6 @@ /obj/machinery/door/firedoor/glass/hidden/steel{ dir = 8 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -9815,6 +9816,9 @@ /turf/simulated/floor/tiled/steel_grid, /area/engineering/workshop) "aBA" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/machinery/power/apc{ dir = 4; name = "east bump"; @@ -9826,9 +9830,6 @@ /obj/effect/floor_decal/corner/yellow/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -10118,6 +10119,9 @@ /turf/simulated/floor/tiled, /area/bridge_hallway) "aCw" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -10134,9 +10138,6 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /turf/simulated/floor/tiled, /area/hallway/station/atrium) "aCx" = ( @@ -10355,6 +10356,9 @@ /turf/simulated/floor/tiled, /area/bridge_hallway) "aCV" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -10366,9 +10370,6 @@ /obj/effect/floor_decal/corner/yellow/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -10667,6 +10668,9 @@ /turf/simulated/floor/tiled, /area/hallway/station/atrium) "aDZ" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -10685,9 +10689,6 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /turf/simulated/floor/tiled, /area/hallway/station/atrium) "aEa" = ( @@ -10837,6 +10838,9 @@ }, /area/engineering/hallway) "aEA" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -10848,9 +10852,6 @@ /obj/effect/floor_decal/corner/yellow/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -11199,6 +11200,9 @@ /turf/simulated/floor/wood, /area/crew_quarters/captain) "aFz" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -11218,9 +11222,6 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /turf/simulated/floor/tiled, /area/hallway/station/atrium) "aFB" = ( @@ -11495,6 +11496,9 @@ /turf/simulated/floor/carpet, /area/library) "aGs" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -11506,9 +11510,6 @@ /obj/effect/floor_decal/corner/yellow/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -11758,6 +11759,9 @@ /turf/simulated/floor/tiled, /area/tether/station/dock_two) "aHz" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -11780,9 +11784,6 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/machinery/light{ icon_state = "tube1"; dir = 4 @@ -11954,6 +11955,9 @@ /turf/simulated/floor/tiled/dark, /area/teleporter) "aIl" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -11965,9 +11969,6 @@ /obj/effect/floor_decal/corner/yellow/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -12367,6 +12368,9 @@ /turf/simulated/floor/plating, /area/engineering/storage) "aKb" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -12378,9 +12382,6 @@ /obj/effect/floor_decal/corner/yellow/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -13200,6 +13201,9 @@ /turf/simulated/floor/tiled/monotile, /area/engineering/workshop) "aML" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -13219,9 +13223,6 @@ /obj/effect/floor_decal/corner/lightgrey/bordercorner2{ dir = 6 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -13375,31 +13376,6 @@ }, /turf/simulated/floor, /area/maintenance/station/eng_lower) -"aOu" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/camera/network/northern_star{ - dir = 9 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/lightgrey/border{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 - }, -/turf/simulated/floor/tiled, -/area/hallway/station/atrium) "aOL" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ @@ -13541,28 +13517,6 @@ }, /turf/simulated/floor, /area/maintenance/station/eng_lower) -"aPR" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/lightgrey/border{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 - }, -/turf/simulated/floor/tiled, -/area/hallway/station/atrium) "aQa" = ( /obj/structure/table/rack{ dir = 8; @@ -13698,6 +13652,9 @@ /turf/simulated/floor/tiled, /area/engineering/foyer) "aQQ" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 8 }, @@ -13712,9 +13669,6 @@ /obj/effect/floor_decal/corner/yellow/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -13989,6 +13943,9 @@ /turf/simulated/floor/carpet/oracarpet, /area/crew_quarters/heads/chief) "aTA" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -14006,9 +13963,6 @@ /obj/effect/floor_decal/corner/lightgrey/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -14433,6 +14387,9 @@ /turf/simulated/floor/tiled, /area/hallway/station/atrium) "aWJ" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -14451,9 +14408,6 @@ /obj/effect/floor_decal/corner/lightgrey/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -14814,6 +14768,9 @@ /turf/simulated/floor/carpet/oracarpet, /area/crew_quarters/heads/chief) "baI" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -14835,9 +14792,6 @@ /obj/effect/floor_decal/corner/lightgrey/bordercorner2{ dir = 5 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -15448,6 +15402,9 @@ /turf/simulated/floor/tiled, /area/hallway/station/atrium) "bdW" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable{ d1 = 4; d2 = 8; @@ -15464,9 +15421,6 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 8 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /turf/simulated/floor/tiled, /area/hallway/station/atrium) "bdZ" = ( @@ -15909,15 +15863,15 @@ /turf/simulated/floor/tiled, /area/engineering/foyer) "beM" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/effect/floor_decal/borderfloor{ dir = 4 }, /obj/effect/floor_decal/corner/yellow/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -16088,6 +16042,9 @@ /turf/simulated/floor/tiled/steel_grid, /area/bridge_hallway) "bgf" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -16113,9 +16070,6 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /turf/simulated/floor/tiled, /area/hallway/station/atrium) "bgr" = ( @@ -16141,6 +16095,9 @@ /turf/simulated/floor/tiled, /area/engineering/foyer) "bgD" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 8 }, @@ -16150,9 +16107,6 @@ /obj/effect/floor_decal/corner/yellow/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -16355,6 +16309,9 @@ /turf/simulated/floor/tiled, /area/crew_quarters/heads/hop) "bhH" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 4; @@ -16380,9 +16337,6 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /turf/simulated/floor/tiled, /area/hallway/station/atrium) "bhJ" = ( @@ -16503,15 +16457,15 @@ /turf/simulated/floor/tiled, /area/storage/tools) "bjo" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/effect/floor_decal/borderfloor{ dir = 4 }, /obj/effect/floor_decal/corner/blue/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -16651,6 +16605,9 @@ /turf/simulated/floor/tiled, /area/hallway/station/atrium) "bjX" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -16667,9 +16624,6 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/structure/disposalpipe/segment{ dir = 2; icon_state = "pipe-c" @@ -16764,6 +16718,9 @@ /turf/simulated/floor/tiled, /area/hallway/station/docks) "bkA" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/machinery/status_display{ layer = 4; pixel_x = 32; @@ -16775,9 +16732,6 @@ /obj/effect/floor_decal/corner/lightgrey/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -16872,15 +16826,15 @@ /turf/simulated/floor/plating, /area/bridge) "bll" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/effect/floor_decal/borderfloor{ dir = 4 }, /obj/effect/floor_decal/corner/blue/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -17243,6 +17197,9 @@ /turf/simulated/floor/tiled, /area/hallway/station/atrium) "boq" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/machinery/light{ dir = 4; icon_state = "tube1" @@ -17253,9 +17210,6 @@ /obj/effect/floor_decal/corner/lightgrey/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -18044,6 +17998,9 @@ /turf/simulated/floor/tiled/dark, /area/bridge) "bsM" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/effect/floor_decal/borderfloor{ dir = 4 }, @@ -18056,9 +18013,6 @@ /obj/effect/floor_decal/corner/blue/bordercorner2{ dir = 6 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -18285,6 +18239,9 @@ /turf/simulated/floor/tiled/steel_grid, /area/bridge) "bvd" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/effect/floor_decal/borderfloor{ dir = 4 }, @@ -18297,9 +18254,6 @@ /obj/effect/floor_decal/corner/blue/bordercorner2{ dir = 5 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -18973,15 +18927,15 @@ /turf/simulated/floor/plating, /area/crew_quarters/captain) "bAr" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/effect/floor_decal/borderfloor{ dir = 4 }, /obj/effect/floor_decal/corner/blue/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -19210,15 +19164,15 @@ /turf/simulated/floor/tiled/steel_grid, /area/crew_quarters/captain) "bBJ" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/effect/floor_decal/borderfloor{ dir = 4 }, /obj/effect/floor_decal/corner/blue/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -19422,15 +19376,15 @@ /turf/simulated/floor/wood, /area/crew_quarters/captain) "bEG" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/effect/floor_decal/borderfloor{ dir = 4 }, /obj/effect/floor_decal/corner/blue/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -19689,15 +19643,15 @@ /turf/simulated/floor/wood, /area/crew_quarters/captain) "bFW" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, /obj/effect/floor_decal/borderfloor{ dir = 4 }, /obj/effect/floor_decal/corner/blue/border{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, @@ -21086,20 +21040,6 @@ }, /turf/simulated/floor/tiled, /area/tether/station/dock_two) -"bQH" = ( -/obj/machinery/firealarm{ - dir = 4; - layer = 3.3; - pixel_x = 26 - }, -/obj/effect/floor_decal/steeldecal/steel_decals10, -/obj/effect/floor_decal/steeldecal/steel_decals10{ - dir = 4 - }, -/obj/structure/table/standard, -/obj/item/device/multitool/tether_buffered, -/turf/simulated/floor/tiled, -/area/tether/station/explorer_prep) "bQJ" = ( /obj/structure/window/reinforced{ dir = 8; @@ -21701,12 +21641,6 @@ }, /turf/simulated/floor/tiled, /area/tether/station/explorer_meeting) -"gsV" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/tether/station/excursion_dock) "hJg" = ( /obj/structure/table/woodentable, /obj/item/weapon/paper_bin{ @@ -21762,7 +21696,7 @@ icon_state = "bordercolor"; dir = 4 }, -/obj/machinery/vending/snack, +/obj/machinery/vending/cola, /turf/simulated/floor/tiled, /area/tether/station/explorer_meeting) "mtd" = ( @@ -21820,8 +21754,10 @@ /turf/simulated/shuttle/wall/voidcraft, /area/shuttle/excursion/tether) "poz" = ( -/obj/machinery/camera/network/northern_star{ - dir = 8 +/obj/machinery/firealarm{ + dir = 4; + layer = 3.3; + pixel_x = 26 }, /turf/simulated/floor/tiled, /area/tether/station/explorer_prep) @@ -21852,10 +21788,10 @@ /turf/simulated/floor/tiled, /area/tether/station/explorer_meeting) "soc" = ( -/obj/machinery/atmospherics/unary/vent_scrubber/on{ +/obj/machinery/camera/network/northern_star, +/obj/machinery/atmospherics/unary/vent_pump/on{ dir = 8 }, -/obj/machinery/camera/network/northern_star, /turf/simulated/floor/tiled/monotile, /area/tether/station/excursion_dock) "sSn" = ( @@ -22024,6 +21960,20 @@ /obj/effect/floor_decal/steeldecal/steel_decals9, /turf/simulated/floor/tiled/monotile, /area/tether/station/excursion_dock) +"DfE" = ( +/obj/effect/floor_decal/steeldecal/steel_decals9{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals9{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals9{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals9, +/obj/structure/closet/secure_closet/guncabinet/excursion, +/turf/simulated/floor/tiled, +/area/tether/station/explorer_prep) "Dne" = ( /obj/structure/table/woodentable, /obj/item/device/taperecorder, @@ -22106,6 +22056,7 @@ icon_state = "bordercolor"; dir = 4 }, +/obj/machinery/vending/snack, /turf/simulated/floor/tiled, /area/tether/station/explorer_meeting) "KNg" = ( @@ -22139,7 +22090,7 @@ icon_state = "bordercolor"; dir = 4 }, -/obj/machinery/vending/cola, +/obj/machinery/photocopier, /turf/simulated/floor/tiled, /area/tether/station/explorer_meeting) "Nyt" = ( @@ -22256,6 +22207,7 @@ dir = 4 }, /obj/effect/floor_decal/steeldecal/steel_decals_central1, +/obj/machinery/door/firedoor/glass, /turf/simulated/floor/tiled, /area/tether/station/explorer_meeting) "RGf" = ( @@ -22340,7 +22292,10 @@ /area/shuttle/excursion/tether) "Vrx" = ( /obj/machinery/camera/network/northern_star, -/turf/simulated/floor/tiled, +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 4 + }, +/turf/simulated/floor/tiled/monotile, /area/tether/station/excursion_dock) "VZf" = ( /obj/structure/bed/chair/office/dark{ @@ -22433,12 +22388,6 @@ }, /turf/simulated/floor/tiled, /area/tether/station/explorer_meeting) -"Zwu" = ( -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/tether/station/excursion_dock) (1,1,1) = {" aaa @@ -30285,8 +30234,8 @@ Vrx aah akC aah -gsV -Zwu +aah +aaP aad CaJ sSn @@ -30403,11 +30352,11 @@ aaI aaI aaW ail -abd +cDQ abd abm abJ -cDQ +arp auS ail abd @@ -32243,7 +32192,7 @@ aad soc nxL PeQ -auR +abc aad aac aaT @@ -32255,13 +32204,13 @@ aHz aIT aKQ aML -aOu -aPR -aPR +aFz +aCw +aCw aTA -aPR +aCw aWJ -aOu +aFz baI bch beS @@ -32369,7 +32318,7 @@ nYM nYM nYM nYM -alA +ash aCy amM amM @@ -32491,7 +32440,7 @@ YUm NEQ mCP epz -alA +ash amg amg amg @@ -32613,7 +32562,7 @@ VZf edg Nyt lHz -alA +ash amg amg amg @@ -32735,7 +32684,7 @@ uzS MaY tEu wmC -alA +ash amg amg amg @@ -32857,7 +32806,7 @@ MaY flX rRn jop -alA +ash amg amg amg @@ -32979,7 +32928,7 @@ mtd irt EKk jop -alA +ash amg amg amg @@ -33089,10 +33038,10 @@ aiv ajo poz aka -bQH akL akL -alu +akL +akL amW aiv SzY @@ -33101,7 +33050,7 @@ hJg mtd tEu wmC -alA +ash amg amg amg @@ -33211,10 +33160,10 @@ aiv aiv aiv aiv -aiv bQJ bQT bQJ +bQJ aiv aiv IjZ @@ -33223,7 +33172,7 @@ cNq PqO eUx QQi -alA +ash amg amg amg @@ -33332,11 +33281,11 @@ aaa aac aac aac -aac -aiv +aei bQK bQK bQK +DfE aiv BZA uDP @@ -33345,7 +33294,7 @@ AmC AmC AmC Dne -alA +ash amg amg amg @@ -33467,7 +33416,7 @@ mcn NuW jKX Tlr -alA +ash amg amg amg @@ -33589,7 +33538,7 @@ ggi ggi ggi wSk -alA +ash amg amg amg @@ -33711,7 +33660,7 @@ aat aat aat aat -alA +ash alA amN aFI From f2fff2358b2acb5c96497331e2e9497044c6da99 Mon Sep 17 00:00:00 2001 From: Leshana Date: Sat, 10 Mar 2018 07:19:34 -0500 Subject: [PATCH 10/21] Fix DEBUG: Runtime in syringes_vr.dm,17: Cannot execute null.Cut() --- code/modules/reagents/reagent_containers/syringes_vr.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/reagents/reagent_containers/syringes_vr.dm b/code/modules/reagents/reagent_containers/syringes_vr.dm index 1c6fb55fe8..3f012a257a 100644 --- a/code/modules/reagents/reagent_containers/syringes_vr.dm +++ b/code/modules/reagents/reagent_containers/syringes_vr.dm @@ -14,7 +14,7 @@ /obj/item/weapon/reagent_containers/syringe/Destroy() qdel_null_list(viruses) - targets.Cut() + LAZYCLEARLIST(targets) return ..() /obj/item/weapon/reagent_containers/syringe/process() From 42f81059f6177dd57176548345b68e4c9f9140f3 Mon Sep 17 00:00:00 2001 From: Leshana Date: Sun, 11 Mar 2018 16:56:05 -0400 Subject: [PATCH 11/21] Removes obsolete custom items Fixes Runtime in item_spawning.dm,38: Cannot create objects of type null. There is no such type as /obj/item/device/pda_mod, and there has not ever been such a type on this codebase. Last time it existed was in pre-github baystation code. --- config/custom_items.txt | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/config/custom_items.txt b/config/custom_items.txt index fe5b71cc51..b3fea582c1 100644 --- a/config/custom_items.txt +++ b/config/custom_items.txt @@ -470,11 +470,11 @@ character_name: Chakat Taiga item_path: /obj/item/clothing/under/fluff/taiga } -{ -ckey: kligor -character_name: Andy Gettemy -item_path: /obj/item/device/pda_mod/fluff/kligor -} +#{ +#ckey: kligor +#character_name: Andy Gettemy +#item_path: /obj/item/device/pda_mod/fluff/kligor +#} { ckey: konabird @@ -858,11 +858,11 @@ item_path: /obj/item/clothing/mask/gas/sexymime } # ######## W CKEYS -{ -ckey: warbrand2 -character_name: Brandy draca -item_path: /obj/item/device/pda_mod/fluff/warbrand2 -} +#{ +#ckey: warbrand2 +#character_name: Brandy draca +#item_path: /obj/item/device/pda_mod/fluff/warbrand2 +#} { ckey: werebear From 82a0d86cf9e154209a19d7e034f55ce7421dd9b3 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Sun, 11 Mar 2018 21:13:53 -0400 Subject: [PATCH 12/21] POLARIS: Log more engine info --- code/modules/mob/new_player/new_player.dm | 1 + code/modules/power/singularity/emitter.dm | 8 +++++--- code/modules/power/singularity/field_generator.dm | 3 +++ .../particle_accelerator/particle_accelerator.dm | 1 + .../particle_accelerator/particle_control.dm | 7 ++++--- code/modules/power/smes.dm | 3 ++- code/modules/power/supermatter/supermatter.dm | 15 +++++++++++---- code/modules/power/tesla/energy_ball.dm | 3 +++ 8 files changed, 30 insertions(+), 11 deletions(-) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index d21a82f9cc..804934838d 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -354,6 +354,7 @@ var/mob/living/character = create_character(T) //creates the human and transfers vars and mind character = job_master.EquipRank(character, rank, 1) //equips the human UpdateFactionList(character) + log_game("JOINED [key_name(character)] as \"[rank]\"") // AIs don't need a spawnpoint, they must spawn at an empty core if(character.mind.assigned_role == "AI") diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index f4f6579420..827bd9aefd 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -48,7 +48,7 @@ /obj/machinery/power/emitter/Destroy() message_admins("Emitter deleted at ([x],[y],[z] - JMP)",0,1) - log_game("Emitter deleted at ([x],[y],[z])") + log_game("EMITTER([x],[y],[z]) Destroyed/deleted.") investigate_log("deleted at ([x],[y],[z])","singulo") ..() @@ -72,7 +72,7 @@ src.active = 0 user << "You turn off [src]." message_admins("Emitter turned off by [key_name(user, user.client)](?) in ([x],[y],[z] - JMP)",0,1) - log_game("Emitter turned off by [user.ckey]([user]) in ([x],[y],[z])") + log_game("EMITTER([x],[y],[z]) OFF by [key_name(user)]") investigate_log("turned off by [user.key]","singulo") else src.active = 1 @@ -80,7 +80,7 @@ src.shot_number = 0 src.fire_delay = get_initial_fire_delay() message_admins("Emitter turned on by [key_name(user, user.client)](?) in ([x],[y],[z] - JMP)",0,1) - log_game("Emitter turned on by [user.ckey]([user]) in ([x],[y],[z])") + log_game("EMITTER([x],[y],[z]) ON by [key_name(user)]") investigate_log("turned on by [user.key]","singulo") update_icon() else @@ -112,11 +112,13 @@ if(!powered) powered = 1 update_icon() + log_game("EMITTER([x],[y],[z]) Regained power and is ON.") investigate_log("regained power and turned on","singulo") else if(powered) powered = 0 update_icon() + log_game("EMITTER([x],[y],[z]) Lost power and was ON.") investigate_log("lost power and turned off","singulo") return diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm index a9251e27ee..dc6fd45163 100644 --- a/code/modules/power/singularity/field_generator.dm +++ b/code/modules/power/singularity/field_generator.dm @@ -90,6 +90,7 @@ field_generator power level display "You turn on the [src.name].", \ "You hear heavy droning") turn_on() + log_game("FIELDGEN([x],[y],[z]) Activated by [key_name(user)]") investigate_log("activated by [user.key].","singulo") src.add_fingerprint(user) @@ -213,6 +214,7 @@ field_generator power level display for(var/mob/M in viewers(src)) M.show_message("\The [src] shuts down!") turn_off() + log_game("FIELDGEN([x],[y],[z]) Lost power and was ON.") investigate_log("ran out of power and deactivated","singulo") src.power = 0 return 0 @@ -338,4 +340,5 @@ field_generator power level display temp = 0 message_admins("A singulo exists and a containment field has failed.",1) investigate_log("has failed whilst a singulo exists.","singulo") + log_game("FIELDGEN([x],[y],[z]) Containment failed while singulo/tesla exists.") O.last_warning = world.time diff --git a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm index 80f90fbacc..a5d2a4ac0a 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm @@ -139,6 +139,7 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin ..() if(master && master.active) master.toggle_power() + log_game("PACCEL([x],[y],[z]) Was moved while active and turned off.") investigate_log("was moved whilst active; it powered down.","singulo") /obj/structure/particle_accelerator/ex_act(severity) diff --git a/code/modules/power/singularity/particle_accelerator/particle_control.dm b/code/modules/power/singularity/particle_accelerator/particle_control.dm index 0bc4adabcf..bcdd0d5036 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_control.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_control.dm @@ -119,7 +119,7 @@ strength = strength_upper_limit else message_admins("PA Control Computer increased to [strength] by [key_name(usr, usr.client)](?) in ([x],[y],[z] - JMP)",0,1) - log_game("PA Control Computer increased to [strength] by [usr.ckey]([usr]) in ([x],[y],[z])") + log_game("PACCEL([x],[y],[z]) [key_name(usr)] increased to [strength]") investigate_log("increased to [strength] by [usr.key]","singulo") strength_change() @@ -130,7 +130,7 @@ strength = 0 else message_admins("PA Control Computer decreased to [strength] by [key_name(usr, usr.client)](?) in ([x],[y],[z] - JMP)",0,1) - log_game("PA Control Computer decreased to [strength] by [usr.ckey]([usr]) in ([x],[y],[z])") + log_game("PACCEL([x],[y],[z]) [key_name(usr)] decreased to [strength]") investigate_log("decreased to [strength] by [usr.key]","singulo") strength_change() @@ -147,6 +147,7 @@ if(src.active) //a part is missing! if( length(connected_parts) < 6 ) + log_game("PACCEL([x],[y],[z]) Failed due to missing parts.") investigate_log("lost a connected part; It powered down.","singulo") toggle_power() return @@ -209,7 +210,7 @@ active = !active investigate_log("turned [active?"ON":"OFF"] by [usr ? usr.key : "outside forces"]","singulo") message_admins("PA Control Computer turned [active ?"ON":"OFF"] by [key_name(usr, usr.client)](?) in ([x],[y],[z] - JMP)",0,1) - log_game("PA Control Computer turned [active ?"ON":"OFF"] by [usr.ckey]([usr]) in ([x],[y],[z])") + log_game("PACCEL([x],[y],[z]) [key_name(usr)] turned [active?"ON":"OFF"].") if(active) update_use_power(2) for(var/obj/structure/particle_accelerator/part in connected_parts) diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index d1189f25fb..e2b37348a9 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -148,6 +148,7 @@ if(output_used < 0.0001) // either from no charge or set to 0 outputting(0) investigate_log("lost power and turned off","singulo") + log_game("SMES([x],[y],[z]) Power depleted.") else if(output_attempt && output_level > 0) outputting = 1 else @@ -374,7 +375,7 @@ output_level = max(0, min(output_level_max, output_level)) // clamp to range investigate_log("input/output; on":"off"] | Input-mode: [input_attempt?"auto":"off"] by [usr.key]","singulo") - + log_game("SMES([x],[y],[z]) [key_name(usr)] changed settings: I:[input_level]([input_attempt]), O:[output_level]([output_attempt])") return 1 diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index df27be9d78..c7b113ae32 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -94,7 +94,7 @@ /obj/machinery/power/supermatter/proc/explode() message_admins("Supermatter exploded at ([x],[y],[z] - JMP)",0,1) - log_game("Supermatter exploded at ([x],[y],[z])") + log_game("SUPERMATTER([x],[y],[z]) Exploded. Power:[power], Oxygen:[oxygen], Damage:[damage], Integrity:[get_integrity()]") anchored = 1 grav_pulling = 1 exploded = 1 @@ -146,11 +146,13 @@ alert_msg = null if(alert_msg) global_announcer.autosay(alert_msg, "Supermatter Monitor", "Engineering") + log_game("SUPERMATTER([x],[y],[z]) Emergency engineering announcement. Power:[power], Oxygen:[oxygen], Damage:[damage], Integrity:[get_integrity()]") //Public alerts if((damage > emergency_point) && !public_alert) global_announcer.autosay("WARNING: SUPERMATTER CRYSTAL DELAMINATION IMMINENT!", "Supermatter Monitor") admin_chat_message(message = "SUPERMATTER DELAMINATING!", color = "#FF2222") //VOREStation Add public_alert = 1 + log_game("SUPERMATTER([x],[y],[z]) Emergency PUBLIC announcement. Power:[power], Oxygen:[oxygen], Damage:[damage], Integrity:[get_integrity()]") else if(safe_warned && public_alert) global_announcer.autosay(alert_msg, "Supermatter Monitor") public_alert = 0 @@ -272,12 +274,17 @@ return 0 // This stops people from being able to really power up the supermatter // Then bring it inside to explode instantly upon landing on a valid turf. - + var/added_energy + var/added_damage var/proj_damage = Proj.get_structure_damage() if(istype(Proj, /obj/item/projectile/beam)) - power += proj_damage * config_bullet_energy * CHARGING_FACTOR / POWER_FACTOR + added_energy = proj_damage * config_bullet_energy * CHARGING_FACTOR / POWER_FACTOR + power += added_energy else - damage += proj_damage * config_bullet_energy + added_damage = proj_damage * config_bullet_energy + damage += added_damage + if(added_energy || added_damage) + log_game("SUPERMATTER([x],[y],[z]) Hit by \"[Proj.name]\". +[added_energy] Energy, +[added_damage] Damage.") return 0 /obj/machinery/power/supermatter/attack_robot(mob/user as mob) diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index d37eec4b5d..9274bb85a6 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -93,6 +93,7 @@ /obj/singularity/energy_ball/proc/handle_energy() if (energy <= 0) + log_game("TESLA([x],[y],[z]) Collapsed entirely.") investigate_log("collapsed.", I_SINGULO) qdel(src) return TRUE @@ -290,6 +291,8 @@ else if(closest_mob) var/shock_damage = Clamp(round(power/400), 10, 90) + rand(-5, 5) closest_mob.electrocute_act(shock_damage, source, 1, ran_zone()) + log_game("TESLA([source.x],[source.y],[source.z]) Shocked [key_name(closest_mob)] for [shock_damage]dmg.") + message_admins("Tesla zapped [key_name_admin(closest_mob)]!") if(issilicon(closest_mob)) var/mob/living/silicon/S = closest_mob if(stun_mobs) From e4ec74af3410e9e4a00827fafbdd9633d6b91bab Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Sun, 11 Mar 2018 21:14:11 -0400 Subject: [PATCH 13/21] VS: Announce tes/singuloose in adminchat --- code/modules/power/singularity/field_generator.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm index dc6fd45163..d32670a2ce 100644 --- a/code/modules/power/singularity/field_generator.dm +++ b/code/modules/power/singularity/field_generator.dm @@ -338,6 +338,7 @@ field_generator power level display if(O.last_warning && temp) if((world.time - O.last_warning) > 50) //to stop message-spam temp = 0 + admin_chat_message(message = "SINGUL/TESLOOSE!", color = "#FF2222") //VOREStation Add message_admins("A singulo exists and a containment field has failed.",1) investigate_log("has failed whilst a singulo exists.","singulo") log_game("FIELDGEN([x],[y],[z]) Containment failed while singulo/tesla exists.") From 2bea97d328d5cf5f40735f5680420f879f3bacc1 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Sun, 11 Mar 2018 21:41:43 -0400 Subject: [PATCH 14/21] Reduce lightweight trait point return --- .../living/carbon/human/species/station/traits_vr/negative.dm | 2 +- code/modules/mob/living/living.dm | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/negative.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/negative.dm index 307fc537ee..f8fdcc79cb 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/negative.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/negative.dm @@ -110,7 +110,7 @@ /datum/trait/lightweight name = "Lightweight" desc = "Your light weight and poor balance make you very susceptible to unhelpful bumping. Think of it like a bowling ball versus a pin." - cost = -4 + cost = -2 var_changes = list("lightweight" = 1) /datum/trait/colorblind diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index de188e9336..a5c363ed54 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -137,8 +137,6 @@ default behaviour is: return // VOREStation Edit - Begin - // Handle grabbing, stomping, and such of micros! - if(handle_micro_bump_other(tmob)) return // Plow that nerd. if(ishuman(tmob)) var/mob/living/carbon/human/H = tmob @@ -147,6 +145,8 @@ default behaviour is: H.Weaken(20) now_pushing = 0 return + // Handle grabbing, stomping, and such of micros! + if(handle_micro_bump_other(tmob)) return // VOREStation Edit - End if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) From bcf962fc326456eba673e5c0a59d40e0906bebef Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Mon, 12 Mar 2018 11:33:58 -0400 Subject: [PATCH 15/21] POLARIS: Readd include_name param on keyname because it's used for other things --- code/_helpers/logging.dm | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/code/_helpers/logging.dm b/code/_helpers/logging.dm index 06b9fc72fa..83f76bcc9e 100644 --- a/code/_helpers/logging.dm +++ b/code/_helpers/logging.dm @@ -140,7 +140,7 @@ //more or less a logging utility //Always return "Something/(Something)", even if it's an error message. -/proc/key_name(var/whom, var/include_link = null, var/highlight_special_characters = 1) +/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 @@ -186,17 +186,18 @@ else . += "INVALID" - var/name = "INVALID" - if(M) - if(M.real_name) - name = M.real_name - else if(M.name) - name = M.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(include_link && is_special_character(M) && highlight_special_characters) - name = "[name]" //Orange - - . += "/([name])" + if(include_link && is_special_character(M) && highlight_special_characters) + name = "[name]" //Orange + + . += "/([name])" return . From 428db6c271d7bf1c3e646b734b7786dc233c6135 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Mon, 12 Mar 2018 18:25:53 -0400 Subject: [PATCH 16/21] POLARIS: Tooltip framework, and mob tooltips --- code/_helpers/mobs.dm | 13 + code/game/atoms.dm | 6 + code/modules/client/client defines.dm | 1 + .../client/preference_setup/global/01_ui.dm | 10 + .../preference_setup/global/setting_datums.dm | 6 + code/modules/client/preferences.dm | 1 + .../client/preferences_toggle_procs.dm | 13 + code/modules/client/ui_style.dm | 9 + code/modules/mob/living/carbon/human/human.dm | 50 ++++ .../mob/living/simple_animal/animals/bat.dm | 1 + .../mob/living/simple_animal/animals/bear.dm | 1 + .../mob/living/simple_animal/animals/carp.dm | 1 + .../mob/living/simple_animal/animals/cat.dm | 2 + .../mob/living/simple_animal/animals/corgi.dm | 2 + .../mob/living/simple_animal/animals/crab.dm | 1 + .../simple_animal/animals/farm_animals.dm | 4 + .../simple_animal/animals/giant_spider.dm | 1 + .../mob/living/simple_animal/animals/goose.dm | 1 + .../living/simple_animal/animals/lizard.dm | 1 + .../mob/living/simple_animal/animals/mouse.dm | 1 + .../living/simple_animal/animals/parrot.dm | 1 + .../living/simple_animal/animals/penguin.dm | 1 + .../mob/living/simple_animal/animals/slime.dm | 1 + .../living/simple_animal/animals/spiderbot.dm | 1 + .../mob/living/simple_animal/simple_animal.dm | 6 + code/modules/mob/login.dm | 4 + code/modules/mob/mob.dm | 11 + code/modules/tooltip/tooltip.dm | 124 +++++++++ code/modules/tooltip/tooltip.html | 249 ++++++++++++++++++ interface/skin.dmf | 8 + vorestation.dme | 1 + 31 files changed, 532 insertions(+) create mode 100644 code/modules/tooltip/tooltip.dm create mode 100644 code/modules/tooltip/tooltip.html diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm index 1ba5ec30b5..76f1f9f780 100644 --- a/code/_helpers/mobs.dm +++ b/code/_helpers/mobs.dm @@ -285,3 +285,16 @@ Proc for attack log creation, because really why not else . = getCompoundIcon(desired) cached_character_icons[cachekey] = . + +/proc/getviewsize(view) + var/viewX + var/viewY + if(isnum(view)) + var/totalviewrange = 1 + 2 * view + viewX = totalviewrange + viewY = totalviewrange + else + var/list/viewrangelist = splittext(view,"x") + viewX = text2num(viewrangelist[1]) + viewY = text2num(viewrangelist[2]) + return list(viewX, viewY) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index c994aff121..c396a54839 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -511,3 +511,9 @@ /atom/proc/AllowDrop() return FALSE + +/atom/proc/make_nametag_name(mob/user) + return name + +/atom/proc/make_nametag_desc(mob/user) + return "" //Desc itself is often too long to use diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm index 3dc5642a81..0623504203 100644 --- a/code/modules/client/client defines.dm +++ b/code/modules/client/client defines.dm @@ -22,6 +22,7 @@ var/adminobs = null var/area = null var/time_died_as_mouse = null //when the client last died as a mouse + var/datum/tooltip/tooltips = null var/adminhelped = 0 diff --git a/code/modules/client/preference_setup/global/01_ui.dm b/code/modules/client/preference_setup/global/01_ui.dm index 09289c1068..6168aa36b0 100644 --- a/code/modules/client/preference_setup/global/01_ui.dm +++ b/code/modules/client/preference_setup/global/01_ui.dm @@ -7,24 +7,28 @@ S["UI_style_color"] >> pref.UI_style_color S["UI_style_alpha"] >> pref.UI_style_alpha S["ooccolor"] >> pref.ooccolor + S["tooltipstyle"] >> pref.tooltipstyle /datum/category_item/player_setup_item/player_global/ui/save_preferences(var/savefile/S) S["UI_style"] << pref.UI_style S["UI_style_color"] << pref.UI_style_color S["UI_style_alpha"] << pref.UI_style_alpha S["ooccolor"] << pref.ooccolor + S["tooltipstyle"] >> pref.tooltipstyle /datum/category_item/player_setup_item/player_global/ui/sanitize_preferences() pref.UI_style = sanitize_inlist(pref.UI_style, all_ui_styles, initial(pref.UI_style)) pref.UI_style_color = sanitize_hexcolor(pref.UI_style_color, initial(pref.UI_style_color)) pref.UI_style_alpha = sanitize_integer(pref.UI_style_alpha, 0, 255, initial(pref.UI_style_alpha)) pref.ooccolor = sanitize_hexcolor(pref.ooccolor, initial(pref.ooccolor)) + pref.tooltipstyle = sanitize_inlist(pref.tooltipstyle, all_tooltip_styles, all_tooltip_styles[1]) /datum/category_item/player_setup_item/player_global/ui/content(var/mob/user) . = "UI Style: [pref.UI_style]
" . += "Custom UI (recommended for White UI):
" . += "-Color: [pref.UI_style_color] 
__
 reset
" . += "-Alpha(transparency): [pref.UI_style_alpha] reset
" + . += "Tooltip Style: [pref.tooltipstyle]
" if(can_select_ooc_color(user)) . += "OOC Color: " if(pref.ooccolor == initial(pref.ooccolor)) @@ -57,6 +61,12 @@ pref.ooccolor = new_ooccolor return TOPIC_REFRESH + else if(href_list["select_tooltip_style"]) + var/tooltip_style_new = input(user, "Choose tooltip style.", "Character Preference", pref.tooltipstyle) as null|anything in all_tooltip_styles + if(!tooltip_style_new || !CanUseTopic(user)) return TOPIC_NOACTION + pref.tooltipstyle = tooltip_style_new + return TOPIC_REFRESH + else if(href_list["reset"]) switch(href_list["reset"]) if("ui") diff --git a/code/modules/client/preference_setup/global/setting_datums.dm b/code/modules/client/preference_setup/global/setting_datums.dm index 222813460b..05d3410467 100644 --- a/code/modules/client/preference_setup/global/setting_datums.dm +++ b/code/modules/client/preference_setup/global/setting_datums.dm @@ -122,6 +122,12 @@ var/list/_client_preferences_by_type enabled_description = "Show" disabled_description = "Hide" +/datum/client_preference/mob_tooltips + description ="Mob tooltips" + key = "MOB_TOOLTIPS" + enabled_description = "Show" + disabled_description = "Hide" + /datum/client_preference/attack_icons description ="Attack icons" key = "ATTACK_ICONS" diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 697d850d51..497aa44a35 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -21,6 +21,7 @@ datum/preferences var/UI_style = "Midnight" var/UI_style_color = "#ffffff" var/UI_style_alpha = 255 + var/tooltipstyle = "Midnight" //Style for popup tooltips //character preferences var/real_name //our character's name diff --git a/code/modules/client/preferences_toggle_procs.dm b/code/modules/client/preferences_toggle_procs.dm index a350942c58..ca6fae65fd 100644 --- a/code/modules/client/preferences_toggle_procs.dm +++ b/code/modules/client/preferences_toggle_procs.dm @@ -207,6 +207,19 @@ feedback_add_details("admin_verb","TFiringMode") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/client/verb/toggle_mob_tooltips() + set name = "Toggle Mob Tooltips" + set category = "Preferences" + set desc = "Toggles displaying name/species over mobs when moused over." + + var/pref_path = /datum/client_preference/mob_tooltips + toggle_preference(pref_path) + prefs.save_preferences() + + src << "You will now [(is_preference_enabled(/datum/client_preference/mob_tooltips)) ? "see" : "not see"] mob tooltips." + + feedback_add_details("admin_verb","TMobTooltips") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + //Toggles for Staff //Developers diff --git a/code/modules/client/ui_style.dm b/code/modules/client/ui_style.dm index d8d683d5d3..4a736aec5e 100644 --- a/code/modules/client/ui_style.dm +++ b/code/modules/client/ui_style.dm @@ -20,6 +20,15 @@ "Hologram" = 'icons/mob/screen1_robot_minimalist.dmi' ) +var/global/list/all_tooltip_styles = list( + "Midnight", //Default for everyone is the first one, + "Plasmafire", + "Retro", + "Slimecore", + "Operative", + "Clockwork" + ) + /proc/ui_style2icon(ui_style) if(ui_style in all_ui_styles) return all_ui_styles[ui_style] diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 6da16a608d..04370d4fd7 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1576,3 +1576,53 @@ if(update_icons) update_icons() + +/mob/living/carbon/human/proc/get_display_species() + //Shows species in tooltip + //Beepboops get special text if obviously beepboop + if(looksSynthetic()) + if(gender == MALE) + return "Android" + else if(gender == FEMALE) + return "Gynoid" + else + return "Synthetic" + //Else species name + if(species) + return species.get_examine_name() + //Else CRITICAL FAILURE! + return "" + +/mob/living/carbon/human/make_nametag_name(mob/user) + return name //Could do fancy stuff here? + +/mob/living/carbon/human/make_nametag_desc(mob/user) + var/msg = "" + if(hasHUD(user,"security")) + //Try to find their name + var/perpname + if(wear_id) + var/obj/item/weapon/card/id/I = wear_id.GetID() + if(I) + perpname = I.registered_name + else + perpname = name + else + perpname = name + //Try to find their record + var/criminal = "None" + if(perpname) + var/datum/data/record/G = find_general_record("name", perpname) + if(G) + var/datum/data/record/S = find_security_record("id", G.fields["id"]) + if(S) + criminal = S.fields["criminal"] + //If it's interesting, append + if(criminal != "None") + msg += "([criminal]) " + + if(hasHUD(user,"medical")) + msg += "(Health: [round((health/getMaxHealth())*100)]%) " + + msg += get_display_species() + return msg diff --git a/code/modules/mob/living/simple_animal/animals/bat.dm b/code/modules/mob/living/simple_animal/animals/bat.dm index 726c94f143..c51c7c1b36 100644 --- a/code/modules/mob/living/simple_animal/animals/bat.dm +++ b/code/modules/mob/living/simple_animal/animals/bat.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/hostile/scarybat name = "space bats" desc = "A swarm of cute little blood sucking bats that looks pretty upset." + tt_desc = "Desmodus rotundus" //Common vampire bat icon = 'icons/mob/bats.dmi' icon_state = "bat" icon_living = "bat" diff --git a/code/modules/mob/living/simple_animal/animals/bear.dm b/code/modules/mob/living/simple_animal/animals/bear.dm index 3cb3fa8cbe..55eda3fcca 100644 --- a/code/modules/mob/living/simple_animal/animals/bear.dm +++ b/code/modules/mob/living/simple_animal/animals/bear.dm @@ -2,6 +2,7 @@ /mob/living/simple_animal/hostile/bear name = "space bear" desc = "RawrRawr!!" + tt_desc = "Ursinae aetherius" //...bearspace? Maybe. icon_state = "bear" icon_living = "bear" icon_dead = "bear_dead" diff --git a/code/modules/mob/living/simple_animal/animals/carp.dm b/code/modules/mob/living/simple_animal/animals/carp.dm index 4dc4daffda..8b6e01c452 100644 --- a/code/modules/mob/living/simple_animal/animals/carp.dm +++ b/code/modules/mob/living/simple_animal/animals/carp.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/hostile/carp name = "space carp" desc = "A ferocious, fang-bearing creature that resembles a fish." + tt_desc = "Cyprinus aetherius" //carpspace? maybe icon_state = "carp" icon_living = "carp" icon_dead = "carp_dead" diff --git a/code/modules/mob/living/simple_animal/animals/cat.dm b/code/modules/mob/living/simple_animal/animals/cat.dm index 1f0c9c6d26..0eb3516d67 100644 --- a/code/modules/mob/living/simple_animal/animals/cat.dm +++ b/code/modules/mob/living/simple_animal/animals/cat.dm @@ -2,6 +2,7 @@ /mob/living/simple_animal/cat name = "cat" desc = "A domesticated, feline pet. Has a tendency to adopt crewmembers." + tt_desc = "Felis catus" intelligence_level = SA_ANIMAL icon_state = "cat2" item_state = "cat2" @@ -155,6 +156,7 @@ /mob/living/simple_animal/cat/fluff/Runtime name = "Runtime" desc = "Her fur has the look and feel of velvet, and her tail quivers occasionally." + tt_desc = "Felis medicalis" gender = FEMALE icon_state = "cat" item_state = "cat" diff --git a/code/modules/mob/living/simple_animal/animals/corgi.dm b/code/modules/mob/living/simple_animal/animals/corgi.dm index a6d0dcd9c0..d5c198ad78 100644 --- a/code/modules/mob/living/simple_animal/animals/corgi.dm +++ b/code/modules/mob/living/simple_animal/animals/corgi.dm @@ -3,6 +3,7 @@ name = "corgi" real_name = "corgi" desc = "It's a corgi." + tt_desc = "Canis familiaris" intelligence_level = SA_ANIMAL icon_state = "corgi" icon_living = "corgi" @@ -37,6 +38,7 @@ real_name = "Ian" //Intended to hold the name without altering it. gender = MALE desc = "It's a corgi." + tt_desc = "Canis commandus" var/turns_since_scan = 0 var/obj/movement_target response_help = "pets" diff --git a/code/modules/mob/living/simple_animal/animals/crab.dm b/code/modules/mob/living/simple_animal/animals/crab.dm index 0d485d859d..de131b9055 100644 --- a/code/modules/mob/living/simple_animal/animals/crab.dm +++ b/code/modules/mob/living/simple_animal/animals/crab.dm @@ -2,6 +2,7 @@ /mob/living/simple_animal/crab name = "crab" desc = "A hard-shelled crustacean. Seems quite content to lounge around all the time." + tt_desc = "Ranina ranina" icon_state = "crab" icon_living = "crab" icon_dead = "crab_dead" diff --git a/code/modules/mob/living/simple_animal/animals/farm_animals.dm b/code/modules/mob/living/simple_animal/animals/farm_animals.dm index 213aff73bf..52904786a4 100644 --- a/code/modules/mob/living/simple_animal/animals/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/animals/farm_animals.dm @@ -2,6 +2,7 @@ /mob/living/simple_animal/retaliate/goat name = "goat" desc = "Not known for their pleasant disposition." + tt_desc = "Oreamnos americanus" icon_state = "goat" icon_living = "goat" icon_dead = "goat_dead" @@ -85,6 +86,7 @@ /mob/living/simple_animal/cow name = "cow" desc = "Known for their milk, just don't tip them over." + tt_desc = "Bos taurus" icon_state = "cow" icon_living = "cow" icon_dead = "cow_dead" @@ -153,6 +155,7 @@ /mob/living/simple_animal/chick name = "\improper chick" desc = "Adorable! They make such a racket though." + tt_desc = "Gallus domesticus" icon_state = "chick" icon_living = "chick" icon_dead = "chick_dead" @@ -203,6 +206,7 @@ var/global/chicken_count = 0 /mob/living/simple_animal/chicken name = "\improper chicken" desc = "Hopefully the eggs are good this season." + tt_desc = "Gallus domesticus" icon_state = "chicken" icon_living = "chicken" icon_dead = "chicken_dead" diff --git a/code/modules/mob/living/simple_animal/animals/giant_spider.dm b/code/modules/mob/living/simple_animal/animals/giant_spider.dm index c0b8d75c54..094a3060b0 100644 --- a/code/modules/mob/living/simple_animal/animals/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/animals/giant_spider.dm @@ -8,6 +8,7 @@ /mob/living/simple_animal/hostile/giant_spider name = "giant spider" desc = "Furry and brown, it makes you shudder to look at it. This one has deep red eyes." + tt_desc = "Atrax robustus gigantus" icon_state = "guard" icon_living = "guard" icon_dead = "guard_dead" diff --git a/code/modules/mob/living/simple_animal/animals/goose.dm b/code/modules/mob/living/simple_animal/animals/goose.dm index ce6dbdfda8..67e0bdad81 100644 --- a/code/modules/mob/living/simple_animal/animals/goose.dm +++ b/code/modules/mob/living/simple_animal/animals/goose.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/hostile/goose name = "space goose" desc = "That's no duck. That's a space goose. You have a bad feeling about this." + tt_desc = "Anser aetherius" //Goose space?! icon_state = "goose" icon_living = "goose" icon_dead = "goose_dead" diff --git a/code/modules/mob/living/simple_animal/animals/lizard.dm b/code/modules/mob/living/simple_animal/animals/lizard.dm index 38822faf0d..c4c1487315 100644 --- a/code/modules/mob/living/simple_animal/animals/lizard.dm +++ b/code/modules/mob/living/simple_animal/animals/lizard.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/lizard name = "Lizard" desc = "A cute tiny lizard." + tt_desc = "Gekko gecko" icon = 'icons/mob/critter.dmi' icon_state = "lizard" icon_living = "lizard" diff --git a/code/modules/mob/living/simple_animal/animals/mouse.dm b/code/modules/mob/living/simple_animal/animals/mouse.dm index 87df901527..123e82a611 100644 --- a/code/modules/mob/living/simple_animal/animals/mouse.dm +++ b/code/modules/mob/living/simple_animal/animals/mouse.dm @@ -2,6 +2,7 @@ name = "mouse" real_name = "mouse" desc = "It's a small rodent." + tt_desc = "Mus musculus" icon_state = "mouse_gray" item_state = "mouse_gray" icon_living = "mouse_gray" diff --git a/code/modules/mob/living/simple_animal/animals/parrot.dm b/code/modules/mob/living/simple_animal/animals/parrot.dm index e495c0e1c7..f48dace302 100644 --- a/code/modules/mob/living/simple_animal/animals/parrot.dm +++ b/code/modules/mob/living/simple_animal/animals/parrot.dm @@ -31,6 +31,7 @@ /mob/living/simple_animal/parrot name = "parrot" desc = "The parrot squawks, \"It's a parrot! BAWWK!\"" + tt_desc = "Poicephalus robustus" icon = 'icons/mob/animal.dmi' icon_state = "parrot_fly" icon_living = "parrot_fly" diff --git a/code/modules/mob/living/simple_animal/animals/penguin.dm b/code/modules/mob/living/simple_animal/animals/penguin.dm index 4bb985d1ac..8463d9ac39 100644 --- a/code/modules/mob/living/simple_animal/animals/penguin.dm +++ b/code/modules/mob/living/simple_animal/animals/penguin.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/penguin name = "space penguin" desc = "An ungainly, waddling, cute, and VERY well-dressed bird." + tt_desc = "Aptenodytes forsteri" icon_state = "penguin" icon_living = "penguin" icon_dead = "penguin_dead" diff --git a/code/modules/mob/living/simple_animal/animals/slime.dm b/code/modules/mob/living/simple_animal/animals/slime.dm index d3a8b1df0c..8c6ef9cf82 100644 --- a/code/modules/mob/living/simple_animal/animals/slime.dm +++ b/code/modules/mob/living/simple_animal/animals/slime.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/old_slime name = "pet slime" desc = "A lovable, domesticated slime." + tt_desc = "Amorphidae proteus" icon = 'icons/mob/slimes.dmi' icon_state = "grey baby slime" icon_living = "grey baby slime" diff --git a/code/modules/mob/living/simple_animal/animals/spiderbot.dm b/code/modules/mob/living/simple_animal/animals/spiderbot.dm index 7ae8edfb7a..83f18c071a 100644 --- a/code/modules/mob/living/simple_animal/animals/spiderbot.dm +++ b/code/modules/mob/living/simple_animal/animals/spiderbot.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/spiderbot name = "spider-bot" desc = "A skittering robotic friend!" + tt_desc = "Maintenance Robot" icon = 'icons/mob/robots.dmi' icon_state = "spiderbot-chassis" icon_living = "spiderbot-chassis" diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 5bf254583a..e6f584708b 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -5,6 +5,7 @@ /mob/living/simple_animal name = "animal" + desc = "" icon = 'icons/mob/animal.dmi' health = 20 maxHealth = 20 @@ -13,6 +14,8 @@ mob_swap_flags = MONKEY|SLIME|HUMAN mob_push_flags = MONKEY|SLIME|HUMAN + var/tt_desc = "Uncataloged Life Form" //Tooltip description + //Settings for played mobs var/show_stat_health = 1 // Does the percentage health show in the stat panel for the mob var/ai_inactive = 0 // Set to 1 to turn off most AI actions @@ -1718,3 +1721,6 @@ /mob/living/simple_animal/retaliate retaliate = 1 destroy_surroundings = 1 + +/mob/living/simple_animal/make_nametag_desc(mob/user) + return "tt_desc" diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index cf50a44f85..9f316ba184 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -58,3 +58,7 @@ //set macro to normal incase it was overriden (like cyborg currently does) client.set_hotkeys_macro("macro", "hotkeymode") + + if(!client.tooltips) + client.tooltips = new(client) + \ No newline at end of file diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 2b2600b658..f9f09be42f 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1143,3 +1143,14 @@ mob/proc/yank_out_object() //Throwing stuff /mob/proc/throw_item(atom/target) return + +/mob/MouseEntered(location, control, params) + if(usr != src && usr.is_preference_enabled(/datum/client_preference/mob_tooltips)) + openToolTip(user = usr, tip_src = src, params = params, title = make_nametag_name(usr), content = make_nametag_desc(usr)) + + ..() + +/mob/MouseExited() + closeToolTip(usr) //No reason not to, really + + ..() diff --git a/code/modules/tooltip/tooltip.dm b/code/modules/tooltip/tooltip.dm new file mode 100644 index 0000000000..1b03157e83 --- /dev/null +++ b/code/modules/tooltip/tooltip.dm @@ -0,0 +1,124 @@ +/* +Tooltips v1.1 - 22/10/15 +Developed by Wire (#goonstation on irc.synirc.net) +- Added support for screen_loc pixel offsets. Should work. Maybe. +- Added init function to more efficiently send base vars + +Configuration: +- Set control to the correct skin element (remember to actually place the skin element) +- Set file to the correct path for the .html file (remember to actually place the html file) +- Attach the datum to the user client on login, e.g. +/client/New() + src.tooltips = new /datum/tooltip(src) + +Usage: +- Define mouse event procs on your (probably HUD) object and simply call the show and hide procs respectively: +/obj/screen/hud + MouseEntered(location, control, params) + usr.client.tooltip.show(params, title = src.name, content = src.desc) + + MouseExited() + usr.client.tooltip.hide() + +Customization: +- Theming can be done by passing the theme var to show() and using css in the html file to change the look +- For your convenience some pre-made themes are included + +Notes: +- You may have noticed 90% of the work is done via javascript on the client. Gotta save those cycles man. +- This is entirely untested in any other codebase besides goonstation so I have no idea if it will port nicely. Good luck! + - After testing and discussion (Wire, Remie, MrPerson, AnturK) ToolTips are ok and work for /tg/station13 +*/ + + +/datum/tooltip + var/client/owner + var/control = "mainwindow.tooltip" + var/showing = 0 + var/queueHide = 0 + var/init = 0 + + +/datum/tooltip/New(client/C) + if (C) + owner = C + owner << browse(file2text('code/modules/tooltip/tooltip.html'), "window=[control]") + ..() + + +/datum/tooltip/proc/show(atom/movable/thing, params = null, title = null, content = null, theme = "default", special = "none") + if (!thing || !params || (!title && !content) || !owner || !isnum(world.icon_size)) + return 0 + if (!init) + //Initialize some vars + init = 1 + owner << output(list2params(list(world.icon_size, control)), "[control]:tooltip.init") + + showing = 1 + + if (title && content) + title = "

[title]

" + content = "

[content]

" + else if (title && !content) + title = "

[title]

" + else if (!title && content) + content = "

[content]

" + + // Strip macros from item names + title = replacetext(title, "\proper", "") + title = replacetext(title, "\improper", "") + + //Make our dumb param object + if(params[1] != "i") //Byond Bug: http://www.byond.com/forum/?post=2352648 + params = "icon-x=16;icon-y=16;[params]" //Put in some placeholders + params = {"{ "cursor": "[params]", "screenLoc": "[thing.screen_loc]" }"} + + //Send stuff to the tooltip + var/view_size = getviewsize(owner.view) + owner << output(list2params(list(params, view_size[1] , view_size[2], "[title][content]", theme, special)), "[control]:tooltip.update") + + //If a hide() was hit while we were showing, run hide() again to avoid stuck tooltips + showing = 0 + if (queueHide) + hide() + + return 1 + + +/datum/tooltip/proc/hide() + if (queueHide) + schedule_task_with_source_in(1, src, .proc/do_hide) + else + do_hide() + + queueHide = showing ? TRUE : FALSE + + return TRUE + +/datum/tooltip/proc/do_hide() + winshow(owner, control, FALSE) + +/* TG SPECIFIC CODE */ + + +//Open a tooltip for user, at a location based on params +//Theme is a CSS class in tooltip.html, by default this wrapper chooses a CSS class based on the user's UI_style (Midnight, Plasmafire, Retro, etc) +//Includes sanity.checks +/proc/openToolTip(mob/user = null, atom/movable/tip_src = null, params = null, title = "", content = "", theme = "") + if(istype(user)) + if(user.client && user.client.tooltips) + if(!theme && user.client.prefs && user.client.prefs.tooltipstyle) + theme = lowertext(user.client.prefs.tooltipstyle) + if(!theme) + theme = "midnight" + user.client.tooltips.show(tip_src, params, title, content, theme) + + +//Arbitrarily close a user's tooltip +//Includes sanity checks. +/proc/closeToolTip(mob/user) + if(istype(user)) + if(user.client && user.client.tooltips) + user.client.tooltips.hide() + + diff --git a/code/modules/tooltip/tooltip.html b/code/modules/tooltip/tooltip.html new file mode 100644 index 0000000000..67fb8a77f1 --- /dev/null +++ b/code/modules/tooltip/tooltip.html @@ -0,0 +1,249 @@ + + + + Tooltip + + + + + +
+
+
+ + + + diff --git a/interface/skin.dmf b/interface/skin.dmf index 0bfc8524ae..ea7d069105 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -1940,6 +1940,14 @@ window "mainwindow" is-checked = false group = "" button-type = pushbox + elem "tooltip" + type = BROWSER + pos = 0,0 + size = 999x999 + anchor1 = none + anchor2 = none + is-visible = false + saved-params = "" window "mapwindow" elem "mapwindow" diff --git a/vorestation.dme b/vorestation.dme index e780d3caf8..4a792be2d3 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -2648,6 +2648,7 @@ #include "code\modules\telesci\telepad.dm" #include "code\modules\telesci\telesci_computer.dm" #include "code\modules\tension\tension.dm" +#include "code\modules\tooltip\tooltip.dm" #include "code\modules\turbolift\_turbolift.dm" #include "code\modules\turbolift\turbolift.dm" #include "code\modules\turbolift\turbolift_areas.dm" From 949ea35aa7c5eb8220ccdedfd796fa25d891b07b Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Mon, 12 Mar 2018 18:26:09 -0400 Subject: [PATCH 17/21] VS: Changes for tooltips --- code/modules/mob/living/carbon/human/human.dm | 2 ++ code/modules/mob/living/simple_animal/animals/fox_vr.dm | 3 +++ code/modules/mob/living/simple_animal/vore/awoo.dm | 1 + code/modules/mob/living/simple_animal/vore/catgirl.dm | 1 + code/modules/mob/living/simple_animal/vore/fennec.dm | 1 + code/modules/mob/living/simple_animal/vore/frog.dm | 1 + code/modules/mob/living/simple_animal/vore/gaslamp.dm | 1 + code/modules/mob/living/simple_animal/vore/horse.dm | 1 + code/modules/mob/living/simple_animal/vore/otie.dm | 1 + code/modules/mob/living/simple_animal/vore/panther.dm | 1 + code/modules/mob/living/simple_animal/vore/wah.dm | 2 ++ code/modules/mob/living/simple_animal/vore/wolf.dm | 1 + 12 files changed, 16 insertions(+) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 04370d4fd7..df0a9333b7 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1579,6 +1579,8 @@ /mob/living/carbon/human/proc/get_display_species() //Shows species in tooltip + if(src.custom_species) //VOREStation Add + return custom_species //VOREStation Add //Beepboops get special text if obviously beepboop if(looksSynthetic()) if(gender == MALE) diff --git a/code/modules/mob/living/simple_animal/animals/fox_vr.dm b/code/modules/mob/living/simple_animal/animals/fox_vr.dm index 65938cb249..90131fc8b9 100644 --- a/code/modules/mob/living/simple_animal/animals/fox_vr.dm +++ b/code/modules/mob/living/simple_animal/animals/fox_vr.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/fox name = "fox" desc = "It's a fox. I wonder what it says?" + tt_desc = "Vulpes vulpes" icon = 'icons/mob/fox_vr.dmi' icon_state = "fox2" icon_living = "fox2" @@ -183,6 +184,7 @@ /mob/living/simple_animal/fox/fluff/Renault name = "Renault" desc = "Renault, the Colony Director's trustworthy fox. I wonder what it says?" + tt_desc = "Vulpes nobilis" befriend_job = "Colony Director" /mob/living/simple_animal/fox/fluff/Renault/init_belly() @@ -218,6 +220,7 @@ /mob/living/simple_animal/fox/syndicate name = "syndi-fox" desc = "It's a DASTARDLY fox! The horror! Call the shuttle!" + tt_desc = "Vulpes malus" icon = 'icons/mob/fox_vr.dmi' icon_state = "syndifox" icon_living = "syndifox" diff --git a/code/modules/mob/living/simple_animal/vore/awoo.dm b/code/modules/mob/living/simple_animal/vore/awoo.dm index 95234454af..fbd6d8dac5 100644 --- a/code/modules/mob/living/simple_animal/vore/awoo.dm +++ b/code/modules/mob/living/simple_animal/vore/awoo.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/retaliate/awoo name = "wolfgirl" desc = "AwooOOOOoooo!" + tt_desc = "Homo lupus" icon = 'icons/mob/vore.dmi' icon_state = "awoo" icon_living = "awoo" diff --git a/code/modules/mob/living/simple_animal/vore/catgirl.dm b/code/modules/mob/living/simple_animal/vore/catgirl.dm index f0c0f8ad25..dc8b5f1d8d 100644 --- a/code/modules/mob/living/simple_animal/vore/catgirl.dm +++ b/code/modules/mob/living/simple_animal/vore/catgirl.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/catgirl name = "catgirl" desc = "Her hobbies are catnaps, knocking things over, and headpats." + tt_desc = "Homo felinus" icon = 'icons/mob/vore.dmi' icon_state = "catgirl" diff --git a/code/modules/mob/living/simple_animal/vore/fennec.dm b/code/modules/mob/living/simple_animal/vore/fennec.dm index e658f8f441..1f7a869a4a 100644 --- a/code/modules/mob/living/simple_animal/vore/fennec.dm +++ b/code/modules/mob/living/simple_animal/vore/fennec.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/fennec name = "fennec" desc = "It's a dusty big-eared sandfox! Adorable!" + tt_desc = "Vulpes zerda" icon = 'icons/mob/vore.dmi' icon_state = "fennec" icon_living = "fennec" diff --git a/code/modules/mob/living/simple_animal/vore/frog.dm b/code/modules/mob/living/simple_animal/vore/frog.dm index 45f73456e8..ae4389914b 100644 --- a/code/modules/mob/living/simple_animal/vore/frog.dm +++ b/code/modules/mob/living/simple_animal/vore/frog.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/hostile/frog name = "giant frog" desc = "You've heard of having a frog in your throat, now get ready for the reverse." + tt_desc = "Anura gigantus" icon = 'icons/mob/vore.dmi' icon_dead = "frog-dead" icon_living = "frog" diff --git a/code/modules/mob/living/simple_animal/vore/gaslamp.dm b/code/modules/mob/living/simple_animal/vore/gaslamp.dm index 121cc6acfc..8df8d216b4 100644 --- a/code/modules/mob/living/simple_animal/vore/gaslamp.dm +++ b/code/modules/mob/living/simple_animal/vore/gaslamp.dm @@ -13,6 +13,7 @@ TODO: Make them light up and heat the air when exposed to oxygen. /mob/living/simple_animal/retaliate/gaslamp name = "gaslamp" desc = "Some sort of floaty alien with a warm glow. This creature is endemic to Virgo-3B." + tt_desc = "Semaeostomeae virginus" icon = 'icons/mob/vore32x64.dmi' icon_state = "gaslamp" icon_living = "gaslamp" diff --git a/code/modules/mob/living/simple_animal/vore/horse.dm b/code/modules/mob/living/simple_animal/vore/horse.dm index 35d8603094..59bbfa4550 100644 --- a/code/modules/mob/living/simple_animal/vore/horse.dm +++ b/code/modules/mob/living/simple_animal/vore/horse.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/horse name = "horse" desc = "Don't look it in the mouth." + tt_desc = "Equus ferus caballus" icon = 'icons/mob/vore.dmi' icon_state = "horse" icon_living = "horse" diff --git a/code/modules/mob/living/simple_animal/vore/otie.dm b/code/modules/mob/living/simple_animal/vore/otie.dm index eb814c5425..184ab76888 100644 --- a/code/modules/mob/living/simple_animal/vore/otie.dm +++ b/code/modules/mob/living/simple_animal/vore/otie.dm @@ -6,6 +6,7 @@ /mob/living/simple_animal/otie //Spawn this one only if you're looking for a bad time. Not friendly. name = "otie" desc = "The classic bioengineered longdog." + tt_desc = "Canis otis" icon = 'icons/mob/vore64x32.dmi' icon_state = "otie" icon_living = "otie" diff --git a/code/modules/mob/living/simple_animal/vore/panther.dm b/code/modules/mob/living/simple_animal/vore/panther.dm index f22fd275a1..3e723e68fc 100644 --- a/code/modules/mob/living/simple_animal/vore/panther.dm +++ b/code/modules/mob/living/simple_animal/vore/panther.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/hostile/panther name = "panther" desc = "Runtime's larger, less cuddly cousin." + tt_desc = "Panthera pardus" icon = 'icons/mob/vore64x64.dmi' icon_state = "panther" icon_living = "panther" diff --git a/code/modules/mob/living/simple_animal/vore/wah.dm b/code/modules/mob/living/simple_animal/vore/wah.dm index b0fd4887bf..316441edd7 100644 --- a/code/modules/mob/living/simple_animal/vore/wah.dm +++ b/code/modules/mob/living/simple_animal/vore/wah.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/wah name = "red panda" desc = "It's a wah! Beware of doom pounce!" + tt_desc = "Ailurus fulgens" icon = 'icons/mob/vore.dmi' icon_state = "wah" icon_living = "wah" @@ -39,6 +40,7 @@ /mob/living/simple_animal/wah/fae name = "dark wah" desc = "Ominous, but still cute!" + tt_desc = "Ailurus brattus" icon_state = "wah_fae" icon_living = "wah_fae" diff --git a/code/modules/mob/living/simple_animal/vore/wolf.dm b/code/modules/mob/living/simple_animal/vore/wolf.dm index e503847030..fe3a970ac0 100644 --- a/code/modules/mob/living/simple_animal/vore/wolf.dm +++ b/code/modules/mob/living/simple_animal/vore/wolf.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/hostile/wolf name = "grey wolf" desc = "My, what big jaws it has!" + tt_desc = "Canis lupus" icon = 'icons/mob/vore.dmi' icon_dead = "wolf-dead" icon_living = "wolf" From 13f506ba6092ea74c7085d4d25e20e5056b23edd Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Mon, 12 Mar 2018 20:25:36 -0400 Subject: [PATCH 18/21] POLARIS: Rename make_nametag_name/desc --- code/game/atoms.dm | 4 ++-- code/modules/mob/living/carbon/human/human.dm | 4 ++-- code/modules/mob/living/simple_animal/simple_animal.dm | 2 +- code/modules/mob/mob.dm | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index c396a54839..e18970802e 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -512,8 +512,8 @@ /atom/proc/AllowDrop() return FALSE -/atom/proc/make_nametag_name(mob/user) +/atom/proc/get_nametag_name(mob/user) return name -/atom/proc/make_nametag_desc(mob/user) +/atom/proc/get_nametag_desc(mob/user) return "" //Desc itself is often too long to use diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index df0a9333b7..facc1ac438 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1595,10 +1595,10 @@ //Else CRITICAL FAILURE! return "" -/mob/living/carbon/human/make_nametag_name(mob/user) +/mob/living/carbon/human/get_nametag_name(mob/user) return name //Could do fancy stuff here? -/mob/living/carbon/human/make_nametag_desc(mob/user) +/mob/living/carbon/human/get_nametag_desc(mob/user) var/msg = "" if(hasHUD(user,"security")) //Try to find their name diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index e6f584708b..cde93f797d 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -1722,5 +1722,5 @@ retaliate = 1 destroy_surroundings = 1 -/mob/living/simple_animal/make_nametag_desc(mob/user) +/mob/living/simple_animal/get_nametag_desc(mob/user) return "tt_desc" diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index f9f09be42f..cb3dc7e2ab 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1146,7 +1146,7 @@ mob/proc/yank_out_object() /mob/MouseEntered(location, control, params) if(usr != src && usr.is_preference_enabled(/datum/client_preference/mob_tooltips)) - openToolTip(user = usr, tip_src = src, params = params, title = make_nametag_name(usr), content = make_nametag_desc(usr)) + openToolTip(user = usr, tip_src = src, params = params, title = get_nametag_name(usr), content = get_nametag_desc(usr)) ..() From b648d03759c21d5bd6eb3c4e80968f01eb144fb3 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Mon, 12 Mar 2018 21:32:08 -0400 Subject: [PATCH 19/21] Fixes #3224 - Elevator leave message typo --- maps/tether/tether-10-colony.dmm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/maps/tether/tether-10-colony.dmm b/maps/tether/tether-10-colony.dmm index 19c2b2a089..1764cceff1 100644 --- a/maps/tether/tether-10-colony.dmm +++ b/maps/tether/tether-10-colony.dmm @@ -11467,11 +11467,11 @@ dir = 2; icon = 'icons/obj/doors/Door2x1glass.dmi'; icon_state = "door_closed"; - name = "Elevator"; - on_enter_occupant_message = "The elevator door closes slowly, You can now head for residential, comercial and several other floors."; + name = "elevator"; + on_enter_occupant_message = "The elevator doors close slowly. You can now head off for the residential, commercial, and other floors."; on_store_message = "has departed for one of the various colony floors"; - on_store_name = "Colonial Oversight"; - on_store_visible_message_2 = "to the colonial districts."; + on_store_name = "Colony Oversight"; + on_store_visible_message_2 = "to the colony districts."; time_till_despawn = 5 }, /turf/unsimulated/floor/steel, From 0dbb0b19df0a1811041acc7eca23242484bb01cb Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Mon, 12 Mar 2018 23:00:12 -0400 Subject: [PATCH 20/21] Block prometheans from using synthparts --- code/modules/organs/robolimbs.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/organs/robolimbs.dm b/code/modules/organs/robolimbs.dm index 12933c0ff2..63376a7203 100644 --- a/code/modules/organs/robolimbs.dm +++ b/code/modules/organs/robolimbs.dm @@ -42,7 +42,7 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ var/lifelike // If set, appears organic. var/skin_tone // If set, applies skin tone rather than part color var/blood_color = "#030303" - var/list/species_cannot_use = list("Teshari") + var/list/species_cannot_use = list("Teshari", "Promethean") //VOREStation Add var/list/monitor_styles //If empty, the model of limbs offers a head compatible with monitors. var/parts = BP_ALL //Defines what parts said brand can replace on a body. var/health_hud_intensity = 1 // Intensity modifier for the health GUI indicator. From 9d95abe508c08ee2d8d0f36bf91b5e5d40966971 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Tue, 13 Mar 2018 10:32:45 -0400 Subject: [PATCH 21/21] Add missing joint sprites --- icons/mob/mask_vr.dmi | Bin 30406 -> 31472 bytes icons/obj/clothing/masks_vr.dmi | Bin 21125 -> 21970 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/mob/mask_vr.dmi b/icons/mob/mask_vr.dmi index c6ce65576fc30c0644f014ce160d42d210899644..331585235816372b62f0b49386faa64f49617f92 100644 GIT binary patch literal 31472 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 RLHuSJUb=R%_;35C{|lq7z@z{G literal 30406 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 diff --git a/icons/obj/clothing/masks_vr.dmi b/icons/obj/clothing/masks_vr.dmi index a96948180b6b79f0ab9d30d2ec1c4664344211ec..3850f292c51abb72e58f9a836be4b2bdaefb3636 100644 GIT binary patch literal 21970 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 literal 21125 zcmbrm1yEg2(SrVOSad+#cVrS=`2TzD`}FUlipV zjw6JO?+cjZXs@=*mgu`6xGcR{$6cs2k=%c#^NuF#?r%H_1=Z#c!yDkllluNw@FIh> zrXtmn$t|rq=k1c>=}#KjIr_zogTo8&9Ik2aT6Cbab-w2_54%UdKf)S*)c9f@>}sUE?jyja~iDh*k3 z%UdN75uG&Vr)Blck!8J7=|$)z3u4dtV-qH* zqD~;BA-9vlDA1C|C~r>m`J?_HRa*Kd-wATz6JL78EJJO&HR<0uO6L>yO@uoJe|!x{ z{1HP<^%T6asR@CE26Nt=M6z5HJ2X-)Kc{zcLUS*t+hjr!e$MdcD`_9lS*8)$F-q1} z-F5nkHJ2)Wk}qoAdw?l59m0;w=Y$io;-K=kIG|4bd!fT6S)gcdItA@+GXT&5FXd%4 zz0wZSz5R&K7kZ@P++ND!y1Jt1#@?`SpyZoqv+J|`P*YIGCx~aHv#)u9C%^Ijy}pXX z6OK>X*~AzMUc?nSIm!6qrhxoXkW(C zg%6>V1Yrap>%D*=%fLC9q=V^1pWD{V?XU^zB%(loX`N4W=F$U~F1W*wd2 z=R??ST2}~6t*UKD0heMItC8H8Q{#d6rz7#B)}%VzU9$np$G7r8YqMDCNf){CRKn3=HR43rQ@vYs3au0xF}Q?3 zVupxYLBfdkFWojXb8~e~%?aDZG!eI%B&;ToEB4ai(MlZRo5>rOT7 znyKJSrZ;fC!EI}GuEvh^^!nmpZ`E zYgWR*tCNlW{b+vN80gBW5`;Hw@Vk(w2!*1&Jl*-2HAz)0ISm29BfI3~<+IAOfIxN; z?Fy^qyA{`NU+;{>mm5My{icI*cyteQg#hH8KP`UYQPURH^#`Y`U;KI|h4^%2OWHVn zOUMlHv;4sh15-&lfhQ&}Ps_Et11-3q?ZJpZ>tbs$$-P~{v`W(K_iLA~Ux=Ydt?{gH zEfSWY_vhR}{oHJ#bBC^9cweRPq3G%9%{2Sg?K5Y6sK7gZH5y|b7`@)Jv(PA1pq9zC zcOU3;<=PE&c6ZC>zE5%7gJVTTeWXLzZSfPCuYMoL0qe0EAi2DGdBD}Uw6pJ8nlrvL z^M!&x)@P>*^Fd&I@ACeNNbov0vK_2E9#x`UnP4F~eV9DEo|uSXpBhLeD3wPXVUX(S zZ}PtsNouLa&3O+`o{JRS0S><5%hWG1TEue zypADr`XSUxbP-MYVJi??=fonUS7C-ixyS+i^^4pe91fr~CCkBEqH*2eqP zvvj;_21pwkrg0F)E58=yB1t>v^Gi)5TtBhvV=pD5nfxn`;@`fUM)kP5$3N}+*ux%D zcV4`{t2cX2XZMWdskHDXRKZ_^?^Odcso3+04Fe4QZsn=UlsdIv@>*cLk$hK)Z88LG z#G9DPAS?#Hw1DQQiaOVHP_>H1>ON! zf1lE^*2-^{-a>G>q*-s}zhMqd`R&wGovfj?E-6QAp?kw{@qku8{C%7zeb`w%Yb7a) zBPq#B%vTb)gP!nnz#0Cedr<%va6b7?Gy=deTWJ~D@fmY(fqv`}ig-3sm8W$sYl`ZS zi-LXx^Uc9cLbnU}<1VAK<|POEl#9Dove%vgHUK^(jcDofDMPN@1|~Bh0Rcih&^C)A zQ)BKkCxI4Rg%$kD&pTz-d$>U`vQ6yBr38-Ue#|bz_ml5q{@_DxZG=XT0E<+qOhYq~ z>LC%Ya3kFdQ4arEeMK&1W&P9|k7UmEh;Pzd1Jv6VUzZ|C*vWy;&dw~**gSpuwA>MgM%;@BSU#v* zLN)dP^#unP*U+XGL$tHN_uA4^x9VS2$3#}gSu(2_?ic%dSO_#y0aOYK3M_1F?Xa~T z-hf*#m&Mslsc;g}bhJt+MpTXb4kXE$3Lg~YtRgCprGO> zARr(YcV|JxqmFQDxl%L?=>9^n%5%g@Ki#s$5EpUWKfY0K9p8|Ax3NQd1-lO%>ciV+ zqR3(thv5x8V0dp0@9*1xp%lW^DK$g@US)_=+*}^@B=edB$#{q&RZ?6s){!-!WSo@( zs4@14lnTdr-;@3r-*LV=u>_dRZm!F;k>}^x>~A+2kIWGE)Twl-=E3=ZCw?T&JZL zubYE90%GFOV`sOckPG*~o!%Eu;maX-s~vb!$bd_I@nau)x-vLb_V|vjyZdux6%_-L zpsTYX4+)P?j>tPN^78XB8pyaA*x9knyT7#E-`$Ls8B2j2(Tg|M)=pe~fMB?|DQHSABZhEXKS<`WHzFv-^G7K17vFuO$@SAAFDB|Z&^#p%7yW?BQJM>gO#1YclSuAb^&T>!a?BLvT|}{Yel7$z@q{_BEBtn zC3AniXT}?@~`booEPKi9y&28aX1b&t^e8AndMOmmqv8# zYT}S)t%ohUffW8v2%BMv<~`A$6&52RFkht!t2Zgjf9_uvB@|7MPDn_g=NsDx#{$jl z5c(12_k@I}?|f$UF8v#kUwEN$$=dz?4G)hFIZJd-*9rhIV(HLn!!od5;fD^(4x>Cn zZ@12N*h=11fgkG&C@ zz|QmtgvcvZvA}=zUjLisW^W<-zuQ>BK_E)}(uC|X_|zCN;$+F4O8D|h@-Xb!er`ra zx!x=>B_b~85dIQ7Tqn|>}uwfyI{5RX8Zj@c)R zA(D;#k8t?F+rxju|NldA{ddjzPFDN8_q!5Kn>;#Hjbk1brd3#4$ksd+UqJX^kFNq= z2g-Zuv{9mEm-Rdx?mgYlPH`b#Qh|xFBP_lPDs7Eq->TR?WJ_z-z#Lpg_A7wCf;Hnm zKtCzN3QI6%0<*$beT5}~TgNrkS=u=*_v4oZ+QkH!HUYSoLKFny-!EG1U09IpnM2eh z+7GAClDwo)O0QdW}y>3Ykmon=zN^+RN*|rA_HyOPLCJ} zSqx9xuYhmfq01{MWZO)~Rd&%M)P}qiD62}Ad0P(87UO9$ey+^^nnvP^wM8Ugy-Vy^ zBUPk@SuMagW|&_MfM09m?=O{U7n|}RhV#ijG$7bUp@t3PghzbiM#UI;jhg8biU8qp zN6rb3@^bwv5@Rh%41F4K$<5kQxR%NNvu8SqjrYBYC-!Hoc!`!alf-mU<)|B)W<1mo zaHJ=SKp4#c`c6oB;Mwm;3?mX_$f=aN4&DZj?sx114F)TTG= zM>}({`MHP1zxP>zwt53utX_eN^xCS8auox{xq^j0KFu_WAqeU`49X>8qc)|K9HMY0 zEHP-r$8_Va2wcfO*QD=fcZ)c=t<6Tvd5uB~?-qiQctI9qPv2c!aE`CUFivO0x`Jlw!!R z)B_cOPm&ML4H-rMl8St5>)*fSdxJ!YYbk6f)CU+rJkMjb;lBEk$~{R|l=HO?=3_2S zPEtp^ZEM^a^XIE#kBbY)`09F<&KkA~g|?Z55~%Y$`NH!gX!zX6X2O>I%;)cwdzkaq zI7NGG!x6ftWIFvTgYWcb4MK7=AL=(glua$W|IAmAMibIJdb`a6$laI2-TX*+TdH^1BFtJ&#|WgpJB zc7VV@6#XV*1%Xcp!T6Nu(0*E1J~q!Yt$s6&npe4_x=kk+_Zc6?p@S#)=Q&DZCM^{K z%}T5DeSYHJC(O*uRr5bH;DTjy=CC@4`Dcgyc^?!B26J~Lg~FzC&p*t3!{4aB{H zp7E2Hs;X8;&9w9&ZJnOg5Bac!#Rq=tA>v;f-CaFv>?FQ(bJ%TJXlJNM*x*kQ{9Uc1 z^-d7@JgThkNii!S*DJMD#xp^yDq>eYjHd_?dbuzFxIWtn8S6ug=`^l)&IXeCV^DC^ zOnjln2+cvecDA=%AEL;OefU^{s^iLp__$kLAC?4i|1!d;4<0b$#Ooe{60wIx*WR+7 z#xWG`+sh~{3&vi2IB}N}il#%~&rf>Ses#L_H6x?c>(*humNx*gprD{q?dTR8t5iHF zAK^iIVU2?H;hyN(D}1lob}2^YvAe)&Y^j)jyyJsAr>GCGx+*zDcf_aM=R4tkmkXZz zr^8Y`sRDML987haxM#-KiS>84ObHpklx1#~8gHQNa)?YowFOah0XSV$6ge;A{a&FE?)%H9h$RoI@-Y_^dthdBe!&!58;mM$iaT>3?tkwk^`cJfmrRS&2X> zXWIgsQgFb|AGtBr?^w(2D}X=}kyjIISnCX>ASdn`p zB^M=uyrYa9M$P-vkR{4Jx`hCzI&t4d_}&5G3!MRA-X571)HQF5C&Sgmu>trqMnsqK z#mkxKEI4uI>W!nH=Zn{`Ei?TuD1hbro1?n={#pTC6ffuI#Dzlj4x2Bs@lSZ3V25ic zwb=lxn=QF;)&F$V`5M8^*wL_sA;y7NJZVe*1<3g_66grg&kb5}L(0jSgH{en!&oJ| zE*Icwe>*6X&n)dIJlD~x>7_&3nksf#1P*=AB+0Q+e+bx;o4UV8`ulP9tzX1ZBMgDA z!U{{Qw5+?4*0A%jxcCbY+STg5IBugDU-(7~APc7!sejiho8HR?%@PV@&cqW?{VXrX zVFMF`{p8q+HqTK9ynk(+QsOq$@`39F$8{RCGuWbM@k2!X9V08Z@!lc;j*BQeaGJ=G z+(T#v-c1hEp3iO^d9bwp_`yORr6^yN3t^$de6kH{x93k_4f%?>PZV50RSk4Eg|*vDQWS6X%&3Q@l@6bXyM> zQrPP1kkN3KnkS&CxqLrx_}BmWa?=+HrV*9H9ndZ8_>j8=zRs3u@*p*dR&D z&dPZL(F*{M&+{q0+-_8p)`SND97V+f!#vVo>j#p)wYTz%~wMo&OoZsb_1Q zB*|3TK2KPZPH@cZuhA8P>KT%F{k#6u2jtGFOtH*F>yEUb|M1+6bcSDiLe^)DV+3rO ze*BLsN~1zLU^jV}FR{AzFUL}}s|NH$@s*|j&s@&`&WHK8L%VI^wTG}{L;xOWcfLpG zzsCB+L*VKgfKhim^?77cwRI>=XrmYz)EMvcPGJ93N$Y&QM?JG12@uT({O>+pPF;A0 z<|GLP-bB;U?l>*~S;{TWaC2AjBNOpFq&iJRZ=(2q%tgIZcl2U!?44*j&^R`9^u_B2 z4>%5Zwp-j|tTf|MqHQNcG}!BW_x?k=DrB*Jp1GyY+%xpUv7)^`+EEXxe&^*~1>Wd{ zCZ3cGWSI<*IR=4X{M%a|_rGd}iCGLEAVoz*uZk!6O0@eyoo87j=A4f!`x$PCxEOx4 z8^mnw=eb@uap7zC;Ol#1H0akj2OHif9G>~y3Zc6_n;ho#H7^i`78N0kPvx&Il5h(T z;5*RUp(dxM_DSCC^8<(ZxelXKK|d_~toi7lt~P!PVr{;Iti_eHJ3-xz{5V^x0s-Z& zEsdM&Wo?dICBfj1_E9l5svv{__;C!hEu2}0k&lVkWn}@s6tlg(u}73ztTpAME1pw% z`R=l>P95g*=eS|$GUGa_U#B>=)a5biCLUegGUFy5&=FRnuUG`{2*V-DgCPtb1=7$C z?k)d;Q(N93K*~bOy0*5cX)oRVRHfh0J$Y3(+Gvd!jCAMHSc*Vag=apJ?27=52PQ;x zKbs~T5=2SXt@?N{rn7ci0|KJ4EfOwE=>{{CvBWNnv}wHQTAGtUY~UJ^U2VA$?ZTO( zALxU06~ZN-7)Jz33pGJ~o@Bs#0@Y1__8i7Hwjm=FLKpC~UI-tO`{My7U$OG_3;9~7 zYlr0Cz>$&NX+MVbjrZOjQzM5aZ*l7J#60ah1AxCG?}LaLCMyNLU&7LhJW=Pd4p~ z!hdUdyK20LF*CpIdNcr-H9k;qt~*3OBn?Z8%QW4dxtYJ^D*WBX0dnXZ8?R<&yJ?k= zSW^=TvPuc+qJI=Pm4W}QR~U1;=kDHvoOCQ^M~|9Qm3sG10OV0ako=9C`p--{v3+j@ z!KF?i4J`u%P#1k6=gc{FBPZK zH>U7t9Fiahx`b3sv)W~|sv5)1w-mv-SLrDoQa2R+8ItML_p`&lCp-vRP%uVNHC#j( zb{sg}6zz>TZwzW|Ng@SP@QvSw*u-HJYnL!!5T+CUL~@rNo7bO8Y@!-GvelzCNnH9j zh%_MOi7OU{BX=t7yOE&tJAV6fDIP{SwJ;;JH2!X3!j|Is6QC7r3*(k~{D*UsnFX#Z z9~?_bn1z(~9;m2$r9((t$itL32t!sYjm0}T5ueYGFh1J%>G{s=Tuh>yJ6b+6@cP;j znUKL@Xc(%83X$Jtvr<=bbZKTUnrtO`zCH(-EZ`KhVHxE~8K&xDg6ql+m{~aWUaAL=OKU(Y%zlYnf z9stmBaTQ;<`InE{Xub*tk(}4*q9l+80>`0a(X=Lu_NzH(K>GD-oKmC4%`xxg>VK#K z!+$(BBXmIPSiVYy_o)@o3I^ZGKkR7(tzD61pj$%n)uivFYZZZjL~)P?BKZ=QO9x} zVM!Hxmr`gzXQ<-m%!IeWi^BK$i0dc)dv|ZK>tRlj8+qgPvNr+km{@``!_@PJro1zNB>JT4Hs6Cx(%aV_p#M50@wom*L{k-Ewc zyiipo{T3IO&c;yRUj;QBOr${m0>8xx{V`BXO=+6=#--tEy^L32dBC6jc%NIRYWm$m zRycaz>e|?MmNSw%tC{ThK%!!`QiGuHqfksB7#alQdnT8M3pvO3uis+YUBNDs zlgV8&zCBMn??5X;1zJ1o2FB}eC9isScmR^)ZDYbVNOA8+HIca)Yg&$vB}BdSY%wSHqRp{vNZN3MzL_L?>OYW zK*U!)0DLU>wayf5=^`vd7Pjmo27`YJRK{R5Q$ME%4!B0e_VJ&(EfZ%HZJ}B!5fNg4IEB)Zw`A=XX`AMf`La?>Z z)cAU^bpWV;Nb?vT*BWO9xrk`Ibu+3E#s#mmj62ik6m^#aAHwyNVaM+KDmyfMD$VAtbiag4fr& zN851r?ir%>9YK>n2h7o{_(S~$;d~dqxlli$G`tM3TzXW8CZpFZoWU9 zgsJ|LkcbE*Jvf>CwC`+p5^H5;rT5PtnL5XXPEncsUBoTyG9(kyrC%;r@TMPR%F4<- zDhyDOj=kd{7o{b$&mi6mJnAn^Ev=PLQn%Szlc{REU%p_kNIhKPVPRo)fQk-*WtwF3 zYAe$^znh_{%Dh;Cu{Z8Ci9wVNHxS-IYY|m^y|A`l5~0k2d*nE}ZJG{yS@@dxdKIh@ zzfZzLHmIAj9VTHIvIsKbJbkne37V8$4CRd2{AlILBP_FxZO3cIUVF#@gp&qMO3Dof zbfn|D+@Nha_RJ~$4O_PDNV-b7~ETfMC!#|T(0Jz zIyMfm9Mz_WC(-^9f`xj4^Z?#ngo-yWCN%|+8{x| z@iR!5HvbZGxqQP~rph2kJKuVwn|_#t3x(m!&$E?aTu2zavfSR@;!{)O01>r_4@WoN zXXuVG-}&m%7#FZx1`R2{X1#)~Wfsx*srlSiJtXr>3B)(!XXP618E9w(gZ@fr zXlS@jFo@x@vdJtipt{svJ8-U@=+}QXT#Ym1=3gU3X5jtpo5CW_TFA!e zf|*bvD&6mIEN$I6HCfpjEv+PWFY!`eKeg4sqqw*jlw>3*Tw*dZMmjp6t!7DtA+f0c1e_Iy5D?E(qg*S z_CprVwbyX<3nhGNGQuoM;omtOQ^J;EkG(|y2{-ipF99F`z#`=^0n2gGwe2Hnrdw`; z5E=0gKJ520_%Xu?XkA6vYC(LAC;_dY3HMk1r&|6oy$3Xe@K?Oa|Gx*1IA7;PhD-Hk zv!R`u;vWz$Qe_zVtJ&SUXTH-%hrtUp+UjuVat9tsWT4HRvfzgU#iW*{^kIB?1DlR- zR8xbNnwB0v%()KAraRB6dFV(1o>LjE#%Y(sF(r$@gkN{~ zO(3zR5F)S%g?;V0s1fA&Og)|Tca(4KJlt6)_>qYq4h~dq z_5?^NQfzn~W{wx@^_)i?FqFHdJ#9E_*=*HQjp>IxwL-ZpA)r_Jva1JndfL(CecEXm z|7|&~MrbznYh1-*;4c=*AvIaqSRq%w&0i9I>xs+f<4d`EHaTYnoVxTwnS!>2PjDU0 zA$nnv#T^q!jywKhTr7jfaK~g+tb!#B-xC z)V9|mCm|Am$r!X{YGxf>cU5&iWHGKKuoTvA*u*>a!esJJ*dI>85vVdOd~I9>mD zU(zk8RKzs5WXK=6uyDflj$v#cYB@#KZirEbB|G7xKwle_BjOZ7yXo&Ruwb*R%NIgC zTKu>OxzAEQS@r=RbMW*`oaqp?2+$+p7qDdNeVA z)Os*?h?LAa0I*kAS7*o2Cqr?tl(-eM_g~cV_?6rS%u_6dF&9>u1WI2{^;8~S7AA39 zV@uoHbNuAvYwhZJT2CAf0FoT(v;~v0_{d3hMyV){i%k@s7wY(&}Wy3$du0}GZ3p%u6QjKNCf??*?RT|>%^cYm6H#$c# zoy*AXWxLT?%O=UTgIwgElD}1Y)gmOWz@2V*T}hhr_k_LJq4N7iNx+u5scww4`Zw3| zN48OteFC%oK#eR{CKQQNPMpDcwR0}*;=&7NV&RjKF_r+E%|!BreeT7FglGg* z@XOZDBZqZ+k8UrOVCE>Rsz#0K!qov!kp{X}Lgtr1pA^3ZQEo}e zceNk3DR!5v2t0TDZ$9Fvsak&uxWivlu<-oaN6DjuV1r;)w#{zI{zj4}e0j|HU)fk6 z8rYUQ94MWSet6wp?(u;Ifve=9&pJ|F$Dh(tz$(a5??!lB{OqYCsdjDgeOYY*jXH*@ z*{F~((}57&Nm@= zm1>I6&rM(Bf{tR$T1!{Rf#sA@Cqy8?)fU4UQ&{TywI9qza40a4*y~uPK(qf?b5Ix* zclnR4wGSc6Ye%%<@!(|?^rKzoHV41cYi6Fk@KbC1NJd76hQP^OsW@KwItl0roZzW@A*i-C$(8XZ@C|(jY7j zst0lN`0qY(7?jh)J(K?ZU+W$MT|O+iK93Iw@rir+*_j$~FNY39cL=lmKId`0(m#t+ z34k;#mX#O$DPnLmeNBXWcb)BVckx}&fiNO6a$d`?=3de|>7e9iyN(-wwu^ee*n8Tg zMlyq?YWq6}wN2*yB60krDy*-*`=VUdWDy+=J*A8fenkqSGZblDh-9Rsh` zcRAFa?<$7lOZ|Gd815agHx@TY`Tl{lK2HS8Z(Q|a3n$0-!r>3{(_VV$k5C@uPZP3} zhRvhRO6aofA?jYU;dEMA2Imk}3?48OX9V21yAws57=wYhU~rfp?~E6^vA)hShS>z# z`i}>AlDz@owW;r@{=w>(#CxubW>9eAA=4FCD{F9=uer&OvZQ8n_tqaTZG`V?l6R>8 z-lO^`3?c*Tlz8FifvbGiM6O|VbT-Gj99QQ{T`;NbXIWfzb|gU}Q?hH!_1a4w?B!{% z{Jo)X%FR&M?tp{I)4{+sM$?0Iyo&Rs`xHwn-1pO>vvCc%QjpSK(2EFdP@y%g5m>-a zz<*}tO~2Ciqv(giB@I34STS4UfjfJ-${i5*?OQq5-D!lmd?a0 zED^!9d;PD9_^oLh5>O9L-^+0|SY}yEJ6_-!qxeNDk}fpBKdJA2jv<%rExL*_8xrK_ zz`zT&&h-xvG3@~p&!^`mGH}#drma^6+gyv+NaY39%c+BA3AS` zEqt`GgNz9~=zcE(5#I`|jW}Q10j=ogIBC3Rq@NJNPjPqDOm?e3M*KqC!pqJEucLs; ziG_mshv)6zzV-d&<7X@eO9%K2uPJfueljS=zZ5ApuS6PgnYO-ks&a)@2*GJoHrc)89Lq;A$WFk8I~yLGx!DoY`Fsw0Dmbw}LS;<#!RUQQFF`*4s6>s_|C zJR)|$d&&g&>*KhX{5zG9EH#%9DrG;*{vwJ0j-hzcbsTTF9q*Y!9~bm-3z>dhc;ixx z8W4c^>r(?ZNdsYME|~5%S>OMHqD9-D{Bul9Ph!;`fkzH>bsF*EtU^ck5+Np~s`=C4 z>>_BKLtb~>7bM>bH(5@gg;o9yWwRWl>>o8w z0wpcAi>IuMZmBrY0Dtq}tlzF+c0motUjB5$h(^t%GY4q74<~RA?F;{O;rk)Pjl*s; ztPC92^_Kf-f{Wkvv2Z`iB5X0SM}PH66e<{kclI(z4%o7Z$_puIX(-e1b<8ut%Rtdi zSg1`NDrEKHM`kUHUSc5jIn{Uyq4h|_}{!h9_t}0n5i<@ z%WZQ&-QLKIs-i8vFI@ z=t?p2<98dvo%+F#3s1k=s6YP;wvm%VGwn%)zOI?H>EY1$Ae z5l-x#N4R^#kTsFPEWG#jFUza?@aP`X={nv>{a@s8C8~OI9{c|J#n?HfsIZYy&nxdb>&Sj9Ta0<+r$5kh1+~$Awm7iI8B>?En)#APVA2 zu8!O>5{;1(AYr6q=5%m&7LIp*2*;pu)9rL)+Pe6bE)r#Ft!kb+im=T6Atw`#xa@L; zP#(VZV(7qfwlSu{@<_6q0rg`rRF*Kf>wgTZjajr`k8RYpVHcDnDVC&w(?HpMszmn} z7i~`)L9*q%#wcR{_K_^Sj&}Xm+;;ZWoE`JJKP#ngtBmKIF{Es)GMh-Xn&%qNwhsgL{) z-cH6r$AXQ}Mlf?*oPF?)n@iGnPea|gJr_ijPm=}^c?=y8P4tjU2X0s+BhKUut0A`q z7g80mk;99>sctJ5AKRr;)@)vW-}HP>;5A96R@qt(AS=SxF6D&ke4Fdx`z0!$TV&O* zTwpkDkEE=yfze4)vOmt#Si@vm?P<$`UZ) zu#*iK|Aa{EbmVjVftAg&9E4yBOi3*%+;lS@k2LIi- zh}+5jJc69~r!Il;dDX1_$X^!qfJtVjI-hf@0@q^neQm}U%F39+gm;r$YiCs26_g4M3ge&y`>za$sX* zWF@+$En!XKH2gx?mso3y`G5!Wy1L9Vw1@jx8YIq5aHFjs>WJlWUb(F1puB2i#z%wx zBKud{1+?4w1MtkXL5=z6PU1&1ZJjTRsmH*mR1m>^_-JUZyfMA%8U_7uFZkJkn4^=F zG2ZDve_=uTNwG<^_CPGs0oOKH?wPR%C!&5!;)l8Bz$1C5Lr->52ZUH`E=jpTkrVoJ$3sPfNRHLZs3 zYwc$ld{Jz)%yV_itT`!)ZsB}dQBkBg1XD(u>yCM`rE!FuBRC(l%$hT5Eb>l>l8TBe zZNkeBa~M1sKf0&K+XM+F3Vc5Infms%FNWKkqiP@3d_h6sP!V%Slywx*$as=&YEMr^ zkxj}aTqq*Ouj2FXlFGph+gr|)KSBwT%-OBltHI(c_|Vz&8FTzQ2!uo@>AeEeI= zpjt`ws6|lc-!FL*1!nyatY9xGWxN(LIp-Le!K@yQrVSk0jI5TQZJSs;k!o}3?R)q3 zqckE80sBTW`v1IS0Eq~X;=lZGw|P#b2~t-V*r*h5?Cac!KEN;Ybc1a3$ccY^O_wYv zp*!O&em9UDpV;cZR*>vi|JMp~Qj`BtA^!Cap>;biV5WHs7*g&Ovc7mloW^fD$Tr>B z3LG?%>b|@};8ZZ#dlfUx{-e0ci***`8r({4+L2}7(#yOFW<neji!l*-n;8ahJ}Yq3I@c`}7@{w}6lx*hSgqaii4g z`$;^73S1r$U=F45fD`~$u+JxMxev639UwEi(E?Jw3yiIn7IFukA~(ShJbVyeMmA=& z+zt|bc`3?b0op!WvD5r6BQ@juO$@I!xfj6)SO0D=Xc+7|vO*iV^TVw|sI#X`302%} zCp~wlYZ0FoN<(oxknb5SO6Du)ck5%(%Ad3-vTL}H1B2~-MHsdW)X#x$2V<8r=A3bsiHa&Oo&3zr z{pT^GWg|hLbn&E*;1SXFBmK?z{QvDMf&V#W%N>3LdPAmvO8!a+I(?fnKeq33R2T5Q zutx=aFRJ}1*>n=m1s@YEnVexb)V!mcw`u&FSFVw&n3S}%f%q>+d-F%dfBP0X z!lIMWr5@;zLoccu298H%Y;1qY4W&rD;=)kg*!neau|LaL&;D9%&7FD~sZ742unyP$ zDOAQ(f~T7HjgQzn^{b~~y6^hB1t}2`(!EBJ<|-DXM=by#g;D(}YKC85xM_nQq4Xr| z7-1-Z78o*;aeP{LhhK3qHp(yJ>B5HOx17KtC?4<}FtGtYnR0+F9<+#!psmygWVN@| z)vLL>@=@}dg?3oBx3|C1(8zh=xA(#2xe*4!6*%n7*Nm#9Rg8sFu7)ZYyAp8`wAE+?JfnRO}g2S&%lQXgg4OZQ*7S0FWMD9Fl zkL){08aqCJYet8r87bWAT()3$1y9Q}aDZ!e_X2NadmZZj=Qd40?hkTnC3?N{iYzH9 zX&4;t^~)r0$58%+kd^%#uvWADqfG_|fBmfZQnECP%FTOl5z398 zZ}#h{9rX$mXGvVSCGFW3puGz2^vI4fW+y?|8TsA)X)N+@tlx}N)ca}*Q+@4d=z`(yv-b99B z;Kx9n73MviFfbegUQT9ZY;Kv%(Qv!>X4-WG-3Qg<*AV4FO0= zNdX3WmODQaxtwmk2DYD{AkFxCr$<}neTTD9s&JU&lMsh!|fqZ^bq)E!0t(@Q9{t;`o zH3-R)74Za{MM!9R)7{`SzEh_zaIHJ4%E2<&mBioSWxw`9W>v2`GAbk}X?V?06aQKs z&qRC;X@J5c_$LH`lVX|2oON z|5pzs_f&T2^=~-EyE7xuKAVEOK(3q$VBek@a);T-#a{$0cdi;L@w7jl1 zlGKfjonSsIAIX4ZwcGY~Sr_kjXOEc>;Kq2C{OXzEZ+8qZm%{x9Pz5Vp-P{Ps$-`S) zrT6FShF4LNBSSADJ|1NM{Hg4xr-s&4br*t$SL=n)=Kz)XWyx&a@d*s;=t1kNyY~#B zbJw`<1-F0Rx{FfJpZ|Hio+c7@TCq}pvoZ+`wMEP8TjvG4NT0D@>|bx0#~OcvavQ$jIcJy{b!9@G2$< zs(YgTb}<~3-jCvz=t!+Po+stosEpJeTc+KQCqW_5%#5M*T{9alxbw@)c>pWk7kgR1 z8f~iU0(L)=y_5F$Z|;!xsr?jg@`9NGoXnCv z>X?fear_bzMqsXy)rG|`CXG?OwVi_`D?e(4r;Sa*k%S8-U;-L)QMC_t2IqR(Y)4oO zZhM{aVOMMaR#2+)^1cfo4OI#;mfL)?wm(xLmn`8cxRyeDbUe_L z@Z;v~Z-Xc~gfMw{Bq4H=F$R(|?7g zZ>^wguF^d$dGpJxBolm1I&Z@%uI2=lfO(7FoTB{7p9Brx%08=`XR^xOr{t$BLH%k& zhupR0L+#>|lU2sI{j#Dw}icK3W||C)Zz z%sX%1{gr!f_Y~^WIio^*=}#wp)Viy+&CJdKjPRk3NW$3I$Rh+B%Qud33TbtL8<=#l z2ce;jK>VF{QAXwz%P~%FYI`Par?n2-T(%ezy8EzpOPusQ&b?KlRRVII>5vM)@a8xc zjKV^w;*0r315cNj?UxPd^5ebG=w!3@-Tj^e-mJwuYOItwsSRKHxN0@Pj>a5if3Sfe zEa;_#6{;|KlN#dyI&kywkUMzoO(jwTb|20Vmc@w3+mAF#^~l!N@l8C$l|g5@2M2qM zp2mxBw>&Z#o08{j3O@2r5V_i)!Lo=Hrp{+DqAz)q>dVyctoHu>z9x#EC0vc!gF}^z zy;Fe{+R1z67X$M~nZs`Rr7pb^%fTC>?WfQ>;VyX;tG6ANHsn zaL*48mDe~0Q!-*>hdMesI2SF<&EGcYTeOT^G=%ew8*n({r&wXXo`i;o-t82{B(RY>#$Whi5{7m3FO0rU2&+I zy@8J2jcqVHA1Zw zyNFAP-F(w~j7`2~ z!~-;1HT3&8Ry1k_$f_(=>NO1kE->Y=F7{M`xcu~KqbHYi^o)!za7>#Sg%|$uyprE) z(BOWpf8kLM8KzY$@ZHV$JnZzyWv%%jMRZ| zoCPW(Df{=~|`D12V(j;%QlbS2i#ossv5| zwt!Z9$lU+Jjg5f(N>bZbAoeEz%=keW`)%getiDbculH&LPD?xU?v>%YB{irbt7+)1;_DcUNz4#k zSXdYbdvP~z$!iZx<|0NlINA*JBqhUgIxHsl$Uc1N*Pp9w^f1=p(ikk47ImAP4l!8j z&BU`V6TL`{Guz7(j@x1pc7#dWQnsD=@oXW?lsv0mG4Xv`%G&&yPHtYoiZJER_mW-` z9TSqh3k4N?Os~y-YEuz7M520dy9OSp=rQq~acfsiLn`I?NN#h`uF{Wo_tGyY?}n@^ z7LBLdgu%<32ENVS-P`OZr8-G!^zmz)njgh8Tnq%ET?ZZ)@#-?s<-`q^$;-^8rsB3{ zrLqlfY^gg2>XSv?mwz7@%*ZpGb&uvrVvEIbZC$(JHR(Y7j5+?aS#2LL-jiQaYk2@- zxA4mQ9S)#f0*l=2)Z-|Pb{7JU6|VyIkxg72eNyal>+?)|O!Y=|u9Y%Y+VYSb|0P(}YcR1aw06A=h8UxK=|9M?>uK7|5aPSjgbaU@N$d z)qy8%OIbN|Z<#9h8!NSjw&C!zDj$L}pn7%*TN)I|o9sjJ-C6ub`UDjh7t22SW_pAT zi+u%wnAz?V{MWkXA3eNsaL$_;4WLYAXQ}w;d>0(6cM7TuK!kddJY*xw2q$&wYXcC* z#>VZd9zQq`zjgB+g*N4A*7jT}8{)Od#k;AaDa>>`L>arbJbEZ zS$AP^nLaVTcYK)-)Bm;8EC&T>3JUL9T)dB9xl)0g3^HqV0_d zL@ex2#ZjXgr0#K4>`pMMm3P1epscfURQoaM-v%(BH>Iy{Z=X>2wF;pM1p^7gq$=e3 z(+8hzp0?sx_yqxpR2FruUnNDzraaxXyf*971yWj?`MQrIDK%rd^ID=Q^zhIy`ovTZ zSEixzRqg>A3T_(^KRYwv=G| zZQzj{Yl4@2ztKX__itunN*YI>!wh}lDtZL3ze%oUU5(*7Ehw)03Rh#!4TpS*#I9dl zUHyWz_!PvgANSAtfVJe328BM1L|K)XTbF&F5a5)|t}_V$b`>}ru6=#1+Ret9+L0w9JX?WDTwgv34WwCl24ZJ$>?g;5LO;uKGv4 zBqqN4`NA$;8|Bw5Q>w3(QI`}Igm%8TN{cjdp3R=GQMu_U+ zuRMMPHz^URxVZwv5DBxo@QJ;cIg+!y;o@VDaz0H<;>3S%!Gsya-mA3joDgjKvu3Kv=hNErv zVWc90m%`AW&pu{|bzi`mc)H~bkHMBUmMb%ZmBMU%828_Wni09BWM$#Xk%8LS0=1^% zlg&)G?%ZJm*^kFM-zBR$uL7J{)3r^}#eW~gZ5G5Ck_{M4uC2aoC(b(f2g^oHi8u0W3?WvI zb)~cnH4!Cj>jxZjffza|tCf$B@BX*cf$~5nBftAZR&PGlO?H{p!l@iF-9|=lQ>TPl z!#VY`Hx?(nN`obW!oyZ|*VXUDLxk*oxVoKPVceEb?zT-pd7eo9BV`Hi7FKt;Tx*x` zD67z-#<0YjZ0 zOQXtoe^m)w9Fjw8`SY& zDmn^y2&gpq&2xArtxdPaE{#@TaT_!1752?vJ?sE0k~^)RVTuYnY|3CfgGeoQEXR`4 z)?nbF@Y31-(`3r!_4(ia4x-5qnF3$q+u$&buAly6VzO~~{NpVfpE684unB^6vi_@%