From 0a0835b8332e535b414badb0e123d78160030379 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Tue, 25 May 2021 20:57:29 +0200 Subject: [PATCH] [MIRROR] Integrated Circuits (Wiremod) (#5949) * Integrated Circuits (Wiremod) * AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Co-authored-by: Watermelon914 <37270891+Watermelon914@users.noreply.github.com> Co-authored-by: Gandalf --- .../map_files/Deltastation/DeltaStation2.dmm | 2077 +++++++++-------- .../map_files/IceBoxStation/IceBoxStation.dmm | 516 ++-- _maps/map_files/KiloStation/KiloStation.dmm | 1164 +++++---- _maps/map_files/MetaStation/MetaStation.dmm | 435 ++-- _maps/map_files/tramstation/tramstation.dmm | 341 ++- code/__DEFINES/dcs/signals.dm | 15 + code/__DEFINES/machines.dm | 2 + code/__DEFINES/wiremod.dm | 93 + .../~skyrat_helpers/integrated_circuits.dm | 104 - code/controllers/subsystem/delay_component.dm | 3 + .../subsystem/processing/clock_component.dm | 5 + code/datums/components/material_container.dm | 17 + code/datums/components/remote_materials.dm | 18 + code/datums/components/shell.dm | 183 ++ code/modules/asset_cache/asset_list_items.dm | 5 + code/modules/balloon_alert/balloon_alert.dm | 20 +- .../research/designs/machine_designs.dm | 8 + .../research/designs/wiremod_designs.dm | 208 ++ .../research/machinery/circuit_imprinter.dm | 3 +- code/modules/research/machinery/protolathe.dm | 3 +- code/modules/research/machinery/techfab.dm | 3 +- code/modules/research/techweb/all_nodes.dm | 36 + .../modules/vehicles/mecha/mech_fabricator.dm | 65 +- code/modules/wiremod/component.dm | 182 ++ code/modules/wiremod/component_printer.dm | 134 ++ .../wiremod/components/abstract/compare.dm | 67 + code/modules/wiremod/components/arithmetic.dm | 75 + code/modules/wiremod/components/clock.dm | 54 + code/modules/wiremod/components/comparison.dm | 44 + code/modules/wiremod/components/concat.dm | 45 + code/modules/wiremod/components/contains.dm | 34 + code/modules/wiremod/components/delay.dm | 43 + code/modules/wiremod/components/dummy.dm | 33 + code/modules/wiremod/components/hear.dm | 43 + code/modules/wiremod/components/index.dm | 47 + code/modules/wiremod/components/length.dm | 33 + code/modules/wiremod/components/light.dm | 72 + code/modules/wiremod/components/logic.dm | 47 + code/modules/wiremod/components/not.dm | 33 + code/modules/wiremod/components/radio.dm | 57 + code/modules/wiremod/components/ram.dm | 51 + code/modules/wiremod/components/random.dm | 45 + code/modules/wiremod/components/self.dm | 24 + code/modules/wiremod/components/species.dm | 39 + code/modules/wiremod/components/speech.dm | 49 + code/modules/wiremod/components/textcase.dm | 50 + code/modules/wiremod/components/tostring.dm | 44 + code/modules/wiremod/components/typecheck.dm | 48 + code/modules/wiremod/integrated_circuit.dm | 351 +++ code/modules/wiremod/marker.dm | 49 + code/modules/wiremod/port.dm | 282 +++ code/modules/wiremod/preset/hello_world.dm | 14 + code/modules/wiremod/preset/speech_relay.dm | 22 + code/modules/wiremod/shell/bot.dm | 18 + code/modules/wiremod/shell/compact_remote.dm | 50 + code/modules/wiremod/shell/controller.dm | 84 + code/modules/wiremod/shell/drone.dm | 68 + code/modules/wiremod/shell/server.dm | 24 + code/modules/wiremod/shell/shell_items.dm | 42 + icons/obj/module.dmi | Bin 17556 -> 18023 bytes icons/obj/wiremod.dmi | Bin 0 -> 7407 bytes icons/obj/wiremod_fab.dmi | Bin 0 -> 8522 bytes icons/ui_icons/tgui/grid_background.png | Bin 0 -> 21650 bytes .../code/controllers/processing/circuit.dm | 94 - .../code/game/data_huds.dm | 49 - .../game/objects/items/devices/multitool.dm | 59 - .../integrated_electronics/core/analyzer.dm | 23 - .../integrated_electronics/core/assemblies.dm | 1050 --------- .../core/clothing/circuit_ears.dm | 47 - .../core/clothing/circuit_glasses.dm | 48 - .../core/clothing/circuit_gloves.dm | 48 - .../core/clothing/circuit_head.dm | 49 - .../core/clothing/circuit_shoes.dm | 48 - .../core/clothing/circuit_suit.dm | 49 - .../core/clothing/circuit_under.dm | 48 - .../core/clothing/clothing.dm | 84 - .../integrated_electronics/core/debugger.dm | 109 - .../integrated_electronics/core/detailer.dm | 50 - .../integrated_electronics/core/helpers.dm | 142 -- .../core/integrated_circuit.dm | 414 ---- .../code/integrated_electronics/core/pins.dm | 216 -- .../integrated_electronics/core/printer.dm | 384 --- .../core/saved_circuits.dm | 380 --- .../core/special_pins/boolean_pin.dm | 26 - .../core/special_pins/char_pin.dm | 27 - .../core/special_pins/color_pin.dm | 49 - .../core/special_pins/dir_pin.dm | 31 - .../core/special_pins/index_pin.dm | 21 - .../core/special_pins/list_pin.dm | 153 -- .../core/special_pins/number_pin.dm | 17 - .../core/special_pins/ref_pin.dm | 24 - .../core/special_pins/selfref_pin.dm | 27 - .../core/special_pins/string_pin.dm | 30 - .../code/integrated_electronics/core/wirer.dm | 103 - .../integrated_electronics/passive/passive.dm | 7 - .../integrated_electronics/passive/power.dm | 152 -- .../integrated_electronics/subtypes/access.dm | 41 - .../subtypes/arithmetic.dm | 344 --- .../subtypes/converters.dm | 425 ---- .../subtypes/data_transfer.dm | 208 -- .../integrated_electronics/subtypes/input.dm | 1469 ------------ .../integrated_electronics/subtypes/lists.dm | 462 ---- .../integrated_electronics/subtypes/logic.dm | 223 -- .../subtypes/manipulation.dm | 752 ------ .../integrated_electronics/subtypes/memory.dm | 140 -- .../integrated_electronics/subtypes/mining.dm | 105 - .../integrated_electronics/subtypes/output.dm | 496 ---- .../integrated_electronics/subtypes/power.dm | 208 -- .../subtypes/reagents.dm | 849 ------- .../integrated_electronics/subtypes/smart.dm | 370 --- .../integrated_electronics/subtypes/text.dm | 271 --- .../integrated_electronics/subtypes/time.dm | 187 -- .../integrated_electronics/subtypes/trig.dm | 138 -- .../designs/integrated_circuit_designs.dm | 87 - .../designs/integrated_circuit_nodes.dm | 14 - .../icons/mob/clothing/circuit_ears.dmi | Bin 374 -> 0 bytes .../icons/mob/clothing/circuit_glasses.dmi | Bin 405 -> 0 bytes .../icons/mob/clothing/circuit_gloves.dmi | Bin 393 -> 0 bytes .../icons/mob/clothing/circuit_head.dmi | Bin 638 -> 0 bytes .../icons/mob/clothing/circuit_shoes.dmi | Bin 396 -> 0 bytes .../icons/mob/clothing/circuit_suit.dmi | Bin 506 -> 0 bytes .../mob/clothing/under/circuit_under.dmi | Bin 754 -> 0 bytes .../obj/assemblies/electronic_components.dmi | Bin 10498 -> 0 bytes .../icons/obj/assemblies/electronic_misc.dmi | Bin 2511 -> 0 bytes .../obj/assemblies/electronic_setups.dmi | Bin 17017 -> 0 bytes .../icons/obj/assemblies/electronic_tools.dmi | Bin 2493 -> 0 bytes .../icons/obj/assemblies/new_assemblies.dmi | Bin 12639 -> 0 bytes .../icons/obj/clothing/circuit_ears.dmi | Bin 477 -> 0 bytes .../icons/obj/clothing/circuit_glasses.dmi | Bin 514 -> 0 bytes .../icons/obj/clothing/circuit_gloves.dmi | Bin 556 -> 0 bytes .../icons/obj/clothing/circuit_head.dmi | Bin 828 -> 0 bytes .../icons/obj/clothing/circuit_shoes.dmi | Bin 430 -> 0 bytes .../icons/obj/clothing/circuit_suit.dmi | Bin 557 -> 0 bytes .../icons/obj/clothing/circuit_under.dmi | Bin 490 -> 0 bytes tgstation.dme | 94 +- .../packages/tgui/components/InfinitePlane.js | 169 ++ tgui/packages/tgui/components/index.js | 1 + .../tgui/interfaces/ComponentPrinter.tsx | 169 ++ .../tgui/interfaces/ExosuitFabricator.js | 122 +- .../tgui/interfaces/IntegratedCircuit.js | 673 ++++++ .../tgui/interfaces/common/Materials.tsx | 153 ++ .../styles/interfaces/IntegratedCircuit.scss | 36 + tgui/packages/tgui/styles/main.scss | 1 + 143 files changed, 7057 insertions(+), 12929 deletions(-) create mode 100644 code/__DEFINES/wiremod.dm delete mode 100644 code/__HELPERS/~skyrat_helpers/integrated_circuits.dm create mode 100644 code/controllers/subsystem/delay_component.dm create mode 100644 code/controllers/subsystem/processing/clock_component.dm create mode 100644 code/datums/components/shell.dm create mode 100644 code/modules/research/designs/wiremod_designs.dm create mode 100644 code/modules/wiremod/component.dm create mode 100644 code/modules/wiremod/component_printer.dm create mode 100644 code/modules/wiremod/components/abstract/compare.dm create mode 100644 code/modules/wiremod/components/arithmetic.dm create mode 100644 code/modules/wiremod/components/clock.dm create mode 100644 code/modules/wiremod/components/comparison.dm create mode 100644 code/modules/wiremod/components/concat.dm create mode 100644 code/modules/wiremod/components/contains.dm create mode 100644 code/modules/wiremod/components/delay.dm create mode 100644 code/modules/wiremod/components/dummy.dm create mode 100644 code/modules/wiremod/components/hear.dm create mode 100644 code/modules/wiremod/components/index.dm create mode 100644 code/modules/wiremod/components/length.dm create mode 100644 code/modules/wiremod/components/light.dm create mode 100644 code/modules/wiremod/components/logic.dm create mode 100644 code/modules/wiremod/components/not.dm create mode 100644 code/modules/wiremod/components/radio.dm create mode 100644 code/modules/wiremod/components/ram.dm create mode 100644 code/modules/wiremod/components/random.dm create mode 100644 code/modules/wiremod/components/self.dm create mode 100644 code/modules/wiremod/components/species.dm create mode 100644 code/modules/wiremod/components/speech.dm create mode 100644 code/modules/wiremod/components/textcase.dm create mode 100644 code/modules/wiremod/components/tostring.dm create mode 100644 code/modules/wiremod/components/typecheck.dm create mode 100644 code/modules/wiremod/integrated_circuit.dm create mode 100644 code/modules/wiremod/marker.dm create mode 100644 code/modules/wiremod/port.dm create mode 100644 code/modules/wiremod/preset/hello_world.dm create mode 100644 code/modules/wiremod/preset/speech_relay.dm create mode 100644 code/modules/wiremod/shell/bot.dm create mode 100644 code/modules/wiremod/shell/compact_remote.dm create mode 100644 code/modules/wiremod/shell/controller.dm create mode 100644 code/modules/wiremod/shell/drone.dm create mode 100644 code/modules/wiremod/shell/server.dm create mode 100644 code/modules/wiremod/shell/shell_items.dm create mode 100644 icons/obj/wiremod.dmi create mode 100644 icons/obj/wiremod_fab.dmi create mode 100644 icons/ui_icons/tgui/grid_background.png delete mode 100644 modular_skyrat/master_files/code/controllers/processing/circuit.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/game/data_huds.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/game/objects/items/devices/multitool.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/analyzer.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/assemblies.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_ears.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_glasses.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_gloves.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_head.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_shoes.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_suit.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_under.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/clothing.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/debugger.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/detailer.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/helpers.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/integrated_circuit.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/pins.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/printer.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/saved_circuits.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/boolean_pin.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/char_pin.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/color_pin.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/dir_pin.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/index_pin.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/list_pin.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/number_pin.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/ref_pin.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/selfref_pin.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/string_pin.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/wirer.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/passive/passive.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/passive/power.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/access.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/arithmetic.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/converters.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/data_transfer.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/input.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/lists.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/logic.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/manipulation.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/memory.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/mining.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/output.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/power.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/reagents.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/smart.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/text.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/time.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/trig.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/research/designs/integrated_circuit_designs.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/code/research/designs/integrated_circuit_nodes.dm delete mode 100644 modular_skyrat/modules/integrated_circuits/icons/mob/clothing/circuit_ears.dmi delete mode 100644 modular_skyrat/modules/integrated_circuits/icons/mob/clothing/circuit_glasses.dmi delete mode 100644 modular_skyrat/modules/integrated_circuits/icons/mob/clothing/circuit_gloves.dmi delete mode 100644 modular_skyrat/modules/integrated_circuits/icons/mob/clothing/circuit_head.dmi delete mode 100644 modular_skyrat/modules/integrated_circuits/icons/mob/clothing/circuit_shoes.dmi delete mode 100644 modular_skyrat/modules/integrated_circuits/icons/mob/clothing/circuit_suit.dmi delete mode 100644 modular_skyrat/modules/integrated_circuits/icons/mob/clothing/under/circuit_under.dmi delete mode 100644 modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/electronic_components.dmi delete mode 100644 modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/electronic_misc.dmi delete mode 100644 modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/electronic_setups.dmi delete mode 100644 modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/electronic_tools.dmi delete mode 100644 modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/new_assemblies.dmi delete mode 100644 modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_ears.dmi delete mode 100644 modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_glasses.dmi delete mode 100644 modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_gloves.dmi delete mode 100644 modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_head.dmi delete mode 100644 modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_shoes.dmi delete mode 100644 modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_suit.dmi delete mode 100644 modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_under.dmi create mode 100644 tgui/packages/tgui/components/InfinitePlane.js create mode 100644 tgui/packages/tgui/interfaces/ComponentPrinter.tsx create mode 100644 tgui/packages/tgui/interfaces/IntegratedCircuit.js create mode 100644 tgui/packages/tgui/interfaces/common/Materials.tsx create mode 100644 tgui/packages/tgui/styles/interfaces/IntegratedCircuit.scss diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index b1ebef8272b..38540b750f2 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -1579,6 +1579,22 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/security/checkpoint/supply) +"ahP" = ( +/obj/structure/cable, +/obj/effect/turf_decal/stripes/corner, +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/science/misc_lab/range) "ahS" = ( /obj/machinery/status_display/evac/directional/east, /obj/machinery/light/directional/east, @@ -3147,6 +3163,12 @@ }, /turf/open/floor/iron, /area/ai_monitored/command/storage/eva) +"asu" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plating/airless, +/area/science/misc_lab/range) "asD" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/sign/barsign{ @@ -3784,31 +3806,6 @@ }, /turf/open/floor/iron, /area/hallway/primary/central/aft) -"ayL" = ( -/obj/machinery/door/firedoor, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/door/airlock/research{ - name = "Toxins Launch Site"; - req_access_txt = "8" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/obj/structure/cable, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 8 - }, -/turf/open/floor/iron, -/area/science/misc_lab) "ayR" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/closet/crate, @@ -5905,6 +5902,18 @@ /obj/machinery/newscaster/directional/south, /turf/open/floor/iron/dark/corner, /area/maintenance/disposal/incinerator) +"aPJ" = ( +/obj/machinery/doppler_array/research/science{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/structure/extinguisher_cabinet/directional/south{ + pixel_x = -26 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "aPS" = ( /obj/effect/turf_decal/tile/yellow{ dir = 1 @@ -6290,6 +6299,10 @@ /obj/machinery/atmospherics/components/unary/portables_connector/visible, /turf/open/floor/iron/dark, /area/security/execution/education) +"aST" = ( +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/iron, +/area/science/misc_lab) "aSY" = ( /obj/effect/landmark/event_spawn, /obj/effect/turf_decal/tile/red{ @@ -6668,6 +6681,13 @@ }, /turf/open/floor/iron/dark, /area/ai_monitored/turret_protected/aisat_interior) +"aXp" = ( +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "aXx" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, @@ -7666,6 +7686,11 @@ }, /turf/open/floor/plating, /area/maintenance/port/aft) +"bfJ" = ( +/obj/structure/training_machine, +/obj/item/target/syndicate, +/turf/open/floor/iron, +/area/science/misc_lab) "bfR" = ( /obj/structure/cable, /obj/effect/turf_decal/stripes/line{ @@ -7822,6 +7847,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/grimy, /area/ai_monitored/turret_protected/aisat_interior) +"bhD" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple, +/turf/open/floor/iron/white, +/area/science/misc_lab) "bhH" = ( /obj/machinery/light/small/directional/north, /obj/effect/turf_decal/tile/blue{ @@ -8272,6 +8304,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/ai_monitored/security/armory) +"bly" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 + }, +/turf/open/floor/iron/white, +/area/science/misc_lab) "blB" = ( /obj/structure/disposalpipe/segment{ dir = 9 @@ -11732,6 +11770,17 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/grimy, /area/service/chapel/main) +"bLH" = ( +/obj/machinery/light/directional/north, +/obj/machinery/component_printer, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/iron/white, +/area/science/misc_lab) "bLU" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -19449,6 +19498,19 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/carpet, /area/commons/dorms) +"cBP" = ( +/obj/effect/landmark/xeno_spawn, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/iron{ + heat_capacity = 1e+006 + }, +/area/science/misc_lab/range) "cBR" = ( /obj/effect/turf_decal/tile/green{ dir = 4 @@ -19865,6 +19927,16 @@ }, /turf/open/floor/iron, /area/maintenance/disposal/incinerator) +"cGu" = ( +/obj/machinery/airalarm/directional/north, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/iron/white, +/area/science/misc_lab) "cGJ" = ( /obj/machinery/door/airlock/maintenance_hatch{ name = "Chapel Maintenance"; @@ -26041,38 +26113,17 @@ }, /turf/open/floor/iron, /area/science/xenobiology) -"djn" = ( -/obj/structure/table/reinforced, -/obj/item/screwdriver, -/obj/effect/spawner/lootdrop/maintenance/two, -/turf/open/floor/iron, -/area/maintenance/port) "djo" = ( /obj/item/kirbyplants/random, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/science/research/abandoned) -"djp" = ( -/obj/structure/table/reinforced, -/obj/machinery/cell_charger, -/turf/open/floor/iron, -/area/maintenance/port) -"djr" = ( -/turf/open/floor/iron, -/area/maintenance/port) "djs" = ( /obj/item/kirbyplants/random, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/science/research/abandoned) -"djv" = ( -/obj/structure/sign/poster/official/random{ - pixel_y = 32 - }, -/obj/structure/rack, -/turf/open/floor/iron, -/area/maintenance/port) "djw" = ( /obj/effect/decal/cleanable/dirt, /obj/item/storage/box/mousetraps, @@ -26585,10 +26636,6 @@ }, /turf/open/floor/iron/dark, /area/service/abandoned_gambling_den) -"dle" = ( -/obj/structure/table/reinforced, -/turf/open/floor/iron, -/area/maintenance/port) "dlf" = ( /obj/effect/turf_decal/stripes/line{ dir = 9 @@ -27436,42 +27483,10 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/maintenance/starboard/aft) -"dog" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/iron, -/area/science/misc_lab/range) -"doh" = ( -/obj/machinery/light/directional/north, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/iron, -/area/science/misc_lab/range) "doi" = ( /obj/effect/turf_decal/stripes/line, /turf/open/floor/iron, /area/science/research/abandoned) -"doj" = ( -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/turf/open/floor/iron, -/area/science/misc_lab/range) -"dok" = ( -/obj/structure/girder, -/turf/open/floor/plating, -/area/maintenance/port) -"dol" = ( -/obj/machinery/light/directional/north, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/turf/open/floor/iron/white, -/area/science/misc_lab/range) "dom" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -27482,17 +27497,6 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/science/research/abandoned) -"doo" = ( -/obj/structure/closet/crate, -/obj/item/target/alien, -/obj/item/target/alien, -/obj/item/target/clown, -/obj/item/target/clown, -/obj/item/target/syndicate, -/obj/item/gun/energy/laser/practice, -/obj/item/gun/energy/laser/practice, -/turf/open/floor/iron/white, -/area/science/misc_lab/range) "doq" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -27783,11 +27787,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/maintenance/starboard/aft) -"dpX" = ( -/obj/structure/training_machine, -/obj/item/target/syndicate, -/turf/open/floor/iron, -/area/science/misc_lab/range) "dpY" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/line, @@ -28037,19 +28036,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/hallway/secondary/construction) -"drz" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/turf/open/floor/iron, -/area/science/misc_lab/range) -"drA" = ( -/obj/structure/sign/poster/official/random{ - pixel_y = -32 - }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/iron, -/area/science/misc_lab/range) "drB" = ( /obj/structure/window/reinforced, /obj/structure/window/reinforced{ @@ -28068,33 +28054,6 @@ }, /turf/open/floor/iron/dark, /area/ai_monitored/aisat/exterior) -"drC" = ( -/obj/structure/table/reinforced, -/obj/machinery/recharger, -/obj/structure/cable, -/obj/machinery/power/apc/auto_name/south, -/turf/open/floor/iron/white, -/area/science/misc_lab/range) -"drD" = ( -/obj/machinery/disposal/bin, -/obj/structure/disposalpipe/trunk{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/science/misc_lab/range) -"drE" = ( -/obj/structure/sign/poster/official/build{ - pixel_y = -32 - }, -/obj/structure/table/reinforced, -/turf/open/floor/iron/white, -/area/science/misc_lab/range) -"drF" = ( -/obj/machinery/vending/assist, -/obj/machinery/firealarm/directional/east, -/obj/machinery/light_switch/directional/south, -/turf/open/floor/iron/white, -/area/science/misc_lab/range) "drG" = ( /obj/machinery/light/directional/south, /obj/structure/reagent_dispensers/water_cooler, @@ -29790,26 +29749,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, /area/service/electronic_marketing_den) -"dze" = ( -/obj/structure/cable, -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 8 - }, -/turf/open/floor/iron, -/area/science/misc_lab) "dzf" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/bot, @@ -30977,10 +30916,6 @@ "dEk" = ( /turf/closed/wall, /area/security/detectives_office/private_investigators_office) -"dEn" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/science/misc_lab) "dEo" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/neutral{ @@ -31362,61 +31297,6 @@ }, /turf/open/floor/iron/dark, /area/security/detectives_office/private_investigators_office) -"dFz" = ( -/obj/structure/chair/office{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/iron, -/area/science/misc_lab) -"dFA" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/turf/open/floor/iron, -/area/science/misc_lab) -"dFB" = ( -/obj/structure/table, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/status_display/evac/directional/north, -/obj/item/crowbar, -/obj/item/wrench, -/obj/item/clothing/mask/gas, -/obj/machinery/camera{ - c_tag = "Science - Toxins Launch Site"; - name = "science camera"; - network = list("ss13","rd") - }, -/obj/machinery/light/directional/north, -/obj/effect/turf_decal/bot, -/turf/open/floor/iron, -/area/science/misc_lab) -"dFC" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/obj/machinery/atmospherics/components/unary/portables_connector/visible, -/turf/open/floor/iron, -/area/science/misc_lab) -"dFD" = ( -/obj/effect/turf_decal/stripes/line, -/obj/machinery/atmospherics/components/unary/portables_connector/visible, -/turf/open/floor/iron, -/area/science/misc_lab) -"dFE" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/obj/machinery/atmospherics/components/unary/portables_connector/visible, -/obj/machinery/airalarm/directional/east, -/obj/machinery/newscaster/directional/north, -/obj/machinery/light_switch/directional/east{ - pixel_y = 26 - }, -/turf/open/floor/iron, -/area/science/misc_lab) "dFI" = ( /obj/item/assembly/signaler{ pixel_y = 8 @@ -31665,63 +31545,6 @@ /obj/effect/spawner/structure/window/reinforced/tinted, /turf/open/floor/plating, /area/science/test_area) -"dGY" = ( -/obj/structure/table/reinforced, -/obj/machinery/computer/security/telescreen/toxins{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/iron, -/area/science/misc_lab) -"dGZ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/iron, -/area/science/misc_lab) -"dHa" = ( -/obj/effect/landmark/xeno_spawn, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/turf/open/floor/iron{ - heat_capacity = 1e+006 - }, -/area/science/misc_lab) -"dHc" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/machinery/atmospherics/components/trinary/filter{ - dir = 8 - }, -/turf/open/floor/iron, -/area/science/misc_lab) -"dHe" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/small/directional/north, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/iron, -/area/science/misc_lab) -"dHg" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/turf/open/floor/iron, -/area/science/misc_lab) "dHh" = ( /obj/structure/table/reinforced, /obj/item/book/manual/wiki/toxins, @@ -31945,23 +31768,6 @@ }, /turf/open/floor/plating/airless, /area/science/test_area) -"dIj" = ( -/obj/structure/chair/office{ - dir = 8 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/item/radio/intercom/directional/west, -/turf/open/floor/iron, -/area/science/misc_lab) -"dIk" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/iron, -/area/science/misc_lab) "dIx" = ( /obj/structure/rack, /obj/effect/decal/cleanable/dirt, @@ -32339,62 +32145,6 @@ }, /turf/open/floor/plating/airless, /area/science/test_area) -"dJJ" = ( -/obj/machinery/doppler_array/research/science{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/obj/structure/extinguisher_cabinet/directional/south{ - pixel_x = -26 - }, -/turf/open/floor/iron, -/area/science/misc_lab) -"dJK" = ( -/obj/machinery/light/directional/south, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/turf/open/floor/iron, -/area/science/misc_lab) -"dJM" = ( -/obj/structure/table, -/obj/effect/decal/cleanable/dirt, -/obj/item/clothing/gloves/color/latex, -/obj/item/clothing/glasses/science, -/obj/item/clothing/glasses/science, -/obj/effect/turf_decal/bot, -/turf/open/floor/iron, -/area/science/misc_lab) -"dJN" = ( -/obj/machinery/research/explosive_compressor, -/obj/effect/turf_decal/bot, -/turf/open/floor/iron, -/area/science/misc_lab) -"dJO" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/bot, -/obj/machinery/firealarm/directional/east, -/turf/open/floor/iron, -/area/science/misc_lab) -"dJQ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/small/directional/south, -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/turf/open/floor/iron, -/area/science/misc_lab) -"dJS" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/turf/open/floor/iron, -/area/science/misc_lab) "dJT" = ( /obj/structure/tank_dispenser, /obj/effect/turf_decal/bot, @@ -32562,26 +32312,6 @@ }, /turf/open/floor/plating/airless, /area/science/test_area) -"dKA" = ( -/obj/structure/sign/warning/vacuum, -/turf/closed/wall, -/area/science/misc_lab) -"dKB" = ( -/obj/structure/sign/warning/securearea, -/turf/closed/wall, -/area/science/misc_lab) -"dKC" = ( -/obj/machinery/door/window/southleft{ - name = "Mass Driver Door"; - req_access_txt = "8" - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/loading_area, -/obj/machinery/computer/pod/old/mass_driver_controller/toxinsdriver{ - pixel_x = 28 - }, -/turf/open/floor/iron, -/area/science/misc_lab) "dKE" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/door/airlock/maintenance_hatch{ @@ -32933,55 +32663,6 @@ }, /turf/open/floor/plating/airless, /area/science/test_area) -"dLI" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/plating/airless, -/area/science/misc_lab) -"dLJ" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plating/airless, -/area/science/misc_lab) -"dLK" = ( -/obj/machinery/door/poddoor/massdriver_toxins, -/obj/structure/fans/tiny, -/turf/open/floor/plating, -/area/science/misc_lab) -"dLL" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/end{ - dir = 8 - }, -/turf/open/floor/iron, -/area/science/misc_lab) -"dLM" = ( -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/iron, -/area/science/misc_lab) -"dLN" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/end{ - dir = 4 - }, -/turf/open/floor/iron, -/area/science/misc_lab) -"dLO" = ( -/obj/machinery/mass_driver/toxins{ - dir = 8 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/end{ - dir = 8 - }, -/turf/open/floor/iron, -/area/science/misc_lab) "dLP" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/reagent_dispensers/fueltank, @@ -34131,6 +33812,23 @@ }, /turf/open/floor/iron, /area/medical/virology) +"dQV" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple, +/turf/open/floor/iron/white, +/area/science/misc_lab) "dQW" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -37581,6 +37279,12 @@ }, /turf/open/floor/iron, /area/commons/fitness/recreation) +"ehi" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 5 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "ehq" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/neutral{ @@ -37990,6 +37694,22 @@ }, /turf/open/floor/iron, /area/medical/medbay/central) +"emq" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/status_display/evac/directional/north, +/obj/item/crowbar, +/obj/item/wrench, +/obj/item/clothing/mask/gas, +/obj/machinery/camera{ + c_tag = "Science - Toxins Launch Site"; + name = "science camera"; + network = list("ss13","rd") + }, +/obj/machinery/light/directional/north, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron, +/area/science/misc_lab/range) "emw" = ( /obj/structure/filingcabinet/security, /turf/open/floor/carpet, @@ -39288,20 +39008,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/medical/medbay/central) -"eGN" = ( -/obj/machinery/power/apc/auto_name/east, -/obj/structure/cable, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible{ - dir = 9 - }, -/turf/open/floor/iron, -/area/science/misc_lab) "eGP" = ( /obj/machinery/door/airlock/maintenance_hatch{ name = "Law Office Maintenance"; @@ -39530,14 +39236,6 @@ /obj/effect/turf_decal/bot, /turf/open/floor/engine, /area/engineering/supermatter/room) -"eJF" = ( -/obj/structure/cable, -/obj/effect/turf_decal/delivery, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 8 - }, -/turf/open/floor/iron/white, -/area/science/misc_lab/range) "eJG" = ( /obj/machinery/light/small/directional/south, /obj/structure/closet/crate/goldcrate, @@ -39769,6 +39467,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/maintenance/port/aft) +"eMn" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plating/airless, +/area/science/misc_lab/range) "eMt" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ @@ -40775,20 +40480,6 @@ }, /turf/open/floor/iron/dark, /area/security/courtroom) -"eYc" = ( -/obj/effect/landmark/xeno_spawn, -/obj/machinery/door/window/brigdoor{ - dir = 4; - name = "Test Range" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 8 - }, -/turf/open/floor/iron, -/area/science/misc_lab/range) "eYi" = ( /obj/item/kirbyplants/random, /obj/effect/turf_decal/tile/green{ @@ -41029,6 +40720,13 @@ }, /turf/open/floor/iron, /area/engineering/atmos/upper) +"faO" = ( +/obj/effect/landmark/event_spawn, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 5 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "faY" = ( /obj/effect/turf_decal/tile/red{ dir = 1 @@ -41142,6 +40840,7 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/hallway/primary/central/aft) +<<<<<<< HEAD "fbV" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ dir = 5 @@ -41157,6 +40856,8 @@ }, /turf/open/floor/iron, /area/engineering/atmos/upper) +======= +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) "fbY" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/disposalpipe/segment, @@ -42178,6 +41879,7 @@ /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible, /turf/open/floor/iron/dark, /area/engineering/atmos) +<<<<<<< HEAD "fqt" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable, @@ -42193,6 +41895,8 @@ }, /turf/open/floor/iron, /area/maintenance/disposal/incinerator) +======= +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) "fqv" = ( /obj/effect/turf_decal/tile/red{ dir = 1 @@ -42226,6 +41930,13 @@ }, /turf/open/floor/iron, /area/maintenance/starboard/fore) +"fqO" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/smart/manifold/cyan/visible{ + dir = 8 + }, +/turf/open/floor/plating, +/area/engineering/atmos) "fqV" = ( /obj/structure/closet/radiation, /obj/machinery/light/small/directional/west, @@ -43698,35 +43409,6 @@ /obj/structure/dresser, /turf/open/floor/iron/grimy, /area/commons/dorms) -"fQf" = ( -/obj/structure/cable, -/obj/effect/turf_decal/stripes/corner, -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/science/misc_lab) -"fQl" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 8 - }, -/turf/open/floor/iron/white, -/area/science/misc_lab/range) "fQy" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/neutral{ @@ -44014,6 +43696,16 @@ }, /turf/open/floor/iron/grimy, /area/command/heads_quarters/hos) +"fUX" = ( +/obj/structure/table/reinforced, +/obj/machinery/computer/security/telescreen/toxins{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "fUZ" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/yellow, @@ -45294,6 +44986,22 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/hallway/secondary/service) +"gpg" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/door/window/brigdoor{ + dir = 4; + name = "Test Range" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 5 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "gpp" = ( /obj/structure/closet/toolcloset, /obj/effect/decal/cleanable/dirt, @@ -45536,6 +45244,12 @@ }, /turf/open/floor/engine/co2, /area/engineering/atmos) +"gsi" = ( +/obj/structure/cable, +/obj/machinery/power/apc/auto_name/south, +/obj/structure/filingcabinet/chestdrawer, +/turf/open/floor/iron/white, +/area/science/misc_lab) "gsn" = ( /obj/machinery/door/airlock/command{ name = "Chief Medical Officer's Office"; @@ -46252,6 +45966,15 @@ /obj/item/flashlight/lantern, /turf/open/floor/iron/grimy, /area/service/chapel/main) +"gDm" = ( +/obj/structure/chair/office{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "gDw" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/red{ @@ -48095,6 +47818,30 @@ }, /turf/open/floor/iron/white, /area/hallway/primary/central/aft) +"hgS" = ( +/obj/machinery/door/airlock/research{ + name = "Circuits Testing Lab"; + req_access_txt = "47" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/door/firedoor, +/obj/structure/cable, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "hgT" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -49375,6 +49122,13 @@ /obj/item/food/grown/poppy/lily, /turf/open/floor/iron/grimy, /area/service/chapel/office) +"hAH" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/end{ + dir = 8 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "hAI" = ( /obj/structure/window, /obj/structure/sink{ @@ -50009,6 +49763,17 @@ /obj/machinery/atmospherics/pipe/smart/simple/purple/visible, /turf/open/floor/iron, /area/engineering/atmos) +"hIQ" = ( +/obj/structure/chair/office{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/item/radio/intercom/directional/west, +/turf/open/floor/iron, +/area/science/misc_lab/range) "hJb" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -50282,12 +50047,6 @@ }, /turf/open/floor/carpet, /area/commons/vacant_room/office) -"hNZ" = ( -/obj/structure/chair/office/light{ - dir = 8 - }, -/turf/open/floor/iron, -/area/maintenance/port) "hOg" = ( /obj/machinery/door/firedoor, /obj/structure/disposalpipe/segment{ @@ -50328,6 +50087,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/maintenance/port/fore) +"hOV" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/science/misc_lab) "hOZ" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -51817,6 +51582,19 @@ }, /turf/open/floor/iron, /area/hallway/primary/central/fore) +"ifR" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/science/misc_lab) "ifX" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable, @@ -53186,6 +52964,16 @@ }, /turf/open/floor/iron, /area/security/prison) +"izv" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "izG" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/blue{ @@ -54204,6 +53992,18 @@ /obj/machinery/power/apc/auto_name/east, /turf/open/floor/iron, /area/cargo/miningoffice) +"iNP" = ( +/obj/structure/sign/poster/official/build{ + pixel_y = -32 + }, +/obj/structure/table/reinforced, +/obj/machinery/recharger, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/science/misc_lab) "iNS" = ( /obj/structure/chair/office{ dir = 4 @@ -54337,6 +54137,16 @@ }, /turf/open/floor/iron, /area/science/research/abandoned) +"iPA" = ( +/obj/machinery/light/directional/south, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "iPI" = ( /obj/effect/turf_decal/tile/blue{ dir = 1 @@ -54888,10 +54698,6 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron, /area/cargo/storage) -"iYN" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/maintenance/port) "iYT" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ dir = 9 @@ -55650,16 +55456,6 @@ }, /turf/open/floor/iron/grimy, /area/service/chapel/main) -"jjN" = ( -/obj/structure/table/reinforced, -/obj/machinery/camera{ - c_tag = "Science - Experimentation Lab"; - name = "science camera"; - network = list("ss13","rd") - }, -/obj/effect/spawner/lootdrop/maintenance, -/turf/open/floor/iron, -/area/maintenance/port) "jkf" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/neutral{ @@ -56430,6 +56226,7 @@ /obj/effect/landmark/xeno_spawn, /turf/open/floor/plating/airless, /area/space/nearstation) +<<<<<<< HEAD "jwE" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/status_display/evac{ @@ -56447,6 +56244,8 @@ }, /turf/open/floor/plating, /area/engineering/atmos) +======= +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) "jwH" = ( /mob/living/simple_animal/mouse/brown/tom, /turf/open/floor/iron, @@ -56747,6 +56546,17 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/cargo/miningoffice) +"jAR" = ( +/obj/structure/cable, +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "jAZ" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -56983,33 +56793,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/medical/medbay/central) -"jEi" = ( -/obj/structure/cable, -/obj/effect/turf_decal/stripes/line, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 8 - }, -/turf/open/floor/iron, -/area/science/misc_lab) -"jEz" = ( -/obj/machinery/camera{ - c_tag = "Science - Firing Range"; - name = "science camera"; - network = list("ss13","rd") - }, -/obj/structure/table/reinforced, -/obj/item/clothing/ears/earmuffs, -/obj/item/clothing/ears/earmuffs, -/obj/item/gun/energy/laser/practice, -/obj/item/gun/energy/laser/practice{ - pixel_x = 3; - pixel_y = -3 - }, -/turf/open/floor/iron/white, -/area/science/misc_lab/range) "jEG" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/landmark/xeno_spawn, @@ -57295,6 +57078,19 @@ /obj/item/pen, /turf/open/floor/iron/grimy, /area/command/bridge) +"jHZ" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 + }, +/obj/effect/landmark/xeno_spawn, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 5 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "jId" = ( /obj/structure/table/wood, /obj/item/lipstick/random{ @@ -59498,6 +59294,19 @@ }, /turf/open/floor/engine/n2, /area/engineering/atmos) +"kon" = ( +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/iron, +/area/science/misc_lab) +"kot" = ( +/obj/structure/sign/warning/securearea, +/turf/closed/wall, +/area/science/misc_lab/range) "koD" = ( /obj/machinery/door/firedoor, /obj/effect/decal/cleanable/dirt, @@ -61157,16 +60966,6 @@ /obj/structure/window/reinforced, /turf/open/floor/iron/dark, /area/commons/fitness/recreation) -"kJJ" = ( -/obj/effect/turf_decal/stripes/line, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 5 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 6 - }, -/turf/open/floor/iron, -/area/science/misc_lab) "kJW" = ( /obj/structure/cable, /obj/machinery/power/apc/auto_name/west, @@ -61848,14 +61647,6 @@ }, /turf/open/floor/iron/dark, /area/service/chapel/office) -"kTQ" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_one_access_txt = "12;47" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/maintenance/port) "kUc" = ( /obj/machinery/computer/atmos_alert, /obj/effect/turf_decal/tile/yellow{ @@ -62003,6 +61794,9 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/security/warden) +"kVu" = ( +/turf/closed/wall, +/area/science/misc_lab/range) "kVD" = ( /obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/tile/neutral{ @@ -62339,6 +62133,22 @@ }, /turf/open/floor/iron, /area/science/research) +"kZB" = ( +/obj/structure/cable, +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/science/misc_lab/range) "kZE" = ( /obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/tile/neutral{ @@ -62736,17 +62546,6 @@ }, /turf/open/floor/iron, /area/commons/storage/primary) -"leq" = ( -/obj/effect/landmark/start/scientist, -/obj/effect/turf_decal/stripes/line, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 8 - }, -/turf/open/floor/iron, -/area/science/misc_lab) "let" = ( /turf/closed/wall/r_wall, /area/engineering/gravity_generator) @@ -62870,6 +62669,13 @@ }, /turf/open/floor/iron, /area/cargo/storage) +"lft" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/end{ + dir = 4 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "lfw" = ( /obj/effect/turf_decal/stripes/corner, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ @@ -62907,6 +62713,19 @@ }, /turf/open/floor/iron, /area/commons/fitness/recreation) +"lgf" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible{ + dir = 5 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "lgs" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -63414,6 +63233,12 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron, /area/command/teleporter) +"lmF" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "lmL" = ( /turf/closed/wall, /area/engineering/supermatter/room) @@ -63731,6 +63556,13 @@ /obj/item/training_toolbox, /turf/open/floor/iron, /area/commons/fitness/recreation) +"lra" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "lrc" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -64791,6 +64623,12 @@ }, /turf/open/floor/iron, /area/service/bar/atrium) +"lHp" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "lHI" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/camera{ @@ -64874,6 +64712,12 @@ }, /turf/open/floor/iron/dark, /area/service/theater/abandoned) +"lIN" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 1 + }, +/turf/closed/wall, +/area/engineering/atmos) "lIP" = ( /obj/machinery/camera{ c_tag = "Holodeck Control"; @@ -65779,30 +65623,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/engineering/atmos) -"lVN" = ( -/obj/machinery/door/airlock/research{ - name = "Research Testing Range"; - req_access_txt = "47" - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/door/firedoor, -/obj/structure/cable, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 8 - }, -/turf/open/floor/iron, -/area/science/misc_lab/range) "lVS" = ( /obj/structure/chair/office{ dir = 8 @@ -65934,15 +65754,6 @@ }, /turf/open/floor/iron, /area/security/checkpoint) -"lXM" = ( -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/turf/open/floor/iron, -/area/science/misc_lab/range) "lYa" = ( /obj/machinery/door/firedoor, /obj/effect/turf_decal/stripes/line, @@ -66184,6 +65995,12 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron, /area/hallway/primary/fore) +"map" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "mat" = ( /obj/effect/decal/cleanable/dirt, /obj/item/kirbyplants/random, @@ -68027,19 +67844,6 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron, /area/commons/storage/primary) -"myW" = ( -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 5 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 8 - }, -/turf/open/floor/iron/white, -/area/science/misc_lab/range) "mzf" = ( /obj/machinery/door/poddoor/preopen{ id = "bridgedoors"; @@ -68549,6 +68353,13 @@ }, /turf/open/floor/plating, /area/engineering/supermatter/room) +"mGu" = ( +/obj/structure/sign/poster/official/random{ + pixel_y = -32 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/iron, +/area/science/misc_lab) "mHf" = ( /obj/structure/chair/comfy/brown{ dir = 8 @@ -68924,6 +68735,12 @@ }, /turf/open/floor/iron, /area/hallway/primary/central/fore) +"mLI" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "mLO" = ( /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/trimline/brown/filled/line{ @@ -68952,6 +68769,21 @@ }, /turf/open/floor/iron, /area/commons/vacant_room/commissary) +"mLZ" = ( +/obj/structure/closet/crate, +/obj/item/target/alien, +/obj/item/target/alien, +/obj/item/target/clown, +/obj/item/target/clown, +/obj/item/target/syndicate, +/obj/item/gun/energy/laser/practice, +/obj/item/gun/energy/laser/practice, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple, +/turf/open/floor/iron/white, +/area/science/misc_lab) "mMg" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/green, @@ -69151,6 +68983,28 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/commons/toilet/restrooms) +"mPh" = ( +/obj/machinery/camera{ + c_tag = "Science - Firing Range"; + name = "science camera"; + network = list("ss13","rd") + }, +/obj/structure/table/reinforced, +/obj/item/clothing/ears/earmuffs, +/obj/item/clothing/ears/earmuffs, +/obj/item/gun/energy/laser/practice, +/obj/item/gun/energy/laser/practice{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/structure/window/reinforced, +/turf/open/floor/iron/white, +/area/science/misc_lab) +"mPo" = ( +/obj/machinery/research/explosive_compressor, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron, +/area/science/misc_lab/range) "mPp" = ( /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/hidden, /turf/closed/wall/r_wall, @@ -69379,6 +69233,7 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, /area/command/meeting_room/council) +<<<<<<< HEAD "mSy" = ( /obj/structure/cable, /obj/effect/turf_decal/stripes/line{ @@ -69395,6 +69250,8 @@ }, /turf/open/floor/iron, /area/engineering/atmos/upper) +======= +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) "mSA" = ( /obj/structure/window/reinforced{ dir = 8 @@ -69780,6 +69637,16 @@ }, /turf/open/floor/plating, /area/maintenance/central/secondary) +"mYu" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 6 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "mYA" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/disposalpipe/segment{ @@ -71311,6 +71178,18 @@ /obj/item/electronics/apc, /turf/open/floor/wood, /area/service/electronic_marketing_den) +"nsn" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 5 + }, +/turf/open/floor/iron, +/area/engineering/atmos/upper) "nsp" = ( /obj/item/reagent_containers/glass/bucket, /obj/effect/decal/cleanable/cobweb/cobweb2, @@ -72326,12 +72205,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/engineering/break_room) -"nDZ" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/iron, -/area/science/misc_lab/range) "nEf" = ( /obj/structure/table/wood, /obj/item/clothing/head/papersack/smiley, @@ -72567,6 +72440,15 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron, /area/engineering/gravity_generator) +"nGU" = ( +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "nGZ" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/line{ @@ -73426,6 +73308,31 @@ /obj/item/radio/intercom/directional/west, /turf/open/floor/iron, /area/cargo/storage) +"nSA" = ( +/obj/machinery/door/firedoor, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/airlock/research{ + name = "Toxins Launch Site"; + req_access_txt = "8" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/structure/cable, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "nSD" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -73726,6 +73633,18 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/maintenance/port/fore) +"nUV" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/table/reinforced, +/obj/item/multitool/circuit{ + pixel_x = 7 + }, +/obj/item/multitool/circuit, +/obj/item/multitool/circuit{ + pixel_x = -8 + }, +/turf/open/floor/iron/white, +/area/science/misc_lab) "nUZ" = ( /obj/machinery/holopad, /obj/structure/cable, @@ -73878,6 +73797,12 @@ }, /turf/open/floor/iron, /area/ai_monitored/command/storage/eva) +"nXC" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "nXD" = ( /obj/item/kirbyplants/random, /obj/machinery/light_switch/directional/west, @@ -75116,6 +75041,10 @@ }, /turf/open/floor/iron/white, /area/hallway/primary/central/aft) +"oly" = ( +/obj/machinery/modular_computer/console/preset/civilian, +/turf/open/floor/iron/white, +/area/science/misc_lab) "olC" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -75388,6 +75317,19 @@ }, /turf/open/floor/iron, /area/maintenance/disposal/incinerator) +"oox" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/science/misc_lab) "ooH" = ( /obj/machinery/camera{ c_tag = "Engineering Hallway - Starboard"; @@ -76482,6 +76424,18 @@ /obj/machinery/air_sensor/atmos/nitrogen_tank, /turf/open/floor/engine/n2, /area/engineering/atmos) +"oDB" = ( +/obj/machinery/door/window/southleft{ + name = "Mass Driver Door"; + req_access_txt = "8" + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/loading_area, +/obj/machinery/computer/pod/old/mass_driver_controller/toxinsdriver{ + pixel_x = 28 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "oDC" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -76655,6 +76609,12 @@ }, /turf/open/floor/iron, /area/engineering/atmos) +"oFL" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "oFV" = ( /obj/structure/window/reinforced{ dir = 4 @@ -77987,25 +77947,6 @@ }, /turf/open/floor/iron, /area/hallway/primary/central/aft) -"oVN" = ( -/obj/item/stack/rods/fifty, -/obj/item/stack/sheet/glass/fifty, -/obj/item/stack/sheet/iron/fifty, -/obj/item/target, -/obj/item/target/syndicate, -/obj/item/target/alien, -/obj/item/target/clown, -/obj/structure/closet/crate/secure{ - desc = "A secure crate containing various materials for building a customised test-site."; - name = "Test Site Materials Crate"; - req_access_txt = "8" - }, -/obj/effect/turf_decal/bot, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 9 - }, -/turf/open/floor/iron, -/area/science/misc_lab) "oVQ" = ( /obj/structure/table/wood, /obj/item/toy/cards/deck/syndicate{ @@ -78380,6 +78321,13 @@ }, /turf/open/floor/plating, /area/security/prison) +"paL" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "paN" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -78903,6 +78851,18 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron, /area/hallway/primary/fore) +"pjj" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 5 + }, +/turf/open/floor/iron, +/area/maintenance/disposal/incinerator) "pjK" = ( /obj/structure/table/wood, /obj/item/folder/red, @@ -79201,10 +79161,6 @@ /obj/machinery/light/directional/east, /turf/open/floor/iron/dark, /area/commons/cryopods) -"pmQ" = ( -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/iron, -/area/science/misc_lab/range) "pmV" = ( /obj/structure/closet/crate/trashcart/laundry, /obj/effect/spawner/lootdrop/prison_contraband, @@ -79694,6 +79650,18 @@ }, /turf/open/floor/iron, /area/security/prison) +"puE" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/machinery/atmospherics/components/unary/portables_connector/visible, +/obj/machinery/airalarm/directional/east, +/obj/machinery/newscaster/directional/north, +/obj/machinery/light_switch/directional/east{ + pixel_y = 26 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "puL" = ( /obj/machinery/holopad, /obj/effect/turf_decal/bot, @@ -81400,22 +81368,6 @@ /obj/item/kirbyplants/random, /turf/open/floor/wood, /area/command/heads_quarters/captain) -"pUp" = ( -/obj/structure/cable, -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/science/misc_lab) "pUx" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/atmos/glass{ @@ -82426,12 +82378,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/commons/fitness/recreation) -"qhc" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/iron, -/area/science/misc_lab/range) "qhd" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -82449,6 +82395,12 @@ }, /turf/open/floor/iron/dark, /area/service/kitchen) +"qhk" = ( +/obj/machinery/vending/assist, +/obj/machinery/firealarm/directional/east, +/obj/machinery/light_switch/directional/south, +/turf/open/floor/iron/white, +/area/science/misc_lab) "qhm" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -82578,6 +82530,10 @@ }, /turf/open/floor/plating, /area/maintenance/central/secondary) +"qje" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/closed/wall, +/area/engineering/atmos) "qjm" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/blue, @@ -83696,6 +83652,15 @@ /obj/machinery/light_switch/directional/east, /turf/open/floor/circuit/green, /area/engineering/main) +"qyo" = ( +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "qyu" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -84404,6 +84369,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/hallway/secondary/entry) +"qGq" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/iron, +/area/science/misc_lab) "qGs" = ( /obj/machinery/light/directional/west, /obj/machinery/camera{ @@ -84664,6 +84633,17 @@ /obj/machinery/atmospherics/pipe/layer_manifold/scrubbers/hidden, /turf/open/floor/iron, /area/science/mixing) +"qKr" = ( +/obj/effect/landmark/start/scientist, +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "qKx" = ( /obj/machinery/power/tesla_coil, /obj/effect/turf_decal/bot, @@ -86323,6 +86303,55 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/brown/visible, /turf/open/floor/iron, /area/engineering/supermatter/room) +"rev" = ( +/obj/structure/cable, +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) +"rew" = ( +/obj/machinery/door/firedoor, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/airlock/research{ + name = "Toxins Mixing Lab"; + req_access_txt = "8" + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "rdtoxins"; + name = "Toxins Lab Shutters" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/structure/cable, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "reB" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/red, @@ -87288,6 +87317,11 @@ }, /turf/open/floor/iron, /area/engineering/main) +"rsF" = ( +/obj/machinery/door/poddoor/massdriver_toxins, +/obj/structure/fans/tiny, +/turf/open/floor/plating, +/area/science/misc_lab/range) "rsL" = ( /obj/structure/plaque/static_plaque/atmos, /turf/closed/wall, @@ -87900,9 +87934,6 @@ /obj/machinery/airalarm/directional/west, /turf/open/floor/wood, /area/service/library/abandoned) -"rCv" = ( -/turf/open/floor/iron, -/area/science/misc_lab/range) "rCA" = ( /obj/item/kirbyplants{ icon_state = "plant-21" @@ -88456,6 +88487,18 @@ /obj/machinery/airalarm/directional/east, /turf/open/floor/iron, /area/science/research) +"rKf" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/rack, +/obj/item/controller, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple, +/obj/item/compact_remote, +/obj/item/compact_remote, +/turf/open/floor/iron/white, +/area/science/misc_lab) "rKh" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ @@ -88587,6 +88630,25 @@ /obj/machinery/atmospherics/pipe/bridge_pipe/orange/visible, /turf/open/space, /area/engineering/atmos) +"rLO" = ( +/obj/item/stack/rods/fifty, +/obj/item/stack/sheet/glass/fifty, +/obj/item/stack/sheet/iron/fifty, +/obj/item/target, +/obj/item/target/syndicate, +/obj/item/target/alien, +/obj/item/target/clown, +/obj/structure/closet/crate/secure{ + desc = "A secure crate containing various materials for building a customised test-site."; + name = "Test Site Materials Crate"; + req_access_txt = "8" + }, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 9 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "rLP" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/red{ @@ -89079,6 +89141,19 @@ }, /turf/open/floor/iron, /area/service/hydroponics) +"rSH" = ( +/obj/structure/cable, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 5 + }, +/turf/open/floor/iron, +/area/engineering/atmos/upper) "rSJ" = ( /obj/structure/disposalpipe/sorting/mail{ dir = 4; @@ -89641,6 +89716,19 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/medical/medbay/central) +"saJ" = ( +/obj/structure/table/reinforced, +/obj/item/storage/toolbox/electrical{ + pixel_y = 5 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/science/misc_lab) "saQ" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/virology{ @@ -89984,6 +90072,28 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron, /area/hallway/secondary/command) +"sfm" = ( +/obj/structure/cable, +/obj/effect/turf_decal/stripes/corner, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/turf/open/floor/iron{ + heat_capacity = 1e+006 + }, +/area/science/misc_lab/range) "sfo" = ( /obj/effect/decal/remains/xeno, /turf/open/floor/engine/vacuum, @@ -90326,6 +90436,10 @@ }, /turf/open/floor/iron, /area/command/gateway) +"skA" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/science/misc_lab/range) "skH" = ( /obj/item/kirbyplants/random, /obj/effect/turf_decal/tile/brown, @@ -91738,6 +91852,16 @@ "sCg" = ( /turf/open/floor/carpet, /area/command/bridge) +"sCm" = ( +/obj/machinery/mass_driver/toxins{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/end{ + dir = 8 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "sCo" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/neutral{ @@ -92344,6 +92468,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/grimy, /area/service/library) +"sJb" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/item/clothing/gloves/color/latex, +/obj/item/clothing/glasses/science, +/obj/item/clothing/glasses/science, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron, +/area/science/misc_lab/range) "sJv" = ( /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ @@ -92470,6 +92603,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/medical/virology) +"sKO" = ( +/obj/structure/sign/poster/official/random{ + pixel_y = 32 + }, +/obj/structure/rack, +/obj/item/integrated_circuit/loaded/speech_relay, +/obj/item/integrated_circuit/loaded/hello_world, +/turf/open/floor/iron/white, +/area/science/misc_lab) "sKP" = ( /obj/effect/turf_decal/stripes/line, /turf/open/floor/iron, @@ -93064,12 +93206,6 @@ }, /turf/open/floor/iron/dark/corner, /area/engineering/atmos) -"sTI" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 8 - }, -/turf/open/floor/iron, -/area/maintenance/port) "sUa" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/sign/departments/medbay/alt, @@ -93130,6 +93266,10 @@ }, /turf/open/floor/engine/vacuum, /area/engineering/atmos) +"sUT" = ( +/obj/structure/sign/nanotrasen, +/turf/closed/wall/r_wall, +/area/science/misc_lab) "sUU" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/yellow, @@ -93478,6 +93618,13 @@ }, /turf/open/floor/iron, /area/security/prison/safe) +"sYB" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/machinery/atmospherics/components/unary/portables_connector/visible, +/turf/open/floor/iron, +/area/science/misc_lab/range) "sYF" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/command{ @@ -94232,16 +94379,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/cafeteria, /area/security/prison) -"tjw" = ( -/obj/effect/turf_decal/stripes/line, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 8 - }, -/turf/open/floor/iron, -/area/science/misc_lab) "tjD" = ( /obj/structure/window/reinforced{ dir = 8 @@ -94972,6 +95109,13 @@ }, /turf/open/floor/iron, /area/maintenance/starboard/fore) +"tuj" = ( +/obj/structure/chair/office/light{ + dir = 1; + pixel_y = 3 + }, +/turf/open/floor/iron/white, +/area/science/misc_lab) "tuq" = ( /obj/effect/landmark/event_spawn, /obj/effect/turf_decal/tile/red{ @@ -95094,6 +95238,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/engineering/main) +"twD" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/components/unary/portables_connector/visible, +/turf/open/floor/iron, +/area/science/misc_lab/range) "txh" = ( /obj/structure/lattice/catwalk, /obj/machinery/atmospherics/pipe/smart/simple/cyan/visible{ @@ -96368,12 +96517,6 @@ }, /turf/open/floor/iron/white, /area/hallway/primary/central/aft) -"tMk" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/turf/open/floor/iron, -/area/science/misc_lab/range) "tMm" = ( /obj/machinery/photocopier, /obj/effect/turf_decal/tile/neutral{ @@ -97514,19 +97657,6 @@ }, /turf/open/floor/iron, /area/maintenance/starboard/fore) -"ubd" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible{ - dir = 5 - }, -/turf/open/floor/iron, -/area/science/misc_lab) "ubv" = ( /obj/effect/turf_decal/delivery, /turf/open/floor/iron, @@ -98097,6 +98227,20 @@ /obj/machinery/firealarm/directional/west, /turf/open/floor/iron/dark, /area/service/chapel/office) +"ujY" = ( +/obj/machinery/power/apc/auto_name/east, +/obj/structure/cable, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible{ + dir = 9 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "ukj" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/purple, @@ -98903,12 +99047,6 @@ /obj/effect/landmark/start/hangover/closet, /turf/open/floor/iron/dark, /area/commons/locker) -"uuM" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 5 - }, -/turf/open/floor/iron, -/area/maintenance/port) "uuR" = ( /obj/effect/landmark/start/cook, /obj/structure/cable, @@ -99107,6 +99245,18 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/iron, /area/hallway/primary/port) +"uxQ" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/machinery/atmospherics/components/trinary/filter{ + dir = 8 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "uyh" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/brown, @@ -100054,6 +100204,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/closed/wall/r_wall, /area/ai_monitored/turret_protected/ai) +"uJJ" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/iron/white, +/area/science/misc_lab) "uJK" = ( /obj/machinery/button/crematorium{ id = "cremawheat"; @@ -100470,6 +100624,13 @@ /obj/machinery/power/apc/auto_name/east, /turf/open/floor/iron/dark, /area/ai_monitored/command/nuke_storage) +"uRm" = ( +/obj/machinery/light/directional/north, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "uRC" = ( /obj/structure/bonfire, /obj/item/reagent_containers/food/drinks/bottle/orangejuice{ @@ -101261,6 +101422,18 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, /area/command/heads_quarters/captain) +"veb" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/obj/machinery/light/directional/south, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/science/misc_lab) "vec" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/tank_holder/emergency_oxygen, @@ -103134,6 +103307,14 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron, /area/hallway/primary/fore) +"vFN" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small/directional/south, +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "vFR" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable, @@ -103153,6 +103334,12 @@ }, /turf/open/floor/iron, /area/security/prison/safe) +"vGv" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "vGx" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ dir = 8 @@ -104861,6 +105048,22 @@ }, /turf/open/floor/carpet, /area/service/chapel/office) +"wbX" = ( +/obj/structure/table/reinforced, +/obj/machinery/cell_charger, +/obj/item/stock_parts/cell/high/plus{ + pixel_x = 5; + pixel_y = 10 + }, +/obj/item/stock_parts/cell/high/plus, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/science/misc_lab) "wcg" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/landmark/xeno_spawn, @@ -105014,16 +105217,16 @@ }, /turf/open/floor/iron/dark, /area/commons/fitness/recreation) -"wei" = ( -/obj/machinery/airalarm/directional/north, -/turf/open/floor/iron/white, -/area/science/misc_lab/range) "wew" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/loot_site_spawner, /turf/open/floor/plating, /area/maintenance/port/aft) +"weA" = ( +/obj/structure/sign/warning/vacuum, +/turf/closed/wall, +/area/science/misc_lab/range) "weH" = ( /obj/machinery/door/firedoor, /obj/structure/cable, @@ -105221,6 +105424,12 @@ }, /turf/open/floor/plating, /area/maintenance/solars/port/fore) +"whX" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/bot, +/obj/machinery/firealarm/directional/east, +/turf/open/floor/iron, +/area/science/misc_lab/range) "whY" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/neutral{ @@ -105353,15 +105562,6 @@ }, /turf/open/floor/iron/dark, /area/ai_monitored/aisat/exterior) -"wjz" = ( -/obj/effect/landmark/blobstart, -/obj/item/beacon, -/obj/structure/cable, -/obj/effect/turf_decal/bot, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/science/misc_lab) "wjF" = ( /obj/structure/chair/office/light{ dir = 1; @@ -105939,6 +106139,14 @@ }, /turf/open/floor/engine/vacuum, /area/engineering/atmos/upper) +"wrZ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small/directional/north, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/iron, +/area/science/misc_lab/range) "wss" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/disposalpipe/segment{ @@ -106617,10 +106825,6 @@ /obj/item/clipboard, /turf/open/floor/iron/cafeteria, /area/security/prison) -"wAA" = ( -/obj/structure/sign/nanotrasen, -/turf/closed/wall/r_wall, -/area/science/misc_lab/range) "wAZ" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -107449,35 +107653,6 @@ /obj/structure/cable, /turf/open/floor/wood, /area/service/electronic_marketing_den) -"wPJ" = ( -/obj/machinery/door/firedoor, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/door/airlock/research{ - name = "Toxins Mixing Lab"; - req_access_txt = "8" - }, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "rdtoxins"; - name = "Toxins Lab Shutters" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/obj/structure/cable, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 8 - }, -/turf/open/floor/iron, -/area/science/mixing) "wPK" = ( /obj/machinery/door/airlock{ id_tag = "AuxToilet1"; @@ -109225,6 +109400,17 @@ }, /turf/open/floor/iron/dark/corner, /area/engineering/atmos) +"xoY" = ( +/obj/structure/cable, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 5 + }, +/turf/open/floor/iron/white, +/area/science/misc_lab) "xpb" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, @@ -110679,6 +110865,9 @@ }, /turf/open/floor/iron, /area/service/hydroponics) +"xKO" = ( +/turf/open/floor/iron, +/area/science/misc_lab) "xKQ" = ( /obj/item/kirbyplants/random, /obj/structure/disposalpipe/segment{ @@ -110699,6 +110888,9 @@ /obj/machinery/atmospherics/components/binary/thermomachine/freezer, /turf/open/floor/iron, /area/science/mixing) +"xLa" = ( +/turf/open/floor/iron/white, +/area/science/misc_lab) "xLd" = ( /obj/machinery/holopad, /obj/effect/turf_decal/tile/neutral{ @@ -111571,6 +111763,15 @@ }, /turf/open/floor/iron/dark, /area/service/bar) +"xXZ" = ( +/obj/effect/landmark/blobstart, +/obj/item/beacon, +/obj/structure/cable, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/science/misc_lab/range) "xYc" = ( /obj/structure/table/wood, /obj/item/flashlight/lamp, @@ -112009,28 +112210,6 @@ /obj/structure/extinguisher_cabinet/directional/north, /turf/open/floor/iron, /area/commons/fitness/recreation) -"ydd" = ( -/obj/structure/cable, -/obj/effect/turf_decal/stripes/corner, -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 8 - }, -/turf/open/floor/iron{ - heat_capacity = 1e+006 - }, -/area/science/misc_lab) "ydg" = ( /obj/machinery/door/poddoor/preopen{ id = "brigprison"; @@ -135125,7 +135304,7 @@ uiP woP bgH aDu -jwE +fqO oVs kQs tMQ @@ -136391,7 +136570,7 @@ wLZ cHk tmu aIy -fqt +pjj gcW mZD hbW @@ -136986,11 +137165,11 @@ nPM nPM nPM nPM -saw -saw -saw -saw -saw +gSi +gSi +gSi +gSi +gSi dhQ dhQ dhQ @@ -137160,9 +137339,9 @@ nMS nMS nMS mdD -fbV +nsn jiy -mSy +rSH fKs sSx vIB @@ -137171,11 +137350,19 @@ qkN vzJ ntl mZD +<<<<<<< HEAD mZD xXs mZD xXs mZD +======= +lIN +xXs +mZD +xXs +qje +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) mZD eJp owx @@ -137240,14 +137427,14 @@ iuP exk swm pfQ -caE -djn -dle -saw -dog -nDZ -drz -saw +tCh +map +vGv +vGv +vGv +vGv +lmF +gSi dul dvZ dxH @@ -137497,14 +137684,14 @@ cjq ced wXQ moY -caE -jjN -hNZ -saw -qhc -dpX -pmQ -saw +tCh +mLI +xKO +xKO +xKO +bfJ +aST +gSi djs dlf dxI @@ -137754,14 +137941,14 @@ cMY cMY ceb moY -caE -djp -qpq -saw -doh -rCv -pmQ -saw +tCh +uRm +qGq +ehi +ehi +faO +aST +gSi dlg dli xwx @@ -138011,14 +138198,14 @@ cNd cMY cea kEw -caE -qpq -qpq -saw -qhc -rCv -drA -saw +tCh +mLI +xKO +xKO +xKO +ehi +mGu +gSi dum dli dpZ @@ -138268,14 +138455,14 @@ dcb cMY cea laE -kTQ -iYN -uuM -saw -qhc -tMk -pmQ -saw +tCh +kon +qyo +qyo +qyo +jHZ +aST +gSi yjc lEl dxJ @@ -138525,14 +138712,14 @@ xtH cMY deX aiu -caE -qpq -sTI -saw -doj -eYc -lXM -saw +tCh +nUV +saJ +wbX +mPh +gpg +nGU +gSi dun lEl dxK @@ -138782,14 +138969,14 @@ lvo cMY deX joJ -caE -xMn -dok -saw -jEz -eJF -drC -saw +tCh +oly +tuj +xLa +xLa +xoY +gsi +gSi duo dmu eMD @@ -139039,14 +139226,14 @@ xXC cMY deY oAw -caE -cea -djr -saw -dol -myW -drD -saw +tCh +bLH +bly +xLa +uJJ +ifR +veb +gSi dup dlg dxL @@ -139296,14 +139483,14 @@ enx cMY cjp hST -caE -cea -cea -saw -wei -fQl -drE -saw +tCh +cGu +hOV +hOV +hOV +oox +iNP +gSi duq dlh dxM @@ -139553,14 +139740,14 @@ dcd cMY deZ joJ -caE -djv -ceb -saw -doo -fQl -drF -saw +tCh +sKO +rKf +bhD +mLZ +dQV +qhk +gSi dur xze dxN @@ -139810,14 +139997,14 @@ rMk cMY deX joJ -caE -caE -caE -saw -wAA -lVN -saw -saw +tCh +tCh +tCh +gSi +sUT +hgS +gSi +gSi dus dwa dom @@ -140853,14 +141040,14 @@ cxO mbI caE aad -gSi -dEn -dEn -gSi -dEn -gSi -dLI -gSi +saw +skA +skA +saw +skA +saw +eMn +saw dOa dOM aad @@ -141110,14 +141297,14 @@ cxN uzE cOj aaa -dEn -dFz -dGY -dIj -dJJ -dEn -dLJ -gSi +skA +gDm +fUX +hIQ +aPJ +skA +asu +saw dOb ert ert @@ -141367,14 +141554,14 @@ cxO oFE cOj aad -dEn -dFA -dGZ -dIk -dJK -dKA -dLK -gSi +skA +nXC +lra +lHp +iPA +weA +rsF +saw dOc ert yiM @@ -141624,14 +141811,14 @@ dzo mbI caE aaa -gSi -dFB -dHa -kJJ -oVN -dEn -dLL -gSi +saw +emq +cBP +mYu +rLO +skA +hAH +saw dOd ert iKu @@ -141881,14 +142068,14 @@ dzp wJa cOj aad -dEn -dFC -ubd -leq -dJM -dKB -dLM -gSi +skA +sYB +lgf +qKr +sJb +kot +aXp +saw dOe hmH yli @@ -142138,14 +142325,14 @@ dzq mbI cOj aaa -dEn -dFD -dHc -tjw -dJN -dEn -dLN -gSi +skA +twD +uxQ +izv +mPo +skA +lft +saw dLW fTa elW @@ -142395,14 +142582,14 @@ cxO oFE caE aad -gSi -dFE -eGN -jEi -dJO -dKC -dLO -gSi +saw +puE +ujY +jAR +whX +oDB +sCm +saw qHZ kwQ bce @@ -142652,14 +142839,14 @@ dzp pxk caE caE -gSi -gSi -gSi -ayL -gSi -gSi -gSi -gSi +saw +saw +saw +nSA +saw +saw +saw +saw uSp hmH etl @@ -142910,11 +143097,11 @@ wJa dBY cea dEo -tCh -dHe -dze -dJQ -tCh +kVu +wrZ +rev +vFN +kVu dLP dNt cGi @@ -143168,9 +143355,9 @@ exk sCo oWN pDd -pUp -wjz -fQf +kZB +xXZ +ahP pYc ucq dWh @@ -143424,11 +143611,11 @@ cjq dBZ cjq dEp -tCh -dHg -ydd -dJS -tCh +kVu +paL +sfm +oFL +kVu dLS dQE agR @@ -143681,11 +143868,11 @@ drP drP drP drP -gSi -gSi -wPJ -gSi -gSi +saw +saw +rew +saw +saw dLS dNw fGR diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index c3d0f0dc4c8..7d80009d90c 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -9889,6 +9889,7 @@ "bfv" = ( /turf/closed/wall/r_wall, /area/ai_monitored/turret_protected/ai_upload) +<<<<<<< HEAD "bfx" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable, @@ -9899,6 +9900,8 @@ }, /turf/open/floor/iron, /area/maintenance/disposal/incinerator) +======= +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) "bfF" = ( /turf/closed/wall, /area/medical/pharmacy) @@ -15417,13 +15420,6 @@ "bJN" = ( /turf/closed/wall, /area/science/xenobiology) -"bJO" = ( -/obj/machinery/door/airlock/research{ - name = "Testing Lab"; - req_access_txt = "47" - }, -/turf/open/floor/iron, -/area/science/misc_lab) "bJP" = ( /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible, /turf/open/floor/plating/snowed/icemoon, @@ -16366,10 +16362,6 @@ /obj/effect/turf_decal/stripes/corner, /turf/open/floor/iron/white, /area/science/xenobiology) -"bQO" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/science/misc_lab) "bQQ" = ( /obj/machinery/door/firedoor, /obj/structure/cable, @@ -17739,12 +17731,14 @@ }, /turf/open/floor/plating, /area/maintenance/aft) -"caY" = ( -/obj/machinery/disposal/bin, -/obj/structure/disposalpipe/trunk{ - dir = 8 +"caW" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 6 }, -/turf/open/floor/iron, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/white, /area/science/misc_lab) "caZ" = ( /obj/effect/turf_decal/tile/blue{ @@ -18081,12 +18075,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/maintenance/port/aft) -"cdz" = ( -/obj/structure/tank_holder, -/turf/open/floor/plating{ - icon_state = "platingdmg2" - }, -/area/maintenance/starboard/aft) "cdI" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ @@ -18294,6 +18282,15 @@ /obj/item/storage/fancy/donut_box, /turf/open/floor/carpet, /area/command/heads_quarters/captain) +"chC" = ( +/obj/structure/table, +/obj/item/storage/toolbox/electrical{ + pixel_y = 5 + }, +/turf/open/floor/iron/white/side{ + dir = 1 + }, +/area/maintenance/starboard/aft) "chH" = ( /obj/structure/closet/firecloset, /turf/open/floor/plating, @@ -18436,10 +18433,6 @@ /obj/structure/closet/crate/solarpanel_small, /turf/open/floor/iron/dark, /area/engineering/engine_smes) -"cka" = ( -/obj/structure/table, -/turf/open/floor/iron, -/area/science/misc_lab) "cko" = ( /obj/structure/disposalpipe/segment, /turf/closed/wall, @@ -21468,6 +21461,13 @@ /obj/structure/window/reinforced, /turf/open/floor/iron/cafeteria, /area/command/heads_quarters/rd) +"dcS" = ( +/obj/machinery/atmospherics/pipe/smart/simple/cyan/visible{ + dir = 9 + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/engineering/atmos) "ddd" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ dir = 4 @@ -21774,6 +21774,9 @@ /obj/item/storage/box, /turf/open/floor/iron, /area/engineering/atmos) +"dov" = ( +/turf/open/floor/iron/white, +/area/science/misc_lab) "doE" = ( /obj/structure/light_construct/directional/east, /turf/open/floor/iron, @@ -23175,6 +23178,14 @@ }, /turf/open/floor/iron, /area/cargo/office) +"egV" = ( +/obj/machinery/atmospherics/components/binary/pump/on{ + dir = 1; + name = "N2 to Airmix" + }, +/obj/machinery/light/directional/south, +/turf/open/floor/iron, +/area/engineering/atmos) "ehm" = ( /obj/machinery/atmospherics/components/unary/outlet_injector/atmos/mix_input{ dir = 8 @@ -24166,6 +24177,10 @@ }, /turf/open/floor/iron, /area/cargo/miningdock) +"eOr" = ( +/obj/structure/cable, +/turf/open/floor/iron/white/side, +/area/science/misc_lab) "eOE" = ( /obj/structure/chair/office{ dir = 1 @@ -25505,6 +25520,13 @@ /obj/effect/landmark/start/cargo_technician, /turf/open/floor/iron, /area/cargo/sorting) +"fIO" = ( +/obj/machinery/atmospherics/pipe/bridge_pipe/cyan/visible, +/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible{ + dir = 4 + }, +/turf/open/floor/iron, +/area/engineering/atmos) "fIP" = ( /obj/machinery/nuclearbomb/selfdestruct, /obj/effect/turf_decal/tile/neutral{ @@ -26147,15 +26169,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/engine/vacuum, /area/science/mixing/chamber) -"fXM" = ( -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/science/misc_lab) "fXZ" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -26181,6 +26194,14 @@ }, /turf/open/floor/iron/grimy, /area/commons/vacant_room/office) +"fZt" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 6 + }, +/turf/open/floor/iron/white, +/area/science/misc_lab) "fZF" = ( /obj/effect/turf_decal/tile/yellow{ dir = 8 @@ -26230,6 +26251,16 @@ /obj/item/trash/semki, /turf/open/floor/iron, /area/maintenance/port/fore) +"gaD" = ( +/obj/structure/table, +/obj/item/stock_parts/cell/high, +/obj/machinery/cell_charger{ + pixel_y = 5 + }, +/turf/open/floor/iron/white/corner{ + dir = 4 + }, +/area/maintenance/starboard/aft) "gaT" = ( /obj/structure/table, /obj/item/paper_bin{ @@ -27734,6 +27765,18 @@ /obj/effect/spawner/lootdrop/maintenance/three, /turf/open/floor/plating, /area/maintenance/port) +"gWT" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/door/airlock/maintenance{ + name = "Testing Lab Maintenance"; + req_access_txt = "47" + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/plating, +/area/maintenance/starboard/aft) "gWZ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ dir = 5 @@ -27959,13 +28002,6 @@ }, /turf/open/floor/iron, /area/cargo/storage) -"her" = ( -/obj/effect/turf_decal/arrows, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) "het" = ( /obj/machinery/light/directional/east, /turf/open/floor/iron/dark, @@ -28873,6 +28909,27 @@ }, /turf/open/floor/iron, /area/security/brig) +"hFE" = ( +/obj/structure/table, +/obj/item/multitool/circuit{ + pixel_x = -8 + }, +/obj/item/multitool/circuit{ + pixel_x = -4 + }, +/obj/item/multitool/circuit, +/obj/item/stock_parts/cell/high{ + pixel_x = 8; + pixel_y = 9 + }, +/obj/item/stock_parts/cell/high{ + pixel_x = 8; + pixel_y = -2 + }, +/turf/open/floor/iron/white/side{ + dir = 4 + }, +/area/science/misc_lab) "hFZ" = ( /obj/machinery/navbeacon{ codes_txt = "delivery;dir=8"; @@ -30510,6 +30567,14 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron, /area/service/bar) +"iGi" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/turf/open/floor/iron/white/side{ + dir = 8 + }, +/area/science/misc_lab) "iGv" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 8 @@ -30975,12 +31040,6 @@ }, /turf/open/floor/iron, /area/hallway/secondary/exit) -"iVn" = ( -/obj/structure/closet/l3closet/scientist{ - pixel_x = -2 - }, -/turf/open/floor/iron, -/area/science/misc_lab) "iVY" = ( /obj/structure/table, /obj/item/assembly/signaler, @@ -31683,6 +31742,11 @@ "joZ" = ( /turf/open/floor/engine/n2, /area/engineering/atmos) +"jpx" = ( +/turf/open/floor/iron/white/side{ + dir = 8 + }, +/area/science/misc_lab) "jpE" = ( /obj/machinery/holopad, /obj/effect/turf_decal/bot, @@ -32866,17 +32930,6 @@ }, /turf/open/floor/iron, /area/security/checkpoint/medical) -"jZb" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 4 - }, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) "jZf" = ( /obj/structure/closet/secure_closet/chemical, /obj/effect/turf_decal/trimline/blue/line, @@ -32933,11 +32986,6 @@ /obj/structure/cable, /turf/open/floor/plating, /area/commons/storage/mining) -"kbE" = ( -/obj/structure/closet/bombcloset, -/obj/structure/extinguisher_cabinet/directional/west, -/turf/open/floor/iron, -/area/science/misc_lab) "kbG" = ( /obj/effect/turf_decal/tile/yellow{ dir = 8 @@ -34868,6 +34916,7 @@ }, /turf/open/floor/iron, /area/engineering/main) +<<<<<<< HEAD "lhV" = ( /obj/machinery/atmospherics/pipe/bridge_pipe/green/visible{ dir = 4 @@ -34878,6 +34927,8 @@ }, /turf/open/floor/iron, /area/engineering/atmos) +======= +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) "liu" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ @@ -35290,15 +35341,6 @@ }, /turf/open/floor/iron/freezer, /area/commons/toilet) -"ltG" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/science/misc_lab) "ltP" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -37826,6 +37868,19 @@ /obj/structure/lattice/catwalk, /turf/open/openspace/icemoon, /area/science/server) +"mIV" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 4 + }, +/obj/structure/sign/warning/securearea{ + pixel_y = 32 + }, +/turf/open/floor/plating, +/area/maintenance/starboard/aft) "mIX" = ( /obj/machinery/atmospherics/pipe/smart/simple/purple/visible{ dir = 5 @@ -38163,6 +38218,7 @@ }, /turf/open/floor/iron, /area/engineering/engine_smes) +<<<<<<< HEAD "mRj" = ( /obj/machinery/light, /obj/machinery/atmospherics/components/binary/pump/on{ @@ -38172,6 +38228,8 @@ /obj/machinery/light/directional/south, /turf/open/floor/iron, /area/engineering/atmos) +======= +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) "mRA" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 1 @@ -39345,14 +39403,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/hallway/primary/central) -"nyR" = ( -/obj/structure/rack, -/obj/item/wrench, -/obj/item/crowbar, -/obj/effect/decal/cleanable/dirt, -/obj/item/hand_labeler, -/turf/open/floor/iron, -/area/science/misc_lab) "nyY" = ( /obj/machinery/computer/crew, /obj/effect/turf_decal/tile/green, @@ -39664,6 +39714,15 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron, /area/service/bar) +"nIs" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/simple/dark/visible, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 10 + }, +/turf/open/floor/iron, +/area/maintenance/disposal/incinerator) "nIt" = ( /obj/machinery/porta_turret/ai{ dir = 4; @@ -39843,6 +39902,12 @@ /obj/machinery/light/directional/north, /turf/open/floor/iron/white, /area/medical/medbay) +"nPK" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/white, +/area/science/misc_lab) "nPP" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/disposalpipe/segment, @@ -39945,6 +40010,7 @@ /obj/structure/cable, /turf/open/floor/plating, /area/maintenance/solars/port/aft) +<<<<<<< HEAD "nRS" = ( /obj/machinery/light{ dir = 4 @@ -39955,6 +40021,8 @@ /obj/machinery/light/directional/east, /turf/open/floor/iron, /area/engineering/atmos) +======= +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) "nSI" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -41472,6 +41540,7 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/wood, /area/service/library) +<<<<<<< HEAD "oOp" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/smart/simple/cyan/visible{ @@ -41480,6 +41549,8 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/engineering/atmos) +======= +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) "oOF" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -41534,6 +41605,10 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron, /area/hallway/primary/central) +"oQI" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/science/xenobiology) "oQS" = ( /obj/machinery/atmospherics/components/binary/pump{ name = "Pure to Port" @@ -41806,6 +41881,14 @@ "pbq" = ( /turf/closed/wall, /area/service/chapel/office) +"pby" = ( +/obj/structure/rack, +/obj/item/integrated_circuit/loaded/speech_relay, +/obj/item/integrated_circuit/loaded/hello_world, +/turf/open/floor/iron/white/side{ + dir = 4 + }, +/area/science/misc_lab) "pbB" = ( /obj/machinery/atmospherics/components/binary/pump/on{ dir = 4; @@ -43799,6 +43882,13 @@ dir = 10 }, /area/science/research) +"qbd" = ( +/obj/machinery/atmospherics/pipe/bridge_pipe/yellow/visible, +/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible{ + dir = 4 + }, +/turf/open/floor/iron, +/area/engineering/atmos) "qbj" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ dir = 8 @@ -44816,6 +44906,15 @@ /obj/item/radio/intercom/directional/east, /turf/open/floor/iron, /area/science/robotics/lab) +"qJG" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/meter/atmos/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/maintenance/starboard/aft) "qJQ" = ( /obj/item/kirbyplants/random, /turf/open/floor/iron/grimy, @@ -45381,6 +45480,15 @@ /obj/structure/cable, /turf/open/floor/iron, /area/hallway/primary/central) +"rbd" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/turf/open/floor/iron/white/corner{ + dir = 1 + }, +/area/science/misc_lab) "rbz" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 8 @@ -46358,6 +46466,13 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/command/gateway) +"rDD" = ( +/obj/machinery/atmospherics/pipe/smart/simple/cyan/visible{ + dir = 6 + }, +/obj/machinery/light/directional/east, +/turf/open/floor/iron, +/area/engineering/atmos) "rDE" = ( /obj/effect/turf_decal/tile/yellow{ dir = 4 @@ -46843,14 +46958,6 @@ /obj/effect/landmark/xeno_spawn, /turf/open/floor/iron, /area/construction) -"rOY" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 6 - }, -/turf/open/floor/iron, -/area/science/misc_lab) "rPX" = ( /obj/structure/disposalpipe/segment, /turf/closed/wall, @@ -48301,13 +48408,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/carpet, /area/command/heads_quarters/hos) -"sHk" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 4 - }, -/turf/open/floor/iron, -/area/science/misc_lab) "sHm" = ( /obj/structure/cable, /turf/open/floor/plating/asteroid/snow/icemoon, @@ -48911,11 +49011,6 @@ }, /turf/open/floor/iron, /area/maintenance/port/fore) -"sXV" = ( -/obj/effect/decal/cleanable/cobweb, -/obj/structure/closet/emcloset, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) "sXZ" = ( /obj/effect/turf_decal/stripes/corner{ dir = 1 @@ -49479,14 +49574,6 @@ }, /turf/open/floor/iron, /area/commons/dorms) -"tny" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/meter/atmos/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 4 - }, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) "tnP" = ( /obj/structure/cable, /obj/machinery/atmospherics/components/trinary/filter/atmos/co2, @@ -49720,19 +49807,6 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron, /area/service/bar) -"ttY" = ( -/obj/structure/sign/warning/securearea{ - pixel_y = 32 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 4 - }, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) "tun" = ( /obj/structure/closet/secure_closet/personal{ anchored = 1 @@ -49857,20 +49931,6 @@ "txw" = ( /turf/open/floor/iron/dark, /area/ai_monitored/command/storage/eva) -"txB" = ( -/obj/structure/rack, -/obj/item/clothing/mask/gas{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/clothing/mask/gas, -/obj/item/clothing/mask/gas{ - pixel_x = -3; - pixel_y = -3 - }, -/obj/machinery/airalarm/directional/west, -/turf/open/floor/iron, -/area/science/misc_lab) "txF" = ( /obj/structure/chair/comfy/black, /turf/open/floor/carpet, @@ -50179,6 +50239,14 @@ }, /turf/open/floor/iron, /area/engineering/atmos) +"tHZ" = ( +/obj/machinery/airalarm/directional/north, +/obj/structure/rack, +/obj/item/controller, +/obj/item/compact_remote, +/obj/item/compact_remote, +/turf/open/floor/iron/white/corner, +/area/science/misc_lab) "tIa" = ( /obj/machinery/camera{ c_tag = "Atmospherics North East" @@ -50234,6 +50302,12 @@ /obj/item/pen, /turf/open/floor/iron, /area/security/office) +"tJy" = ( +/obj/machinery/component_printer, +/turf/open/floor/iron/white/side{ + dir = 4 + }, +/area/science/misc_lab) "tKl" = ( /obj/structure/cable, /obj/structure/railing, @@ -51980,11 +52054,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/hallway/primary/port) -"uCq" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable, -/turf/open/floor/iron, -/area/science/misc_lab) "uCs" = ( /obj/machinery/light/small/directional/south, /turf/open/floor/plating, @@ -52264,6 +52333,13 @@ }, /turf/open/floor/iron, /area/engineering/atmos) +"uLK" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/turf/open/floor/iron/white/corner{ + dir = 8 + }, +/area/science/misc_lab) "uLQ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ dir = 4 @@ -52539,6 +52615,14 @@ }, /turf/open/floor/iron, /area/command/teleporter) +"uWL" = ( +/obj/machinery/modular_computer/console/preset/civilian{ + dir = 4 + }, +/turf/open/floor/iron/white/side{ + dir = 4 + }, +/area/science/misc_lab) "uXm" = ( /obj/machinery/door/morgue{ name = "Confession Booth (Chaplain)"; @@ -52750,6 +52834,17 @@ dir = 8 }, /area/science/research) +"vdD" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/iron/white/side{ + dir = 9 + }, +/area/maintenance/starboard/aft) "vdE" = ( /obj/structure/chair/office{ dir = 1 @@ -53252,6 +53347,13 @@ /obj/structure/girder, /turf/open/floor/iron/white, /area/maintenance/port/fore) +"vwQ" = ( +/obj/machinery/door/airlock/research{ + name = "Circuit Testing Lab"; + req_access_txt = "47" + }, +/turf/open/floor/iron, +/area/science/misc_lab) "vwX" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/effect/decal/cleanable/dirt, @@ -53979,6 +54081,9 @@ "vOj" = ( /turf/closed/wall, /area/security/office) +"vOl" = ( +/turf/open/floor/iron/white/side, +/area/science/misc_lab) "vOu" = ( /turf/closed/wall, /area/hallway/primary/aft) @@ -54519,6 +54624,7 @@ }, /turf/open/floor/iron, /area/engineering/main) +<<<<<<< HEAD "wed" = ( /obj/machinery/atmospherics/pipe/bridge_pipe/green/visible{ dir = 4 @@ -54529,6 +54635,8 @@ }, /turf/open/floor/iron, /area/engineering/atmos) +======= +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) "weh" = ( /obj/machinery/airalarm/directional/west, /obj/machinery/camera{ @@ -54612,6 +54720,12 @@ dir = 9 }, /area/science/research) +"wgT" = ( +/obj/structure/chair/office{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/science/misc_lab) "whg" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ dir = 4 @@ -55712,17 +55826,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/science/storage) -"wQy" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/door/airlock/maintenance{ - name = "Testing Lab Maintenance"; - req_access_txt = "47" - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/plating, -/area/maintenance/starboard/aft) "wQH" = ( /obj/structure/table/wood, /obj/machinery/airalarm/directional/east, @@ -57210,6 +57313,15 @@ }, /turf/open/floor/iron, /area/engineering/atmos) +"xGt" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment, +/turf/open/floor/iron/white/corner{ + dir = 1 + }, +/area/maintenance/starboard/aft) "xGS" = ( /obj/structure/disposalpipe/segment, /obj/machinery/light/directional/west, @@ -57278,6 +57390,13 @@ }, /turf/open/floor/engine, /area/engineering/supermatter) +"xIk" = ( +/obj/effect/turf_decal/arrows, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/iron/white, +/area/maintenance/starboard/aft) "xIt" = ( /obj/machinery/space_heater, /obj/structure/sign/poster/official/random{ @@ -57788,6 +57907,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/commons/dorms) +"xWW" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 4 + }, +/turf/open/floor/iron/white/side{ + dir = 8 + }, +/area/science/misc_lab) "xXc" = ( /obj/machinery/door/airlock/maintenance{ name = "Crematorium Maintenance"; @@ -91185,7 +91313,7 @@ hnq rLU rGD ciH -lhV +qbd sAE nqb qoC @@ -91443,7 +91571,7 @@ rLU oKF tQD hYi -mRj +egV cmC rjM ccm @@ -92727,7 +92855,7 @@ kuR ruE hvb nsg -wed +fIO dFW fJb bIZ @@ -93239,7 +93367,7 @@ rLU gsC jhK wNJ -nRS +rDD pBb pBb mkZ @@ -93496,7 +93624,7 @@ fJb uqR fJb oiX -oOp +dcS ojf ojf fsN @@ -96841,7 +96969,7 @@ bAw bxo akE wLA -bfx +nIs bBl bEv bEV @@ -103770,9 +103898,9 @@ bJN bJN bDb bDb +oQI bDb -bDb -bDb +oQI bDb bDb bDb @@ -104026,13 +104154,13 @@ tMH hgm bhA bPN -kbE -iVn -txB -nyR -bQZ -sXV -cdz +tHZ +pby +tJy +uWL +hFE +gaD +mtK bTC uTB cmo @@ -104283,14 +104411,14 @@ bzE bzE bWo bPK -bQO -vHt -bQO -vHt -bQZ -ttY -iLm -iLm +vOl +dov +dov +wgT +dov +chC +mtK +mIV iLm iLm iLm @@ -104539,15 +104667,15 @@ dcG rNt bWr bWo -bJO -bYj -rOY -ltG -fXM -wQy -jZb -jsw -tny +vwQ +eOr +fZt +caW +nPK +vdD +xGt +gWT +qJG jsw jsw cri @@ -104797,13 +104925,13 @@ tCL cdM bWo bPK -uCq -pWN -sHk -caY -bQZ -cNW +uLK +iGi +xWW +jpx +rbd cNW +mtK qUz cNW cNW @@ -105057,17 +105185,17 @@ bPN uOi cba gZY -eeY +vHt bQZ nlW -her +xIk xtu cNW qQH cvO bNA cNW -cOe +cdu iLm tkC cNW @@ -105571,7 +105699,7 @@ kQl bYj pWN bOv -cka +eeY bQZ gSR qiP diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm index b60b387d8b0..3c6cc5d0e42 100644 --- a/_maps/map_files/KiloStation/KiloStation.dmm +++ b/_maps/map_files/KiloStation/KiloStation.dmm @@ -4842,16 +4842,18 @@ }, /area/maintenance/port/fore) "anS" = ( -/obj/machinery/mass_driver{ - dir = 4; - id = "toxinsdriver" +/obj/machinery/door/airlock/maintenance{ + name = "Testing Lab Maintainance"; + req_access_txt = "8" }, -/obj/effect/turf_decal/stripes/end{ +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ dir = 8 }, -/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 9 + }, /turf/open/floor/plating, -/area/science/mixing) +/area/maintenance/starboard) "anT" = ( /obj/structure/table/wood, /obj/item/clipboard, @@ -11296,15 +11298,6 @@ /obj/effect/turf_decal/tile/purple, /turf/open/floor/iron/showroomfloor, /area/science/genetics) -"aLP" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/bot, -/obj/structure/closet/cardboard, -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/turf/open/floor/plating, -/area/maintenance/starboard) "aLQ" = ( /obj/effect/turf_decal/bot, /obj/structure/rack, @@ -12300,7 +12293,6 @@ }, /obj/effect/turf_decal/tile/purple, /obj/machinery/meter, -/obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ dir = 4 }, @@ -12308,6 +12300,7 @@ dir = 10 }, /obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible, +/obj/structure/cable, /turf/open/floor/iron/showroomfloor, /area/science/mixing/chamber) "aOK" = ( @@ -12372,10 +12365,10 @@ /obj/effect/turf_decal/stripes/corner{ dir = 8 }, -/obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ dir = 4 }, +/obj/structure/cable, /turf/open/floor/iron/showroomfloor, /area/science/mixing/chamber) "aOS" = ( @@ -13647,7 +13640,6 @@ /obj/effect/turf_decal/stripes/corner{ dir = 1 }, -/obj/structure/cable, /turf/open/floor/plating{ icon_state = "panelscorched" }, @@ -14153,14 +14145,8 @@ /area/medical/storage) "aSQ" = ( /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/stripes/line, -/obj/structure/cable, -/turf/open/floor/plating{ - icon_state = "platingdmg1" - }, -/area/maintenance/starboard) +/turf/closed/wall/rust, +/area/science/test_area) "aSR" = ( /obj/item/kirbyplants{ icon_state = "plant-18" @@ -15867,8 +15853,12 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/cable, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/iron/dark, -/area/science/mixing) +/area/science/test_area) "aYd" = ( /turf/closed/wall/r_wall, /area/science/lab) @@ -16956,9 +16946,17 @@ }, /area/maintenance/central) "baC" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/science/mixing) +/obj/structure/rack, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple, +/obj/item/integrated_circuit/loaded/speech_relay, +/obj/item/integrated_circuit/loaded/hello_world, +/obj/machinery/light_switch/directional/south, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/iron/showroomfloor, +/area/science/test_area) "baD" = ( /obj/structure/table/reinforced, /obj/item/wrench, @@ -17524,25 +17522,18 @@ /turf/open/floor/engine, /area/science/mixing/chamber) "bcb" = ( -/obj/structure/chair{ +/obj/effect/turf_decal/tile/purple{ dir = 4 }, -/obj/machinery/computer/security/telescreen{ - desc = "Used for watching the test chamber."; - dir = 8; - layer = 4; - name = "Test Chamber Telescreen"; - network = list("toxins"); - pixel_x = 30 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/purple{ dir = 1 }, -/turf/open/floor/iron/dark, -/area/science/mixing) +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/iron/showroomfloor, +/area/science/test_area) "bcc" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 4 @@ -17605,6 +17596,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/structure/cable, /turf/open/floor/iron/dark, /area/science/mixing/chamber) "bck" = ( @@ -17826,38 +17818,19 @@ /turf/open/floor/iron/showroomfloor, /area/science/lab) "bcR" = ( -/obj/item/target, -/obj/item/target/syndicate, -/obj/item/target/alien, -/obj/item/target/clown, -/obj/structure/closet/crate/secure{ - desc = "A secure crate containing various materials for building a customised test-site."; - name = "Test Site Materials Crate"; - req_access_txt = "8" - }, -/obj/effect/turf_decal/bot, /obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/tile/neutral{ dir = 8 }, /obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/dark, -/area/science/mixing) -"bcS" = ( -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ +/obj/effect/turf_decal/stripes/corner{ dir = 4 }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 +/obj/structure/sign/warning/explosives/alt{ + pixel_x = -32 }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/showroomfloor, -/area/science/mixing) +/turf/open/floor/iron/dark, +/area/science/test_area) "bcW" = ( /obj/effect/turf_decal/tile/purple{ dir = 8 @@ -18161,9 +18134,9 @@ /obj/effect/turf_decal/tile/purple{ dir = 1 }, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/showroomfloor, -/area/science/mixing) +/area/science/test_area) "bdW" = ( /obj/structure/transit_tube/horizontal{ dir = 1 @@ -18318,36 +18291,26 @@ /turf/open/floor/iron, /area/hallway/primary/fore) "bej" = ( -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ dir = 8 }, -/obj/effect/turf_decal/tile/purple, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ dir = 9 }, +/turf/open/floor/iron/showroomfloor, +/area/science/test_area) +"bek" = ( +/obj/structure/chair/office/light{ + dir = 4 + }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ dir = 8 }, -/obj/effect/turf_decal/stripes/corner{ - dir = 8 +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 9 }, /turf/open/floor/iron/showroomfloor, -/area/science/mixing) -"bek" = ( -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/obj/effect/turf_decal/tile/purple, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 8 - }, -/turf/open/floor/iron/showroomfloor, -/area/science/mixing) +/area/science/test_area) "bem" = ( /obj/effect/turf_decal/tile/purple{ dir = 4 @@ -18544,7 +18507,7 @@ "beH" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, -/area/science/mixing) +/area/science/test_area) "beI" = ( /obj/machinery/portable_atmospherics/canister/toxins, /obj/effect/turf_decal/bot, @@ -19064,17 +19027,6 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/maintenance/starboard) -"bge" = ( -/obj/machinery/door/airlock/external{ - name = "External Airlock"; - req_access_txt = "13" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/obj/structure/cable, -/turf/open/floor/iron/dark, -/area/maintenance/starboard) "bgf" = ( /obj/structure/lattice/catwalk, /obj/structure/cable, @@ -19241,7 +19193,7 @@ "bgy" = ( /obj/machinery/door/firedoor/heavy, /obj/machinery/door/airlock/research{ - name = "Toxins Launch Room"; + name = "Testing Lab"; req_access_txt = "8" }, /obj/effect/turf_decal/stripes/corner{ @@ -19250,8 +19202,9 @@ /obj/effect/turf_decal/stripes/corner{ dir = 1 }, +/obj/structure/cable, /turf/open/floor/iron/dark, -/area/science/mixing) +/area/science/test_area) "bgA" = ( /obj/effect/turf_decal/tile/purple{ dir = 4 @@ -19777,15 +19730,12 @@ }, /area/maintenance/starboard) "bic" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 9 + dir = 6 }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 9 + dir = 6 }, /obj/structure/cable, /turf/open/floor/plating, @@ -20171,27 +20121,23 @@ /turf/open/floor/iron/dark, /area/security/courtroom) "bkX" = ( -/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, /obj/effect/turf_decal/tile/purple{ dir = 1 }, /obj/effect/turf_decal/tile/purple{ dir = 8 }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ dir = 8 }, -/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 9 + }, /turf/open/floor/iron/showroomfloor, -/area/science/mixing) +/area/science/test_area) "blc" = ( /obj/machinery/door/airlock/maintenance{ name = "kitchen maintenance"; @@ -20825,18 +20771,6 @@ /obj/structure/closet/firecloset, /turf/open/floor/iron/dark, /area/hallway/primary/starboard) -"bpg" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 4 - }, -/turf/open/floor/plating{ - icon_state = "panelscorched" - }, -/area/science/mixing) "bpk" = ( /obj/effect/decal/cleanable/blood/old, /obj/effect/decal/cleanable/dirt, @@ -30746,32 +30680,6 @@ icon_state = "platingdmg3" }, /area/maintenance/port/aft) -"cbe" = ( -/obj/effect/turf_decal/loading_area{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating{ - icon_state = "platingdmg1" - }, -/area/science/mixing) -"cbf" = ( -/obj/machinery/door/poddoor{ - id = "toxinsdriver"; - name = "Toxins Launcher Bay Door" - }, -/obj/effect/turf_decal/delivery, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 4 - }, -/turf/open/floor/iron/dark, -/area/science/mixing) "cbg" = ( /obj/effect/turf_decal/delivery, /obj/effect/decal/cleanable/dirt, @@ -33591,6 +33499,22 @@ /obj/structure/cable, /turf/open/floor/iron/showroomfloor, /area/security/execution/education) +"cjV" = ( +/obj/machinery/door/window/southleft{ + name = "Mass Driver Door"; + req_access_txt = "7" + }, +/obj/effect/turf_decal/loading_area, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron/dark, +/area/science/test_area) "cjZ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ dir = 6 @@ -41109,6 +41033,7 @@ /obj/effect/turf_decal/stripes/corner, /obj/effect/spawner/lootdrop/maintenance, /obj/effect/loot_site_spawner, +/obj/structure/closet/cardboard, /turf/open/floor/plating{ icon_state = "platingdmg3" }, @@ -41135,6 +41060,11 @@ }, /turf/open/floor/iron, /area/hallway/secondary/exit/departure_lounge) +"cOD" = ( +/obj/machinery/space_heater, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/maintenance/starboard) "cPa" = ( /turf/closed/wall/r_wall/rust, /area/security/prison/safe) @@ -41625,6 +41555,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/grass, /area/service/chapel/main) +"cZU" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/maintenance/starboard) "cZV" = ( /obj/effect/turf_decal/tile/brown, /obj/effect/turf_decal/tile/brown{ @@ -41748,6 +41687,17 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron, /area/security/brig) +"dcM" = ( +/obj/machinery/door/poddoor{ + id = "toxinsdriver"; + name = "Toxins Launcher Bay Door" + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/science/test_area) "dcO" = ( /obj/effect/turf_decal/bot, /obj/effect/turf_decal/tile/neutral{ @@ -42581,6 +42531,12 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/service/janitor) +"dxa" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/turf/closed/wall, +/area/maintenance/starboard) "dxn" = ( /obj/machinery/air_sensor/atmos/nitrous_tank, /turf/open/floor/engine/n2o, @@ -42610,6 +42566,31 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/command/heads_quarters/cmo) +"dxS" = ( +/obj/structure/table, +/obj/machinery/cell_charger{ + pixel_y = 5 + }, +/obj/item/stock_parts/cell/high, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/machinery/light/directional/south, +/obj/item/stock_parts/cell/high{ + pixel_x = 8; + pixel_y = -2 + }, +/obj/item/stock_parts/cell/high{ + pixel_x = 8; + pixel_y = 9 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/iron/showroomfloor, +/area/science/test_area) "dyi" = ( /obj/effect/landmark/start/bartender, /turf/open/floor/wood, @@ -42830,6 +42811,11 @@ }, /turf/open/floor/iron, /area/commons/storage/primary) +"dDz" = ( +/obj/structure/lattice, +/obj/structure/grille/broken, +/turf/open/space/basic, +/area/space) "dDS" = ( /obj/machinery/porta_turret/ai{ dir = 1 @@ -43275,6 +43261,41 @@ /obj/item/pen, /turf/open/floor/iron/dark, /area/service/bar) +"dPm" = ( +/obj/effect/turf_decal/stripes/corner, +/obj/structure/table, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 9 + }, +/obj/item/paper_bin{ + pixel_x = -4; + pixel_y = 4 + }, +/obj/item/assembly/signaler{ + desc = "Used to remotely activate devices. Allows for syncing when using a secure signaler on another. Slightly scooted."; + pixel_x = 8; + pixel_y = 4 + }, +/obj/item/assembly/signaler{ + desc = "Used to remotely activate devices. Allows for syncing when using a secure signaler on another. Slightly scooted."; + pixel_x = 8; + pixel_y = 4 + }, +/obj/item/assembly/signaler{ + desc = "Used to remotely activate devices. Allows for syncing when using a secure signaler on another. Slightly scooted."; + pixel_x = 8; + pixel_y = 4 + }, +/obj/item/pen, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/iron/showroomfloor, +/area/science/test_area) "dPy" = ( /obj/effect/turf_decal/tile/purple{ dir = 4 @@ -44634,6 +44655,10 @@ /obj/structure/cable, /turf/open/floor/plating, /area/engineering/supermatter/room) +"ewV" = ( +/obj/structure/lattice/catwalk, +/turf/open/space/basic, +/area/space) "exe" = ( /obj/effect/turf_decal/tile/yellow, /obj/effect/turf_decal/tile/yellow{ @@ -46258,21 +46283,25 @@ }, /area/maintenance/starboard/aft) "ffM" = ( -/obj/machinery/door/window/southleft{ - name = "Mass Driver Door"; - req_access_txt = "7" - }, -/obj/effect/turf_decal/loading_area, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/purple{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/obj/effect/turf_decal/tile/purple{ + dir = 1 }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/small/directional/west, -/turf/open/floor/iron/dark, -/area/science/mixing) +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 9 + }, +/turf/open/floor/iron/showroomfloor, +/area/science/test_area) "ffO" = ( /obj/machinery/atmospherics/components/binary/pump{ dir = 4; @@ -46305,6 +46334,17 @@ icon_state = "platingdmg3" }, /area/engineering/supermatter/room) +"fga" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/maintenance/starboard) "fgq" = ( /obj/machinery/conveyor{ dir = 4; @@ -47991,6 +48031,17 @@ }, /turf/open/floor/iron/showroomfloor, /area/security/warden) +"fOT" = ( +/obj/machinery/doppler_array/research/science{ + dir = 4 + }, +/obj/item/radio/intercom/directional/east, +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/iron/dark, +/area/science/test_area) "fOZ" = ( /obj/structure/filingcabinet/chestdrawer, /obj/effect/turf_decal/tile/blue{ @@ -48246,6 +48297,10 @@ /obj/machinery/status_display/evac/directional/south, /turf/open/floor/iron, /area/hallway/secondary/exit/departure_lounge) +"fVn" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/science/test_area) "fVr" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 9 @@ -48712,6 +48767,14 @@ /obj/effect/decal/cleanable/greenglow, /turf/open/floor/iron/dark, /area/engineering/gravity_generator) +"giX" = ( +/obj/structure/lattice/catwalk, +/obj/structure/railing, +/obj/structure/railing{ + dir = 1 + }, +/turf/open/space/basic, +/area/space) "gjG" = ( /obj/effect/turf_decal/tile/yellow{ dir = 4 @@ -49740,6 +49803,25 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/iron/dark, /area/service/chapel/office) +"gGX" = ( +/obj/item/target, +/obj/item/target/syndicate, +/obj/item/target/alien, +/obj/item/target/clown, +/obj/structure/closet/crate/secure{ + desc = "A secure crate containing various materials for building a customised test-site."; + name = "Test Site Materials Crate"; + req_access_txt = "8" + }, +/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/turf/open/floor/iron/dark, +/area/science/test_area) "gHq" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ dir = 6 @@ -50428,6 +50510,23 @@ }, /turf/open/floor/iron/white, /area/security/prison) +"gZY" = ( +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/turf/open/floor/iron/showroomfloor, +/area/science/test_area) "haI" = ( /obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/tile/neutral{ @@ -51278,6 +51377,17 @@ }, /turf/open/floor/iron/dark, /area/engineering/break_room) +"hvo" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/structure/extinguisher_cabinet/directional/north, +/obj/machinery/component_printer, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/dark, +/area/science/test_area) "hwo" = ( /obj/item/storage/firstaid/regular{ pixel_x = 3; @@ -52194,6 +52304,17 @@ "hUi" = ( /turf/open/floor/wood, /area/service/library) +"hUx" = ( +/obj/machinery/mass_driver{ + dir = 4; + id = "toxinsdriver" + }, +/obj/effect/turf_decal/stripes/end{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/science/test_area) "hUK" = ( /obj/item/radio{ pixel_x = 5; @@ -53534,6 +53655,18 @@ }, /turf/open/floor/grass, /area/service/chapel/main) +"iAU" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/iron/showroomfloor, +/area/science/test_area) "iBe" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/decal/cleanable/dirt, @@ -55163,6 +55296,16 @@ }, /turf/open/floor/iron/dark, /area/maintenance/starboard/aft) +"jkW" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/power/apc/auto_name/north, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/dark, +/area/science/test_area) "jkY" = ( /obj/effect/turf_decal/bot, /obj/machinery/holopad, @@ -55452,6 +55595,33 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron/dark, /area/service/bar) +"jtb" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/machinery/button/massdriver{ + id = "toxinsdriver"; + pixel_x = 24; + pixel_y = -24 + }, +/obj/machinery/computer/security/telescreen{ + desc = "Used for watching the test chamber."; + dir = 8; + layer = 4; + name = "Test Chamber Telescreen"; + network = list("toxins"); + pixel_x = 30 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/light/small/directional/south, +/obj/machinery/airalarm/directional/south, +/turf/open/floor/iron/dark, +/area/science/test_area) "jtw" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/loot_site_spawner, @@ -60540,16 +60710,20 @@ /turf/open/floor/engine/vacuum, /area/maintenance/disposal/incinerator) "lxK" = ( -/obj/machinery/doppler_array/research/science{ - dir = 4 - }, -/obj/item/radio/intercom/directional/east, -/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/table, +/obj/item/storage/toolbox/electrical{ + pixel_y = 5 + }, +/obj/structure/cable, +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, /turf/open/floor/iron/dark, -/area/science/mixing) +/area/science/test_area) "lxO" = ( /obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/tile/neutral{ @@ -61081,6 +61255,21 @@ /obj/structure/closet/athletic_mixed, /turf/open/floor/plating, /area/maintenance/port/aft) +"lKm" = ( +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating{ + icon_state = "platingdmg1" + }, +/area/science/test_area) "lKu" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, @@ -61439,6 +61628,11 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/ai_monitored/turret_protected/aisat/foyer) +"lTo" = ( +/obj/structure/lattice/catwalk, +/obj/structure/railing, +/turf/open/space/basic, +/area/space) "lTM" = ( /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ @@ -64429,6 +64623,21 @@ }, /turf/open/floor/iron, /area/engineering/atmos) +"nlf" = ( +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/showroomfloor, +/area/science/test_area) "nlh" = ( /obj/structure/frame/machine, /obj/effect/turf_decal/stripes/line{ @@ -64595,6 +64804,10 @@ icon_state = "platingdmg3" }, /area/maintenance/port/aft) +"npa" = ( +/obj/structure/sign/warning/securearea, +/turf/closed/wall, +/area/space) "npd" = ( /obj/machinery/power/compressor{ comp_id = "incineratorturbine"; @@ -64925,6 +65138,22 @@ /obj/structure/extinguisher_cabinet/directional/west, /turf/open/floor/iron/dark, /area/security/courtroom) +"nzb" = ( +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/iron/showroomfloor, +/area/science/test_area) "nzl" = ( /obj/machinery/airalarm/directional/south, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -66509,6 +66738,18 @@ }, /turf/open/floor/iron/dark, /area/engineering/main) +"ojK" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/science/test_area) "ojM" = ( /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/tile/neutral{ @@ -66639,6 +66880,11 @@ /obj/structure/cable, /turf/open/floor/plating, /area/command/heads_quarters/hop) +"olO" = ( +/obj/structure/lattice, +/obj/structure/grille, +/turf/open/space/basic, +/area/space) "olX" = ( /obj/structure/flora/grass/jungle, /obj/structure/flora/ausbushes/grassybush, @@ -67993,24 +68239,6 @@ }, /turf/open/floor/iron, /area/cargo/storage) -"oOa" = ( -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/machinery/light/small/directional/north, -/obj/machinery/camera{ - c_tag = "Toxins Launch Site"; - name = "science camera"; - network = list("ss13","rd") - }, -/obj/structure/extinguisher_cabinet/directional/north, -/obj/structure/sign/warning/explosives/alt{ - pixel_x = -32 - }, -/obj/machinery/research/explosive_compressor, -/turf/open/floor/iron/dark, -/area/science/mixing) "oOf" = ( /turf/open/floor/engine/plasma, /area/engineering/atmos) @@ -68933,6 +69161,17 @@ icon_state = "platingdmg1" }, /area/maintenance/disposal/incinerator) +"pji" = ( +/obj/machinery/door/airlock/external{ + name = "External Airlock"; + req_access_txt = "13" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/structure/cable, +/turf/open/floor/iron/dark, +/area/space/nearstation) "pjn" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -75724,6 +75963,22 @@ }, /turf/open/floor/wood, /area/commons/locker) +"shr" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/light/small/directional/north, +/obj/machinery/camera{ + c_tag = "Toxins Launch Site"; + name = "science camera"; + network = list("ss13","rd") + }, +/obj/machinery/research/explosive_compressor, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/dark, +/area/science/test_area) "sih" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ dir = 1 @@ -76476,6 +76731,20 @@ /obj/machinery/airalarm/directional/east, /turf/open/floor/iron/dark, /area/engineering/storage/tcomms) +"sDo" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating{ + icon_state = "platingdmg3" + }, +/area/maintenance/starboard) "sDp" = ( /obj/structure/sign/warning/securearea, /turf/closed/wall/rust, @@ -77842,6 +78111,23 @@ }, /turf/open/floor/iron/dark, /area/command/heads_quarters/captain) +"tno" = ( +/obj/structure/table, +/obj/item/multitool/circuit{ + pixel_x = -8 + }, +/obj/item/multitool/circuit{ + pixel_x = -4 + }, +/obj/item/multitool/circuit, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple, +/obj/machinery/firealarm/directional/south, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/iron/showroomfloor, +/area/science/test_area) "tnC" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -78010,6 +78296,9 @@ /obj/machinery/status_display/evac/directional/west, /turf/open/floor/iron/dark, /area/security/processing) +"tpF" = ( +/turf/closed/wall, +/area/science/test_area) "tpP" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -78518,6 +78807,20 @@ }, /turf/open/floor/plating, /area/commons/fitness/recreation) +"tAG" = ( +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, +/turf/open/floor/iron/showroomfloor, +/area/science/test_area) "tAI" = ( /obj/effect/turf_decal/bot, /obj/effect/decal/cleanable/dirt, @@ -79670,32 +79973,19 @@ /turf/open/floor/iron/dark, /area/command/teleporter) "tWc" = ( -/obj/structure/chair{ - dir = 4 - }, -/obj/machinery/button/massdriver{ - id = "toxinsdriver"; - pixel_x = 24; - pixel_y = -24 - }, -/obj/machinery/computer/security/telescreen{ - desc = "Used for watching the test chamber."; - dir = 8; - layer = 4; - name = "Test Chamber Telescreen"; - network = list("toxins"); - pixel_x = 30 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple, +/obj/machinery/modular_computer/console/preset/civilian{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 }, -/obj/machinery/light/small/directional/south, -/obj/machinery/airalarm/directional/south, -/turf/open/floor/iron/dark, -/area/science/mixing) +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 9 + }, +/turf/open/floor/iron/showroomfloor, +/area/science/test_area) "tWd" = ( /obj/structure/flora/grass/jungle/b, /obj/structure/flora/ausbushes/ywflowers, @@ -79735,6 +80025,26 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron/dark, /area/command/heads_quarters/rd) +"tWQ" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/machinery/computer/security/telescreen{ + desc = "Used for watching the test chamber."; + dir = 8; + layer = 4; + name = "Test Chamber Telescreen"; + network = list("toxins"); + pixel_x = 30 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/turf/open/floor/iron/dark, +/area/science/test_area) "tXk" = ( /obj/structure/table, /obj/effect/turf_decal/tile/neutral{ @@ -80283,6 +80593,14 @@ }, /turf/open/floor/plating, /area/cargo/warehouse) +"uhx" = ( +/obj/effect/loot_site_spawner, +/obj/structure/closet/crate{ + icon_state = "crateopen" + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/maintenance/starboard) "uhO" = ( /obj/machinery/light/floor, /turf/open/floor/engine/vacuum, @@ -83215,6 +83533,9 @@ }, /turf/open/floor/iron/dark, /area/science/xenobiology) +"vun" = ( +/turf/closed/wall/rust, +/area/space) "vuX" = ( /obj/effect/turf_decal/box/corners, /obj/effect/turf_decal/tile/neutral, @@ -84377,6 +84698,17 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/security/interrogation) +"vUr" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 6 + }, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/maintenance/starboard) "vUt" = ( /obj/effect/turf_decal/tile/yellow{ dir = 4 @@ -84523,6 +84855,15 @@ /obj/effect/landmark/start/security_officer, /turf/open/floor/iron/dark, /area/security/office) +"vXM" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 9 + }, +/turf/open/floor/plating, +/area/maintenance/starboard) "vXS" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 1 @@ -87042,15 +87383,19 @@ /obj/effect/turf_decal/tile/purple{ dir = 1 }, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, /obj/effect/turf_decal/tile/purple{ dir = 1 }, -/obj/machinery/firealarm/directional/west, +/obj/structure/rack, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/item/controller, +/obj/machinery/light/directional/west, +/obj/item/compact_remote, +/obj/item/compact_remote, /turf/open/floor/iron/showroomfloor, -/area/science/mixing) +/area/science/test_area) "xfz" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ @@ -88735,6 +89080,9 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron, /area/hallway/primary/fore) +"xOP" = ( +/turf/closed/wall/rust, +/area/science/test_area) "xPl" = ( /obj/effect/turf_decal/bot, /obj/machinery/disposal/bin, @@ -89540,6 +89888,10 @@ }, /turf/open/floor/iron, /area/engineering/break_room) +"yib" = ( +/obj/structure/girder, +/turf/open/floor/plating, +/area/maintenance/starboard) "yid" = ( /obj/effect/turf_decal/delivery, /obj/machinery/door/poddoor/shutters{ @@ -131228,14 +131580,14 @@ bdh aPm aOF bcf -bbN -oOa +tpF +tpF xfe bkX ffM anS -bbN -bfw +vXM +bic bic wkN loE @@ -131490,9 +131842,9 @@ bcR bdV bej baC -cbe -bcD -azG +tpF +yib +vUr bkd pDR wkN @@ -131744,12 +132096,12 @@ aOQ bcj bgy aYc -bcS +bdV bek -baC -bpg -bbN -bfM +tno +xOP +uhx +vUr avA acm wJf @@ -132003,10 +132355,10 @@ beH lxK bcb tWc -bbN -cbf -bbN -bfQ +dxS +xOP +cOD +vUr avA acm wJf @@ -132256,14 +132608,14 @@ beo hdj aOT bbi -awi -bbN -baC -baC -bcD -cbg -cbk -bfW +caT +hvo +iAU +dPm +tpF +tpF +xOP +vUr bkd qJs tIc @@ -132514,14 +132866,14 @@ cbk aOU aRE aSQ -aUZ -aYi -aYZ -baN -bdj -aWN -bfX -ava +shr +bdV +nzb +cjV +hUx +tpF +bfw +dxa aaa aaa aaa @@ -132769,15 +133121,15 @@ aim alT lqr aOY -cbj -aLP -auz -cOn -cOo -hqC -cuf -cbm -bgb +fga +aSQ +gGX +iAU +gZY +fVn +lKm +xOP +sDo bkd aaa aaa @@ -133026,16 +133378,16 @@ cOr aKl cOv ava -bkd -bkd -ava +cZU +xOP +jkW +nlf +tAG +fVn +ojK +tpF +bfM avA -avA -bkd -bBX -ava -iYL -bkd aaa aaa aaa @@ -133283,16 +133635,16 @@ avA aKn avA bkd -aeu -aeu -aeu -acm -aaa -acm -aaa -bkd -bge -ava +cZU +tpF +fOT +tWQ +jtb +tpF +dcM +tpF +bfQ +avA aaa aaa aaa @@ -133540,16 +133892,16 @@ cmi aKr cCs ava -aeu -alm -acm -aaQ -aeo -aeo -acm -acm -bgf -acm +cZU +xOP +tpF +fVn +fVn +xOP +cbg +cbk +bfW +bkd aaa aaa aaa @@ -133797,16 +134149,16 @@ agy cLR agy bkd -aeu -aeU -aaa -acm -aaa -acm -aaa -acm -qDp -acm +cZU +cZU +aUZ +aYi +aYZ +baN +bdj +aWN +bfX +ava aaa aaa aaa @@ -134054,16 +134406,16 @@ aaa aaa aaa bhq -aeu -aUz -aaa -aaQ -aaa -acm -aaa -acm -qDp -aaa +avA +avA +auz +cOn +cOo +hqC +cuf +cbm +bgb +bkd aaa aaa aaa @@ -134311,16 +134663,16 @@ aaa aaa aaa akA -aeu aeU -aaa -aeo -aaa -acm -aaa -acm -eiW -aaa +aeU +ava +avA +avA +bkd +bBX +ava +iYL +bkd aaa aaa aaa @@ -134569,15 +134921,15 @@ aaa aaa aod aeu -aeu aeU -acm +aUz +cry aaa -acK acm -acK -viq -aaa +acm +anH +pji +vun aaa aaa aaa @@ -134826,15 +135178,15 @@ cOd aob aoe aeu -aeu -aeu +aeU +aeU alm acm -acm +aeo aaa acm -viq -aaa +bgf +cmJ aaa aaa aaa @@ -135083,14 +135435,14 @@ acm acK qJs aeu -aeu +aUz aeu aeu aaa acm aaa acm -acK +qDp aaa qJs acm @@ -135344,10 +135696,10 @@ aeu aeu aeu aaa -aeo -aaa acm +aaa acK +qDp acm aaQ aeo @@ -135601,10 +135953,10 @@ aeu aeu aeu aeu -aeo +acm aaa acm -acK +eiW aaa aaa acm @@ -135858,10 +136210,10 @@ aeu aeu aeu aeu -aaQ +acK aaa acm -qDp +viq aaQ aeo aeo @@ -136118,7 +136470,7 @@ aeu acm aaa acm -eiW +viq aaa acm aaa @@ -136375,7 +136727,7 @@ acm acm aaa acm -jTL +acK aeo aeo aaa @@ -136629,9 +136981,9 @@ aeu aeu aeU aaa -acK +aeo +acm acm -acK acK acm aaa @@ -136886,9 +137238,9 @@ aeu aeU aUz aaa -acm +aeo aaa -aaQ +acm acK aeo aaa @@ -137143,10 +137495,10 @@ aeu aeU aaa aaa -acm +aaQ aaa -aeo -viq +acm +qDp aaa aaa aaa @@ -137402,13 +137754,13 @@ aaa aaa acm aaa -aeo acK +eiW aeo aaQ aaa aaa -aaB +aaa aaa aaa aaa @@ -137657,10 +138009,10 @@ aaa aaa aaa aaa -aaQ +acm aaa -aeo -acK +aaQ +jTL aaa aaa aaa @@ -137910,14 +138262,14 @@ aeu aUz aaa aaa -aaB aaa aaa aaa +aaa +acK +aaa aeo -aaa -acm -viq +acK aaa aaa aaa @@ -138171,10 +138523,10 @@ aaa aaa aaa aaa -aeo +acm aaa -aaQ -eiW +aeo +acK aaa aaa aaa @@ -138430,8 +138782,8 @@ aaa aaa acm aaa -acm -acK +aeo +viq aaa aaa aaa @@ -138962,10 +139314,10 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa +cqi +cqi +cqi +cmJ aaa aaa aaa @@ -139219,13 +139571,13 @@ aaa aaa aaa aaa +cqi +npa +cmJ +dDz +olO aaa -aaa -aaa -aaa -aaa -aaa -aaa +cmJ aaa aaa aaa @@ -139476,10 +139828,10 @@ aaa aaa aaa aaa +cqi +uku aaa -aaa -aaa -aaa +cmJ aaa aaa aaa @@ -139733,10 +140085,10 @@ aaa aaa aaa aaa +cqi +dNv aaa -aaa -aaa -aaa +dDz aaa aaa aaa @@ -139990,10 +140342,10 @@ aaa aaa aaa aaa +cqi +uku aaa -aaa -aaa -aaa +olO aaa aaa aaa @@ -140247,13 +140599,13 @@ aaa aaa aaa aaa +cqi +cqi +uku +cmJ aaa aaa -aaa -aaa -aaa -aaa -aaa +cmJ aaa aaa aaa @@ -142309,7 +142661,7 @@ aaa aaa aaa aaa -aaa +cmJ aaa aaa aaa @@ -143079,15 +143431,15 @@ aaa aaa aaa aaa +cmJ +aaa +aaa +ewV aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +aaB aaa aaa aaa @@ -143336,10 +143688,10 @@ aaa aaa aaa aaa +dDz aaa aaa -aaa -aaa +ewV aaa aaa aaa @@ -143589,14 +143941,14 @@ aaa aaa aaa aaa +aaB aaa aaa aaa +olO aaa -aaa -aaa -aaa -aaa +cmJ +lTo aaa aaa aaa @@ -143850,10 +144202,10 @@ aaa aaa aaa aaa +olO aaa -aaa -aaa -aaa +dDz +giX aaa aaa aaa @@ -144107,10 +144459,10 @@ aaa aaa aaa aaa +cmJ aaa -aaa -aaa -aaa +cmJ +ewV aaa aaa aaa diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index a4b5105bfd4..e7188af4eaa 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -2744,6 +2744,27 @@ /obj/structure/cable, /turf/open/floor/iron, /area/security/brig) +"atX" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/window/northleft{ + dir = 2; + name = "Atmospherics Desk"; + req_access_txt = "24" + }, +/obj/item/folder/yellow, +/obj/item/pen, +/obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/preopen{ + id = "atmos"; + name = "Atmospherics Blast Door" + }, +/obj/effect/turf_decal/delivery, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/simple/scrubbers/hidden, +/turf/open/floor/iron, +/area/engineering/atmos) "aua" = ( /obj/structure/table/reinforced, /obj/item/folder/red, @@ -3469,6 +3490,12 @@ }, /turf/open/floor/iron, /area/security/brig) +"azM" = ( +/obj/machinery/atmospherics/pipe/smart/manifold/cyan/visible{ + dir = 4 + }, +/turf/open/floor/iron, +/area/engineering/atmos) "azP" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/chair, @@ -7959,6 +7986,16 @@ dir = 4 }, /area/medical/break_room) +"brK" = ( +/obj/effect/turf_decal/trimline/blue/filled/corner, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/purple/filled/warning{ + dir = 4 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "brO" = ( /obj/structure/transit_tube/diagonal/topleft, /turf/open/space, @@ -15854,17 +15891,6 @@ }, /turf/open/floor/iron, /area/command/heads_quarters/ce) -"cWc" = ( -/obj/structure/table, -/obj/item/reagent_containers/glass/beaker/large{ - pixel_y = 6 - }, -/obj/item/reagent_containers/dropper{ - pixel_y = -5 - }, -/obj/machinery/airalarm/directional/south, -/turf/open/floor/iron, -/area/science/misc_lab) "cWl" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -18111,6 +18137,10 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron/dark, /area/security/brig) +"dCg" = ( +/obj/machinery/component_printer, +/turf/open/floor/iron/white, +/area/science/misc_lab) "dCi" = ( /obj/structure/closet, /obj/effect/spawner/lootdrop/maintenance, @@ -19394,6 +19424,7 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/iron/white, /area/maintenance/aft/secondary) +<<<<<<< HEAD "dZg" = ( /obj/machinery/atmospherics/pipe/bridge_pipe/cyan/visible, /obj/effect/spawner/structure/window/reinforced, @@ -19402,6 +19433,8 @@ }, /turf/open/floor/plating, /area/engineering/atmos) +======= +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) "eae" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ @@ -21084,6 +21117,14 @@ }, /turf/open/floor/iron/white, /area/science/mixing) +"eAF" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/white, +/area/science/misc_lab) "eAP" = ( /obj/machinery/holopad, /obj/structure/cable, @@ -23208,6 +23249,14 @@ }, /turf/open/floor/plating/airless, /area/maintenance/space_hut) +"fiB" = ( +/obj/structure/table, +/obj/structure/cable, +/obj/item/controller, +/obj/item/compact_remote, +/obj/item/compact_remote, +/turf/open/floor/iron/white, +/area/science/misc_lab) "fiJ" = ( /obj/structure/table, /obj/machinery/recharger, @@ -26579,6 +26628,7 @@ /obj/item/radio/intercom/directional/west, /turf/open/floor/iron, /area/command/heads_quarters/rd) +<<<<<<< HEAD "grs" = ( /obj/effect/turf_decal/tile/green, /obj/effect/turf_decal/tile/green{ @@ -26593,6 +26643,8 @@ }, /turf/open/floor/iron, /area/engineering/atmos) +======= +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) "grw" = ( /obj/machinery/light/directional/west, /obj/machinery/computer/camera_advanced/base_construction/aux{ @@ -27657,13 +27709,6 @@ }, /turf/open/floor/iron, /area/science/xenobiology) -"gIA" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 10 - }, -/turf/open/floor/engine, -/area/science/misc_lab/range) "gIF" = ( /obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/tile/purple{ @@ -27935,20 +27980,6 @@ /obj/effect/turf_decal/tile/purple, /turf/open/floor/iron, /area/hallway/primary/aft) -"gQp" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 4 - }, -/obj/machinery/door/window/northright{ - dir = 8; - name = "Research Test Chamber"; - req_access_txt = "7" - }, -/turf/open/floor/engine, -/area/science/misc_lab/range) "gQU" = ( /obj/structure/window/reinforced, /obj/effect/turf_decal/tile/blue{ @@ -31204,12 +31235,6 @@ }, /turf/open/floor/plating, /area/maintenance/disposal) -"ibT" = ( -/obj/machinery/power/apc/auto_name/north, -/obj/structure/cable, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, -/turf/open/floor/iron/white, -/area/science/misc_lab) "icp" = ( /obj/machinery/light/directional/south, /obj/machinery/aug_manipulator, @@ -32272,6 +32297,23 @@ }, /turf/open/floor/iron/white, /area/science/research) +"isK" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/bridge_pipe/purple/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/bridge_pipe/cyan/visible, +/turf/open/floor/iron, +/area/engineering/atmos) "isO" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ dir = 8 @@ -33353,6 +33395,7 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/wood, /area/service/bar) +<<<<<<< HEAD "iNB" = ( /obj/structure/table/reinforced, /obj/machinery/door/window/northleft{ @@ -33375,6 +33418,8 @@ /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/hidden, /turf/open/floor/iron, /area/engineering/atmos) +======= +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) "iND" = ( /obj/machinery/door/airlock/external{ name = "Escape Pod Two" @@ -35742,6 +35787,19 @@ /obj/structure/cable, /turf/open/floor/plating, /area/commons/storage/primary) +"jHt" = ( +/obj/structure/table, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/item/paper_bin, +/obj/item/pen, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/white, +/area/science/misc_lab) "jHx" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ @@ -36092,15 +36150,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/maintenance/port) -"jNE" = ( -/obj/structure/window/reinforced{ - dir = 8 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/turf/open/floor/engine, -/area/science/misc_lab/range) "jNH" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 8 @@ -36212,12 +36261,6 @@ dir = 8 }, /area/science/lab) -"jPj" = ( -/obj/structure/table, -/obj/item/crowbar, -/obj/structure/cable, -/turf/open/floor/iron/white, -/area/science/misc_lab) "jPt" = ( /obj/item/kirbyplants/random, /obj/effect/turf_decal/trimline/purple/corner{ @@ -36609,12 +36652,15 @@ "jVV" = ( /turf/closed/wall/r_wall, /area/command/heads_quarters/hos) +<<<<<<< HEAD "jVY" = ( /obj/machinery/atmospherics/pipe/smart/simple/dark/visible{ dir = 4 }, /turf/open/space, /area/space/nearstation) +======= +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) "jWu" = ( /obj/effect/turf_decal/tile/yellow{ dir = 4 @@ -36734,6 +36780,11 @@ }, /turf/open/floor/plating, /area/maintenance/starboard) +"jXY" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/start/scientist, +/turf/open/floor/engine, +/area/science/misc_lab/range) "jYj" = ( /obj/structure/chair/stool{ pixel_y = 8 @@ -36986,6 +37037,12 @@ }, /turf/open/floor/iron, /area/service/hydroponics) +"kcX" = ( +/obj/structure/rack, +/obj/item/integrated_circuit/loaded/hello_world, +/obj/item/integrated_circuit/loaded/speech_relay, +/turf/open/floor/iron/white, +/area/science/misc_lab) "kdb" = ( /obj/machinery/computer/security/mining, /obj/machinery/keycard_auth/directional/north, @@ -38110,6 +38167,15 @@ /obj/machinery/light_switch/directional/east, /turf/open/floor/iron, /area/security/office) +"kwZ" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/machinery/atmospherics/components/binary/thermomachine/heater, +/turf/open/floor/iron/dark/corner{ + dir = 1 + }, +/area/engineering/atmos) "kxl" = ( /obj/effect/turf_decal/tile/neutral{ dir = 8 @@ -38893,6 +38959,12 @@ /obj/effect/landmark/blobstart, /turf/open/floor/iron, /area/cargo/warehouse) +"kJS" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/iron/white, +/area/science/misc_lab) "kJV" = ( /obj/structure/table, /obj/item/paper_bin{ @@ -39148,6 +39220,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/service/bar) +"kPm" = ( +/obj/machinery/atmospherics/pipe/smart/simple/dark/visible{ + dir = 4 + }, +/obj/structure/lattice, +/turf/open/space, +/area/space/nearstation) "kPn" = ( /obj/structure/table/reinforced, /obj/item/folder/yellow, @@ -41247,6 +41326,7 @@ /obj/structure/chair/comfy/black, /turf/open/floor/iron/dark, /area/security/office) +<<<<<<< HEAD "lza" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/bridge_pipe/cyan/visible, @@ -41255,6 +41335,8 @@ }, /turf/open/floor/plating, /area/engineering/atmos) +======= +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) "lzj" = ( /obj/structure/table, /obj/item/hand_labeler, @@ -41559,6 +41641,14 @@ }, /turf/open/floor/iron, /area/commons/vacant_room/commissary) +"lGi" = ( +/obj/effect/turf_decal/tile/purple, +/obj/structure/cable, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/science/misc_lab) "lGl" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ @@ -43354,6 +43444,13 @@ }, /turf/open/floor/carpet, /area/commons/vacant_room/office) +"mle" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/bridge_pipe/purple/visible{ + dir = 4 + }, +/turf/open/floor/plating, +/area/engineering/atmos) "mlo" = ( /obj/structure/cable, /obj/machinery/door/airlock/maintenance{ @@ -45136,6 +45233,7 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/engine, /area/engineering/supermatter) +<<<<<<< HEAD "mNQ" = ( /obj/machinery/computer/atmos_control/tank/mix_tank{ dir = 8 @@ -45146,6 +45244,8 @@ }, /turf/open/floor/iron, /area/engineering/atmos) +======= +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) "mNW" = ( /obj/structure/disposalpipe/segment, /turf/open/floor/iron/dark, @@ -46082,6 +46182,14 @@ /obj/machinery/duct, /turf/open/floor/iron/freezer, /area/commons/toilet/restrooms) +"ncQ" = ( +/obj/machinery/atmospherics/pipe/bridge_pipe/yellow/visible, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4; + name = "Mix to Engine" + }, +/turf/open/floor/iron, +/area/engineering/atmos) "ncV" = ( /obj/machinery/button/door/directional/west{ id = "transitlockdown"; @@ -46287,15 +46395,6 @@ }, /turf/open/floor/iron/white, /area/medical/virology) -"nfX" = ( -/obj/structure/table, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/item/paper_bin, -/obj/item/pen, -/turf/open/floor/iron/white, -/area/science/misc_lab) "nfZ" = ( /obj/structure/sign/poster/contraband/missing_gloves, /turf/closed/wall, @@ -49043,10 +49142,6 @@ }, /turf/open/floor/iron, /area/science/mixing) -"nXH" = ( -/obj/item/kirbyplants/random, -/turf/open/floor/iron/white, -/area/science/misc_lab) "nYo" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 4 @@ -50407,6 +50502,7 @@ dir = 1 }, /area/command/gateway) +<<<<<<< HEAD "owa" = ( /obj/machinery/atmospherics/pipe/smart/simple/yellow/visible, /obj/machinery/atmospherics/components/binary/pump{ @@ -50415,6 +50511,8 @@ }, /turf/open/floor/iron, /area/engineering/atmos) +======= +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) "owm" = ( /obj/structure/lattice/catwalk, /turf/open/space/basic, @@ -54925,6 +55023,7 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/carpet, /area/service/library) +<<<<<<< HEAD "pVT" = ( /obj/effect/turf_decal/tile/yellow{ dir = 4 @@ -54934,6 +55033,8 @@ dir = 1 }, /area/engineering/atmos) +======= +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) "pVX" = ( /obj/machinery/light_switch/directional/north, /turf/open/floor/iron/freezer, @@ -56831,17 +56932,6 @@ }, /turf/open/floor/iron/white, /area/medical/medbay/central) -"qDm" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 9 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/start/scientist, -/turf/open/floor/engine, -/area/science/misc_lab/range) "qDr" = ( /obj/machinery/status_display/evac/directional/north, /obj/machinery/porta_turret/ai, @@ -59051,12 +59141,6 @@ /obj/structure/sign/warning/securearea, /turf/closed/wall/r_wall, /area/science/mixing) -"rpH" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 9 - }, -/turf/open/floor/engine, -/area/science/misc_lab/range) "rpK" = ( /obj/structure/urinal/directional/north, /obj/effect/landmark/start/hangover, @@ -60182,6 +60266,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/hallway/primary/central) +"rHp" = ( +/obj/machinery/door/window/northright{ + dir = 8; + name = "Research Test Chamber"; + req_access_txt = "7" + }, +/turf/open/floor/engine, +/area/science/misc_lab/range) "rHI" = ( /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ @@ -62391,12 +62483,15 @@ /obj/structure/fans/tiny, /turf/open/floor/plating, /area/service/chapel/main) +<<<<<<< HEAD "srl" = ( /obj/machinery/atmospherics/pipe/smart/simple/cyan/visible{ dir = 9 }, /turf/open/floor/iron, /area/engineering/atmos) +======= +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) "ssm" = ( /obj/machinery/portable_atmospherics/canister/oxygen, /obj/effect/turf_decal/bot, @@ -64523,6 +64618,14 @@ }, /turf/open/floor/iron, /area/hallway/primary/port) +"tbP" = ( +/obj/structure/table, +/obj/machinery/airalarm/directional/south, +/obj/item/storage/toolbox/electrical{ + pixel_y = 5 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "tbR" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ @@ -66995,6 +67098,7 @@ /obj/effect/spawner/lootdrop/gross_decal_spawner, /turf/open/floor/wood, /area/maintenance/port/aft) +<<<<<<< HEAD "tTH" = ( /obj/machinery/light{ dir = 4 @@ -67011,6 +67115,8 @@ }, /turf/open/floor/iron, /area/engineering/atmos) +======= +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) "tTJ" = ( /obj/machinery/mass_driver/toxins, /turf/open/floor/plating, @@ -67491,11 +67597,6 @@ /obj/effect/loot_site_spawner, /turf/open/floor/plating, /area/maintenance/starboard/aft) -"ucA" = ( -/obj/effect/turf_decal/tile/purple, -/obj/structure/cable, -/turf/open/floor/iron/white, -/area/science/misc_lab) "ucI" = ( /obj/machinery/light/directional/south, /obj/effect/turf_decal/tile/neutral, @@ -68924,13 +69025,6 @@ /obj/machinery/holopad, /turf/open/floor/iron, /area/commons/locker) -"uxB" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/white, -/area/science/misc_lab) "uxN" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -70914,6 +71008,17 @@ /obj/machinery/status_display/evac/directional/south, /turf/open/floor/engine, /area/engineering/supermatter/room) +"vhc" = ( +/obj/machinery/computer/atmos_control/tank/mix_tank{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/layer_manifold/cyan/visible, +/turf/open/floor/iron, +/area/engineering/atmos) "vhr" = ( /obj/machinery/airalarm/directional/south, /obj/effect/turf_decal/tile/neutral{ @@ -71382,13 +71487,6 @@ /obj/structure/cable, /turf/closed/wall/r_wall, /area/ai_monitored/turret_protected/ai) -"vns" = ( -/obj/structure/table, -/obj/item/flashlight/lamp, -/obj/machinery/power/apc/auto_name/north, -/obj/structure/cable, -/turf/open/floor/iron/white, -/area/science/misc_lab/range) "vnv" = ( /obj/effect/turf_decal/tile/purple, /obj/effect/turf_decal/tile/purple{ @@ -72995,6 +73093,21 @@ }, /turf/open/floor/iron/dark, /area/science/robotics/lab) +"vPY" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/components/binary/pump/on{ + dir = 4; + name = "Unfiltered & Air to Mix" + }, +/obj/machinery/atmospherics/pipe/smart/simple/cyan/visible/layer4, +/turf/open/floor/iron, +/area/engineering/atmos) "vQs" = ( /obj/structure/table, /obj/item/stock_parts/subspace/transmitter, @@ -73012,6 +73125,19 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden, /turf/open/floor/plating, /area/engineering/supermatter/room) +"vQQ" = ( +/obj/structure/table, +/obj/machinery/power/apc/auto_name/north, +/obj/structure/cable, +/obj/item/multitool/circuit{ + pixel_x = 7 + }, +/obj/item/multitool/circuit, +/obj/item/multitool/circuit{ + pixel_x = -8 + }, +/turf/open/floor/iron/white, +/area/science/misc_lab/range) "vRT" = ( /obj/machinery/light/directional/south, /obj/item/stack/sheet/cardboard{ @@ -76005,18 +76131,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/maintenance/aft) -"wVM" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 4 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/science/misc_lab) "wWa" = ( /obj/effect/turf_decal/tile/blue{ dir = 8 @@ -76772,6 +76886,13 @@ icon_state = "platingdmg2" }, /area/maintenance/starboard) +"xiB" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible{ + dir = 4 + }, +/turf/open/floor/plating, +/area/engineering/atmos) "xiO" = ( /obj/machinery/light/small/directional/south, /obj/effect/turf_decal/stripes/red/line, @@ -77366,17 +77487,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/commons/locker) -"xtp" = ( -/obj/structure/table, -/obj/effect/turf_decal/trimline/blue/filled/corner, -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 4 - }, -/obj/effect/turf_decal/trimline/purple/filled/warning{ - dir = 4 - }, -/turf/open/floor/iron, -/area/science/misc_lab) "xtw" = ( /obj/item/stack/rods, /turf/open/space/basic, @@ -77872,6 +77982,15 @@ }, /turf/open/floor/iron, /area/hallway/primary/central) +"xAx" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/science/misc_lab) "xAy" = ( /obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/tile/neutral{ @@ -78967,6 +79086,18 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/medical/medbay/central) +"xRK" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 6 + }, +/turf/open/floor/engine, +/area/science/misc_lab/range) "xRU" = ( /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ @@ -113057,7 +113188,7 @@ hzH hCb awD cXm -cWc +tbP ihQ ihQ ihQ @@ -113310,11 +113441,11 @@ vey quV ooL yeb -ibT +kcX cYl iPj eCd -xtp +brK nhL qXy hUy @@ -113825,9 +113956,9 @@ cdU oKY yeb yjC -ucA -uxB -wVM +lGi +eAF +xAx sVU nhL oLk @@ -114081,11 +114212,11 @@ wjL quV sUf yeb -vns -jPj -nfX -wVM -nXH +vQQ +fiB +jHt +kJS +dCg nhL iYn nGU @@ -114340,8 +114471,8 @@ dlc cuZ fXC dFB -jNE -gQp +xRK +rHp fen uDv gTZ @@ -114597,8 +114728,8 @@ ooL cuZ uzH cwZ -gIA -qDm +cFB +jXY dGP uDv lWY @@ -114855,7 +114986,7 @@ cuZ pcn oxa cFB -rpH +pcn vNS uDv wLY @@ -120225,7 +120356,7 @@ bqZ wgC lNR nsB -iNB +atX icJ gZN uvW @@ -124089,7 +124220,7 @@ qJm egV hjv hjv -owa +ncQ cwM hjv hjv @@ -124594,11 +124725,11 @@ aOY kbv iCt jMk -pVT -srl -tTH -mNQ -grs +kwZ +azM +isK +vhc +vPY nIZ lxw lVV @@ -124853,9 +124984,15 @@ ack jMk jMk jMk +<<<<<<< HEAD dZg mjX lza +======= +mle +cor +xiB +>>>>>>> b84a9f97b28 (Integrated Circuits (Wiremod) (#59232)) cor vNA cor @@ -125122,7 +125259,7 @@ bMx aaf cQi aaf -jVY +kPm aaf cQi aaf diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index ca8c20383ce..bdfb9f443cf 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -12459,6 +12459,7 @@ req_one_access_txt = "47" }, /obj/effect/decal/cleanable/dirt, +/obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/maintenance/starboard/secondary) "aSq" = ( @@ -14816,6 +14817,14 @@ /obj/effect/landmark/start/cargo_technician, /turf/open/floor/iron, /area/cargo/storage) +"bAq" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plating, +/area/maintenance/starboard/secondary) "bAE" = ( /turf/open/floor/iron/dark, /area/command/heads_quarters/cmo) @@ -19724,6 +19733,9 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron, /area/engineering/main) +"duT" = ( +/turf/open/space/basic, +/area/mine/explored) "duU" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 9 @@ -19926,6 +19938,7 @@ }, /obj/effect/turf_decal/sand/plating, /obj/item/assembly/mousetrap/armed, +/obj/structure/cable, /turf/open/floor/plating, /area/maintenance/starboard/secondary) "dzX" = ( @@ -20586,6 +20599,8 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/decal/cleanable/dirt, /obj/effect/spawner/lootdrop/food_packaging, +/obj/structure/cable, +/obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/maintenance/starboard/secondary) "dKr" = ( @@ -21090,6 +21105,14 @@ /obj/effect/landmark/start/depsec/medical, /turf/open/floor/iron, /area/security/checkpoint/medical) +"dVY" = ( +/obj/effect/turf_decal/trimline/purple/filled/line{ + dir = 5 + }, +/obj/machinery/light/directional/north, +/obj/machinery/component_printer, +/turf/open/floor/iron, +/area/science/misc_lab) "dWa" = ( /obj/structure/weightmachine/weightlifter, /obj/effect/turf_decal/trimline/red/filled/line{ @@ -24200,6 +24223,7 @@ /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 4 }, +/obj/structure/disposalpipe/segment, /turf/open/floor/iron/white, /area/science/mixing) "fiQ" = ( @@ -25254,6 +25278,7 @@ dir = 8 }, /obj/effect/decal/cleanable/dirt, +/obj/structure/cable, /turf/open/floor/plating, /area/maintenance/starboard/secondary) "fFE" = ( @@ -31304,6 +31329,14 @@ }, /turf/open/floor/iron/white, /area/medical/psychology) +"hVW" = ( +/obj/effect/turf_decal/trimline/purple/filled/line{ + dir = 1 + }, +/obj/machinery/power/apc/auto_name/north, +/obj/structure/cable, +/turf/open/floor/iron, +/area/science/misc_lab) "hVZ" = ( /obj/structure/holosign/barrier/atmos, /turf/open/floor/plating, @@ -32130,6 +32163,7 @@ /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 4 }, +/obj/structure/disposalpipe/segment, /turf/open/floor/iron/white, /area/science/mixing) "iok" = ( @@ -32223,6 +32257,9 @@ dir = 10 }, /obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/obj/structure/cable, +/obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/maintenance/starboard/secondary) "iqY" = ( @@ -32519,6 +32556,15 @@ /obj/machinery/newscaster/security_unit/directional/north, /turf/open/floor/iron/white, /area/science/research) +"ixB" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "ixJ" = ( /obj/machinery/door/airlock/command/glass{ name = "Bridge"; @@ -33751,6 +33797,10 @@ }, /turf/open/space/basic, /area/space/nearstation) +"iRT" = ( +/obj/structure/chair/office/light, +/turf/open/floor/iron, +/area/science/misc_lab) "iRW" = ( /obj/effect/turf_decal/trimline/red/filled/corner, /obj/effect/turf_decal/trimline/red/filled/corner{ @@ -35844,6 +35894,12 @@ }, /turf/open/floor/iron/dark, /area/ai_monitored/turret_protected/aisat_interior) +"jKX" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "jLa" = ( /obj/structure/table/glass, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -37045,11 +37101,18 @@ /turf/open/floor/iron/dark, /area/service/bar) "kgw" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/maintenance/starboard/secondary) +/obj/effect/turf_decal/trimline/purple/filled/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/obj/machinery/light_switch/directional/west, +/turf/open/floor/iron, +/area/science/misc_lab) "kgy" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /obj/effect/turf_decal/trimline/blue/filled/line{ @@ -37639,6 +37702,10 @@ }, /turf/open/floor/wood, /area/command/heads_quarters/hop) +"kqO" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/science/misc_lab) "kqR" = ( /obj/effect/landmark/xeno_spawn, /obj/machinery/atmospherics/pipe/smart/manifold4w/orange/visible{ @@ -38141,6 +38208,7 @@ /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 4 }, +/obj/structure/disposalpipe/segment, /turf/open/floor/iron/white, /area/science/mixing) "kAc" = ( @@ -38639,6 +38707,7 @@ /area/hallway/secondary/command) "kIX" = ( /obj/effect/turf_decal/trimline/purple/filled/corner, +/obj/structure/disposalpipe/segment, /turf/open/floor/iron/white, /area/science/mixing) "kJo" = ( @@ -39767,6 +39836,7 @@ }, /obj/machinery/holopad, /obj/effect/turf_decal/bot, +/obj/structure/disposalpipe/segment, /turf/open/floor/iron/white, /area/science/mixing) "lgb" = ( @@ -40038,12 +40108,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ dir = 8 }, -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Research Maintnenace"; - req_one_access_txt = "47" - }, /obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, +/obj/machinery/door/airlock/research{ + name = "Circuit Laboratory"; + req_access_txt = "47" + }, +/turf/open/floor/iron, /area/maintenance/starboard/secondary) "lll" = ( /obj/effect/turf_decal/stripes/line{ @@ -43200,6 +43270,17 @@ }, /turf/open/floor/iron/dark, /area/command/teleporter) +"mzy" = ( +/obj/effect/turf_decal/trimline/purple/filled/line{ + dir = 6 + }, +/obj/structure/rack, +/obj/machinery/light/directional/south, +/obj/item/controller, +/obj/item/compact_remote, +/obj/item/compact_remote, +/turf/open/floor/iron, +/area/science/misc_lab) "mzF" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/grille/broken, @@ -45538,15 +45619,20 @@ /turf/open/floor/engine, /area/engineering/supermatter) "nAo" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ - dir = 9 +/obj/effect/turf_decal/trimline/purple/filled/corner{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/purple/filled/corner{ + dir = 1 }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ - dir = 9 + dir = 4 }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/maintenance/starboard/secondary) +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "nAu" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 4 @@ -47334,12 +47420,20 @@ /turf/open/floor/engine/plasma, /area/engineering/atmos) "omI" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/grille/broken, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/maintenance/starboard/secondary) +/obj/effect/turf_decal/trimline/purple/filled/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "omZ" = ( /obj/effect/turf_decal/siding/thinplating/corner{ dir = 4 @@ -47561,6 +47655,21 @@ /obj/effect/turf_decal/trimline/purple/filled/line, /turf/open/floor/iron/dark, /area/science/xenobiology) +"orv" = ( +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Research Maintnenace"; + req_one_access_txt = "47" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/obj/structure/cable, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plating, +/area/science/misc_lab) "orw" = ( /obj/effect/turf_decal/trimline/yellow/warning, /obj/effect/decal/cleanable/dirt, @@ -48355,6 +48464,15 @@ }, /turf/open/floor/iron/dark, /area/ai_monitored/security/armory) +"oHX" = ( +/obj/effect/turf_decal/trimline/purple/filled/line{ + dir = 10 + }, +/obj/structure/rack, +/obj/item/integrated_circuit/loaded/speech_relay, +/obj/item/integrated_circuit/loaded/hello_world, +/turf/open/floor/iron, +/area/science/misc_lab) "oIj" = ( /obj/effect/turf_decal/trimline/purple/filled/line, /obj/effect/turf_decal/trimline/neutral/filled/warning, @@ -49606,6 +49724,17 @@ /obj/structure/cable, /turf/open/floor/circuit, /area/ai_monitored/turret_protected/aisat_interior) +"pft" = ( +/obj/effect/turf_decal/trimline/purple/filled/line{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, +/obj/machinery/airalarm/directional/north, +/obj/structure/cable, +/turf/open/floor/iron, +/area/science/misc_lab) "pfC" = ( /obj/structure/cable, /obj/effect/turf_decal/trimline/purple/filled/corner{ @@ -49617,6 +49746,19 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/engine, /area/science/xenobiology) +"pfP" = ( +/obj/effect/turf_decal/trimline/purple/filled/line{ + dir = 6 + }, +/obj/structure/table, +/obj/item/stock_parts/cell/high/plus{ + pixel_x = -8; + pixel_y = 9 + }, +/obj/machinery/cell_charger, +/obj/item/stock_parts/cell/high/plus, +/turf/open/floor/iron, +/area/science/misc_lab) "pgb" = ( /obj/effect/landmark/event_spawn, /turf/open/floor/engine, @@ -50479,6 +50621,9 @@ /turf/open/floor/iron/white, /area/science/research) "pwI" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/open/floor/iron/white, /area/science/mixing) "pwP" = ( @@ -53532,6 +53677,19 @@ /obj/machinery/navbeacon/wayfinding/incinerator, /turf/open/floor/iron, /area/maintenance/disposal/incinerator) +"qKS" = ( +/obj/effect/turf_decal/trimline/purple/filled/line{ + dir = 4 + }, +/obj/machinery/disposal/bin{ + pixel_x = -2; + pixel_y = -2 + }, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "qLb" = ( /obj/structure/industrial_lift/tram{ icon_state = "plating" @@ -55769,6 +55927,13 @@ }, /turf/open/floor/iron, /area/science/research) +"rEw" = ( +/obj/effect/turf_decal/trimline/purple/filled/line, +/obj/machinery/modular_computer/console/preset/civilian{ + dir = 1 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "rFc" = ( /obj/machinery/rnd/production/circuit_imprinter, /obj/effect/turf_decal/trimline/yellow/filled/end{ @@ -58725,15 +58890,15 @@ /turf/open/floor/plating, /area/maintenance/central) "sOv" = ( -/obj/structure/disposalpipe/segment{ - dir = 10 - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ dir = 10 }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ dir = 10 }, +/obj/structure/disposalpipe/junction/flip{ + dir = 8 + }, /turf/open/floor/iron/white, /area/science/mixing) "sOF" = ( @@ -58823,6 +58988,9 @@ /obj/item/radio/intercom/directional/south, /turf/open/floor/iron/white, /area/medical/virology) +"sQi" = ( +/turf/closed/wall, +/area/science/misc_lab) "sQq" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -63233,6 +63401,9 @@ }, /turf/open/openspace, /area/hallway/primary/tram/left) +"utS" = ( +/turf/open/floor/iron, +/area/science/misc_lab) "uus" = ( /obj/structure/table, /obj/item/paper_bin{ @@ -65318,6 +65489,7 @@ dir = 8 }, /obj/effect/turf_decal/sand/plating, +/obj/structure/cable, /turf/open/floor/plating, /area/maintenance/starboard/secondary) "vmv" = ( @@ -66995,6 +67167,13 @@ /obj/effect/turf_decal/sand/plating, /turf/open/floor/plating, /area/security/office) +"vVw" = ( +/obj/effect/turf_decal/trimline/purple/filled/corner, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "vVz" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ dir = 5 @@ -70722,6 +70901,12 @@ /obj/item/toy/figure/assistant, /turf/open/floor/plating/airless, /area/science/test_area) +"xmK" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/iron/white, +/area/science/mixing) "xmN" = ( /obj/machinery/door/firedoor, /obj/effect/turf_decal/trimline/neutral/filled/line{ @@ -72562,6 +72747,23 @@ }, /turf/open/floor/engine, /area/engineering/supermatter/room) +"xVI" = ( +/obj/effect/turf_decal/trimline/purple/filled/corner{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/purple/filled/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/obj/structure/cable, +/obj/structure/disposalpipe/segment, +/turf/open/floor/iron, +/area/science/misc_lab) "xVP" = ( /obj/effect/turf_decal/siding/thinplating{ dir = 1 @@ -73166,6 +73368,27 @@ /obj/machinery/firealarm/directional/north, /turf/open/floor/iron, /area/engineering/atmos) +"yit" = ( +/obj/effect/turf_decal/trimline/purple/filled/line{ + dir = 4 + }, +/obj/structure/table, +/obj/item/multitool/circuit{ + pixel_x = 7; + pixel_y = -4 + }, +/obj/item/multitool/circuit{ + pixel_y = -4 + }, +/obj/item/multitool/circuit{ + pixel_x = -8; + pixel_y = -4 + }, +/obj/item/storage/toolbox/electrical{ + pixel_y = 13 + }, +/turf/open/floor/iron, +/area/science/misc_lab) "yiH" = ( /obj/effect/turf_decal/sand, /obj/structure/closet/crate, @@ -119027,7 +119250,7 @@ aRL aRL aRL aRL -aRL +sQi der der der @@ -119271,7 +119494,7 @@ lVH mSi plm iPd -pwI +xmK lfS kIX ioj @@ -119280,16 +119503,16 @@ ioj kzY aSm iqM -kgw -kgw +bAq +bAq dKl -kgw -kgw -kgw +bAq +orv +xVI omI kgw nAo -aRO +oHX der mkm czI @@ -119541,12 +119764,12 @@ idX aRL aRL aRL -aRL -aRL -aRL -aRL -aRL -aRL +sQi +pft +ixB +utS +vVw +mzy der der der @@ -119798,13 +120021,13 @@ aRO aRO aRL aae -aae -aae -aae -aae -aae -aae -aae +sQi +hVW +jKX +iRT +rEw +sQi +sQi aae aae aae @@ -120055,12 +120278,12 @@ vrN kCq aRL aae -aae -aae -aae -aae -aae -aae +sQi +dVY +qKS +yit +pfP +sQi aae aae aae @@ -120312,12 +120535,12 @@ aRO fGL aRL aae -aae -aae -aae -aae -aae -aae +sQi +kqO +sQi +sQi +kqO +sQi aae aae aae @@ -120570,7 +120793,7 @@ aRL aRL aae aae -aae +duT aae aae aBM diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 08b5c2b09f9..1b7b0a414ba 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -1268,3 +1268,18 @@ // Exosca signals /// Sent on exoscan failure/manual interruption: () #define COMSIG_EXOSCAN_INTERRUPTED "exoscan_interrupted" + +// Component signals +/// From /datum/port/output/set_output: (output_value) +#define COMSIG_PORT_SET_OUTPUT "port_set_output" +/// From /datum/port/input/set_input: (input_value) +#define COMSIG_PORT_SET_INPUT "port_set_input" +/// Sent when a port calls disconnect(). From /datum/port/disconnect: () +#define COMSIG_PORT_DISCONNECT "port_disconnect" +/// Sent on the output port when an input port registers on it: (datum/port/input/registered_port) +#define COMSIG_PORT_OUTPUT_CONNECT "port_output_connect" + +/// Sent when a [/obj/item/circuit_component] is added to a circuit. +#define COMSIG_CIRCUIT_ADD_COMPONENT "circuit_add_component" + /// Cancels adding the component to the circuit. + #define COMPONENT_CANCEL_ADD_COMPONENT (1<<0) diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm index 497e0c0b175..76cd698402b 100644 --- a/code/__DEFINES/machines.dm +++ b/code/__DEFINES/machines.dm @@ -46,6 +46,8 @@ #define AWAY_LATHE (1<<8) /// Imprinters for offstation roles. More limited tech tree. #define AWAY_IMPRINTER (1<<9) +/// For wiremod/integrated circuits. Uses various minerals. +#define COMPONENT_PRINTER (1<<10) //Note: More than one of these can be added to a design but imprinter and lathe designs are incompatable. //Modular computer/NTNet defines diff --git a/code/__DEFINES/wiremod.dm b/code/__DEFINES/wiremod.dm new file mode 100644 index 00000000000..af791d66174 --- /dev/null +++ b/code/__DEFINES/wiremod.dm @@ -0,0 +1,93 @@ +#define PORT_INPUT_RECEIVE_DELAY 0.2 SECONDS + +/// Helper define that can only be used in /obj/item/circuit_component/input_received() +#define COMPONENT_TRIGGERED_BY(trigger, port) (trigger.input_value && trigger == port) + +// Port types. Determines what the port can connect to + +/// Can accept any datatype. Only works for inputs, output types will runtime. +#define PORT_TYPE_ANY null + +// Fundamental datatypes +/// String datatype +#define PORT_TYPE_STRING "string" +#define PORT_MAX_STRING_LENGTH 500 +/// Number datatype +#define PORT_TYPE_NUMBER "number" +/// Signal datatype +#define PORT_TYPE_SIGNAL "signal" +/// List datatype +#define PORT_TYPE_LIST "list" + +// Other datatypes +/// Atom datatype +#define PORT_TYPE_ATOM "entity" + +/// The maximum range between a port and an atom +#define PORT_ATOM_MAX_RANGE 7 + +#define COMPONENT_DEFAULT_NAME "component" + +/// The minimum position of the x and y co-ordinates of the component in the UI +#define COMPONENT_MIN_RANDOM_POS 200 +/// The maximum position of the x and y co-ordinates of the component in the UI +#define COMPONENT_MAX_RANDOM_POS 400 + +/// The maximum position in both directions that a component can be in. +/// Prevents someone from positioning a component at an absurdly high value. +#define COMPONENT_MAX_POS 10000 + +// Components + +/// The value that is sent whenever a component is simply sending a signal. This can be anything. +#define COMPONENT_SIGNAL 1 + +// Comparison defines +#define COMP_COMPARISON_EQUAL "=" +#define COMP_COMPARISON_NOT_EQUAL "!=" +#define COMP_COMPARISON_GREATER_THAN ">" +#define COMP_COMPARISON_LESS_THAN "<" +#define COMP_COMPARISON_GREATER_THAN_OR_EQUAL ">=" +#define COMP_COMPARISON_LESS_THAN_OR_EQUAL "<=" + +// Delay defines +/// The minimum delay value that the delay component can have. +#define COMP_DELAY_MIN_VALUE 0.1 + +// Logic defines +#define COMP_LOGIC_AND "AND" +#define COMP_LOGIC_OR "OR" +#define COMP_LOGIC_XOR "XOR" + +// Arithmetic defines +#define COMP_ARITHMETIC_ADD "Add" +#define COMP_ARITHMETIC_SUBTRACT "Subtract" +#define COMP_ARITHMETIC_MULTIPLY "Multiply" +#define COMP_ARITHMETIC_DIVIDE "Divide" +#define COMP_ARITHMETIC_MIN "Minimum" +#define COMP_ARITHMETIC_MAX "Maximum" + +// Text defines +#define COMP_TEXT_LOWER "To Lower" +#define COMP_TEXT_UPPER "To Upper" + +// Typecheck component +#define COMP_TYPECHECK_MOB "organism" +#define COMP_TYPECHECK_HUMAN "humanoid" + +// Clock component +#define COMP_CLOCK_DELAY 0.9 SECONDS + +// Shells + +/// Whether a circuit is stuck on a shell and cannot be removed (by a user) +#define SHELL_FLAG_CIRCUIT_FIXED (1<<0) + +/// Whether the shell needs to be anchored for the circuit to be on. +#define SHELL_FLAG_REQUIRE_ANCHOR (1<<1) + +// Shell capacities. These can be converted to configs very easily later +#define SHELL_CAPACITY_SMALL 10 +#define SHELL_CAPACITY_MEDIUM 25 +#define SHELL_CAPACITY_LARGE 50 +#define SHELL_CAPACITY_VERY_LARGE 500 diff --git a/code/__HELPERS/~skyrat_helpers/integrated_circuits.dm b/code/__HELPERS/~skyrat_helpers/integrated_circuits.dm deleted file mode 100644 index 001986ea9d7..00000000000 --- a/code/__HELPERS/~skyrat_helpers/integrated_circuits.dm +++ /dev/null @@ -1,104 +0,0 @@ -// Integrated Circuits helpers -/// isnum() returns TRUE for NaN. Also, NaN != NaN. Checkmate, BYOND. -#define isnan(x) ( (x) != (x) ) - -#define isinf(x) (isnum((x)) && (((x) == text2num("inf")) || ((x) == text2num("-inf")))) - -/// NaN isn't a number, damn it. Infinity is a problem too. -#define isnum_safe(x) ( isnum((x)) && !isnan((x)) && !isinf((x)) ) - -#define string2charlist(string) (splittext(string, regex("(.)")) - splittext(string, "")) - -/// Encodes a string to hex -/proc/strtohex(str) - if(!istext(str)||!str) - return - var/r - var/c - for(var/i = 1 to length(str)) - c = text2ascii(str,i) - r += num2hex(c, 2) - return r - -/// Decodes hex to raw byte string. If safe=TRUE, returns null on incorrect input strings instead of CRASHing -/proc/hextostr(str, safe=FALSE) - if(!istext(str)||!str) - return - var/r - var/c - for(var/i = 1 to length(str)/2) - c = hex2num(copytext(str,i*2-1,i*2+1)) - if(isnull(c)) - return null - r += ascii2text(c) - return r - -// this proc is used for various pathfinding and locomotion circuits -/proc/get_step_towards2(atom/ref , atom/trg) - var/base_dir = get_dir(ref, get_step_towards(ref,trg)) - var/turf/temp = get_step_towards(ref,trg) - - if(temp.is_blocked_turf(TRUE)) - var/dir_alt1 = turn(base_dir, 90) - var/dir_alt2 = turn(base_dir, -90) - var/turf/turf_last1 = temp - var/turf/turf_last2 = temp - var/free_tile = null - var/breakpoint = 0 - - while(!free_tile && breakpoint < 10) - if(!turf_last1.is_blocked_turf(TRUE)) - free_tile = turf_last1 - break - if(!turf_last2.is_blocked_turf(TRUE)) - free_tile = turf_last2 - break - turf_last1 = get_step(turf_last1,dir_alt1) - turf_last2 = get_step(turf_last2,dir_alt2) - breakpoint++ - - if(!free_tile) - return get_step(ref, base_dir) - else - return get_step_towards(ref,free_tile) - - else - return get_step(ref, base_dir) - -// same as do_mob except for movables and it allows both to drift and doesn't draw progressbar. Used by inject circuit. -/proc/do_atom(atom/movable/user , atom/movable/target, time = 30, uninterruptible = 0,datum/callback/extra_checks = null) - if(!user || !target) - return TRUE - var/user_loc = user.loc - - var/drifting = FALSE - if(!user.Process_Spacemove(0) && user.inertia_dir) - drifting = TRUE - - var/target_drifting = FALSE - if(!target.Process_Spacemove(0) && target.inertia_dir) - target_drifting = TRUE - - var/target_loc = target.loc - - var/endtime = world.time+time - . = TRUE - while (world.time < endtime) - stoplag(1) - if(QDELETED(user) || QDELETED(target)) - . = 0 - break - if(uninterruptible) - continue - - if(drifting && !user.inertia_dir) - drifting = FALSE - user_loc = user.loc - - if(target_drifting && !target.inertia_dir) - target_drifting = FALSE - target_loc = target.loc - - if((!drifting && user.loc != user_loc) || (!target_drifting && target.loc != target_loc) || (extra_checks && !extra_checks.Invoke())) - . = FALSE - break diff --git a/code/controllers/subsystem/delay_component.dm b/code/controllers/subsystem/delay_component.dm new file mode 100644 index 00000000000..098dd8c65cc --- /dev/null +++ b/code/controllers/subsystem/delay_component.dm @@ -0,0 +1,3 @@ +TIMER_SUBSYSTEM_DEF(circuit_component) + name = "Circuit Components" + priority = FIRE_PRIORITY_DEFAULT diff --git a/code/controllers/subsystem/processing/clock_component.dm b/code/controllers/subsystem/processing/clock_component.dm new file mode 100644 index 00000000000..d07acaa6d79 --- /dev/null +++ b/code/controllers/subsystem/processing/clock_component.dm @@ -0,0 +1,5 @@ +/// The subsystem used to tick [/datum/component/acid] instances. +PROCESSING_SUBSYSTEM_DEF(clock_component) + name = "Clock Component" + flags = SS_NO_INIT|SS_BACKGROUND|SS_KEEP_TIMING + wait = COMP_CLOCK_DELAY diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm index 4515f5ad2ae..8b5be7d1be7 100644 --- a/code/datums/components/material_container.dm +++ b/code/datums/components/material_container.dm @@ -415,3 +415,20 @@ if(!istype(mat)) mat = GET_MATERIAL_REF(mat) return materials[mat] + +/// List format is list(material_name = list(amount = ..., ref = ..., etc.)) +/datum/component/material_container/ui_data(mob/user) + var/list/data = list() + + for(var/datum/material/material as anything in materials) + var/amount = materials[material] + + data += list(list( + "name" = material.name, + "ref" = REF(material), + "amount" = amount, + "sheets" = round(amount / MINERAL_MATERIAL_AMOUNT), + "removable" = amount >= MINERAL_MATERIAL_AMOUNT, + )) + + return data diff --git a/code/datums/components/remote_materials.dm b/code/datums/components/remote_materials.dm index 566b3b5c1d3..8e62811c598 100644 --- a/code/datums/components/remote_materials.dm +++ b/code/datums/components/remote_materials.dm @@ -130,3 +130,21 @@ handles linking back and forth. return "[mat_container.total_amount] / [mat_container.max_amount == INFINITY ? "Unlimited" : mat_container.max_amount] ([silo ? "remote" : "local"])" else return "0 / 0" + +/// Ejects the given material ref and logs it, or says out loud the problem. +/datum/component/remote_materials/proc/eject_sheets(datum/material/material_ref, eject_amount) + var/atom/movable/movable_parent = parent + if (!istype(movable_parent)) + return 0 + + if (!mat_container) + movable_parent.say("No access to material storage, please contact the quartermaster.") + return 0 + if (on_hold()) + movable_parent.say("Mineral access is on hold, please contact the quartermaster.") + return 0 + var/count = mat_container.retrieve_sheets(eject_amount, material_ref, movable_parent.drop_location()) + var/list/matlist = list() + matlist[material_ref] = eject_amount + silo_log(parent, "ejected", -count, "sheets", matlist) + return count diff --git a/code/datums/components/shell.dm b/code/datums/components/shell.dm new file mode 100644 index 00000000000..5926e418bd6 --- /dev/null +++ b/code/datums/components/shell.dm @@ -0,0 +1,183 @@ +/// Makes an atom a shell that is able to take in an attached circuit. +/datum/component/shell + dupe_mode = COMPONENT_DUPE_UNIQUE + + /// The circuitboard attached to this shell + var/obj/item/integrated_circuit/attached_circuit + + /// Flags containing what this shell can do + var/shell_flags = 0 + + /// The capacity of the shell. + var/capacity = INFINITY + + /// A list of components that cannot be removed + var/list/obj/item/circuit_component/unremovable_circuit_components + +/datum/component/shell/Initialize(unremovable_circuit_components, capacity, shell_flags) + . = ..() + if(!ismovable(parent)) + return COMPONENT_INCOMPATIBLE + + src.shell_flags = shell_flags || src.shell_flags + src.capacity = capacity || src.capacity + src.unremovable_circuit_components = unremovable_circuit_components + + for(var/obj/item/circuit_component/circuit_component as anything in unremovable_circuit_components) + circuit_component.removable = FALSE + +/datum/component/shell/RegisterWithParent() + RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/on_attack_by) + RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_examine) + RegisterSignal(parent, COMSIG_ATOM_ATTACK_GHOST, .proc/on_attack_ghost) + if(!(shell_flags & SHELL_FLAG_CIRCUIT_FIXED)) + RegisterSignal(parent, COMSIG_ATOM_TOOL_ACT(TOOL_SCREWDRIVER), .proc/on_screwdriver_act) + RegisterSignal(parent, COMSIG_ATOM_TOOL_ACT(TOOL_MULTITOOL), .proc/on_multitool_act) + if(shell_flags & SHELL_FLAG_REQUIRE_ANCHOR) + RegisterSignal(parent, COMSIG_OBJ_DEFAULT_UNFASTEN_WRENCH, .proc/on_unfasten) + +/datum/component/shell/UnregisterFromParent() + UnregisterSignal(parent, list( + COMSIG_PARENT_ATTACKBY, + COMSIG_ATOM_TOOL_ACT(TOOL_SCREWDRIVER), + COMSIG_ATOM_TOOL_ACT(TOOL_MULTITOOL), + COMSIG_OBJ_DEFAULT_UNFASTEN_WRENCH, + COMSIG_PARENT_EXAMINE, + COMSIG_ATOM_ATTACK_GHOST + )) + + QDEL_NULL(attached_circuit) + +/datum/component/shell/Destroy(force, silent) + QDEL_LIST(unremovable_circuit_components) + return ..() + +/datum/component/shell/proc/on_attack_ghost(datum/source, mob/dead/observer/ghost) + SIGNAL_HANDLER + if(attached_circuit) + INVOKE_ASYNC(attached_circuit, /datum.proc/ui_interact, ghost) + +/datum/component/shell/proc/on_examine(datum/source, mob/user, list/examine_text) + SIGNAL_HANDLER + if(!attached_circuit) + return + + examine_text += "There is an integrated circuit attached. Use a multitool to access the wiring. Use a screwdriver to remove it from [source]." + var/obj/item/stock_parts/cell/cell = attached_circuit.cell + examine_text += "The charge meter reads [cell ? round(cell.percent(), 1) : 0]%." + + +/** + * Called when the shell is wrenched. + * + * Only applies if the shell has SHELL_FLAG_REQUIRE_ANCHOR. + * Disables the integrated circuit if unanchored, otherwise enable the circuit. + */ +/datum/component/shell/proc/on_unfasten(atom/source, anchored) + SIGNAL_HANDLER + attached_circuit?.on = anchored +/** + * Called when an item hits the parent. This is the method to add the circuitboard to the component. + */ +/datum/component/shell/proc/on_attack_by(atom/source, obj/item/item, mob/living/attacker) + SIGNAL_HANDLER + if(istype(item, /obj/item/stock_parts/cell)) + source.balloon_alert(attacker, "can't pull cell in directly!") + return + + if(!istype(item, /obj/item/integrated_circuit)) + return + var/obj/item/integrated_circuit/logic_board = item + . = COMPONENT_NO_AFTERATTACK + + if(logic_board.shell) // I'll be surprised if this ever happens + return + + if(attached_circuit) + source.balloon_alert(attacker, "there is already a circuitboard inside!") + return + + if(length(logic_board.attached_components) > capacity) + source.balloon_alert(attacker, "this is too large to fit into [parent]!") + return + + attach_circuit(logic_board, attacker) + +/datum/component/shell/proc/on_multitool_act(atom/source, mob/user, obj/item/tool) + SIGNAL_HANDLER + if(!attached_circuit) + return + + attached_circuit.interact(user) + return COMPONENT_BLOCK_TOOL_ATTACK + +/** + * Called when a screwdriver is used on the parent. Removes the circuitboard from the component. + */ +/datum/component/shell/proc/on_screwdriver_act(atom/source, mob/user, obj/item/tool) + SIGNAL_HANDLER + if(!attached_circuit) + return + + tool.play_tool_sound(parent) + source.balloon_alert(user, "You unscrew [attached_circuit] from [parent].") + remove_circuit() + return COMPONENT_BLOCK_TOOL_ATTACK + +/** + * Checks for when the circuitboard moves. If it moves, removes it from the component. + */ +/datum/component/shell/proc/on_circuit_moved(obj/item/integrated_circuit/circuit, atom/new_loc) + SIGNAL_HANDLER + if(new_loc != parent) + remove_circuit() + +/** + * Checks for when the circuitboard deletes so that it can be unassigned. + */ +/datum/component/shell/proc/on_circuit_delete(datum/source) + SIGNAL_HANDLER + remove_circuit() + +/datum/component/shell/proc/on_circuit_add_component(datum/source, obj/item/circuit_component/added_comp) + SIGNAL_HANDLER + return COMPONENT_CANCEL_ADD_COMPONENT + +/** + * Attaches a circuit to the parent. Doesn't do any checks to see for any existing circuits so that should be done beforehand. + */ +/datum/component/shell/proc/attach_circuit(obj/item/integrated_circuit/circuitboard, mob/living/user) + if(!user.transferItemToLoc(circuitboard, parent)) + return + attached_circuit = circuitboard + RegisterSignal(circuitboard, COMSIG_MOVABLE_MOVED, .proc/on_circuit_moved) + RegisterSignal(circuitboard, COMSIG_PARENT_QDELETING, .proc/on_circuit_delete) + for(var/obj/item/circuit_component/to_add as anything in unremovable_circuit_components) + to_add.forceMove(attached_circuit) + attached_circuit.add_component(to_add) + RegisterSignal(circuitboard, COMSIG_CIRCUIT_ADD_COMPONENT, .proc/on_circuit_add_component) + attached_circuit.set_shell(parent) + + if(shell_flags & SHELL_FLAG_REQUIRE_ANCHOR) + var/atom/movable/parent_atom = parent + on_unfasten(parent_atom, parent_atom.anchored) + +/** + * Removes the circuit from the component. Doesn't do any checks to see for an existing circuit so that should be done beforehand. + */ +/datum/component/shell/proc/remove_circuit() + attached_circuit.on = TRUE + attached_circuit.remove_current_shell() + UnregisterSignal(attached_circuit, list( + COMSIG_MOVABLE_MOVED, + COMSIG_PARENT_QDELETING, + COMSIG_CIRCUIT_ADD_COMPONENT, + )) + if(attached_circuit.loc == parent) + var/atom/parent_atom = parent + attached_circuit.forceMove(parent_atom.drop_location()) + + for(var/obj/item/circuit_component/to_remove as anything in unremovable_circuit_components) + attached_circuit.remove_component(to_remove) + to_remove.moveToNullspace() + attached_circuit = null diff --git a/code/modules/asset_cache/asset_list_items.dm b/code/modules/asset_cache/asset_list_items.dm index 1484d49b671..60f99615658 100644 --- a/code/modules/asset_cache/asset_list_items.dm +++ b/code/modules/asset_cache/asset_list_items.dm @@ -59,6 +59,11 @@ "ntosradarpointerS.png" = 'icons/ui_icons/tgui/ntosradar_pointer_S.png' ) +/datum/asset/simple/circuit_assets + assets = list( + "grid_background.png" = 'icons/ui_icons/tgui/grid_background.png' + ) + /datum/asset/spritesheet/simple/pda name = "pda" assets = list( diff --git a/code/modules/balloon_alert/balloon_alert.dm b/code/modules/balloon_alert/balloon_alert.dm index 495f5dba90d..d6f17d6ffe9 100644 --- a/code/modules/balloon_alert/balloon_alert.dm +++ b/code/modules/balloon_alert/balloon_alert.dm @@ -2,7 +2,11 @@ #define BALLOON_TEXT_SPAWN_TIME (0.2 SECONDS) #define BALLOON_TEXT_FADE_TIME (0.1 SECONDS) #define BALLOON_TEXT_FULLY_VISIBLE_TIME (0.7 SECONDS) -#define BALLOON_TEXT_TOTAL_LIFETIME (BALLOON_TEXT_SPAWN_TIME + BALLOON_TEXT_FULLY_VISIBLE_TIME + BALLOON_TEXT_FADE_TIME) +#define BALLOON_TEXT_TOTAL_LIFETIME(mult) (BALLOON_TEXT_SPAWN_TIME + BALLOON_TEXT_FULLY_VISIBLE_TIME*mult + BALLOON_TEXT_FADE_TIME) +/// The increase in duration per character in seconds +#define BALLOON_TEXT_CHAR_LIFETIME_INCREASE_MULT (0.05) +/// The amount of characters needed before this increase takes into effect +#define BALLOON_TEXT_CHAR_LIFETIME_INCREASE_MIN 10 /// Creates text that will float from the atom upwards to the viewer. /atom/proc/balloon_alert(mob/viewer, text) @@ -48,10 +52,16 @@ viewer_client?.images += balloon_alert + var/duration_mult = 1 + var/duration_length = length(text) - BALLOON_TEXT_CHAR_LIFETIME_INCREASE_MIN + + if(duration_length > 0) + duration_mult += duration_length*BALLOON_TEXT_CHAR_LIFETIME_INCREASE_MULT + animate( balloon_alert, pixel_y = world.icon_size * 1.2, - time = BALLOON_TEXT_TOTAL_LIFETIME, + time = BALLOON_TEXT_TOTAL_LIFETIME(1), easing = SINE_EASING | EASE_OUT, ) @@ -64,12 +74,14 @@ animate( alpha = 0, - time = BALLOON_TEXT_FULLY_VISIBLE_TIME, + time = BALLOON_TEXT_FULLY_VISIBLE_TIME*duration_mult, easing = CUBIC_EASING | EASE_IN, ) - addtimer(CALLBACK(GLOBAL_PROC, .proc/remove_image_from_client, balloon_alert, viewer_client), BALLOON_TEXT_TOTAL_LIFETIME) + addtimer(CALLBACK(GLOBAL_PROC, .proc/remove_image_from_client, balloon_alert, viewer_client), BALLOON_TEXT_TOTAL_LIFETIME(duration_mult)) +#undef BALLOON_TEXT_CHAR_LIFETIME_INCREASE_MIN +#undef BALLOON_TEXT_CHAR_LIFETIME_INCREASE_MULT #undef BALLOON_TEXT_FADE_TIME #undef BALLOON_TEXT_FULLY_VISIBLE_TIME #undef BALLOON_TEXT_SPAWN_TIME diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index 308144785de..12f697b8a23 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -772,3 +772,11 @@ build_path = /obj/item/circuitboard/machine/exodrone_launcher category = list ("Engineering Machinery") departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/board/component_printer + name = "Machine Design (Component Printer)" + desc = "The circuit board for a component printer" + id = "component_printer" + build_path = /obj/item/circuitboard/machine/component_printer + category = list("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE diff --git a/code/modules/research/designs/wiremod_designs.dm b/code/modules/research/designs/wiremod_designs.dm new file mode 100644 index 00000000000..ff75b1b6824 --- /dev/null +++ b/code/modules/research/designs/wiremod_designs.dm @@ -0,0 +1,208 @@ +/datum/design/integrated_circuit + name = "Integrated Circuit" + desc = "The foundation of all circuits. All Circuitry go onto this." + id = "integrated_circuit" + build_path = /obj/item/integrated_circuit + build_type = IMPRINTER | COMPONENT_PRINTER + category = list("Circuitry", "Core") + materials = list(/datum/material/glass = 1000, /datum/material/iron = 1000) + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/circuit_multitool + name = "Circuit Multitool" + desc = "A circuit multitool to mark entities and load them into." + id = "circuit_multitool" + build_path = /obj/item/multitool/circuit + build_type = PROTOLATHE | COMPONENT_PRINTER + category = list("Circuitry", "Core") + materials = list(/datum/material/glass = 1000, /datum/material/iron = 1000) + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + + +/datum/design/component + name = "Component ( NULL ENTRY )" + desc = "A component that goes into an integrated circuit." + build_type = IMPRINTER | COMPONENT_PRINTER + materials = list(/datum/material/glass = 1000) + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + category = list("Circuitry", "Components") + +/datum/design/component/arithmetic + name = "Arithmetic Component" + desc = "General arithmetic component with add/subtract/multiplication/division capabilities." + id = "comp_arithmetic" + build_path = /obj/item/circuit_component/arithmetic + +/datum/design/component/clock + name = "Clock Component" + desc = "A component that repeatedly fires." + id = "comp_clock" + build_path = /obj/item/circuit_component/clock + +/datum/design/component/comparison + name = "Comparison Component" + desc = "A component that compares two objects." + id = "comp_comparison" + build_path = /obj/item/circuit_component/compare/comparison + +/datum/design/component/logic + name = "Logic Component" + desc = "A component with 'and' and 'or' capabilities." + id = "comp_logic" + build_path = /obj/item/circuit_component/compare/logic + +/datum/design/component/delay + name = "Delay Component" + desc = "A component that delays a signal by a specified duration." + id = "comp_delay" + build_path = /obj/item/circuit_component/delay + +/datum/design/component/index + name = "Index Component" + desc = "A component that returns the value of a list at a given index." + id = "comp_index" + build_path = /obj/item/circuit_component/index + +/datum/design/component/length + name = "Length Component" + desc = "A component that returns the length of its input." + id = "comp_length" + build_path = /obj/item/circuit_component/length + +/datum/design/component/light + name = "Light Component" + desc = "A component that emits a light of a specific brightness and colour. Requires a shell." + id = "comp_light" + build_path = /obj/item/circuit_component/light + +/datum/design/component/not + name = "Not Component" + desc = "A component that inverts its input." + id = "comp_not" + build_path = /obj/item/circuit_component/not + +/datum/design/component/ram + name = "RAM Component" + desc = "A component that retains a variable." + id = "comp_ram" + build_path = /obj/item/circuit_component/ram + +/datum/design/component/random + name = "Random Component" + desc = "A component that returns random values." + id = "comp_random" + build_path = /obj/item/circuit_component/random + +/datum/design/component/species + name = "Get Species Component" + desc = "A component that returns the species of its input." + id = "comp_species" + build_path = /obj/item/circuit_component/species + +/datum/design/component/speech + name = "Speech Component" + desc = "A component that sends a message. Requires a shell." + id = "comp_speech" + build_path = /obj/item/circuit_component/speech + +/datum/design/component/tostring + name = "To String Component" + desc = "A component that converts its input to text." + id = "comp_tostring" + build_path = /obj/item/circuit_component/tostring + +/datum/design/component/typecheck + name = "Typecheck Component" + desc = "A component that checks the type of its input." + id = "comp_typecheck" + build_path = /obj/item/circuit_component/compare/typecheck + +/datum/design/component/concat + name = "Concatenation Component" + desc = "A component that combines strings." + id = "comp_concat" + build_path = /obj/item/circuit_component/concat + +/datum/design/component/textcase + name = "Textcase Component" + desc = "A component that makes its input uppercase or lowercase." + id = "comp_textcase" + build_path = /obj/item/circuit_component/textcase + +/datum/design/component/hear + name = "Voice Activator Component" + desc = "A component that listens for messages. Requires a shell." + id = "comp_hear" + build_path = /obj/item/circuit_component/hear + +/datum/design/component/contains + name = "String Contains Component" + desc = "Checks if a string contains a word/letter" + id = "comp_string_contains" + build_path = /obj/item/circuit_component/compare/contains + +/datum/design/component/self + name = "Self Component" + desc = "A component that returns the current shell." + id = "comp_self" + build_path = /obj/item/circuit_component/self + +/datum/design/component/radio + name = "Radio Component" + desc = "A component that can listen and send frequencies." + id = "comp_radio" + build_path = /obj/item/circuit_component/radio + + +/datum/design/compact_remote_shell + name = "Compact Remote Shell" + desc = "A handheld shell with one big button." + id = "compact_remote_shell" + build_path = /obj/item/compact_remote + materials = list(/datum/material/glass = 2000, /datum/material/iron = 5000) + build_type = PROTOLATHE | COMPONENT_PRINTER + category = list("Circuitry", "Shells") + +/datum/design/controller_shell + name = "Controller Shell" + desc = "A handheld shell with several buttons." + id = "controller_shell" + build_path = /obj/item/controller + build_type = PROTOLATHE | COMPONENT_PRINTER + materials = list(/datum/material/glass = 2000, /datum/material/iron = 7000) + category = list("Circuitry", "Shells") + +/datum/design/bot_shell + name = "Bot Shell" + desc = "An immobile shell that can store more components." + id = "bot_shell" + build_path = /obj/item/shell/bot + build_type = PROTOLATHE | COMPONENT_PRINTER + materials = list(/datum/material/glass = 2000, /datum/material/iron = 10000) + category = list("Circuitry", "Shells") + +/datum/design/drone_shell + name = "Drone Shell" + desc = "A shell with the ability to move itself around." + id = "drone_shell" + build_path = /obj/item/shell/drone + build_type = PROTOLATHE | COMPONENT_PRINTER + materials = list( + /datum/material/glass = 2000, + /datum/material/iron = 11000, + /datum/material/gold = 500, + ) + category = list("Circuitry", "Shells") + +/datum/design/server_shell + name = "Server Shell" + desc = "A very large shell that cannot be moved around. Stores the most components." + id = "server_shell" + materials = list( + /datum/material/glass = 5000, + /datum/material/iron = 15000, + /datum/material/gold = 1500, + ) + build_path = /obj/item/shell/server + build_type = PROTOLATHE | COMPONENT_PRINTER + category = list("Circuitry", "Shells") diff --git a/code/modules/research/machinery/circuit_imprinter.dm b/code/modules/research/machinery/circuit_imprinter.dm index ab44ffa8fbe..fabe05ac597 100644 --- a/code/modules/research/machinery/circuit_imprinter.dm +++ b/code/modules/research/machinery/circuit_imprinter.dm @@ -14,7 +14,8 @@ "Subspace Telecomms", "Research Machinery", "Misc. Machinery", - "Computer Parts" + "Computer Parts", + "Circuitry" ) production_animation = "circuit_imprinter_ani" allowed_buildtypes = IMPRINTER diff --git a/code/modules/research/machinery/protolathe.dm b/code/modules/research/machinery/protolathe.dm index 99ac2f26982..4ac7ee688b4 100644 --- a/code/modules/research/machinery/protolathe.dm +++ b/code/modules/research/machinery/protolathe.dm @@ -15,7 +15,8 @@ "Weapons", "Ammo", "Firing Pins", - "Computer Parts" + "Computer Parts", + "Circuitry" ) production_animation = "protolathe_n" allowed_buildtypes = PROTOLATHE diff --git a/code/modules/research/machinery/techfab.dm b/code/modules/research/machinery/techfab.dm index 68a57bf54ef..a0afaf8b671 100644 --- a/code/modules/research/machinery/techfab.dm +++ b/code/modules/research/machinery/techfab.dm @@ -26,7 +26,8 @@ "Subspace Telecomms", "Research Machinery", "Misc. Machinery", - "Computer Parts" + "Computer Parts", + "Circuitry" ) console_link = FALSE production_animation = "protolathe_n" diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 8d1384e01da..ce1f6a4dc68 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -62,6 +62,16 @@ "stethoscope", "surgical_drapes", "hospital_gown", "syringe", "plumbing_rcd", "beaker", "large_beaker", "xlarge_beaker", "dropper", "defibmountdefault", "surgical_tape", "portable_chem_mixer") //SKYRAT EDIT ADDITION: added "surgical_drapes" +/datum/techweb_node/basic_circuitry + id = "basic_circuitry" + starting_node = TRUE + display_name = "Basic Integrated Circuits" + description = "Research on how to fully exploit the power of integrated circuits" + design_ids = list("integrated_circuit", "circuit_multitool", "comp_arithmetic", "comp_clock", "comp_comparison", "comp_delay", "comp_hear", + "comp_index", "comp_length", "comp_light", "comp_logic", "comp_not", "comp_ram", "comp_random", "comp_species", "comp_textcase", + "comp_speech", "comp_concat", "comp_speech", "comp_self", "comp_radio", "comp_tostring", "comp_typecheck", "compact_remote_shell", "component_printer", + "comp_string_contains") + /////////////////////////Biotech///////////////////////// /datum/techweb_node/biotech @@ -286,6 +296,32 @@ design_ids = list("mech_plasma_cutter") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) +/////////////////////////integrated circuits tech///////////////////////// + +/datum/techweb_node/adv_shells + id = "adv_shells" + display_name = "Advanced Shell Research" + description = "Grants access to more complicated shell designs." + prereq_ids = list("basic_circuitry", "engineering") + design_ids = list("controller_shell", "bot_shell") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + +/datum/techweb_node/movable_shells_tech + id = "movable_shells" + display_name = "Movable Shell Research" + description = "Grants access to movable shells." + prereq_ids = list("adv_shells", "robotics") + design_ids = list("drone_shell") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000) + +/datum/techweb_node/server_shell_tech + id = "server_shell" + display_name = "Server Technology Research" + description = "Grants access to a server shell that has a very high capacity for components." + prereq_ids = list("adv_shells", "computer_hardware_basic") + design_ids = list("server_shell") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000) + /////////////////////////robotics tech///////////////////////// /datum/techweb_node/robotics id = "robotics" diff --git a/code/modules/vehicles/mecha/mech_fabricator.dm b/code/modules/vehicles/mecha/mech_fabricator.dm index c2af3ddd89b..47d17130875 100644 --- a/code/modules/vehicles/mecha/mech_fabricator.dm +++ b/code/modules/vehicles/mecha/mech_fabricator.dm @@ -177,37 +177,6 @@ return part -/** - * Generates a list of resources / materials available to this Exosuit Fab - * - * Returns null if there is no material container available. - * List format is list(material_name = list(amount = ..., ref = ..., etc.)) - */ -/obj/machinery/mecha_part_fabricator/proc/output_available_resources() - var/datum/component/material_container/materials = rmat.mat_container - - var/list/material_data = list() - - if(materials) - for(var/mat_id in materials.materials) - var/datum/material/M = mat_id - var/list/material_info = list() - var/amount = materials.materials[mat_id] - - material_info = list( - "name" = M.name, - "ref" = REF(M), - "amount" = amount, - "sheets" = round(amount / MINERAL_MATERIAL_AMOUNT), - "removable" = amount >= MINERAL_MATERIAL_AMOUNT - ) - - material_data += list(material_info) - - return material_data - - return null - /** * Intended to be called when an item starts printing. * @@ -488,7 +457,7 @@ /obj/machinery/mecha_part_fabricator/ui_data(mob/user) var/list/data = list() - data["materials"] = output_available_resources() + data["materials"] = rmat.mat_container?.ui_data() if(being_built) var/list/part = list( @@ -588,36 +557,18 @@ queue.Swap(index,new_index) return if("remove_mat") - // Remove a material from the fab - var/mat_ref = params["ref"] + var/datum/material/material = locate(params["ref"]) var/amount = text2num(params["amount"]) - var/datum/material/mat = locate(mat_ref) - eject_sheets(mat, amount) + + if (!amount) + return + + // SAFETY: eject_sheets checks for valid mats + rmat.eject_sheets(material, amount) return return FALSE -/** - * Eject material sheets. - * - * Returns the number of sheets successfully ejected. - * eject_sheet - Byond REF of the material to eject. - * eject_amt - Number of sheets to attempt to eject. - */ -/obj/machinery/mecha_part_fabricator/proc/eject_sheets(eject_sheet, eject_amt) - var/datum/component/material_container/mat_container = rmat.mat_container - if (!mat_container) - say("No access to material storage, please contact the quartermaster.") - return 0 - if (rmat.on_hold()) - say("Mineral access is on hold, please contact the quartermaster.") - return 0 - var/count = mat_container.retrieve_sheets(text2num(eject_amt), eject_sheet, drop_location()) - var/list/matlist = list() - matlist[eject_sheet] = text2num(eject_amt) - rmat.silo_log(src, "ejected", -count, "sheets", matlist) - return count - /obj/machinery/mecha_part_fabricator/proc/AfterMaterialInsert(item_inserted, id_inserted, amount_inserted) var/datum/material/M = id_inserted add_overlay("fab-load-[M.name]") diff --git a/code/modules/wiremod/component.dm b/code/modules/wiremod/component.dm new file mode 100644 index 00000000000..e8a3cc7d610 --- /dev/null +++ b/code/modules/wiremod/component.dm @@ -0,0 +1,182 @@ +/** + * # Integrated Circuit Component + * + * A component that performs a function when given an input + * + * Can be attached to an integrated circuitboard, where it can then + * be connected between other components to provide an output or to receive + * an input. This is the base type of all components + */ +/obj/item/circuit_component + name = COMPONENT_DEFAULT_NAME + icon = 'icons/obj/module.dmi' + icon_state = "component" + inhand_icon_state = "electronic" + + /// The name of the component shown on the UI + var/display_name = "Generic" + + /// The integrated_circuit that this component is attached to. + var/obj/item/integrated_circuit/parent + + /// A list that contains the outpurt ports on this component + /// Used to connect between the ports + var/list/datum/port/output/output_ports = list() + + /// A list that contains the components the input ports on this component + /// Used to connect between the ports + var/list/datum/port/input/input_ports = list() + + /// Generic trigger input for triggering this component + var/datum/port/input/trigger_input + var/datum/port/output/trigger_output + + var/has_trigger = FALSE + + /// Used to determine the x position of the component within the UI + var/rel_x = 0 + /// Used to determine the y position of the component within the UI + var/rel_y = 0 + + /// The power usage whenever this component receives an input + var/power_usage_per_input = 1 + + /// The current selected option + var/current_option + /// The options that this component can take on. Limited to strings + var/list/options + + // Whether the component is removable or not. Only affects user UI + var/removable = TRUE + +/obj/item/circuit_component/Initialize() + . = ..() + if(name == COMPONENT_DEFAULT_NAME) + name = "[lowertext(display_name)] [COMPONENT_DEFAULT_NAME]" + if(length(options)) + current_option = options[1] + + return INITIALIZE_HINT_LATELOAD + +/obj/item/circuit_component/LateInitialize() + . = ..() + if(has_trigger) + trigger_input = add_input_port("Trigger", PORT_TYPE_SIGNAL) + trigger_output = add_output_port("Triggered", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/Destroy() + if(parent) + parent.remove_component(src) + parent = null + + trigger_input = null + trigger_output = null + + QDEL_LIST(output_ports) + QDEL_LIST(input_ports) + return ..() + +/** + * Called when a shell is registered from the component/the component is added to a circuit. + * + * Register all signals here on the shell. + * Arguments: + * * shell - Shell being registered + */ +/obj/item/circuit_component/proc/register_shell(atom/movable/shell) + return + +/** + * Called when a shell is unregistered from the component/the component is removed from a circuit. + * + * Unregister all signals here on the shell. + * Arguments: + * * shell - Shell being unregistered + */ +/obj/item/circuit_component/proc/unregister_shell(atom/movable/shell) + return + +/** + * Disconnects a component from other components + * + * Disconnects both the input and output ports of the component + */ +/obj/item/circuit_component/proc/disconnect() + for(var/datum/port/output/port_to_disconnect as anything in output_ports) + port_to_disconnect.disconnect() + + for(var/datum/port/input/port_to_disconnect as anything in input_ports) + port_to_disconnect.disconnect() + +/** + * Sets the option on this component + * + * Can only be a value from the options variable + * Arguments: + * * option - The option that has been switched to. + */ +/obj/item/circuit_component/proc/set_option(option) + current_option = option + input_received() + +/** + * Matches the output port's datatype with the input port's current connected port. + * + * Returns true if datatype was changed, otherwise returns false. + * Arguments: + * * input_port - The input port to check the connected port from. + * * output_port - The output port to convert. Warning, this does change the output port. + */ +/obj/item/circuit_component/proc/match_port_datatype(datum/port/input/input_port, datum/port/output/output_port) + if(input_port.connected_port) + var/datum/port/connected_port = input_port.connected_port + if(connected_port.datatype != output_port.datatype) + output_port.set_datatype(connected_port.datatype) + return TRUE + return FALSE + + +/** + * Adds an input port and returns it + * + * Arguments: + * * name - The name of the input port + * * type - The datatype it handles + * * trigger - Whether this input port triggers an update on the component when updated. + */ +/obj/item/circuit_component/proc/add_input_port(name, type, trigger = TRUE, default = null) + var/datum/port/input/input_port = new(src, name, type, trigger, default) + input_ports += input_port + return input_port + + +/** + * Adds an output port and returns it + * + * Arguments: + * * name - The name of the output port + * * type - The datatype it handles. + */ +/obj/item/circuit_component/proc/add_output_port(name, type) + var/datum/port/output/output_port = new(src, name, type) + output_ports += output_port + return output_port + +/** + * Called whenever an input is received from one of the ports. + * + * Return value indicates that the circuit should not do anything + * Arguments: + * * port - Can be null. The port that sent the input + */ +/obj/item/circuit_component/proc/input_received(datum/port/input/port) + SHOULD_CALL_PARENT(TRUE) + if(!parent?.on) + return TRUE + + var/obj/item/stock_parts/cell/cell = parent.get_cell() + if(!cell?.use(power_usage_per_input)) + return TRUE + + if(has_trigger && !COMPONENT_TRIGGERED_BY(trigger_input, port)) + return TRUE diff --git a/code/modules/wiremod/component_printer.dm b/code/modules/wiremod/component_printer.dm new file mode 100644 index 00000000000..b04d5c70592 --- /dev/null +++ b/code/modules/wiremod/component_printer.dm @@ -0,0 +1,134 @@ +/// Component printer, creates components for integrated circuits. +/obj/machinery/component_printer + name = "component printer" + desc = "Produces components for the creation of integrated circuits." + icon = 'icons/obj/wiremod_fab.dmi' + icon_state = "fab-idle" + circuit = /obj/item/circuitboard/machine/component_printer + + /// The internal material bus + var/datum/component/remote_materials/materials + + density = TRUE + + /// The techweb the printer will get researched designs from + var/datum/techweb/techweb + +/obj/machinery/component_printer/Initialize(mapload) + . = ..() + + techweb = SSresearch.science_tech + + materials = AddComponent( \ + /datum/component/remote_materials, \ + "component_printer", \ + mapload, \ + mat_container_flags = BREAKDOWN_FLAGS_LATHE, \ + ) + +/obj/machinery/component_printer/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ComponentPrinter", name) + ui.open() + +/obj/machinery/component_printer/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/sheetmaterials) + ) + +/obj/machinery/component_printer/ui_act(action, list/params) + . = ..() + if (.) + return + + switch (action) + if ("print") + var/design_id = params["designId"] + if (!techweb.researched_designs[design_id]) + return TRUE + + var/datum/design/design = SSresearch.techweb_design_by_id(design_id) + if (!(design.build_type & COMPONENT_PRINTER)) + return TRUE + + if (materials.on_hold()) + say("Mineral access is on hold, please contact the quartermaster.") + return TRUE + + if (!materials.mat_container?.has_materials(design.materials)) + say("Not enough materials.") + return TRUE + + balloon_alert_to_viewers("printed [design.name]") + materials.mat_container?.use_materials(design.materials) + materials.silo_log(src, "printed", -1, design.name, design.materials) + var/atom/printed_design = new design.build_path(drop_location()) + printed_design.pixel_x = printed_design.base_pixel_x + rand(-5, 5) + printed_design.pixel_y = printed_design.base_pixel_y + rand(-5, 5) + if ("remove_mat") + var/datum/material/material = locate(params["ref"]) + var/amount = text2num(params["amount"]) + + if (!amount) + return TRUE + + // SAFETY: eject_sheets checks for valid mats + materials.eject_sheets(material, amount) + + return TRUE + +/obj/machinery/component_printer/ui_data(mob/user) + var/list/data = list() + data["materials"] = materials.mat_container.ui_data() + return data + +/obj/machinery/component_printer/ui_static_data(mob/user) + var/list/data = list() + + var/list/designs = list() + + // for (var/datum/design/component/component_design_type as anything in subtypesof(/datum/design/component)) + for (var/researched_design_id in techweb.researched_designs) + var/datum/design/design = SSresearch.techweb_design_by_id(researched_design_id) + if (!(design.build_type & COMPONENT_PRINTER)) + continue + + designs[researched_design_id] = list( + "name" = design.name, + "description" = design.desc, + "materials" = get_material_cost_data(design.materials), + "categories" = design.category, + ) + + data["designs"] = designs + + return data + +/obj/machinery/component_printer/crowbar_act(mob/living/user, obj/item/tool) + if(..()) + return TRUE + return default_deconstruction_crowbar(tool) + +/obj/machinery/component_printer/screwdriver_act(mob/living/user, obj/item/tool) + if(..()) + return TRUE + return default_deconstruction_screwdriver(user, "fab-o", "fab-idle", tool) + +/obj/machinery/component_printer/proc/get_material_cost_data(list/materials) + var/list/data = list() + + for (var/datum/material/material_type as anything in materials) + data[initial(material_type.name)] = materials[material_type] + + return data + +/obj/item/circuitboard/machine/component_printer + name = "\improper Component Printer (Machine Board)" + greyscale_colors = CIRCUIT_COLOR_SCIENCE + build_path = /obj/machinery/component_printer + req_components = list( + /obj/item/stock_parts/matter_bin = 2, + /obj/item/stock_parts/manipulator = 2, + /obj/item/reagent_containers/glass/beaker = 2, + ) diff --git a/code/modules/wiremod/components/abstract/compare.dm b/code/modules/wiremod/components/abstract/compare.dm new file mode 100644 index 00000000000..c5fff8aa6ad --- /dev/null +++ b/code/modules/wiremod/components/abstract/compare.dm @@ -0,0 +1,67 @@ +/** + * # Compare Component + * + * Abstract component to build conditional components + */ +/obj/item/circuit_component/compare + display_name = "Compare" + + /// The amount of input ports to have + var/input_port_amount = 4 + + /// The trigger for the true/false signals + var/datum/port/input/compare + + /// Signals sent on compare + var/datum/port/output/true + var/datum/port/output/false + + /// The result from the output + var/datum/port/output/result + +/obj/item/circuit_component/compare/Initialize() + . = ..() + for(var/port_id in 1 to input_port_amount) + var/letter = ascii2text(text2ascii("A") + (port_id-1)) + add_input_port(letter, PORT_TYPE_ANY) + + load_custom_ports() + compare = add_input_port("Compare", PORT_TYPE_SIGNAL) + + true = add_output_port("True", PORT_TYPE_SIGNAL) + false = add_output_port("False", PORT_TYPE_SIGNAL) + result = add_output_port("Result", PORT_TYPE_NUMBER) + +/** + * Used by derivatives to load their own ports in for custom use. + */ +/obj/item/circuit_component/compare/proc/load_custom_ports() + return + +/obj/item/circuit_component/compare/Destroy() + true = null + false = null + result = null + compare = null + return ..() + +/obj/item/circuit_component/compare/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/list/ports = input_ports.Copy() + if(input_port_amount) + ports.Cut(input_port_amount+1) + + var/logic_result = do_comparisons(ports) + if(COMPONENT_TRIGGERED_BY(compare, port)) + if(logic_result) + true.set_output(COMPONENT_SIGNAL) + else + false.set_output(COMPONENT_SIGNAL) + result.set_output(logic_result) + +/// Do the comparisons and return a result +/obj/item/circuit_component/compare/proc/do_comparisons(list/ports) + return FALSE diff --git a/code/modules/wiremod/components/arithmetic.dm b/code/modules/wiremod/components/arithmetic.dm new file mode 100644 index 00000000000..75a574dc92c --- /dev/null +++ b/code/modules/wiremod/components/arithmetic.dm @@ -0,0 +1,75 @@ +/** + * # Arithmetic Component + * + * General arithmetic unit with add/sub/mult/divide capabilities + * This one only works with numbers. + */ +/obj/item/circuit_component/arithmetic + display_name = "Arithmetic" + + /// The amount of input ports to have + var/input_port_amount = 4 + + /// The result from the output + var/datum/port/output/output + + has_trigger = TRUE + +GLOBAL_LIST_INIT(comp_arithmetic_options, list( + COMP_ARITHMETIC_ADD, + COMP_ARITHMETIC_SUBTRACT, + COMP_ARITHMETIC_MULTIPLY, + COMP_ARITHMETIC_DIVIDE, + COMP_ARITHMETIC_MIN, + COMP_ARITHMETIC_MAX, +)) + +/obj/item/circuit_component/arithmetic/Initialize() + options = GLOB.comp_arithmetic_options + . = ..() + for(var/port_id in 1 to input_port_amount) + var/letter = ascii2text(text2ascii("A") + (port_id-1)) + add_input_port(letter, PORT_TYPE_NUMBER) + + output = add_output_port("Output", PORT_TYPE_NUMBER) + +/obj/item/circuit_component/arithmetic/Destroy() + output = null + return ..() + +/obj/item/circuit_component/arithmetic/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/list/ports = input_ports.Copy() + var/datum/port/input/first_port = ports[1] + ports -= first_port + ports -= trigger_input + var/result = first_port.input_value + + for(var/datum/port/input/input_port as anything in ports) + var/value = input_port.input_value + if(isnull(value)) + continue + + switch(current_option) + if(COMP_ARITHMETIC_ADD) + result += value + if(COMP_ARITHMETIC_SUBTRACT) + result -= value + if(COMP_ARITHMETIC_MULTIPLY) + result *= value + if(COMP_ARITHMETIC_DIVIDE) + // Protect from div by zero errors. + if(value == 0) + result = null + break + result /= value + if(COMP_ARITHMETIC_MAX) + result = max(result, value) + if(COMP_ARITHMETIC_MIN) + result = min(result, value) + + output.set_output(result) + trigger_output.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/components/clock.dm b/code/modules/wiremod/components/clock.dm new file mode 100644 index 00000000000..9fe6c5699e7 --- /dev/null +++ b/code/modules/wiremod/components/clock.dm @@ -0,0 +1,54 @@ +/** + * # Clock Component + * + * Fires every tick of the circuit timer SS + */ +/obj/item/circuit_component/clock + display_name = "Clock" + + /// Whether the clock is on or not + var/datum/port/input/on + + /// The signal from this clock component + var/datum/port/output/signal + +/obj/item/circuit_component/clock/Initialize() + . = ..() + on = add_input_port("On", PORT_TYPE_NUMBER) + + signal = add_output_port("Signal", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/clock/input_received(datum/port/input/port) + . = ..() + if(.) + return + + if(on.input_value) + start_process() + else + stop_process() + +/obj/item/circuit_component/clock/Destroy() + on = null + signal = null + stop_process() + return ..() + +/obj/item/circuit_component/clock/process(delta_time) + signal.set_output(COMPONENT_SIGNAL) + +/** + * Adds the component to the SSclock_component process list + * + * Starts ticking to send signals between periods of time + */ +/obj/item/circuit_component/clock/proc/start_process() + START_PROCESSING(SSclock_component, src) + +/** + * Removes the component to the SSclock_component process list + * + * Signals stop getting sent. + */ +/obj/item/circuit_component/clock/proc/stop_process() + STOP_PROCESSING(SSclock_component, src) diff --git a/code/modules/wiremod/components/comparison.dm b/code/modules/wiremod/components/comparison.dm new file mode 100644 index 00000000000..2d3ef3be516 --- /dev/null +++ b/code/modules/wiremod/components/comparison.dm @@ -0,0 +1,44 @@ +/** + * # Comparison Component + * + * Compares two objects + */ +/obj/item/circuit_component/compare/comparison + display_name = "Comparison" + + input_port_amount = 2 + +GLOBAL_LIST_INIT(comp_comparison_options, list( + COMP_COMPARISON_EQUAL, + COMP_COMPARISON_NOT_EQUAL, + COMP_COMPARISON_GREATER_THAN, + COMP_COMPARISON_LESS_THAN, + COMP_COMPARISON_GREATER_THAN_OR_EQUAL, + COMP_COMPARISON_LESS_THAN_OR_EQUAL +)) + +/obj/item/circuit_component/compare/comparison/Initialize() + options = GLOB.comp_comparison_options + return ..() + +/obj/item/circuit_component/compare/comparison/do_comparisons(list/ports) + if(length(ports) < input_port_amount) + return FALSE + + // Comparison component only compares the first two ports + var/input1 = input_ports[1].input_value + var/input2 = input_ports[2].input_value + + switch(current_option) + if(COMP_COMPARISON_EQUAL) + return input1 == input2 + if(COMP_COMPARISON_NOT_EQUAL) + return input1 != input2 + if(COMP_COMPARISON_GREATER_THAN) + return input1 > input2 + if(COMP_COMPARISON_GREATER_THAN_OR_EQUAL) + return input1 >= input2 + if(COMP_COMPARISON_LESS_THAN) + return input1 < input2 + if(COMP_COMPARISON_LESS_THAN_OR_EQUAL) + return input1 <= input2 diff --git a/code/modules/wiremod/components/concat.dm b/code/modules/wiremod/components/concat.dm new file mode 100644 index 00000000000..cd073cc7cea --- /dev/null +++ b/code/modules/wiremod/components/concat.dm @@ -0,0 +1,45 @@ +/** + * # Concatenate Component + * + * General string concatenation component. Puts strings together. + */ +/obj/item/circuit_component/concat + display_name = "Concatenate" + + /// The amount of input ports to have + var/input_port_amount = 4 + + /// The result from the output + var/datum/port/output/output + has_trigger = TRUE + +/obj/item/circuit_component/concat/Initialize() + . = ..() + for(var/port_id in 1 to input_port_amount) + var/letter = ascii2text(text2ascii("A") + (port_id-1)) + add_input_port(letter, PORT_TYPE_STRING) + + output = add_output_port("Output", PORT_TYPE_STRING) + +/obj/item/circuit_component/concat/Destroy() + output = null + return ..() + +/obj/item/circuit_component/concat/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/result = "" + var/list/ports = input_ports.Copy() + ports -= trigger_input + + for(var/datum/port/input/input_port as anything in ports) + var/value = input_port.input_value + if(isnull(value)) + continue + + result += "[value]" + + output.set_output(result) + trigger_output.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/components/contains.dm b/code/modules/wiremod/components/contains.dm new file mode 100644 index 00000000000..3f5c34e595a --- /dev/null +++ b/code/modules/wiremod/components/contains.dm @@ -0,0 +1,34 @@ +/** + * # String Contains Component + * + * Checks if a string contains a word/letter + */ +/obj/item/circuit_component/compare/contains + display_name = "String Contains" + + input_port_amount = 0 + + var/datum/port/input/needle + var/datum/port/input/haystack + +/obj/item/circuit_component/compare/contains/load_custom_ports() + needle = add_input_port("Needle", PORT_TYPE_STRING) + haystack = add_input_port("Haystack", PORT_TYPE_STRING) + +/obj/item/circuit_component/compare/contains/Destroy() + needle = null + haystack = null + return ..() + + +/obj/item/circuit_component/compare/contains/do_comparisons(list/ports) + if(length(ports) < input_port_amount) + return + + var/to_find = needle.input_value + var/to_search = haystack.input_value + + if(!to_find || !to_search) + return + + return findtext(to_search, to_find) diff --git a/code/modules/wiremod/components/delay.dm b/code/modules/wiremod/components/delay.dm new file mode 100644 index 00000000000..ff659162d2a --- /dev/null +++ b/code/modules/wiremod/components/delay.dm @@ -0,0 +1,43 @@ +/** + * # Delay Component + * + * Delays a signal by a specified duration. + */ +/obj/item/circuit_component/delay + display_name = "Delay" + + /// Amount to delay by + var/datum/port/input/delay_amount + /// Input signal to fire the delay + var/datum/port/input/trigger + + /// The output of the signal + var/datum/port/output/output + +/obj/item/circuit_component/delay/Initialize() + . = ..() + delay_amount = add_input_port("Delay", PORT_TYPE_NUMBER, FALSE) + trigger = add_input_port("Trigger", PORT_TYPE_SIGNAL) + + output = add_output_port("Result", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/delay/Destroy() + output = null + trigger = null + delay_amount = null + return ..() + +/obj/item/circuit_component/delay/input_received(datum/port/input/port) + . = ..() + if(.) + return + + if(!COMPONENT_TRIGGERED_BY(trigger, port)) + return + + var/delay = delay_amount.input_value + if(delay > COMP_DELAY_MIN_VALUE) + // Convert delay into deciseconds + addtimer(CALLBACK(output, /datum/port/output.proc/set_output, trigger.input_value), delay*10, timer_subsystem =SScircuit_component) + else + output.set_output(trigger.input_value) diff --git a/code/modules/wiremod/components/dummy.dm b/code/modules/wiremod/components/dummy.dm new file mode 100644 index 00000000000..58f63ef2776 --- /dev/null +++ b/code/modules/wiremod/components/dummy.dm @@ -0,0 +1,33 @@ +/** + * # Dummy Component + * + * Dummy component that does nothing, only for debugging purposes + * + * Has two input and output ports that do nothing + */ +/obj/item/circuit_component/dummy + display_name = "Dummy Component" + + /// The input ports of the dummy component + var/datum/port/input/receive1 + var/datum/port/input/receive2 + + /// The output ports of the dummy component + var/datum/port/output/output1 + var/datum/port/output/output2 + +/obj/item/circuit_component/dummy/Initialize() + . = ..() + receive1 = add_input_port("Receive 1", PORT_TYPE_ANY) + receive2 = add_input_port("Receive 2", PORT_TYPE_ANY) + + output1 = add_output_port("Output 1", PORT_TYPE_NUMBER) + output2 = add_output_port("Output 2", PORT_TYPE_NUMBER) + +/obj/item/circuit_component/dummy/Destroy() + // Cleaned up in parent proc + receive1 = null + receive2 = null + output1 = null + output2 = null + return ..() diff --git a/code/modules/wiremod/components/hear.dm b/code/modules/wiremod/components/hear.dm new file mode 100644 index 00000000000..92dad54c4ce --- /dev/null +++ b/code/modules/wiremod/components/hear.dm @@ -0,0 +1,43 @@ +/** + * # Hear Component + * + * Listens for messages. Requires a shell. + */ +/obj/item/circuit_component/hear + display_name = "Voice Activator" + + flags_1 = HEAR_1 + + /// The message heard + var/datum/port/output/message_port + /// The language heard + var/datum/port/output/language_port + /// The speaker + var/datum/port/output/speaker_port + /// The trigger sent when this event occurs + var/datum/port/output/trigger_port + +/obj/item/circuit_component/hear/Initialize() + . = ..() + message_port = add_output_port("Message", PORT_TYPE_STRING) + language_port = add_output_port("Language", PORT_TYPE_STRING) + speaker_port = add_output_port("Speaker", PORT_TYPE_ATOM) + trigger_port = add_output_port("Triggered", PORT_TYPE_SIGNAL) + + +/obj/item/circuit_component/hear/Destroy() + message_port = null + language_port = null + speaker_port = null + trigger_port = null + return ..() + +/obj/item/circuit_component/hear/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, list/message_mods) + if(speaker == parent?.shell) + return + + message_port.set_output(raw_message) + if(message_language) + language_port.set_output(initial(message_language.name)) + speaker_port.set_output(speaker) + trigger_port.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/components/index.dm b/code/modules/wiremod/components/index.dm new file mode 100644 index 00000000000..cc1d69e612e --- /dev/null +++ b/code/modules/wiremod/components/index.dm @@ -0,0 +1,47 @@ +/** + * # Index Component + * + * Return the index of a list + */ +/obj/item/circuit_component/index + display_name = "Index List" + + /// The input port + var/datum/port/input/list_port + var/datum/port/input/index_port + + /// The result from the output + var/datum/port/output/output + has_trigger = TRUE + +/obj/item/circuit_component/index/Initialize() + . = ..() + index_port = add_input_port("Index", PORT_TYPE_ANY) + list_port = add_input_port("List", PORT_TYPE_LIST) + + output = add_output_port("Value", PORT_TYPE_ANY) + +/obj/item/circuit_component/index/Destroy() + list_port = null + index_port = null + output = null + return ..() + +/obj/item/circuit_component/index/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/index = index_port.input_value + var/list/list_input = list_port.input_value + + if(!islist(list_input) || !index) + output.set_output(null) + return + + if(isnum(index) && (index < 1 || index > length(list_input))) + output.set_output(null) + return + + output.set_output(list_input[index]) + trigger_output.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/components/length.dm b/code/modules/wiremod/components/length.dm new file mode 100644 index 00000000000..9a52fe5d542 --- /dev/null +++ b/code/modules/wiremod/components/length.dm @@ -0,0 +1,33 @@ +/** + * # Length Component + * + * Return the length of an input + */ +/obj/item/circuit_component/length + display_name = "Length" + + /// The input port + var/datum/port/input/input_port + + /// The result from the output + var/datum/port/output/output + has_trigger = TRUE + +/obj/item/circuit_component/length/Initialize() + . = ..() + input_port = add_input_port("Input", PORT_TYPE_ANY) + + output = add_output_port("Length", PORT_TYPE_NUMBER) + +/obj/item/circuit_component/length/Destroy() + input_port = null + output = null + return ..() + +/obj/item/circuit_component/length/input_received(datum/port/input/port) + . = ..() + if(.) + return + + output.set_output(length(input_port.input_value)) + trigger_output.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/components/light.dm b/code/modules/wiremod/components/light.dm new file mode 100644 index 00000000000..49384636968 --- /dev/null +++ b/code/modules/wiremod/components/light.dm @@ -0,0 +1,72 @@ +/** + * # Light Component + * + * Emits a light of a specific brightness and colour. Requires a shell. + */ +/obj/item/circuit_component/light + display_name = "Light" + + /// The colours of the light + var/datum/port/input/red + var/datum/port/input/green + var/datum/port/input/blue + + /// The brightness + var/datum/port/input/brightness + + /// Whether the light is on or not + var/datum/port/input/on + + var/max_power = 5 + var/min_lightness = 0.4 + var/shell_light_color + +/obj/item/circuit_component/light/Initialize() + . = ..() + red = add_input_port("Red", PORT_TYPE_NUMBER) + green = add_input_port("Green", PORT_TYPE_NUMBER) + blue = add_input_port("Blue", PORT_TYPE_NUMBER) + brightness = add_input_port("Brightness", PORT_TYPE_NUMBER) + + on = add_input_port("On", PORT_TYPE_NUMBER) + + +/obj/item/circuit_component/light/Destroy() + red = null + green = null + blue = null + brightness = null + on = null + return ..() + +/obj/item/circuit_component/light/register_shell(atom/movable/shell) + . = ..() + input_received() + +/obj/item/circuit_component/light/unregister_shell(atom/movable/shell) + shell.set_light_on(FALSE) + return ..() + +/obj/item/circuit_component/light/input_received(datum/port/input/port) + . = ..() + brightness.set_input(min(max(brightness.input_value || 0, 0), max_power), FALSE) + red.set_input(min(max(red.input_value, 0), 255), FALSE) + blue.set_input(min(max(blue.input_value, 0), 255), FALSE) + green.set_input(min(max(green.input_value, 0), 255), FALSE) + var/list/hsl = rgb2hsl(red.input_value || 0, green.input_value || 0, blue.input_value || 0) + var/list/light_col = hsl2rgb(hsl[1], hsl[2], max(min_lightness, hsl[3])) + shell_light_color = rgb(light_col[1], light_col[2], light_col[3]) + if(.) + return + + if(parent.shell) + set_atom_light(parent.shell) + +/obj/item/circuit_component/light/proc/set_atom_light(atom/movable/target_atom) + // Clamp anyways just for safety + var/bright_val = min(max(brightness.input_value || 0, 0), max_power) + + target_atom.set_light_power(bright_val) + target_atom.set_light_range(bright_val) + target_atom.set_light_color(shell_light_color) + target_atom.set_light_on(!!on.input_value) diff --git a/code/modules/wiremod/components/logic.dm b/code/modules/wiremod/components/logic.dm new file mode 100644 index 00000000000..02a37194279 --- /dev/null +++ b/code/modules/wiremod/components/logic.dm @@ -0,0 +1,47 @@ +/** + * # Logic Component + * + * General logic unit with AND OR capabilities + */ +/obj/item/circuit_component/compare/logic + display_name = "Logic" + + +GLOBAL_LIST_INIT(comp_logic_options, list( + COMP_LOGIC_AND, + COMP_LOGIC_OR, + COMP_LOGIC_XOR +)) + +/obj/item/circuit_component/compare/logic/Initialize() + options = GLOB.comp_logic_options + return ..() + +/obj/item/circuit_component/compare/logic/do_comparisons(list/ports) + . = FALSE + // Used by XOR + var/total_ports = 0 + var/total_true_ports = 0 + for(var/datum/port/input/port as anything in ports) + if(isnull(port.input_value)) + continue + + total_ports += 1 + switch(current_option) + if(COMP_LOGIC_AND) + if(!port.input_value) + return FALSE + . = TRUE + if(COMP_LOGIC_OR) + if(port.input_value) + return TRUE + if(COMP_LOGIC_XOR) + if(port.input_value) + . = TRUE + total_true_ports += 1 + + if(current_option == COMP_LOGIC_XOR) + if(total_ports == total_true_ports) + return FALSE + if(.) + return TRUE diff --git a/code/modules/wiremod/components/not.dm b/code/modules/wiremod/components/not.dm new file mode 100644 index 00000000000..c70c1966879 --- /dev/null +++ b/code/modules/wiremod/components/not.dm @@ -0,0 +1,33 @@ +/** + * # Logic Component + * + * General logic unit with AND OR capabilities + */ +/obj/item/circuit_component/not + display_name = "Not" + + /// The input port + var/datum/port/input/input_port + + /// The result from the output + var/datum/port/output/result + has_trigger = TRUE + +/obj/item/circuit_component/not/Initialize() + . = ..() + input_port = add_input_port("Input", PORT_TYPE_ANY) + + result = add_output_port("Result", PORT_TYPE_NUMBER) + +/obj/item/circuit_component/not/Destroy() + input_port = null + result = null + return ..() + +/obj/item/circuit_component/not/input_received(datum/port/input/port) + . = ..() + if(.) + return + + result.set_output(!input_port.input_value) + trigger_output.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/components/radio.dm b/code/modules/wiremod/components/radio.dm new file mode 100644 index 00000000000..f20b1458c2d --- /dev/null +++ b/code/modules/wiremod/components/radio.dm @@ -0,0 +1,57 @@ +/** + * # Radio Component + * + * Listens out for signals on the designated frequencies and + */ +/obj/item/circuit_component/radio + display_name = "Radio" + + /// Frequency input + var/datum/port/input/freq + /// Signal input + var/datum/port/input/code + + /// Current frequency value + var/current_freq = DEFAULT_SIGNALER_CODE + + var/datum/radio_frequency/radio_connection + +/obj/item/circuit_component/radio/Initialize() + . = ..() + freq = add_input_port("Frequency", PORT_TYPE_NUMBER, default = FREQ_SIGNALER) + code = add_input_port("Code", PORT_TYPE_NUMBER, default = DEFAULT_SIGNALER_CODE) + trigger_input = add_input_port("Send", PORT_TYPE_SIGNAL) + trigger_output = add_output_port("Received", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/radio/Destroy() + freq = null + code = null + trigger_input = null + trigger_output = null + SSradio.remove_object(src, current_freq) + radio_connection = null + return ..() + +/obj/item/circuit_component/radio/input_received(datum/port/input/port) + . = ..() + freq.set_input(sanitize_frequency(freq.input_value, TRUE), FALSE) + if(.) + return + var/frequency = freq.input_value + + SSradio.remove_object(src, current_freq) + radio_connection = SSradio.add_object(src, frequency, RADIO_SIGNALER) + current_freq = frequency + + if(COMPONENT_TRIGGERED_BY(trigger_input, port)) + var/datum/signal/signal = new(list("code" = round(code.input_value) || 0)) + radio_connection.post_signal(src, signal) + +/obj/item/circuit_component/radio/receive_signal(datum/signal/signal) + . = FALSE + if(!signal) + return + if(signal.data["code"] != round(code.input_value || 0)) + return + + trigger_output.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/components/ram.dm b/code/modules/wiremod/components/ram.dm new file mode 100644 index 00000000000..194f4474e54 --- /dev/null +++ b/code/modules/wiremod/components/ram.dm @@ -0,0 +1,51 @@ +/** + * # RAM Component + * + * Stores the current input when triggered. + * Players will need to think logically when using the RAM component + * as there can be race conditions due to the delays of transferring signals + */ +/obj/item/circuit_component/ram + display_name = "RAM" + + /// The input to store + var/datum/port/input/input_port + /// The trigger to store the current value of the input + var/datum/port/input/trigger + /// Clears the current input + var/datum/port/input/clear + + /// The current set value + var/datum/port/output/output + +/obj/item/circuit_component/ram/Initialize() + . = ..() + input_port = add_input_port("Input", PORT_TYPE_ANY) + trigger = add_input_port("Store", PORT_TYPE_SIGNAL) + clear = add_input_port("Clear", PORT_TYPE_SIGNAL) + + output = add_output_port("Stored Value", PORT_TYPE_ANY) + +/obj/item/circuit_component/ram/Destroy() + input_port = null + trigger = null + clear = null + output = null + return ..() + +/obj/item/circuit_component/ram/input_received(datum/port/input/port) + . = ..() + match_port_datatype(input_port, output) + if(.) + return + + if(COMPONENT_TRIGGERED_BY(clear, port)) + output.set_output(null) + return + + if(!COMPONENT_TRIGGERED_BY(trigger, port)) + return + + var/input_val = input_port.input_value + + output.set_output(input_val) diff --git a/code/modules/wiremod/components/random.dm b/code/modules/wiremod/components/random.dm new file mode 100644 index 00000000000..4c1cf149b5f --- /dev/null +++ b/code/modules/wiremod/components/random.dm @@ -0,0 +1,45 @@ +/** + * # Random Component + * + * Generates a random number between specific values + */ +/obj/item/circuit_component/random + display_name = "Random" + + /// The minimum value that the random number can be + var/datum/port/input/minimum + /// The maximum value that the random number can be + var/datum/port/input/maximum + + has_trigger = TRUE + + /// The result from the output + var/datum/port/output/output + +/obj/item/circuit_component/random/Initialize() + . = ..() + minimum = add_input_port("Minimum", PORT_TYPE_NUMBER, FALSE) + maximum = add_input_port("Maximum", PORT_TYPE_NUMBER, FALSE) + + output = add_output_port("Output", PORT_TYPE_NUMBER) + +/obj/item/circuit_component/random/Destroy() + minimum = null + maximum = null + output = null + return ..() + +/obj/item/circuit_component/random/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/min_val = minimum.input_value || 0 + var/max_val = maximum.input_value || 0 + + if(max_val < min_val) + output.set_output(0) + return + + output.set_output(rand(min_val, max_val)) + trigger_output.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/components/self.dm b/code/modules/wiremod/components/self.dm new file mode 100644 index 00000000000..fdd69567da7 --- /dev/null +++ b/code/modules/wiremod/components/self.dm @@ -0,0 +1,24 @@ +/** + * # Self Component + * + * Return the current shell. + */ +/obj/item/circuit_component/self + display_name = "Self" + + /// The shell this component is attached to. + var/datum/port/output/output + +/obj/item/circuit_component/self/Initialize() + . = ..() + output = add_output_port("Self", PORT_TYPE_ATOM) + +/obj/item/circuit_component/self/Destroy() + output = null + return ..() + +/obj/item/circuit_component/self/register_shell(atom/movable/shell) + output.set_output(shell) + +/obj/item/circuit_component/self/unregister_shell(atom/movable/shell) + output.set_output(null) diff --git a/code/modules/wiremod/components/species.dm b/code/modules/wiremod/components/species.dm new file mode 100644 index 00000000000..5799f0580c6 --- /dev/null +++ b/code/modules/wiremod/components/species.dm @@ -0,0 +1,39 @@ +/** + * # Get Species Component + * + * Return the species of a mob + */ +/obj/item/circuit_component/species + display_name = "Get Species" + + /// The input port + var/datum/port/input/input_port + + /// The result from the output + var/datum/port/output/output + + has_trigger = TRUE + +/obj/item/circuit_component/species/Initialize() + . = ..() + input_port = add_input_port("Organism", PORT_TYPE_ATOM) + + output = add_output_port("Species", PORT_TYPE_STRING) + +/obj/item/circuit_component/species/Destroy() + input_port = null + output = null + return ..() + +/obj/item/circuit_component/species/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/mob/living/carbon/human/human = input_port.input_value + if(!istype(human) || !human.has_dna()) + output.set_output(null) + return + + output.set_output(human.dna.species.name) + trigger_output.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/components/speech.dm b/code/modules/wiremod/components/speech.dm new file mode 100644 index 00000000000..aafbbfdd1e0 --- /dev/null +++ b/code/modules/wiremod/components/speech.dm @@ -0,0 +1,49 @@ +/** + * # Speech Component + * + * Sends a message. Requires a shell. + */ +/obj/item/circuit_component/speech + display_name = "Speech" + + /// The message to send + var/datum/port/input/message + /// The trigger to send the message + var/datum/port/input/trigger + + /// The cooldown for this component of how often it can send speech messages. + var/speech_cooldown = 1 SECONDS + + COOLDOWN_DECLARE(next_speech) + +/obj/item/circuit_component/speech/Initialize() + . = ..() + message = add_input_port("Message", PORT_TYPE_STRING, FALSE) + + trigger = add_input_port("Trigger", PORT_TYPE_SIGNAL) + + +/obj/item/circuit_component/speech/Destroy() + message = null + trigger = null + return ..() + +/obj/item/circuit_component/speech/input_received(datum/port/input/port) + . = ..() + if(.) + return + + if(!COMPONENT_TRIGGERED_BY(trigger, port)) + return + + if(!COOLDOWN_FINISHED(src, next_speech)) + return + + if(message.input_value) + var/atom/movable/shell = parent.shell + // Prevents appear as the individual component if there is a shell. + if(shell) + shell.say(message.input_value) + else + say(message.input_value) + COOLDOWN_START(src, next_speech, speech_cooldown) diff --git a/code/modules/wiremod/components/textcase.dm b/code/modules/wiremod/components/textcase.dm new file mode 100644 index 00000000000..1963455fc8e --- /dev/null +++ b/code/modules/wiremod/components/textcase.dm @@ -0,0 +1,50 @@ +/** + * # Text Component + * + * Either makes the text upper case or lower case. + */ +/obj/item/circuit_component/textcase + display_name = "Text Case" + + /// The input port + var/datum/port/input/input_port + + /// The result of the text operation + var/datum/port/output/output + + has_trigger = TRUE + +GLOBAL_LIST_INIT(comp_text_operations, list( + COMP_TEXT_LOWER, + COMP_TEXT_UPPER +)) + +/obj/item/circuit_component/textcase/Initialize() + options = GLOB.comp_text_operations + . = ..() + input_port = add_input_port("Input", PORT_TYPE_STRING) + output = add_output_port("Output", PORT_TYPE_STRING) + +/obj/item/circuit_component/textcase/Destroy() + input_port = null + output = null + return ..() + +/obj/item/circuit_component/textcase/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/value = input_port.input_value + if(isnull(value)) + return + + var/result + switch(current_option) + if(COMP_TEXT_LOWER) + result = lowertext(value) + if(COMP_TEXT_UPPER) + result = uppertext(value) + + output.set_output(result) + trigger_output.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/components/tostring.dm b/code/modules/wiremod/components/tostring.dm new file mode 100644 index 00000000000..d37a4827167 --- /dev/null +++ b/code/modules/wiremod/components/tostring.dm @@ -0,0 +1,44 @@ +/** + * # To String Component + * + * Converts any value into a string + */ +/obj/item/circuit_component/tostring + display_name = "To String" + + /// The input port + var/datum/port/input/input_port + + /// The result from the output + var/datum/port/output/output + + has_trigger = TRUE + + var/min_range = 5 + +/obj/item/circuit_component/tostring/Initialize() + . = ..() + input_port = add_input_port("Input", PORT_TYPE_ANY) + + output = add_output_port("Output", PORT_TYPE_STRING) + +/obj/item/circuit_component/tostring/Destroy() + input_port = null + output = null + return ..() + +/obj/item/circuit_component/tostring/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/input_value = input_port.input_value + if(isatom(input_value)) + var/turf/location = get_turf(src) + var/atom/object = input_value + if(object.z != location.z || get_dist(location, object) > min_range) + output.set_output(PORT_TYPE_ATOM) + return + + output.set_output("[input_value]") + trigger_output.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/components/typecheck.dm b/code/modules/wiremod/components/typecheck.dm new file mode 100644 index 00000000000..cf8cf8270e9 --- /dev/null +++ b/code/modules/wiremod/components/typecheck.dm @@ -0,0 +1,48 @@ +/** + * # Typecheck Component + * + * Checks the type of a value + */ +/obj/item/circuit_component/compare/typecheck + display_name = "Typecheck" + + input_port_amount = 1 + + has_trigger = TRUE + + +GLOBAL_LIST_INIT(comp_typecheck_options, list( + PORT_TYPE_STRING, + PORT_TYPE_NUMBER, + PORT_TYPE_LIST, + PORT_TYPE_ATOM, + COMP_TYPECHECK_MOB, + COMP_TYPECHECK_HUMAN, +)) + +/obj/item/circuit_component/compare/typecheck/Initialize() + options = GLOB.comp_typecheck_options + return ..() + +/obj/item/circuit_component/compare/typecheck/do_comparisons(list/ports) + if(!length(ports)) + return + . = FALSE + + // We're only comparing the first port/value. There shouldn't be any more. + var/datum/port/input/input_port = ports[1] + var/input_val = input_port.input_value + switch(current_option) + if(PORT_TYPE_STRING) + return istext(input_val) + if(PORT_TYPE_NUMBER) + return isnum(input_val) + if(PORT_TYPE_LIST) + return islist(input_val) + if(PORT_TYPE_ATOM) + return isatom(input_val) + if(COMP_TYPECHECK_MOB) + return ismob(input_val) + if(COMP_TYPECHECK_HUMAN) + return ishuman(input_val) + trigger_output.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/integrated_circuit.dm b/code/modules/wiremod/integrated_circuit.dm new file mode 100644 index 00000000000..0715b55cc35 --- /dev/null +++ b/code/modules/wiremod/integrated_circuit.dm @@ -0,0 +1,351 @@ +/** + * # Integrated Circuitboard + * + * A circuitboard that holds components that work together + * + * Has a limited amount of power. + */ +/obj/item/integrated_circuit + name = "integrated circuit" + icon = 'icons/obj/module.dmi' + icon_state = "integrated_circuit" + inhand_icon_state = "electronic" + + /// The power of the integrated circuit + var/obj/item/stock_parts/cell/cell + + /// The shell that this circuitboard is attached to. Used by components. + var/atom/movable/shell + + /// The attached components + var/list/obj/item/circuit_component/attached_components = list() + + /// Whether the integrated circuit is on or not. Handled by the shell. + var/on = FALSE + +/obj/item/integrated_circuit/loaded/Initialize() + . = ..() + cell = new /obj/item/stock_parts/cell/high(src) + +/obj/item/integrated_circuit/Destroy() + for(var/obj/item/circuit_component/to_delete in attached_components) + remove_component(to_delete) + qdel(to_delete) + shell = null + QDEL_NULL(cell) + return ..() + +/obj/item/integrated_circuit/examine(mob/user) + . = ..() + if(cell) + . += "The charge meter reads [cell ? round(cell.percent(), 1) : 0]%." + else + . += "There is no power cell installed." + +/obj/item/integrated_circuit/attackby(obj/item/I, mob/living/user, params) + . = ..() + if(istype(I, /obj/item/circuit_component)) + add_component(I, user) + return + + if(istype(I, /obj/item/stock_parts/cell)) + if(cell) + balloon_alert(user, "There already is a cell inside!") + return + if(!user.transferItemToLoc(I, src)) + return + cell = I + I.add_fingerprint(user) + user.visible_message("[user] inserts a power cell into [src].", "You insert the power cell into [src].") + return + + if(I.tool_behaviour == TOOL_SCREWDRIVER) + if(!cell) + return + I.play_tool_sound(src) + user.visible_message("[user] unscrews the power cell from [src].", "You unscrew the power cell from [src].") + cell.forceMove(drop_location()) + cell = null + return + +/** + * Registers an movable atom as a shell + * + * No functionality is done here. This is so that input components + * can properly register any signals on the shell. + * Arguments: + * * new_shell - The new shell to register. + */ +/obj/item/integrated_circuit/proc/set_shell(atom/movable/new_shell) + remove_current_shell() + on = TRUE + shell = new_shell + RegisterSignal(shell, COMSIG_PARENT_QDELETING, .proc/remove_current_shell) + for(var/obj/item/circuit_component/attached_component as anything in attached_components) + attached_component.register_shell(shell) + // Their input ports may be updated with user values, but the outputs haven't updated + // because on is FALSE + attached_component.input_received() + +/** + * Unregisters the current shell attached to this circuit. + */ +/obj/item/integrated_circuit/proc/remove_current_shell() + SIGNAL_HANDLER + if(!shell) + return + for(var/obj/item/circuit_component/attached_component as anything in attached_components) + attached_component.unregister_shell(shell) + UnregisterSignal(shell, COMSIG_PARENT_QDELETING) + shell = null + on = FALSE + +/** + * Adds a component to the circuitboard + * + * Once the component is added, the ports can be attached to other components + */ +/obj/item/integrated_circuit/proc/add_component(obj/item/circuit_component/to_add, mob/living/user) + if(to_add.parent) + return + + if(SEND_SIGNAL(src, COMSIG_CIRCUIT_ADD_COMPONENT, to_add, user) & COMPONENT_CANCEL_ADD_COMPONENT) + return + + var/success = FALSE + if(user) + success = user.transferItemToLoc(to_add, src) + else + success = to_add.forceMove(src) + + if(!success) + return + + to_add.rel_x = rand(COMPONENT_MIN_RANDOM_POS, COMPONENT_MAX_RANDOM_POS) + to_add.rel_y = rand(COMPONENT_MIN_RANDOM_POS, COMPONENT_MAX_RANDOM_POS) + to_add.parent = src + attached_components += to_add + RegisterSignal(to_add, COMSIG_MOVABLE_MOVED, .proc/component_move_handler) + SStgui.update_uis(src) + + if(shell) + to_add.register_shell(shell) + +/obj/item/integrated_circuit/proc/component_move_handler(obj/item/circuit_component/source) + SIGNAL_HANDLER + if(source.loc != src) + remove_component(source) + +/** + * Removes a component to the circuitboard + * + * This removes all connects between the ports + */ +/obj/item/integrated_circuit/proc/remove_component(obj/item/circuit_component/to_remove) + if(shell) + to_remove.unregister_shell(shell) + + UnregisterSignal(to_remove, COMSIG_MOVABLE_MOVED) + attached_components -= to_remove + to_remove.disconnect() + to_remove.parent = null + SStgui.update_uis(src) + +/obj/item/integrated_circuit/get_cell() + return cell + +/obj/item/integrated_circuit/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/simple/circuit_assets) + ) + +/obj/item/integrated_circuit/ui_data(mob/user) + . = list() + .["components"] = list() + for(var/obj/item/circuit_component/component as anything in attached_components) + var/list/component_data = list() + component_data["input_ports"] = list() + for(var/datum/port/input/port as anything in component.input_ports) + var/current_data = port.input_value + if(isatom(current_data)) // Prevent passing the name of the atom. + current_data = null + component_data["input_ports"] += list(list( + "name" = port.name, + "type" = port.datatype, + "ref" = REF(port), // The ref is the identifier to work out what it is connected to + "connected_to" = REF(port.connected_port), + "color" = port.color, + "current_data" = current_data, + )) + component_data["output_ports"] = list() + for(var/datum/port/output/port as anything in component.output_ports) + component_data["output_ports"] += list(list( + "name" = port.name, + "type" = port.datatype, + "ref" = REF(port), + "color" = port.color + )) + + component_data["name"] = component.display_name + component_data["x"] = component.rel_x + component_data["y"] = component.rel_y + component_data["option"] = component.current_option + component_data["options"] = component.options + component_data["removable"] = component.removable + .["components"] += list(component_data) + +/obj/item/integrated_circuit/ui_host(mob/user) + if(shell) + return shell + return ..() + +/obj/item/integrated_circuit/ui_state(mob/user) + if(!shell) + return GLOB.hands_state + return GLOB.physical_obscured_state + +/obj/item/integrated_circuit/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "IntegratedCircuit", name) + ui.open() + ui.set_autoupdate(FALSE) + +#define WITHIN_RANGE(id, table) (id >= 1 && id <= length(table)) + +/obj/item/integrated_circuit/ui_act(action, list/params) + . = ..() + if(.) + return + + switch(action) + if("add_connection") + var/input_component_id = text2num(params["input_component_id"]) + var/output_component_id = text2num(params["output_component_id"]) + var/input_port_id = text2num(params["input_port_id"]) + var/output_port_id = text2num(params["output_port_id"]) + if(!WITHIN_RANGE(input_component_id, attached_components) || !WITHIN_RANGE(output_component_id, attached_components)) + return + var/obj/item/circuit_component/input_component = attached_components[input_component_id] + var/obj/item/circuit_component/output_component = attached_components[output_component_id] + + if(!WITHIN_RANGE(input_port_id, input_component.input_ports) || !WITHIN_RANGE(output_port_id, output_component.output_ports)) + return + var/datum/port/input/input_port = input_component.input_ports[input_port_id] + var/datum/port/output/output_port = output_component.output_ports[output_port_id] + + if(input_port.datatype && !output_port.compatible_datatype(input_port.datatype)) + return + + input_port.register_output_port(output_port) + . = TRUE + if("remove_connection") + var/component_id = text2num(params["component_id"]) + var/is_input = params["is_input"] + var/port_id = text2num(params["port_id"]) + + if(!WITHIN_RANGE(component_id, attached_components)) + return + var/obj/item/circuit_component/component = attached_components[component_id] + + var/list/port_table + if(is_input) + port_table = component.input_ports + else + port_table = component.output_ports + + if(!WITHIN_RANGE(port_id, port_table)) + return + + var/datum/port/port = port_table[port_id] + port.disconnect() + . = TRUE + if("detach_component") + var/component_id = text2num(params["component_id"]) + if(!WITHIN_RANGE(component_id, attached_components)) + return + var/obj/item/circuit_component/component = attached_components[component_id] + if(!component.removable) + return + component.disconnect() + remove_component(component) + usr.put_in_hands(component) + . = TRUE + if("set_component_coordinates") + var/component_id = text2num(params["component_id"]) + if(!WITHIN_RANGE(component_id, attached_components)) + return + var/obj/item/circuit_component/component = attached_components[component_id] + component.rel_x = min(max(-COMPONENT_MAX_POS, text2num(params["rel_x"])), COMPONENT_MAX_POS) + component.rel_y = min(max(-COMPONENT_MAX_POS, text2num(params["rel_y"])), COMPONENT_MAX_POS) + . = TRUE + if("set_component_option") + var/component_id = text2num(params["component_id"]) + if(!WITHIN_RANGE(component_id, attached_components)) + return + var/obj/item/circuit_component/component = attached_components[component_id] + var/option = params["option"] + if(!(option in component.options)) + return + component.set_option(option) + . = TRUE + if("set_component_input") + var/component_id = text2num(params["component_id"]) + var/port_id = text2num(params["port_id"]) + if(!WITHIN_RANGE(component_id, attached_components)) + return + var/obj/item/circuit_component/component = attached_components[component_id] + if(!WITHIN_RANGE(port_id, component.input_ports)) + return + var/datum/port/input/port = component.input_ports[port_id] + + if(port.connected_port) + return + + if(params["set_null"]) + port.set_input(null) + return TRUE + + if(params["marked_atom"]) + if(port.datatype != PORT_TYPE_ATOM && port.datatype != PORT_TYPE_ANY) + return + var/obj/item/multitool/circuit/marker = usr.get_active_held_item() + if(!istype(marker)) + return TRUE + if(!marker.marked_atom) + port.set_input(null) + marker.say("Cleared port ('[port.name]')'s value.") + return TRUE + marker.say("Updated port ('[port.name]')'s value to the marked entity.") + port.set_input(marker.marked_atom) + return TRUE + + var/user_input = params["input"] + switch(port.datatype) + if(PORT_TYPE_NUMBER) + port.set_input(text2num(user_input)) + if(PORT_TYPE_ANY) + var/any_type = copytext(user_input, 1, PORT_MAX_STRING_LENGTH) + port.set_input(text2num(any_type) || any_type) + if(PORT_TYPE_STRING) + port.set_input(copytext(user_input, 1, PORT_MAX_STRING_LENGTH)) + . = TRUE + if("get_component_value") + var/component_id = text2num(params["component_id"]) + var/port_id = text2num(params["port_id"]) + if(!WITHIN_RANGE(component_id, attached_components)) + return + var/obj/item/circuit_component/component = attached_components[component_id] + if(!WITHIN_RANGE(port_id, component.output_ports)) + return + + var/datum/port/output/port = component.output_ports[port_id] + var/value = port.output_value + if(isatom(value)) + value = port.convert_value(port.output_value) + else if(isnull(value)) + value = "null" + balloon_alert(usr, "[port.name] value: [value]") + . = TRUE + +#undef WITHIN_RANGE diff --git a/code/modules/wiremod/marker.dm b/code/modules/wiremod/marker.dm new file mode 100644 index 00000000000..1bae6b6569c --- /dev/null +++ b/code/modules/wiremod/marker.dm @@ -0,0 +1,49 @@ +/obj/item/multitool/circuit + name = "circuit multitool" + desc = "A circuit multitool. Used to mark entities which can then be uploaded to components by pressing the upload button on a port. \ + Acts as a normal multitool otherwise. Use in hand to clear marked entity so that you can mark another entity." + + /// The marked atom of this multitool + var/atom/marked_atom + +/obj/item/multitool/circuit/Destroy() + marked_atom = null + return ..() + +/obj/item/multitool/circuit/examine(mob/user) + . = ..() + . += "It has [marked_atom? "a" : "no"] marked entity registered." + +/obj/item/multitool/circuit/attack_self(mob/user, modifiers) + . = ..() + if(.) + return + if(!marked_atom) + return + + say("Cleared marked targets.") + clear_marked_atom() + return TRUE + +/obj/item/multitool/circuit/melee_attack_chain(mob/user, atom/target, params) + var/is_right_clicking = LAZYACCESS(params2list(params), RIGHT_CLICK) + + if(marked_atom || !user.Adjacent(target) || is_right_clicking) + return ..() + + say("Marked [target].") + marked_atom = target + RegisterSignal(marked_atom, COMSIG_PARENT_QDELETING, .proc/cleanup_marked_atom) + return TRUE + +/// Clears the current marked atom +/obj/item/multitool/circuit/proc/clear_marked_atom() + if(!marked_atom) + return + UnregisterSignal(marked_atom, COMSIG_PARENT_QDELETING) + marked_atom = null + +/obj/item/multitool/circuit/proc/cleanup_marked_atom(datum/source) + SIGNAL_HANDLER + if(source == marked_atom) + clear_marked_atom() diff --git a/code/modules/wiremod/port.dm b/code/modules/wiremod/port.dm new file mode 100644 index 00000000000..5bbcb6c87f7 --- /dev/null +++ b/code/modules/wiremod/port.dm @@ -0,0 +1,282 @@ +/** + * # Component Port + * + * A base type port used by a component + * + * Connects to other ports. This is an abstract type that should not be instanciated + */ +/datum/port + /// The component this port is attached to + var/obj/item/circuit_component/connected_component + + /// Name of the port. Used when displaying the port. + var/name + + /// The port type. Ports can only connect to each other if the type matches + var/datatype + + /// The port color. If unset, appears as blue. + var/color + +/datum/port/New(obj/item/circuit_component/to_connect, name, datatype) + if(!to_connect) + qdel(src) + return + . = ..() + // Don't need to do src.connected_component here, but it looks inline + // with the other variable declarations + src.connected_component = to_connect + src.name = name + src.datatype = datatype + src.color = datatype_to_color() + + +///Converts the datatype into an appropriate colour +/datum/port/proc/datatype_to_color() + switch(datatype) + if(PORT_TYPE_ATOM) + return "purple" + if(PORT_TYPE_NUMBER) + return "green" + if(PORT_TYPE_STRING) + return "orange" + if(PORT_TYPE_LIST) + return "white" + if(PORT_TYPE_SIGNAL) + return "teal" + +/datum/port/Destroy(force) + if(!force && !QDELETED(connected_component)) + // This should never happen. Ports should be deleted with their components + stack_trace("Attempted to delete a port with a non-destroyed connected_component! (port name: [name], component type: [connected_component.type])") + return QDEL_HINT_LETMELIVE + connected_component = null + return ..() + +/** + * Returns the value to be set for the port + * + * Used for implicit conversions between outputs and inputs (e.g. number -> string) + * and applying/removing signals on inputs + */ +/datum/port/proc/convert_value(prev_value, value_to_convert) + if(prev_value == value_to_convert) + return prev_value + . = value_to_convert + + switch(datatype) + if(PORT_TYPE_STRING) + // So that they can't easily get the name like this. + if(isatom(value_to_convert)) + return PORT_TYPE_ATOM + else + return "[value_to_convert]" + + if(isatom(value_to_convert)) + var/atom/atom_to_check = value_to_convert + if(QDELETED(atom_to_check)) + return null + +/** + * Sets the datatype of the port. + * + * Arguments: + * * type_to_set - The type this port is set to. + */ +/datum/port/proc/set_datatype(type_to_set) + datatype = type_to_set + color = datatype_to_color() + disconnect() + if(connected_component) + SStgui.update_uis(connected_component) + +/** + * Disconnects a port from all other ports + * + * Called by [/obj/item/circuit_component] whenever it is disconnected from + * an integrated circuit + */ +/datum/port/proc/disconnect() + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(src, COMSIG_PORT_DISCONNECT) + + +/** + * # Output Port + * + * An output port that many input ports can connect to + * + * Sends a signal whenever the output value is changed + */ +/datum/port/output + /// The output value of the port + var/output_value + +/datum/port/output/disconnect() + set_output(null) + return ..() + +/datum/port/output/Destroy(force) + output_value = null + return ..() + +/** + * Sets the output value of the port + * + * Arguments: + * * value - The value to set it to + */ +/datum/port/output/proc/set_output(value) + if(isatom(output_value)) + UnregisterSignal(output_value, COMSIG_PARENT_QDELETING) + output_value = convert_value(output_value, value) + if(isatom(output_value)) + RegisterSignal(output_value, COMSIG_PARENT_QDELETING, .proc/null_output) + + SEND_SIGNAL(src, COMSIG_PORT_SET_OUTPUT, output_value) + +/// Signal handler proc to null the output if an atom is deleted. An update is not sent because this was not set. +/datum/port/output/proc/null_output(datum/source) + SIGNAL_HANDLER + if(output_value == source) + output_value = null + +/datum/port/output/set_datatype(type_to_set) + . = ..() + set_output(null) + +/** + * Determines if a datatype is compatible with this port. + * + * Arguments: + * * other_datatype - The datatype to check + */ +/datum/port/output/proc/compatible_datatype(datatype_to_check) + if(datatype_to_check == datatype) + return TRUE + + switch(datatype) + if(PORT_TYPE_NUMBER) + // Can easily convert a number to string. Everything else has to use a tostring component + return datatype_to_check == PORT_TYPE_STRING || datatype_to_check == PORT_TYPE_SIGNAL + if(PORT_TYPE_SIGNAL) + // A signal port is just a number port but distinguishable + return datatype_to_check == PORT_TYPE_NUMBER + + return FALSE + +/** + * # Input Port + * + * An input port that can only be connected to 1 output port + * + * Registers a signal on the target output port to listen out for any output + * so that an update can be sent to the attached component + */ +/datum/port/input + /// The output value of the port + var/input_value + + /// The connected output port + var/datum/port/output/connected_port + + /// The delay before updating the input value whenever a modification is made. + /// This does not apply when when the output port is registered + var/input_receive_delay = PORT_INPUT_RECEIVE_DELAY + + /// Whether this port triggers an update whenever an output is received. + var/trigger = FALSE + + /// The default value of this input + var/default + +/datum/port/input/New(obj/item/circuit_component/to_connect, name, datatype, trigger, default) + . = ..() + src.trigger = trigger + src.default = default + set_input(default, FALSE) + +/** + * Connects the input port to the output port + * + * Sets the input_value and registers a signal to receive future updates. + * Arguments: + * * port_to_register - The port to connect the input port to + */ +/datum/port/input/proc/register_output_port(datum/port/output/port_to_register) + unregister_output_port() + + RegisterSignal(port_to_register, COMSIG_PORT_SET_OUTPUT, .proc/receive_output) + RegisterSignal(port_to_register, list( + COMSIG_PORT_DISCONNECT, + COMSIG_PARENT_QDELETING + ), .proc/unregister_output_port) + + connected_port = port_to_register + SEND_SIGNAL(connected_port, COMSIG_PORT_OUTPUT_CONNECT, src) + set_input(connected_port.output_value) + + +/** + * Sets a timer depending on the value of the input_receive_delay + * + * The timer will call a proc that updates the value. + * Arguments: + * * connected_port - The connected output port + * * new_value - The new value received from the output port + */ +/datum/port/input/proc/receive_output(datum/port/output/connected_port, new_value) + SIGNAL_HANDLER + if(input_receive_delay) + addtimer(CALLBACK(src, .proc/set_input, new_value), input_receive_delay, timer_subsystem = SScircuit_component) + else + set_input(new_value) + +/** + * Updates the value of the input + * + * It updates the value of the input and calls input_received on the connected component + * Arguments: + * * port_to_register - The port to connect the input port to + */ +/datum/port/input/proc/set_input(new_value, send_update = TRUE) + if(isatom(input_value)) + UnregisterSignal(input_value, COMSIG_PARENT_QDELETING) + input_value = convert_value(input_value, new_value) + if(isatom(input_value)) + RegisterSignal(input_value, COMSIG_PARENT_QDELETING, .proc/null_output) + + SEND_SIGNAL(src, COMSIG_PORT_SET_INPUT, input_value) + if(trigger && send_update) + connected_component.input_received(src) + +/// Signal handler proc to null the input if an atom is deleted. An update is not sent because this was not set by anything. +/datum/port/input/proc/null_output(datum/source) + SIGNAL_HANDLER + if(input_value == source) + input_value = null + +/datum/port/input/disconnect() + unregister_output_port() + return ..() + +/datum/port/input/set_datatype(type_to_set) + . = ..() + set_input(default) + +/datum/port/input/proc/unregister_output_port() + SIGNAL_HANDLER + if(!connected_port) + return + UnregisterSignal(connected_port, list( + COMSIG_PARENT_QDELETING, + COMSIG_PORT_SET_OUTPUT, + COMSIG_PORT_DISCONNECT + )) + connected_port = null + set_input(default) + +/datum/port/input/Destroy() + unregister_output_port() + connected_port = null + return ..() diff --git a/code/modules/wiremod/preset/hello_world.dm b/code/modules/wiremod/preset/hello_world.dm new file mode 100644 index 00000000000..9aee88a300a --- /dev/null +++ b/code/modules/wiremod/preset/hello_world.dm @@ -0,0 +1,14 @@ +/** + * # Hello World preset + * + * Says "Hello World" when triggered. Needs to be wired up and connected first. + */ +/obj/item/integrated_circuit/loaded/hello_world + +/obj/item/integrated_circuit/loaded/hello_world/Initialize() + . = ..() + var/obj/item/circuit_component/speech/speech = new() + add_component(speech) + + speech.message.set_input("Hello World") + diff --git a/code/modules/wiremod/preset/speech_relay.dm b/code/modules/wiremod/preset/speech_relay.dm new file mode 100644 index 00000000000..1b6cd65d561 --- /dev/null +++ b/code/modules/wiremod/preset/speech_relay.dm @@ -0,0 +1,22 @@ +/** + * # Speech Relay preset + * + * Acts like poly. Says whatever it hears. + */ +/obj/item/integrated_circuit/loaded/speech_relay + +/obj/item/integrated_circuit/loaded/speech_relay/Initialize() + . = ..() + var/obj/item/circuit_component/hear/hear = new() + add_component(hear) + hear.rel_x = 100 + hear.rel_y = 200 + + var/obj/item/circuit_component/speech/speech = new() + add_component(speech) + speech.rel_x = 400 + speech.rel_y = 200 + + speech.message.register_output_port(hear.message_port) + speech.trigger.register_output_port(hear.trigger_port) + diff --git a/code/modules/wiremod/shell/bot.dm b/code/modules/wiremod/shell/bot.dm new file mode 100644 index 00000000000..8145d307692 --- /dev/null +++ b/code/modules/wiremod/shell/bot.dm @@ -0,0 +1,18 @@ +/** + * # Bot + * + * Immobile (but not dense) shells that can interact with world. + */ +/obj/structure/bot + name = "bot" + icon = 'icons/obj/wiremod.dmi' + icon_state = "setup_medium_box" + + density = FALSE + light_system = MOVABLE_LIGHT + light_on = FALSE + +/obj/structure/bot/Initialize() + . = ..() + AddComponent(/datum/component/shell, null, SHELL_CAPACITY_LARGE) + diff --git a/code/modules/wiremod/shell/compact_remote.dm b/code/modules/wiremod/shell/compact_remote.dm new file mode 100644 index 00000000000..cc3b5327243 --- /dev/null +++ b/code/modules/wiremod/shell/compact_remote.dm @@ -0,0 +1,50 @@ +/** + * # Compact Remote + * + * A handheld device with one big button. + */ +/obj/item/compact_remote + name = "compact remote" + icon = 'icons/obj/wiremod.dmi' + icon_state = "setup_small_simple" + inhand_icon_state = "electronic" + worn_icon_state = "electronic" + lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' + righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' + light_system = MOVABLE_LIGHT_DIRECTIONAL + light_on = FALSE + +/obj/item/compact_remote/Initialize() + . = ..() + AddComponent(/datum/component/shell, list( + new /obj/item/circuit_component/compact_remote() + ), SHELL_CAPACITY_SMALL) + +/obj/item/circuit_component/compact_remote + display_name = "Compact Remote" + + /// Called when attack_self is called on the shell. + var/datum/port/output/signal + +/obj/item/circuit_component/compact_remote/Initialize() + . = ..() + signal = add_output_port("Signal", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/compact_remote/Destroy() + signal = null + return ..() + +/obj/item/circuit_component/compact_remote/register_shell(atom/movable/shell) + RegisterSignal(shell, COMSIG_ITEM_ATTACK_SELF, .proc/send_trigger) + +/obj/item/circuit_component/compact_remote/unregister_shell(atom/movable/shell) + UnregisterSignal(shell, COMSIG_ITEM_ATTACK_SELF) + +/** + * Called when the shell item is used in hand. + */ +/obj/item/circuit_component/compact_remote/proc/send_trigger(atom/source, mob/user) + SIGNAL_HANDLER + source.balloon_alert(user, "clicked primary button") + playsound(source, get_sfx("terminal_type"), 25, FALSE) + signal.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/shell/controller.dm b/code/modules/wiremod/shell/controller.dm new file mode 100644 index 00000000000..c9cc153a9db --- /dev/null +++ b/code/modules/wiremod/shell/controller.dm @@ -0,0 +1,84 @@ +/** + * # Compact Remote + * + * A handheld device with several buttons. + * In game, this translates to having different signals for normal usage, alt-clicking, and ctrl-clicking when in your hand. + */ +/obj/item/controller + name = "controller" + icon = 'icons/obj/wiremod.dmi' + icon_state = "setup_small_calc" + inhand_icon_state = "electronic" + worn_icon_state = "electronic" + lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' + righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' + light_system = MOVABLE_LIGHT_DIRECTIONAL + light_on = FALSE + +/obj/item/controller/Initialize() + . = ..() + AddComponent(/datum/component/shell, list( + new /obj/item/circuit_component/controller() + ), SHELL_CAPACITY_MEDIUM) + +/obj/item/circuit_component/controller + display_name = "Controller" + + /// The three separate buttons that are called in attack_hand on the shell. + var/datum/port/output/signal + var/datum/port/output/alt + var/datum/port/output/right + +/obj/item/circuit_component/controller/Initialize() + . = ..() + signal = add_output_port("Signal", PORT_TYPE_SIGNAL) + alt = add_output_port("Alternate Signal", PORT_TYPE_SIGNAL) + right = add_output_port("Extra Signal", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/controller/Destroy() + signal = null + alt = null + right = null + return ..() + +/obj/item/circuit_component/controller/register_shell(atom/movable/shell) + RegisterSignal(shell, COMSIG_ITEM_ATTACK_SELF, .proc/send_trigger) + RegisterSignal(shell, COMSIG_CLICK_ALT, .proc/send_alternate_signal) + RegisterSignal(shell, COMSIG_CLICK_ALT_SECONDARY, .proc/send_right_signal) + +/obj/item/circuit_component/controller/unregister_shell(atom/movable/shell) + UnregisterSignal(shell, list( + COMSIG_ITEM_ATTACK_SELF, + COMSIG_CLICK_ALT_SECONDARY, + COMSIG_CLICK_ALT, + )) + +/** + * Called when the shell item is used in hand, including right click. + */ +/obj/item/circuit_component/controller/proc/send_trigger(atom/source, mob/user) + SIGNAL_HANDLER + if(!user.Adjacent(source)) + return + source.balloon_alert(user, "clicked primary button") + playsound(source, get_sfx("terminal_type"), 25, FALSE) + signal.set_output(COMPONENT_SIGNAL) + +/** + * Called when the shell item is alt-clicked + */ +/obj/item/circuit_component/controller/proc/send_alternate_signal(atom/source, mob/user) + SIGNAL_HANDLER + if(!user.Adjacent(source)) + return + source.balloon_alert(user, "clicked alternate button") + playsound(source, get_sfx("terminal_type"), 25, FALSE) + alt.set_output(COMPONENT_SIGNAL) + +/obj/item/circuit_component/controller/proc/send_right_signal(atom/source, mob/user) + SIGNAL_HANDLER + if(!user.Adjacent(source)) + return + source.balloon_alert(user, "clicked extra button") + playsound(source, get_sfx("terminal_type"), 25, FALSE) + right.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/shell/drone.dm b/code/modules/wiremod/shell/drone.dm new file mode 100644 index 00000000000..356bc20b438 --- /dev/null +++ b/code/modules/wiremod/shell/drone.dm @@ -0,0 +1,68 @@ +/** + * # Drone + * + * A movable mob that can be fed inputs on which direction to travel. + */ +/mob/living/circuit_drone + name = "drone" + icon = 'icons/obj/wiremod.dmi' + icon_state = "setup_medium_med" + living_flags = 0 + light_system = MOVABLE_LIGHT_DIRECTIONAL + light_on = FALSE + +/mob/living/circuit_drone/Initialize() + . = ..() + AddComponent(/datum/component/shell, list( + new /obj/item/circuit_component/bot_circuit() + ), SHELL_CAPACITY_LARGE) + +/mob/living/circuit_drone/updatehealth() + . = ..() + if(health < 0) + gib(no_brain = TRUE, no_organs = TRUE, no_bodyparts = TRUE) + +/mob/living/circuit_drone/spawn_gibs() + new /obj/effect/gibspawner/robot(drop_location(), src, get_static_viruses()) + +/obj/item/circuit_component/bot_circuit + display_name = "Drone" + + /// The inputs to allow for the drone to move + var/datum/port/input/north + var/datum/port/input/east + var/datum/port/input/south + var/datum/port/input/west + +/obj/item/circuit_component/bot_circuit/Initialize() + . = ..() + north = add_input_port("Move North", PORT_TYPE_SIGNAL) + east = add_input_port("Move East", PORT_TYPE_SIGNAL) + south = add_input_port("Move South", PORT_TYPE_SIGNAL) + west = add_input_port("Move West", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/bot_circuit/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/mob/living/shell = parent.shell + if(!istype(shell) || shell.stat) + return + + var/direction + + if(COMPONENT_TRIGGERED_BY(north, port)) + direction = NORTH + else if(COMPONENT_TRIGGERED_BY(east, port)) + direction = EAST + else if(COMPONENT_TRIGGERED_BY(south, port)) + direction = SOUTH + else if(COMPONENT_TRIGGERED_BY(west, port)) + direction = WEST + + if(!direction) + return + + if(shell.Process_Spacemove(direction)) + shell.Move(get_step(shell, direction), direction) diff --git a/code/modules/wiremod/shell/server.dm b/code/modules/wiremod/shell/server.dm new file mode 100644 index 00000000000..d63deb18f1e --- /dev/null +++ b/code/modules/wiremod/shell/server.dm @@ -0,0 +1,24 @@ +/** + * # Server + * + * Immobile (but not dense) shells that can interact with + * world. + */ +/obj/structure/server + name = "server" + icon = 'icons/obj/wiremod.dmi' + icon_state = "setup_stationary" + + density = TRUE + light_system = MOVABLE_LIGHT + light_on = FALSE + +/obj/structure/server/Initialize() + . = ..() + AddComponent(/datum/component/shell, null, SHELL_CAPACITY_VERY_LARGE, SHELL_FLAG_REQUIRE_ANCHOR) + +/obj/structure/server/wrench_act(mob/living/user, obj/item/tool) + set_anchored(!anchored) + tool.play_tool_sound(src) + balloon_alert(user, "You [anchored?"secure":"unsecure"] [src].") + return TRUE diff --git a/code/modules/wiremod/shell/shell_items.dm b/code/modules/wiremod/shell/shell_items.dm new file mode 100644 index 00000000000..ebc2f3ca512 --- /dev/null +++ b/code/modules/wiremod/shell/shell_items.dm @@ -0,0 +1,42 @@ +/** + * # Shell Item + * + * Printed out by protolathes. Screwdriver to complete the shell. + */ +/obj/item/shell + name = "assembly" + desc = "A shell assembly that can be completed by screwdrivering it." + icon = 'icons/obj/wiremod.dmi' + var/shell_to_spawn + var/screw_delay = 3 SECONDS + +/obj/item/shell/screwdriver_act(mob/living/user, obj/item/tool) + user.visible_message("[user] begins finishing [src].", "You begin finishing [src].") + tool.play_tool_sound(src) + if(!do_after(user, screw_delay, src)) + return + user.visible_message("[user] finishes [src].", "You finish [src].") + + var/turf/drop_loc = drop_location() + + qdel(src) + if(drop_loc) + new shell_to_spawn(drop_loc) + + return TRUE + +/obj/item/shell/bot + name = "bot assembly" + icon_state = "setup_medium_box-open" + shell_to_spawn = /obj/structure/bot + +/obj/item/shell/drone + name = "drone assembly" + icon_state = "setup_medium_med-open" + shell_to_spawn = /mob/living/circuit_drone + +/obj/item/shell/server + name = "server assembly" + icon_state = "setup_stationary-open" + shell_to_spawn = /obj/structure/server + screw_delay = 10 SECONDS diff --git a/icons/obj/module.dmi b/icons/obj/module.dmi index 707ab1b47e716a64193c06a1cbbe081c57b12c46..d70a56695ef14bf5b6db602df5dfd385158e23ab 100644 GIT binary patch literal 18023 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

1QjZM|rgOwmv8(FeEdHS#Wrq=@=?r`U-l~ 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 K*>Y)<;QtG|plDwJ literal 17556 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 literal 0 HcmV?d00001 diff --git a/icons/ui_icons/tgui/grid_background.png b/icons/ui_icons/tgui/grid_background.png new file mode 100644 index 0000000000000000000000000000000000000000..228d373456cec0ba541e8f2f652edc9c2334b751 GIT binary patch literal 21650 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 RA4fqTEj4}BVilW^{{x4e&vyU- literal 0 HcmV?d00001 diff --git a/modular_skyrat/master_files/code/controllers/processing/circuit.dm b/modular_skyrat/master_files/code/controllers/processing/circuit.dm deleted file mode 100644 index 68cc2e62ff0..00000000000 --- a/modular_skyrat/master_files/code/controllers/processing/circuit.dm +++ /dev/null @@ -1,94 +0,0 @@ -PROCESSING_SUBSYSTEM_DEF(circuit) - name = "Circuit" - stat_tag = "CIR" - init_order = INIT_ORDER_CIRCUIT - flags = NONE - - var/cipherkey - - var/regex/bad_regex - var/list/all_components = list() // Associative list of [component_name]:[component_path] pairs - var/list/cached_components = list() // Associative list of [component_path]:[component] pairs - var/list/all_assemblies = list() // Associative list of [assembly_name]:[assembly_path] pairs - var/list/cached_assemblies = list() // Associative list of [assembly_path]:[assembly] pairs - var/list/all_circuits = list() // Associative list of [circuit_name]:[circuit_path] pairs - var/list/circuit_fabricator_recipe_list = list() // Associative list of [category_name]:[list_of_circuit_paths] pairs - var/cost_multiplier = MINERAL_MATERIAL_AMOUNT / 10 // Each circuit cost unit is 200cm3 - -/datum/controller/subsystem/processing/circuit/Initialize(start_timeofday) - SScircuit.cipherkey = uppertext(random_string(2000+rand(0,10), GLOB.alphabet)) - circuits_init() - //Setup the input regex - bad_regex = new("\[^\\w{}:\",.\\-*&+ =\'\\(\\)\\\[\\\]#\]", "g") - return ..() - -/datum/controller/subsystem/processing/circuit/proc/circuits_init() - //Cached lists for free performance - for(var/path in typesof(/obj/item/integrated_circuit)) - var/obj/item/integrated_circuit/IC = path - var/name = initial(IC.name) - all_components[name] = path // Populating the component lists - cached_components[IC] = new path - - if(!(initial(IC.spawn_flags) & (IC_SPAWN_DEFAULT | IC_SPAWN_RESEARCH))) - continue - - var/category = initial(IC.category_text) - if(!circuit_fabricator_recipe_list[category]) - circuit_fabricator_recipe_list[category] = list() - var/list/category_list = circuit_fabricator_recipe_list[category] - category_list += IC // Populating the fabricator categories - - for(var/path in typesof(/obj/item/electronic_assembly)) - var/obj/item/electronic_assembly/A = path - var/name = initial(A.name) - all_assemblies[name] = path - cached_assemblies[A] = new path - - - circuit_fabricator_recipe_list["Assemblies"] = list( - /obj/item/electronic_assembly/default, - /obj/item/electronic_assembly/calc, - /obj/item/electronic_assembly/clam, - /obj/item/electronic_assembly/simple, - /obj/item/electronic_assembly/hook, - /obj/item/electronic_assembly/pda, - /obj/item/electronic_assembly/small/default, - /obj/item/electronic_assembly/small/cylinder, - /obj/item/electronic_assembly/small/scanner, - /obj/item/electronic_assembly/small/hook, - /obj/item/electronic_assembly/small/box, - /obj/item/electronic_assembly/medium/default, - /obj/item/electronic_assembly/medium/box, - /obj/item/electronic_assembly/medium/clam, - /obj/item/electronic_assembly/medium/medical, - ///obj/item/electronic_assembly/medium/gun, - /obj/item/electronic_assembly/medium/radio, - /obj/item/electronic_assembly/large/default, - /obj/item/electronic_assembly/large/scope, - /obj/item/electronic_assembly/large/terminal, - /obj/item/electronic_assembly/large/arm, - /obj/item/electronic_assembly/large/tall, - /obj/item/electronic_assembly/large/industrial, - /obj/item/electronic_assembly/drone/default, - /obj/item/electronic_assembly/drone/arms, - /obj/item/electronic_assembly/drone/secbot, - /obj/item/electronic_assembly/drone/medbot, - /obj/item/electronic_assembly/drone/genbot, - /obj/item/electronic_assembly/drone/android, - /obj/item/electronic_assembly/wallmount/tiny, - /obj/item/electronic_assembly/wallmount/light, - /obj/item/electronic_assembly/wallmount, - /obj/item/electronic_assembly/wallmount/heavy - ///obj/item/weapon/implant/integrated_circuit - ) - - circuit_fabricator_recipe_list["Tools"] = list( - /obj/item/integrated_electronics/wirer, - /obj/item/integrated_electronics/debugger, - /obj/item/integrated_electronics/analyzer, - /obj/item/integrated_electronics/detailer, - /obj/item/card/data, - /obj/item/card/data/full_color, - /obj/item/card/data/disk - ) diff --git a/modular_skyrat/modules/integrated_circuits/code/game/data_huds.dm b/modular_skyrat/modules/integrated_circuits/code/game/data_huds.dm deleted file mode 100644 index 3f7323acfca..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/game/data_huds.dm +++ /dev/null @@ -1,49 +0,0 @@ -/*~~~~~~~~~~~~ - Circuitry! -~~~~~~~~~~~~~*/ -/obj/item/electronic_assembly/proc/diag_hud_set_circuithealth(hide = FALSE) - var/image/holder = hud_list[DIAG_CIRCUIT_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size - if((!isturf(loc))||hide) //if not on the ground dont show overlay - holder.icon_state = null - else - holder.icon_state = "huddiag[RoundDiagBar(obj_integrity/max_integrity)]" - -/obj/item/electronic_assembly/proc/diag_hud_set_circuitcell(hide = FALSE) - var/image/holder = hud_list[DIAG_BATT_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size - if((!isturf(loc))||hide) //if not on the ground dont show overlay - holder.icon_state = null - else if(battery) - var/chargelvl = battery.charge/battery.maxcharge - holder.icon_state = "hudbatt[RoundDiagBar(chargelvl)]" - else - holder.icon_state = "hudnobatt" - -/obj/item/electronic_assembly/proc/diag_hud_set_circuitstat(hide = FALSE) //On, On and dangerous, or Off - var/image/holder = hud_list[DIAG_STAT_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size - if((!isturf(loc))||hide) //if not on the ground don't show overlay - holder.icon_state = null - else if(!battery) - holder.icon_state = "hudoffline" - else if(battery.charge == 0) - holder.icon_state = "hudoffline" - else if(combat_circuits) //has a circuit that can harm people - holder.icon_state = prefered_hud_icon + "-red" - else //Bot is on and not dangerous - holder.icon_state = prefered_hud_icon - -/obj/item/electronic_assembly/proc/diag_hud_set_circuittracking(hide = FALSE) - var/image/holder = hud_list[DIAG_TRACK_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - world.icon_size - if((!isturf(loc))||hide) //if not on the ground dont show overlay - holder.icon_state = null - else if(long_range_circuits) - holder.icon_state = "hudtracking" - else - holder.icon_state = null diff --git a/modular_skyrat/modules/integrated_circuits/code/game/objects/items/devices/multitool.dm b/modular_skyrat/modules/integrated_circuits/code/game/objects/items/devices/multitool.dm deleted file mode 100644 index 558674eb431..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/game/objects/items/devices/multitool.dm +++ /dev/null @@ -1,59 +0,0 @@ -/obj/item/multitool - var/datum/integrated_io/selected_io = null //functional for integrated circuits. - -/obj/item/multitool/attack_self(mob/user) - if(selected_io) - selected_io = null - to_chat(user, "You clear the wired connection from the multitool.") - update_icon() - -/obj/item/multitool/update_icon() - ..() - if(selected_io) - icon_state = "multitool_red" - else - icon_state = "multitool" - -/obj/item/multitool/proc/wire(var/datum/integrated_io/io, mob/user) - if(!io.holder.assembly) - to_chat(user, "\The [io.holder] needs to be secured inside an assembly first.") - return - - if(selected_io) - if(io == selected_io) - to_chat(user, "Wiring \the [selected_io.holder]'s [selected_io.name] into itself is rather pointless.") - return - if(io.io_type != selected_io.io_type) - to_chat(user, "Those two types of channels are incompatible. The first is a [selected_io.io_type], \ - while the second is a [io.io_type].") - return - if(io.holder.assembly && io.holder.assembly != selected_io.holder.assembly) - to_chat(user, "Both \the [io.holder] and \the [selected_io.holder] need to be inside the same assembly.") - return - io.connect_pin(selected_io) - - to_chat(user, "You connect \the [selected_io.holder]'s [selected_io.name] to \the [io.holder]'s [io.name].") - selected_io.holder.interact(user) // This is to update the UI. - selected_io = null - - else - selected_io = io - to_chat(user, "You link \the multitool to \the [selected_io.holder]'s [selected_io.name] data channel.") - - update_icon() - - -/obj/item/multitool/proc/unwire(var/datum/integrated_io/io1, var/datum/integrated_io/io2, mob/user) - if(!io1.linked.len || !io2.linked.len) - to_chat(user, "There is nothing connected to the data channel.") - return - - if(!(io1 in io2.linked) || !(io2 in io1.linked) ) - to_chat(user, "These data pins aren't connected!") - return - else - io1.disconnect_pin(io2) - to_chat(user, "You clip the data connection between the [io1.holder.displayed_name]'s \ - [io1.name] and the [io2.holder.displayed_name]'s [io2.name].") - io1.holder.interact(user) // This is to update the UI. - update_icon() diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/analyzer.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/analyzer.dm deleted file mode 100644 index e9f9ab20b6d..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/analyzer.dm +++ /dev/null @@ -1,23 +0,0 @@ -/obj/item/integrated_electronics/analyzer - name = "circuit analyzer" - desc = "A tool that scans assemblies and gives the user a printout to recreate it in a circuit printer." - icon = 'modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/electronic_tools.dmi' - icon_state = "analyzer" - flags_1 = CONDUCT_1 - w_class = WEIGHT_CLASS_SMALL - custom_materials = list(/datum/material/iron=200) - -/obj/item/integrated_electronics/analyzer/afterattack(var/atom/A, var/mob/living/user) - . = ..() - if(istype(A, /obj/item/electronic_assembly)) - var/obj/item/electronic_assembly/EA = A - if(EA.idlock) - to_chat(user, "[A] is currently identity-locked and can't be analyzed.") - return FALSE - - var/saved = "[A.name] analyzed! On circuit printers with cloning enabled, you may use the code below to clone the circuit:

[SScircuit.save_electronic_assembly(A)]" - if(saved) - to_chat(user, "You scan [A].") - user << browse(saved, "window=circuit_scan;size=500x600;border=1;can_resize=1;can_close=1;can_minimize=1") - else - to_chat(user, "[A] is not complete enough to be encoded!") diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/assemblies.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/assemblies.dm deleted file mode 100644 index a7929201134..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/assemblies.dm +++ /dev/null @@ -1,1050 +0,0 @@ -#define IC_MAX_SIZE_BASE 25 -#define IC_COMPLEXITY_BASE 75 - -/obj/item/electronic_assembly - name = "electronic assembly" - obj_flags = CAN_BE_HIT | UNIQUE_RENAME - desc = "A case designed for building small electronics." - w_class = WEIGHT_CLASS_SMALL - icon = 'modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/electronic_setups.dmi' - icon_state = "setup_small" - item_flags = NOBLUDGEON - datum_flags = DF_USE_TAG - custom_materials = list(/datum/material/iron=400) - var/list/assembly_components = list() - var/list/ckeys_allowed_to_scan = list() // Players who built the circuit can scan it as a ghost. - var/max_components = IC_MAX_SIZE_BASE - var/max_complexity = IC_COMPLEXITY_BASE - var/opened = TRUE - var/obj/item/stock_parts/cell/battery // Internal cell which most circuits need to work. - var/cell_type = /obj/item/stock_parts/cell - var/can_charge = TRUE //Can it be charged in a recharger? - var/can_fire_equipped = FALSE //Can it fire/throw weapons when the assembly is being held? - var/charge_sections = 4 - var/charge_tick = FALSE - var/charge_delay = 4 - var/use_cyborg_cell = TRUE - var/ext_next_use = 0 - var/atom/collw - var/obj/item/card/id/access_card - var/allowed_circuit_action_flags = IC_ACTION_COMBAT | IC_ACTION_LONG_RANGE //which circuit flags are allowed - var/combat_circuits = 0 //number of combat cicuits in the assembly, used for diagnostic hud - var/long_range_circuits = 0 //number of long range cicuits in the assembly, used for diagnostic hud - var/prefered_hud_icon = "hudstat" // Used by the AR circuit to change the hud icon. - var/creator // circuit creator if any - var/static/next_assembly_id = 0 - var/sealed = FALSE - var/datum/weakref/idlock = null - - hud_possible = list(DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD, DIAG_CIRCUIT_HUD) //diagnostic hud overlays - max_integrity = 50 - pass_flags = 0 - armor = list("melee" = 50, "bullet" = 70, "laser" = 70, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0) - anchored = FALSE - var/can_anchor = TRUE - var/detail_color = COLOR_ASSEMBLY_BLACK - -/obj/item/electronic_assembly/New() - ..() - src.max_components = round(max_components) - src.max_complexity = round(max_complexity) - -/obj/item/electronic_assembly/GenerateTag() - tag = "assembly_[next_assembly_id++]" - -/obj/item/electronic_assembly/examine(mob/user) - . = ..() - if(can_anchor) - to_chat(user, "The anchoring bolts [anchored ? "are" : "can be"] wrenched in place and the maintenance panel [opened ? "can be" : "is"] screwed in place.") - else - to_chat(user, "The maintenance panel [opened ? "can be" : "is"] screwed in place.") - - if((isobserver(user) && ckeys_allowed_to_scan[user.ckey]) || isAdminGhostAI(user)) - to_chat(user, "You can
scan this circuit.") - - for(var/obj/item/integrated_circuit/I in assembly_components) - I.external_examine(user) - if(opened) - interact(user) - -/obj/item/electronic_assembly/proc/check_interactivity(mob/user) - if(!istype(user, /mob)) - return - return user.canUseTopic(src, BE_CLOSE) - -/obj/item/electronic_assembly/Bump(atom/AM) - collw = AM - .=..() - if((istype(collw, /obj/machinery/door/airlock) || istype(collw, /obj/machinery/door/window)) && (!isnull(access_card))) - var/obj/machinery/door/D = collw - if(D.check_access(access_card)) - D.open() - -/obj/item/electronic_assembly/Initialize() - .=..() - START_PROCESSING(SScircuit, src) - - set_custom_materials(list(GET_MATERIAL_REF(/datum/material/iron)=round((max_complexity + max_components) / 4) * SScircuit.cost_multiplier)) - - //sets up diagnostic hud view - prepare_huds() - for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) - diag_hud.add_to_hud(src) - diag_hud_set_circuithealth() - diag_hud_set_circuitcell() - diag_hud_set_circuitstat() - diag_hud_set_circuittracking() - - access_card = new /obj/item/card/id(src) - -/obj/item/electronic_assembly/Destroy() - STOP_PROCESSING(SScircuit, src) - for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) - diag_hud.remove_from_hud(src) - QDEL_NULL(access_card) - return ..() - -/obj/item/electronic_assembly/process() - handle_idle_power() - check_pulling() - - //updates diagnostic hud - diag_hud_set_circuithealth() - diag_hud_set_circuitcell() - -/obj/item/electronic_assembly/proc/handle_idle_power() - - // First we generate power. - for(var/obj/item/integrated_circuit/passive/power/P in assembly_components) - P.make_energy() - - // Now spend it. - for(var/obj/item/integrated_circuit/I in assembly_components) - if(I.power_draw_idle) - if(!draw_power(I.power_draw_idle)) - I.power_fail() - -/obj/item/electronic_assembly/interact(mob/user, circuit) - ui_interact(user, circuit) - -/obj/item/electronic_assembly/ui_interact(mob/user, obj/item/integrated_circuit/circuit_pins) - . = ..() - if(!check_interactivity(user)) - return - - var/total_part_size = return_total_size() - var/total_complexity = return_total_complexity() - var/datum/browser/popup = new(user, "scannernew", name, 800, 630) // Set up the popup browser window - popup.add_stylesheet("scannernew", 'html/browser/assembly_ui.css') - - var/HTML = "[name]\ - \ - Refresh | Rename
\ - [total_part_size]/[max_components] ([round((total_part_size / max_components) * 100, 0.1)]%) space taken up in the assembly.
\ - [total_complexity]/[max_complexity] ([round((total_complexity / max_complexity) * 100, 0.1)]%) maximum complexity.
" - if(battery) - HTML += "[round(battery.charge, 0.1)]/[battery.maxcharge] ([round(battery.percent(), 0.1)]%) cell charge. Remove" - else - HTML += "No power cell detected!" - HTML += "" - - - //Getting the newest viewed circuit to compare with new circuit list - if(!circuit_pins || !istype(circuit_pins,/obj/item/integrated_circuit) || !(circuit_pins in assembly_components)) - if(assembly_components.len > 0) - circuit_pins = assembly_components[1] - - - HTML += "
Components:
" - - var/builtin_components = "" - var/removables = "" - var/remove_num = 1 - - for(var/obj/item/integrated_circuit/circuit in assembly_components) - if(!circuit.removable) - if(circuit == circuit_pins) - builtin_components += "[circuit.displayed_name]
" - else - builtin_components += "[circuit.displayed_name]
" - - // Non-inbuilt circuits come after inbuilt circuits - else - removables += "[remove_num]. | " - if(circuit == circuit_pins) - removables += "[circuit.displayed_name]
" - else - removables += "[circuit.displayed_name]
" - remove_num++ - - // Put removable circuits (if any) in separate categories from non-removable - if(builtin_components) - HTML += "
Built in:
[builtin_components]
Removable:
" - - HTML += removables - - HTML += "
" - - - //Getting the newest circuit's pin - if(!circuit_pins || !istype(circuit_pins,/obj/item/integrated_circuit)) - if(assembly_components.len > 0) - circuit_pins = assembly_components[1] - - if(circuit_pins) - HTML += "
[circuit_pins.displayed_name]
" - - HTML += "Refresh | \ - Rename | \ - Copy Ref | \ - Interact" - if(circuit_pins.removable) - HTML += " | Remove" - HTML += "

" - - var/table_edge_width = "30%" - var/table_middle_width = "40%" - - HTML += "\ - \ - \ - \ - " - - var/column_width = 3 - var/row_height = max(circuit_pins.inputs.len, circuit_pins.outputs.len, 1) - - for(var/i = 1 to row_height) - HTML += "" - for(var/j = 1 to column_width) - var/datum/integrated_io/io = null - var/words = "" - var/height = 1 - switch(j) - if(1) - io = circuit_pins.get_pin_ref(IC_INPUT, i) - if(io) - words += "[io.display_pin_type()] [io.name] \ - [io.display_data(io.data)]
" - if(io.linked.len) - words += "" - - if(circuit_pins.outputs.len > circuit_pins.inputs.len) - height = 1 - if(2) - if(i == 1) - words += "[circuit_pins.displayed_name]
[circuit_pins.name != circuit_pins.displayed_name ? "([circuit_pins.name])":""]
[circuit_pins.desc]" - height = row_height - else - continue - if(3) - io = circuit_pins.get_pin_ref(IC_OUTPUT, i) - if(io) - words += "[io.display_pin_type()] [io.name] \ - [io.display_data(io.data)]
" - if(io.linked.len) - words += "" - - if(circuit_pins.inputs.len > circuit_pins.outputs.len) - height = 1 - HTML += "" - HTML += "" - - for(var/activator in circuit_pins.activators) - var/datum/integrated_io/io = activator - var/words = "" - - words += "[io] \ - [io.data?"\":"\"]
" - if(io.linked.len) - words += "" - - HTML += "" - - HTML += "\ -
Complexity: [circuit_pins.complexity]\ -
Cooldown per use: [circuit_pins.cooldown_per_use/10] sec" - if(circuit_pins.ext_cooldown) - HTML += "
External manipulation cooldown: [circuit_pins.ext_cooldown/10] sec" - if(circuit_pins.power_draw_idle) - HTML += "
Power Draw: [circuit_pins.power_draw_idle] W (Idle)" - if(circuit_pins.power_draw_per_use) - HTML += "
Power Draw: [circuit_pins.power_draw_per_use] W (Active)" // Borgcode says that power cells' checked_use() takes joules as input. - HTML += "
[circuit_pins.extended_desc]
[words]
[words]
" - - - HTML += "
" - - popup.set_content(HTML) - popup.open() - -/obj/item/electronic_assembly/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["ghostscan"]) - if((isobserver(usr) && ckeys_allowed_to_scan[usr.ckey]) || isAdminGhostAI(usr)) - if(assembly_components.len) - var/saved = "On circuit printers with cloning enabled, you may use the code below to clone the circuit:

[SScircuit.save_electronic_assembly(src)]" - usr << browse(saved, "window=circuit_scan;size=500x600;border=1;can_resize=1;can_close=1;can_minimize=1") - else - to_chat(usr, "The circuit is empty!") - return - - if(!check_interactivity(usr)) - return - - if(href_list["rename"]) - rename(usr) - - if(href_list["remove_cell"]) - if(!battery) - to_chat(usr, "There's no power cell to remove from \the [src].") - else - battery.forceMove(drop_location()) - playsound(src, 'sound/items/Crowbar.ogg', 50, 1) - to_chat(usr, "You pull \the [battery] out of \the [src]'s power supplier.") - battery = null - diag_hud_set_circuitstat() //update diagnostic hud - - var/obj/item/integrated_circuit/component - - if(href_list["component"]) - component = locate(href_list["component"]) in assembly_components - - if(!component) - return - - - if(href_list["scan"]) - var/obj/held_item = usr.get_active_held_item() - if(istype(held_item, /obj/item/integrated_electronics/debugger)) - var/obj/item/integrated_electronics/debugger/D = held_item - if(D.accepting_refs) - D.afterattack(component, usr, TRUE) - else - to_chat(usr, "The debugger's 'ref scanner' needs to be on.") - else - to_chat(usr, "You need a debugger set to 'ref' mode to do that.") - - // Builtin components are not supposed to be removed or rearranged - if(!component.removable) - return - - add_allowed_scanner(usr.ckey) - - // Find the position of a first removable component - var/first_removable_pos = 0 - for(var/i in assembly_components) - first_removable_pos++ - var/obj/item/integrated_circuit/temp_component = i - if(temp_component.removable) - break - - if(href_list["remove"]) - if(try_remove_component(component, usr)) - component = null - - if(href_list["rename_component"]) - component.rename_component(usr) - if(component.assembly) - component.assembly.add_allowed_scanner(usr.ckey) - - if(href_list["interact"]) - var/obj/item/I = usr.get_active_held_item() - if(istype(I)) - I.melee_attack_chain(usr, component) - else - component.attack_hand(usr) - - // Adjust the position - if(href_list["change_pos"]) - var/new_pos = max(input(usr,"Write the new number","New position") as num,1) - - if(new_pos > assembly_components.len) - new_pos = assembly_components.len - - if(new_pos < first_removable_pos) - new_pos = first_removable_pos - - assembly_components.Remove(component) - assembly_components.Insert(new_pos, component) - - interact(usr, component) // To refresh the UI. - -/obj/item/electronic_assembly/pickup(mob/living/user) - . = ..() - //update diagnostic hud when picked up, true is used to force the hud to be hidden - diag_hud_set_circuithealth(TRUE) - diag_hud_set_circuitcell(TRUE) - diag_hud_set_circuitstat(TRUE) - diag_hud_set_circuittracking(TRUE) - -/obj/item/electronic_assembly/dropped(mob/user) - . = ..() - //update diagnostic hud when dropped - diag_hud_set_circuithealth() - diag_hud_set_circuitcell() - diag_hud_set_circuitstat() - diag_hud_set_circuittracking() - -/obj/item/electronic_assembly/proc/rename() - var/mob/M = usr - if(!check_interactivity(M)) - return - - var/input = reject_bad_name(input("What do you want to name this?", "Rename", src.name) as null|text, TRUE) - if(!check_interactivity(M)) - return - if(src && input) - to_chat(M, "The machine now has a label reading '[input]'.") - name = input - -/obj/item/electronic_assembly/proc/add_allowed_scanner(ckey) - ckeys_allowed_to_scan[ckey] = TRUE - -/obj/item/electronic_assembly/proc/can_move() - return FALSE - -/obj/item/electronic_assembly/update_icon() - if(opened) - icon_state = initial(icon_state) + "-open" - else - icon_state = initial(icon_state) - cut_overlays() - if(detail_color == COLOR_ASSEMBLY_BLACK) //Black colored overlay looks almost but not exactly like the base sprite, so just cut the overlay and avoid it looking kinda off. - return - var/mutable_appearance/detail_overlay = mutable_appearance('modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/electronic_setups.dmi', "[icon_state]-color") - detail_overlay.color = detail_color - add_overlay(detail_overlay) - ..() - -/obj/item/electronic_assembly/proc/return_total_complexity() - var/returnvalue = 0 - for(var/obj/item/integrated_circuit/part in assembly_components) - returnvalue += part.complexity - return(returnvalue) - -/obj/item/electronic_assembly/proc/return_total_size() - var/returnvalue = 0 - for(var/obj/item/integrated_circuit/part in assembly_components) - returnvalue += part.size - return(returnvalue) - -// Returns true if the circuit made it inside. -/obj/item/electronic_assembly/proc/try_add_component(obj/item/integrated_circuit/IC, mob/user) - if(!opened) - to_chat(user, "\The [src]'s hatch is closed, you can't put anything inside.") - return FALSE - - if(IC.w_class > w_class) - to_chat(user, "\The [IC] is way too big to fit into \the [src].") - return FALSE - - var/total_part_size = return_total_size() - var/total_complexity = return_total_complexity() - - if(IC.max_allowed) - var/current_components - for(var/obj/item/integrated_circuit/component as anything in assembly_components) - if(component.type == IC.type) - current_components++ - if(current_components >= IC.max_allowed) - to_chat(user, "You can't seem to add the '[IC]', as there are too many installed already.") - return FALSE - - if((total_part_size + IC.size) > max_components) - to_chat(user, "You can't seem to add the '[IC]', as there's insufficient space.") - return FALSE - if((total_complexity + IC.complexity) > max_complexity) - to_chat(user, "You can't seem to add the '[IC]', since this setup's too complicated for the case.") - return FALSE - if((allowed_circuit_action_flags & IC.action_flags) != IC.action_flags) - to_chat(user, "You can't seem to add the '[IC]', since the case doesn't support the circuit type.") - return FALSE - - if(!user.transferItemToLoc(IC, src)) - return FALSE - - to_chat(user, "You slide [IC] inside [src].") - playsound(src, 'sound/items/Deconstruct.ogg', 50, 1) - add_allowed_scanner(user.ckey) - investigate_log("had [IC]([IC.type]) inserted by [key_name(user)].", INVESTIGATE_CIRCUIT) - - add_component(IC) - return TRUE - - -// Actually puts the circuit inside, doesn't perform any checks. -/obj/item/electronic_assembly/proc/add_component(obj/item/integrated_circuit/component) - component.forceMove(get_object()) - component.assembly = src - assembly_components |= component - - //increment numbers for diagnostic hud - if(component.action_flags & IC_ACTION_COMBAT) - combat_circuits += 1; - if(component.action_flags & IC_ACTION_LONG_RANGE) - long_range_circuits += 1; - - //diagnostic hud update - diag_hud_set_circuitstat() - diag_hud_set_circuittracking() - -/obj/item/electronic_assembly/proc/try_remove_component(obj/item/integrated_circuit/IC, mob/user, silent) - if(!opened) - if(!silent) - to_chat(user, "[src]'s hatch is closed, so you can't fiddle with the internal components.") - return FALSE - - if(!IC.removable) - if(!silent) - to_chat(user, "[src] is permanently attached to the case.") - return FALSE - - remove_component(IC) - if(!silent) - to_chat(user, "You pop \the [IC] out of the case, and slide it out.") - playsound(src, 'sound/items/crowbar.ogg', 50, 1) - user.put_in_hands(IC) - add_allowed_scanner(user.ckey) - investigate_log("had [IC]([IC.type]) removed by [key_name(user)].", INVESTIGATE_CIRCUIT) - - return TRUE - -// Actually removes the component, doesn't perform any checks. -/obj/item/electronic_assembly/proc/remove_component(obj/item/integrated_circuit/component) - component.disconnect_all() - component.forceMove(drop_location()) - component.assembly = null - - assembly_components -= component - - //decrement numbers for diagnostic hud - if(component.action_flags & IC_ACTION_COMBAT) - combat_circuits -= 1; - if(component.action_flags & IC_ACTION_LONG_RANGE) - long_range_circuits -= 1; - - //diagnostic hud update - diag_hud_set_circuitstat() - diag_hud_set_circuittracking() - - -/obj/item/electronic_assembly/afterattack(atom/target, mob/user, proximity) - . = ..() - for(var/obj/item/integrated_circuit/input/S in assembly_components) - if(S.sense(target,user,proximity)) - visible_message(" [user] waves [src] around [target].") - - -/obj/item/electronic_assembly/screwdriver_act(mob/living/user, obj/item/I) - if(sealed) - to_chat(user,"The assembly is sealed. Any attempt to force it open would break it.") - return FALSE - if(..()) - return TRUE - I.play_tool_sound(src) - opened = !opened - to_chat(user, "You [opened ? "open" : "close"] the maintenance hatch of [src].") - update_icon() - return TRUE - -/obj/item/electronic_assembly/welder_act(mob/living/user, obj/item/I) - var/type_to_use - - if(!sealed) - type_to_use = input("What would you like to do?","[src] type setting") as null|anything in list("repair", "seal") - else - type_to_use = input("What would you like to do?","[src] type setting") as null|anything in list("repair", "unseal") - - switch(type_to_use) - if("repair") - if(obj_integrity < max_integrity) - obj_integrity = min(obj_integrity + 20,max_integrity) - to_chat(user,"Integrity: [obj_integrity] / [max_integrity]") - to_chat(user,"You fix the dents and scratches of the assembly.") - return TRUE - - else - to_chat(user,"The assembly is already in impeccable condition.") - return FALSE - - if("seal") - if(!opened) - sealed = TRUE - if(I.use_tool(src, user, 50, volume=100, amount=3)) - to_chat(user,"You seal the assembly, making it impossible to be opened.") - return TRUE - - else - to_chat(user,"You need to close the assembly first before sealing it indefinitely!") - return FALSE - - if("unseal") - to_chat(user,"You start unsealing the assembly carefully...") - if(I.use_tool(src, user, 50, volume=250, amount=3)) - for(var/obj/item/integrated_circuit/IC in assembly_components) - if(prob(50)) - IC.disconnect_all() - - to_chat(user,"You unsealed the assembly.") - sealed = FALSE - return TRUE - -/obj/item/electronic_assembly/attackby(obj/item/I, mob/living/user) - if(can_anchor && default_unfasten_wrench(user, I, 20)) - return - - // ID-Lock part: check if we have an id-lock and only lock if we're not trying to get values from it, to prevent accidents - if(istype(I, /obj/item/integrated_electronics/debugger)) - var/obj/item/integrated_electronics/debugger/debugger = I - if(debugger.idlock) - // check if unlocked to lock - if(!idlock) - idlock = debugger.idlock - to_chat(user,"You lock \the [src].") - - //if locked, unlock if ids match - else - if(idlock.resolve() == debugger.idlock.resolve()) - idlock = null - to_chat(user,"You unlock \the [src].") - - else - to_chat(user,"The scanned ID doesn't match with \the [src]'s lock.") - - debugger.idlock = null - return - - if(istype(I, /obj/item/integrated_circuit)) - if(!user.canUnEquip(I)) - return FALSE - if(try_add_component(I, user)) - return TRUE - else - for(var/obj/item/integrated_circuit/input/S in assembly_components) - S.attackby_react(I,user) - return ..() - - else if(I.tool_behaviour == TOOL_MULTITOOL || istype(I, /obj/item/integrated_electronics/wirer) || istype(I, /obj/item/integrated_electronics/debugger)) - if(opened) - interact(user) - return TRUE - else - to_chat(user, "[src]'s hatch is closed, so you can't fiddle with the internal components.") - for(var/obj/item/integrated_circuit/input/S in assembly_components) - S.attackby_react(I,user) - return ..() - - else if(istype(I, /obj/item/stock_parts/cell)) - if(!opened) - to_chat(user, "[src]'s hatch is closed, so you can't access \the [src]'s power supplier.") - for(var/obj/item/integrated_circuit/input/S in assembly_components) - S.attackby_react(I,user) - return ..() - if(battery) - to_chat(user, "[src] already has \a [battery] installed. Remove it first if you want to replace it.") - for(var/obj/item/integrated_circuit/input/S in assembly_components) - S.attackby_react(I,user) - return ..() - I.forceMove(src) - battery = I - diag_hud_set_circuitstat() //update diagnostic hud - playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) - to_chat(user, "You slot the [I] inside \the [src]'s power supplier.") - return TRUE - - else if(istype(I, /obj/item/integrated_electronics/detailer)) - var/obj/item/integrated_electronics/detailer/D = I - detail_color = D.detail_color - update_icon() - - else - if(user.combat_mode) - return ..() - var/list/input_selection = list() - //Check all the components asking for an input - for(var/obj/item/integrated_circuit/input in assembly_components) - if((input.demands_object_input && opened) || (input.demands_object_input && input.can_input_object_when_closed)) - var/i = 0 - //Check if there is another component with the same name and append a number for identification - for(var/s in input_selection) - var/obj/item/integrated_circuit/s_circuit = input_selection[s] //The for-loop iterates the keys of the associative list. - if(s_circuit.name == input.name && s_circuit.displayed_name == input.displayed_name && s_circuit != input) - i++ - var/disp_name= "[input.displayed_name] \[[input]\]" - if(i) - disp_name += " ([i+1])" - //Associative lists prevent me from needing another list and using a Find proc - input_selection[disp_name] = input - - var/obj/item/integrated_circuit/choice - if(input_selection) - if(input_selection.len == 1) - choice = input_selection[input_selection[1]] - else - var/selection = input(user, "Where do you want to insert that item?", "Interaction") as null|anything in input_selection - if(!check_interactivity(user)) - return ..() - if(selection) - choice = input_selection[selection] - if(choice) - choice.additem(I, user) - for(var/obj/item/integrated_circuit/input/S in assembly_components) - S.attackby_react(I,user) - return ..() - - -/obj/item/electronic_assembly/attack_self(mob/user) - if(!check_interactivity(user)) - return - if(opened) - interact(user) - - var/list/input_selection = list() - //Check all the components asking for an input - for(var/obj/item/integrated_circuit/input/input in assembly_components) - if(input.can_be_asked_input) - var/i = 0 - //Check if there is another component with the same name and append a number for identification - for(var/s in input_selection) - var/obj/item/integrated_circuit/s_circuit = input_selection[s] //The for-loop iterates the keys of an associative list. - if(s_circuit.name == input.name && s_circuit.displayed_name == input.displayed_name && s_circuit != input) - i++ - var/disp_name= "[input.displayed_name] \[[input]\]" - if(i) - disp_name += " ([i+1])" - //Associative lists prevent me from needing another list and using a Find proc - input_selection[disp_name] = input - - var/obj/item/integrated_circuit/input/choice - - - if(input_selection) - if(input_selection.len ==1) - choice = input_selection[input_selection[1]] - else - var/selection = input(user, "What do you want to interact with?", "Interaction") as null|anything in input_selection - if(!check_interactivity(user)) - return - if(selection) - choice = input_selection[selection] - - if(choice) - choice.ask_for_input(user) - -/obj/item/electronic_assembly/emp_act(severity) - . = ..() - if(. & EMP_PROTECT_CONTENTS) - return - for(var/I in src) - var/atom/movable/AM = I - AM.emp_act(severity) - -// Returns true if power was successfully drawn. -/obj/item/electronic_assembly/proc/draw_power(amount) - if(battery && battery.use(amount * GLOB.CELLRATE)) - return TRUE - return FALSE - -// Ditto for giving. -/obj/item/electronic_assembly/proc/give_power(amount) - if(battery && battery.give(amount * GLOB.CELLRATE)) - return TRUE - return FALSE - -/obj/item/electronic_assembly/Moved(oldLoc, dir) - for(var/I in assembly_components) - var/obj/item/integrated_circuit/IC = I - IC.ext_moved(oldLoc, dir) - if(light) //Update lighting objects (From light circuits). - update_light() - ..() - -/obj/item/electronic_assembly/stop_pulling() - for(var/I in assembly_components) - var/obj/item/integrated_circuit/IC = I - IC.stop_pulling() - ..() - - -// Returns the object that is supposed to be used in attack messages, location checks, etc. -// Override in children for special behavior. -/obj/item/electronic_assembly/proc/get_object() - return src - -// Returns the location to be used for dropping items. -// Same as the regular drop_location(), but with checks being run on acting_object if necessary. -/obj/item/integrated_circuit/drop_location() - var/atom/movable/acting_object = get_object() - - // plz no infinite loops - if(acting_object == src) - return ..() - - return acting_object.drop_location() - -/obj/item/electronic_assembly/attack_tk(mob/user) - if(anchored) - return - ..() - -/obj/item/electronic_assembly/attack_hand(mob/user) - if(anchored) - attack_self(user) - return - ..() - -/obj/item/electronic_assembly/default //The /default electronic_assemblys are to allow the introduction of the new naming scheme without breaking old saves. - name = "type-a electronic assembly" - -/obj/item/electronic_assembly/calc - name = "type-b electronic assembly" - icon_state = "setup_small_calc" - desc = "A case designed for building small electronics. This one resembles a pocket calculator." - -/obj/item/electronic_assembly/clam - name = "type-c electronic assembly" - icon_state = "setup_small_clam" - desc = "A case designed for building small electronics. This one has a clamshell design." - -/obj/item/electronic_assembly/simple - name = "type-d electronic assembly" - icon_state = "setup_small_simple" - desc = "A case designed for building small electronics. This one has a simple design." - -/obj/item/electronic_assembly/hook - name = "type-e electronic assembly" - icon_state = "setup_small_hook" - desc = "A case designed for building small electronics. This one looks like it has a belt clip, but it's purely decorative." - -/obj/item/electronic_assembly/pda - name = "type-f electronic assembly" - icon_state = "setup_small_pda" - desc = "A case designed for building small electronics. This one resembles a PDA." - -/obj/item/electronic_assembly/small - name = "electronic device" - icon_state = "setup_device" - desc = "A case designed for building tiny-sized electronics." - w_class = WEIGHT_CLASS_TINY - max_components = IC_MAX_SIZE_BASE / 2 - max_complexity = IC_COMPLEXITY_BASE / 2 - -/obj/item/electronic_assembly/small/default - name = "type-a electronic device" - -/obj/item/electronic_assembly/small/cylinder - name = "type-b electronic device" - icon_state = "setup_device_cylinder" - desc = "A case designed for building tiny-sized electronics. This one has a cylindrical design." - -/obj/item/electronic_assembly/small/scanner - name = "type-c electronic device" - icon_state = "setup_device_scanner" - desc = "A case designed for building tiny-sized electronics. This one has a scanner-like design." - -/obj/item/electronic_assembly/small/hook - name = "type-d electronic device" - icon_state = "setup_device_hook" - desc = "A case designed for building tiny-sized electronics. This one looks like it has a belt clip, but it's purely decorative." - -/obj/item/electronic_assembly/small/box - name = "type-e electronic device" - icon_state = "setup_device_box" - desc = "A case designed for building tiny-sized electronics. This one has a box design." - -/obj/item/electronic_assembly/medium - name = "electronic mechanism" - icon_state = "setup_medium" - desc = "A case designed for building medium-sized electonics." - w_class = WEIGHT_CLASS_NORMAL - max_components = IC_MAX_SIZE_BASE * 2 - max_complexity = IC_COMPLEXITY_BASE * 2 - -/obj/item/electronic_assembly/medium/default - name = "type-a electronic mechanism" - -/obj/item/electronic_assembly/medium/box - name = "type-b electronic mechanism" - icon_state = "setup_medium_box" - desc = "A case designed for building medium-sized electonics. This one has a box design." - -/obj/item/electronic_assembly/medium/clam - name = "type-c electronic mechanism" - icon_state = "setup_medium_clam" - desc = "A case designed for building medium-sized electonics. This one has a clamshell design." - -/obj/item/electronic_assembly/medium/medical - name = "type-d electronic mechanism" - icon_state = "setup_medium_med" - desc = "A case designed for building medium-sized electonics. This one resembles medical apparatus." - -/* SKYRAT PORT temp removal -/obj/item/electronic_assembly/medium/gun - name = "type-e electronic mechanism" - icon_state = "setup_medium_gun" - item_state = "circuitgun" - desc = "A case designed for building medium-sized electonics. This one resembles a gun, or some type of tool, if you're feeling optimistic. It can fire guns and throw items while the user is holding it." - lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' - can_fire_equipped = TRUE -*/ - -/obj/item/electronic_assembly/medium/radio - name = "type-f electronic mechanism" - icon_state = "setup_medium_radio" - desc = "A case designed for building medium-sized electonics. This one resembles an old radio." - -/obj/item/electronic_assembly/large - name = "electronic machine" - icon_state = "setup_large" - desc = "A case designed for building large electronics." - w_class = WEIGHT_CLASS_BULKY - max_components = IC_MAX_SIZE_BASE * 4 - max_complexity = IC_COMPLEXITY_BASE * 4 - -/obj/item/electronic_assembly/large/default - name = "type-a electronic machine" - -/obj/item/electronic_assembly/large/scope - name = "type-b electronic machine" - icon_state = "setup_large_scope" - desc = "A case designed for building large electronics. This one resembles an oscilloscope." - -/obj/item/electronic_assembly/large/terminal - name = "type-c electronic machine" - icon_state = "setup_large_terminal" - desc = "A case designed for building large electronics. This one resembles a computer terminal." - -/obj/item/electronic_assembly/large/arm - name = "type-d electronic machine" - icon_state = "setup_large_arm" - desc = "A case designed for building large electronics. This one resembles a robotic arm." - -/obj/item/electronic_assembly/large/tall - name = "type-e electronic machine" - icon_state = "setup_large_tall" - desc = "A case designed for building large electronics. This one has a tall design." - -/obj/item/electronic_assembly/large/industrial - name = "type-f electronic machine" - icon_state = "setup_large_industrial" - desc = "A case designed for building mobile electronics. This one resembles industrial machinery." - -/obj/item/electronic_assembly/drone - name = "electronic drone" - icon_state = "setup_drone" - desc = "A case designed for building mobile electronics." - w_class = WEIGHT_CLASS_BULKY - max_components = IC_MAX_SIZE_BASE * 3 - max_complexity = IC_COMPLEXITY_BASE * 3 - allowed_circuit_action_flags = IC_ACTION_MOVEMENT | IC_ACTION_COMBAT | IC_ACTION_LONG_RANGE - can_anchor = FALSE - -/obj/item/electronic_assembly/drone/can_move() - return TRUE - -/obj/item/electronic_assembly/drone/default - name = "type-a electronic drone" - -/obj/item/electronic_assembly/drone/arms - name = "type-b electronic drone" - icon_state = "setup_drone_arms" - desc = "A case designed for building mobile electronics. This one is armed and dangerous." - -/obj/item/electronic_assembly/drone/secbot - name = "type-c electronic drone" - icon_state = "setup_drone_secbot" - desc = "A case designed for building mobile electronics. This one resembles a Securitron." - -/obj/item/electronic_assembly/drone/medbot - name = "type-d electronic drone" - icon_state = "setup_drone_medbot" - desc = "A case designed for building mobile electronics. This one resembles a Medibot." - -/obj/item/electronic_assembly/drone/genbot - name = "type-e electronic drone" - icon_state = "setup_drone_genbot" - desc = "A case designed for building mobile electronics. This one has a generic bot design." - -/obj/item/electronic_assembly/drone/android - name = "type-f electronic drone" - icon_state = "setup_drone_android" - desc = "A case designed for building mobile electronics. This one has a hominoid design." - -/obj/item/electronic_assembly/wallmount - name = "wall-mounted electronic assembly" - icon_state = "setup_wallmount_medium" - desc = "A case designed for building medium-sized electronics.. It has a magnetized backing to allow it to stick to walls, but you'll still need to wrench the anchoring bolts in place to keep it on." - w_class = WEIGHT_CLASS_NORMAL - max_components = IC_MAX_SIZE_BASE * 2 - max_complexity = IC_COMPLEXITY_BASE * 2 - -/obj/item/electronic_assembly/wallmount/heavy - name = "heavy wall-mounted electronic assembly" - icon_state = "setup_wallmount_large" - desc = "A case designed for building large electronics. It has a magnetized backing to allow it to stick to walls, but you'll still need to wrench the anchoring bolts in place to keep it on." - w_class = WEIGHT_CLASS_BULKY - max_components = IC_MAX_SIZE_BASE * 4 - max_complexity = IC_COMPLEXITY_BASE * 4 - -/obj/item/electronic_assembly/wallmount/light - name = "light wall-mounted electronic assembly" - icon_state = "setup_wallmount_small" - desc = "A case designed for building small electronics. It has a magnetized backing to allow it to stick to walls, but you'll still need to wrench the anchoring bolts in place to keep it on." - w_class = WEIGHT_CLASS_SMALL - max_components = IC_MAX_SIZE_BASE - max_complexity = IC_COMPLEXITY_BASE - -/obj/item/electronic_assembly/wallmount/tiny - name = "tiny wall-mounted electronic assembly" - icon_state = "setup_wallmount_tiny" - desc = "It's a case, for building tiny electronics with. It has a magnetized backing to allow it to stick to walls, but you'll still need to wrench the anchoring bolts in place to keep it on." - w_class = WEIGHT_CLASS_TINY - max_components = IC_MAX_SIZE_BASE / 2 - max_complexity = IC_COMPLEXITY_BASE / 2 - -/obj/item/electronic_assembly/wallmount/proc/mount_assembly(turf/on_wall, mob/user) //Yeah, this is admittedly just an abridged and kitbashed version of the wallframe attach procs. - if(get_dist(on_wall,user)>1) - return - var/ndir = get_dir(on_wall, user) - if(!(ndir in GLOB.cardinals)) - return - var/turf/T = get_turf(user) - if(!isfloorturf(T)) - to_chat(user, "You cannot place [src] on this spot!") - return - if(gotwallitem(T, ndir)) - to_chat(user, "There's already an item on this wall!") - return - playsound(src.loc, 'sound/machines/click.ogg', 75, 1) - user.visible_message("[user.name] attaches [src] to the wall.", - "You attach [src] to the wall.", - "You hear clicking.") - user.dropItemToGround(src) - switch(ndir) - if(NORTH) - pixel_y = -31 - if(SOUTH) - pixel_y = 31 - if(EAST) - pixel_x = -31 - if(WEST) - pixel_x = 31 diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_ears.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_ears.dm deleted file mode 100644 index 058eef7beae..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_ears.dm +++ /dev/null @@ -1,47 +0,0 @@ -// Ear -/obj/item/clothing/ears/circuitry - name = "electronic earwear" - desc = "It's a wearable case for electronics. This one appears to be a technical-looking headset." - icon = 'modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_ears.dmi' - icon_state = "circuitry" - worn_icon_state = "circuitry" // Needed since icon_state gets updated by the assembly - worn_icon = 'modular_skyrat/modules/integrated_circuits/icons/mob/clothing/circuit_ears.dmi' - actions_types = list(/datum/action/item_action/toggle_circuit) - -/obj/item/clothing/ears/circuitry/Initialize() - setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small) - integrated_circuit.update_icon() - return ..() - -/obj/item/clothing/ears/circuitry/examine(mob/user) - . = ..() - if(integrated_circuit) - . += integrated_circuit.examine(user) - -/obj/item/clothing/ears/circuitry/emp_act(severity) - if(integrated_circuit) - integrated_circuit.emp_act(severity) - ..() - -/obj/item/clothing/ears/circuitry/attackby(obj/item/I, mob/user, params) - if(I.tool_behaviour == TOOL_SCREWDRIVER && integrated_circuit.screwdriver_act(user, I)) - return TRUE - if(integrated_circuit.attackby(I, user, params)) - return TRUE - ..() - -/obj/item/clothing/ears/circuitry/attack_self(mob/user) - if(integrated_circuit) - if(integrated_circuit.opened) - integrated_circuit.attack_self(user) - else - action_circuit.do_work() - else - ..() - -/obj/item/clothing/ears/circuitry/Destroy() - if(integrated_circuit) - integrated_circuit.clothing = null - action_circuit = null // Will get deleted by qdel-ing the integrated_circuit assembly. - qdel(integrated_circuit) - return ..() diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_glasses.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_glasses.dm deleted file mode 100644 index 07196a3502c..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_glasses.dm +++ /dev/null @@ -1,48 +0,0 @@ -// Glasses. -/obj/item/clothing/glasses/circuitry - name = "electronic goggles" - desc = "It's a wearable case for electronics. This one is a pair of goggles, with wiring sticking out. \ - Could this augment your vision?" // Sadly it won't, or at least not yet. - icon = 'modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_glasses.dmi' - icon_state = "circuitry" - worn_icon_state = "circuitry" // Needed since icon_state gets updated by the assembly - worn_icon = 'modular_skyrat/modules/integrated_circuits/icons/mob/clothing/circuit_glasses.dmi' - actions_types = list(/datum/action/item_action/toggle_circuit) - -/obj/item/clothing/glasses/circuitry/Initialize() - setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small) - integrated_circuit.update_icon() - return ..() - -/obj/item/clothing/glasses/circuitry/examine(mob/user) - . = ..() - if(integrated_circuit) - . += integrated_circuit.examine(user) - -/obj/item/clothing/glasses/circuitry/emp_act(severity) - if(integrated_circuit) - integrated_circuit.emp_act(severity) - ..() - -/obj/item/clothing/glasses/circuitry/attackby(obj/item/I, mob/user, params) - if(I.tool_behaviour == TOOL_SCREWDRIVER && integrated_circuit.screwdriver_act(user, I)) - return TRUE - if(integrated_circuit.attackby(I, user, params)) - return TRUE - ..() - -/obj/item/clothing/glasses/circuitry/attack_self(mob/user) - if(integrated_circuit) - if(integrated_circuit.opened) - integrated_circuit.attack_self(user) - else - action_circuit.do_work() - else - ..() - -/obj/item/clothing/glasses/circuitry/Destroy() - if(integrated_circuit) - integrated_circuit.clothing = null - action_circuit = null // Will get deleted by qdel-ing the integrated_circuit assembly. - qdel(integrated_circuit) - return ..() diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_gloves.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_gloves.dm deleted file mode 100644 index 664a826c649..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_gloves.dm +++ /dev/null @@ -1,48 +0,0 @@ -// Gloves. -/obj/item/clothing/gloves/circuitry - name = "electronic gloves" - desc = "It's a wearable case for electronics. This one is a pair of black gloves, with wires woven into them. A small \ - device with a screen is attached to the left glove." - icon = 'modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_gloves.dmi' - icon_state = "circuitry" - worn_icon_state = "circuitry" // Needed since icon_state gets updated by the assembly - worn_icon = 'modular_skyrat/modules/integrated_circuits/icons/mob/clothing/circuit_gloves.dmi' - actions_types = list(/datum/action/item_action/toggle_circuit) - -/obj/item/clothing/gloves/circuitry/Initialize() - setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small) - integrated_circuit.update_icon() - return ..() - -/obj/item/clothing/gloves/circuitry/examine(mob/user) - . = ..() - if(integrated_circuit) - . += integrated_circuit.examine(user) - -/obj/item/clothing/gloves/circuitry/emp_act(severity) - if(integrated_circuit) - integrated_circuit.emp_act(severity) - ..() - -/obj/item/clothing/gloves/circuitry/attackby(obj/item/I, mob/user, params) - if(I.tool_behaviour == TOOL_SCREWDRIVER && integrated_circuit.screwdriver_act(user, I)) - return TRUE - if(integrated_circuit.attackby(I, user, params)) - return TRUE - ..() - -/obj/item/clothing/gloves/circuitry/attack_self(mob/user) - if(integrated_circuit) - if(integrated_circuit.opened) - integrated_circuit.attack_self(user) - else - action_circuit.do_work() - else - ..() - -/obj/item/clothing/gloves/circuitry/Destroy() - if(integrated_circuit) - integrated_circuit.clothing = null - action_circuit = null // Will get deleted by qdel-ing the integrated_circuit assembly. - qdel(integrated_circuit) - return ..() diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_head.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_head.dm deleted file mode 100644 index d716cf30bf1..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_head.dm +++ /dev/null @@ -1,49 +0,0 @@ -// Head -/obj/item/clothing/head/circuitry - name = "electronic headwear" - desc = "It's a wearable case for electronics. This one appears to be a very technical-looking piece that \ - goes around the collar, with a heads-up-display attached on the right." - icon = 'modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_head.dmi' - icon_state = "circuitry" - worn_icon_state = "circuitry" // Needed since icon_state gets updated by the assembly - worn_icon = 'modular_skyrat/modules/integrated_circuits/icons/mob/clothing/circuit_head.dmi' - mutant_variants = FALSE // not yet? - actions_types = list(/datum/action/item_action/toggle_circuit) - -/obj/item/clothing/head/circuitry/Initialize() - setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small) - integrated_circuit.update_icon() - return ..() - -/obj/item/clothing/head/circuitry/examine(mob/user) - . = ..() - if(integrated_circuit) - . += integrated_circuit.examine(user) - -/obj/item/clothing/head/circuitry/emp_act(severity) - if(integrated_circuit) - integrated_circuit.emp_act(severity) - ..() - -/obj/item/clothing/head/circuitry/attackby(obj/item/I, mob/user, params) - if(I.tool_behaviour == TOOL_SCREWDRIVER && integrated_circuit.screwdriver_act(user, I)) - return TRUE - if(integrated_circuit.attackby(I, user, params)) - return TRUE - ..() - -/obj/item/clothing/head/circuitry/attack_self(mob/user) - if(integrated_circuit) - if(integrated_circuit.opened) - integrated_circuit.attack_self(user) - else - action_circuit.do_work() - else - ..() - -/obj/item/clothing/head/circuitry/Destroy() - if(integrated_circuit) - integrated_circuit.clothing = null - action_circuit = null // Will get deleted by qdel-ing the integrated_circuit assembly. - qdel(integrated_circuit) - return ..() diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_shoes.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_shoes.dm deleted file mode 100644 index 9249fdb5d1e..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_shoes.dm +++ /dev/null @@ -1,48 +0,0 @@ -// Shoes -/obj/item/clothing/shoes/circuitry - name = "electronic boots" - desc = "It's a wearable case for electronics. This one is a pair of boots, with wires attached to a small \ - cover." - icon = 'modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_shoes.dmi' - icon_state = "circuitry" - worn_icon_state = "circuitry" // Needed since icon_state gets updated by the assembly - worn_icon = 'modular_skyrat/modules/integrated_circuits/icons/mob/clothing/circuit_shoes.dmi' - actions_types = list(/datum/action/item_action/toggle_circuit) - -/obj/item/clothing/shoes/circuitry/Initialize() - setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small) - integrated_circuit.update_icon() - return ..() - -/obj/item/clothing/shoes/circuitry/examine(mob/user) - . = ..() - if(integrated_circuit) - . += integrated_circuit.examine(user) - -/obj/item/clothing/shoes/circuitry/emp_act(severity) - if(integrated_circuit) - integrated_circuit.emp_act(severity) - ..() - -/obj/item/clothing/shoes/circuitry/attackby(obj/item/I, mob/user, params) - if(I.tool_behaviour == TOOL_SCREWDRIVER && integrated_circuit.screwdriver_act(user, I)) - return TRUE - if(integrated_circuit.attackby(I, user, params)) - return TRUE - ..() - -/obj/item/clothing/shoes/circuitry/attack_self(mob/user) - if(integrated_circuit) - if(integrated_circuit.opened) - integrated_circuit.attack_self(user) - else - action_circuit.do_work() - else - ..() - -/obj/item/clothing/shoes/circuitry/Destroy() - if(integrated_circuit) - integrated_circuit.clothing = null - action_circuit = null // Will get deleted by qdel-ing the integrated_circuit assembly. - qdel(integrated_circuit) - return ..() diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_suit.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_suit.dm deleted file mode 100644 index cf0d0004c07..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_suit.dm +++ /dev/null @@ -1,49 +0,0 @@ -// Exo-slot -/obj/item/clothing/suit/circuitry - name = "electronic chestpiece" - desc = "It's a wearable case for electronics. This one appears to be a very technical-looking vest, that \ - almost looks professionally made, however the wiring popping out betrays that idea." - icon = 'modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_suit.dmi' - icon_state = "circuitry" - worn_icon_state = "circuitry" // Needed since icon_state gets updated by the assembly - worn_icon = 'modular_skyrat/modules/integrated_circuits/icons/mob/clothing/circuit_suit.dmi' - mutant_variants = FALSE - actions_types = list(/datum/action/item_action/toggle_circuit) - -/obj/item/clothing/suit/circuitry/Initialize() - setup_integrated_circuit(/obj/item/electronic_assembly/clothing/large) - integrated_circuit.update_icon() - return ..() - -/obj/item/clothing/suit/circuitry/examine(mob/user) - . = ..() - if(integrated_circuit) - . += integrated_circuit.examine(user) - -/obj/item/clothing/suit/circuitry/emp_act(severity) - if(integrated_circuit) - integrated_circuit.emp_act(severity) - ..() - -/obj/item/clothing/suit/circuitry/attackby(obj/item/I, mob/user, params) - if(I.tool_behaviour == TOOL_SCREWDRIVER && integrated_circuit.screwdriver_act(user, I)) - return TRUE - if(integrated_circuit.attackby(I, user, params)) - return TRUE - ..() - -/obj/item/clothing/suit/circuitry/attack_self(mob/user) - if(integrated_circuit) - if(integrated_circuit.opened) - integrated_circuit.attack_self(user) - else - action_circuit.do_work() - else - ..() - -/obj/item/clothing/suit/circuitry/Destroy() - if(integrated_circuit) - integrated_circuit.clothing = null - action_circuit = null // Will get deleted by qdel-ing the integrated_circuit assembly. - qdel(integrated_circuit) - return ..() diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_under.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_under.dm deleted file mode 100644 index 2808aa58202..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/circuit_under.dm +++ /dev/null @@ -1,48 +0,0 @@ -// Jumpsuit. -/obj/item/clothing/under/circuitry - name = "electronic jumpsuit" - desc = "It's a wearable case for electronics. This on is a black jumpsuit with wiring weaved into the fabric." - can_adjust = FALSE - icon = 'modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_under.dmi' - icon_state = "circuitry" - worn_icon_state = "circuitry" // Needed since icon_state gets updated by the assembly - worn_icon = 'modular_skyrat/modules/integrated_circuits/icons/mob/clothing/under/circuit_under.dmi' - actions_types = list(/datum/action/item_action/toggle_circuit) - -/obj/item/clothing/under/circuitry/Initialize() - setup_integrated_circuit(/obj/item/electronic_assembly/clothing) - integrated_circuit.update_icon() - return ..() - -/obj/item/clothing/under/circuitry/examine(mob/user) - . = ..() - if(integrated_circuit) - . += integrated_circuit.examine(user) - -/obj/item/clothing/under/circuitry/emp_act(severity) - if(integrated_circuit) - integrated_circuit.emp_act(severity) - ..() - -/obj/item/clothing/under/circuitry/attackby(obj/item/I, mob/user, params) - if(I.tool_behaviour == TOOL_SCREWDRIVER && integrated_circuit.screwdriver_act(user, I)) - return TRUE - if(integrated_circuit.attackby(I, user, params)) - return TRUE - ..() - -/obj/item/clothing/under/circuitry/attack_self(mob/user) - if(integrated_circuit) - if(integrated_circuit.opened) - integrated_circuit.attack_self(user) - else - action_circuit.do_work() - else - ..() - -/obj/item/clothing/under/circuitry/Destroy() - if(integrated_circuit) - integrated_circuit.clothing = null - action_circuit = null // Will get deleted by qdel-ing the integrated_circuit assembly. - qdel(integrated_circuit) - return ..() diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/clothing.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/clothing.dm deleted file mode 100644 index 71650c5e1e5..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/clothing/clothing.dm +++ /dev/null @@ -1,84 +0,0 @@ - -// The base subtype for assemblies that can be worn. Certain pieces will have more or less capabilities -// E.g. Glasses have less room than something worn over the chest. -// Note that the electronic assembly is INSIDE the object that actually gets worn, in a similar way to implants. - -/obj/item/electronic_assembly/clothing - name = "electronic clothing" - icon_state = "circuitry" - worn_icon_state = "circuitry" // Needed since icon_state gets updated by the assembly - // Needs to match the clothing's base icon_state. - desc = "It's a case, for building machines attached to clothing." - w_class = WEIGHT_CLASS_SMALL - max_components = IC_MAX_SIZE_BASE - max_complexity = IC_COMPLEXITY_BASE - var/obj/item/clothing/clothing = null - -/* SKYRAT PORT - NanoUI stuff commented out, idk if it will cause issues -/obj/item/electronic_assembly/clothing/nano_host() - return clothing - -/obj/item/electronic_assembly/clothing/resolve_nano_host() - return clothing -*/ - -/obj/item/electronic_assembly/clothing/update_icon() - ..() - clothing.icon_state = icon_state - // We don't need to update the mob sprite since it won't (and shouldn't) actually get changed. - -// This is 'small' relative to the size of regular clothing assemblies. -/obj/item/electronic_assembly/clothing/small - max_components = IC_MAX_SIZE_BASE / 2 - max_complexity = IC_COMPLEXITY_BASE / 2 - w_class = WEIGHT_CLASS_TINY - -// Ditto. -/obj/item/electronic_assembly/clothing/large - max_components = IC_MAX_SIZE_BASE * 2 - max_complexity = IC_COMPLEXITY_BASE * 2 - w_class = WEIGHT_CLASS_NORMAL - -/* -// Integrated button for doing integrated button things -*/ - -/obj/item/integrated_circuit/built_in - name = "integrated circuit" - desc = "It's a tiny chip! This one doesn't seem to do much, however." - icon_state = "template" - size = -1 - w_class = WEIGHT_CLASS_TINY - removable = FALSE // Determines if a circuit is removable from the assembly. - -// Triggered when clothing assembly's hud button is clicked (or used inhand). -/obj/item/integrated_circuit/built_in/action_button - name = "external trigger circuit" - desc = "A built in chip that outputs a pulse when an external control event occurs." - extended_desc = "This outputs a pulse if the assembly's HUD button is clicked while the assembly is closed." - complexity = 0 - activators = list("on activation" = IC_PINTYPE_PULSE_OUT) - -/obj/item/integrated_circuit/built_in/action_button/do_work() - activate_pin(1) - -/* -// Extra vars for clothing here -*/ -/obj/item/clothing/ - var/obj/item/electronic_assembly/clothing/integrated_circuit = null - var/obj/item/integrated_circuit/built_in/action_button/action_circuit = null // This gets pulsed when someone clicks the button on the hud. - -// Does most of the repeatative setup. -/obj/item/clothing/proc/setup_integrated_circuit(new_type) - // Set up the internal circuit holder. - integrated_circuit = new new_type(src) - integrated_circuit.clothing = src - integrated_circuit.name = name - - // Clothing assemblies can be triggered by clicking on the HUD. This allows that to occur. - action_circuit = new(src.integrated_circuit) - integrated_circuit.add_component(action_circuit) - -/datum/action/item_action/toggle_circuit - name = "Toggle Integrated Circuit" diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/debugger.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/debugger.dm deleted file mode 100644 index db5e525e2f5..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/debugger.dm +++ /dev/null @@ -1,109 +0,0 @@ -/obj/item/integrated_electronics/debugger - name = "circuit debugger" - desc = "This small tool allows one working with custom machinery to directly set data to a specific pin, useful for writing \ - settings to specific circuits, or for debugging purposes. It can also pulse activation pins." - icon = 'modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/electronic_tools.dmi' - icon_state = "debugger" - flags_1 = CONDUCT_1 - item_flags = NOBLUDGEON - w_class = WEIGHT_CLASS_SMALL - custom_materials = list(/datum/material/iron=200) - var/data_to_write = null - var/accepting_refs = FALSE - var/copy_values = FALSE - var/copy_id = FALSE - var/datum/weakref/idlock = null - -/obj/item/integrated_electronics/debugger/attack_self(mob/user) - var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref","copy","null","id lock") - if(!ISADVANCEDTOOLUSER(user)) - return - - var/new_data = null - switch(type_to_use) - if("string") - accepting_refs = FALSE - copy_values = FALSE - copy_id = FALSE - new_data = stripped_input(user, "Now type in a string.","[src] string writing", no_trim = TRUE) - if(istext(new_data) && ISADVANCEDTOOLUSER(user)) - data_to_write = new_data - to_chat(user, "You set \the [src]'s memory to \"[new_data]\".") - if("number") - accepting_refs = FALSE - copy_values = FALSE - copy_id = FALSE - new_data = input(user, "Now type in a number.","[src] number writing") as null|num - if(isnum_safe(new_data) && ISADVANCEDTOOLUSER(user)) - data_to_write = new_data - to_chat(user, "You set \the [src]'s memory to [new_data].") - if("ref") - accepting_refs = TRUE - copy_values = FALSE - copy_id = FALSE - to_chat(user, "You turn \the [src]'s ref scanner on. Slide it across \ - an object for a ref of that object to save it in memory.") - if("copy") - accepting_refs = FALSE - copy_values = TRUE - copy_id = FALSE - to_chat(user, "You turn \the [src]'s value copier on. Use it on a pin \ - to save its current value in memory.") - if("null") - data_to_write = null - copy_values = FALSE - to_chat(user, "You set \the [src]'s memory to absolutely nothing.") - if("id lock") - accepting_refs = FALSE - copy_values = FALSE - copy_id = TRUE - to_chat(user, "You turn \the [src]'s id card scanner on. Use your own card \ - to store the identity and id-lock an assembly.") - -/obj/item/integrated_electronics/debugger/afterattack(atom/target, mob/living/user, proximity) - . = ..() - if(accepting_refs && proximity) - data_to_write = WEAKREF(target) - visible_message("[user] slides \a [src]'s over \the [target].") - to_chat(user, "You set \the [src]'s memory to a reference to [target.name] \[Ref\]. The ref scanner is \ - now off.") - accepting_refs = FALSE - - else if(copy_id && proximity) - if(istype(target,/obj/item/card/id)) - idlock = WEAKREF(target) - to_chat(user, "You set \the [src]'s card memory to [target.name]. The id card scanner is \ - now off.") - - else - to_chat(user, "You turn the id card scanner is off.") - - copy_id = FALSE - return - -/obj/item/integrated_electronics/debugger/proc/write_data(var/datum/integrated_io/io, mob/user) - //If the pin can take data: - if(io.io_type == DATA_CHANNEL) - //If the debugger is set to copy, copy the data in the pin onto it - if(copy_values) - data_to_write = io.data - to_chat(user, "You let the debugger copy the data.") - copy_values = FALSE - return - - //Else, write the data to the pin - io.write_data_to_pin(data_to_write) - var/data_to_show = data_to_write - //This is only to convert a weakref into a name for better output - if(isweakref(data_to_write)) - var/datum/weakref/w = data_to_write - var/atom/A = w.resolve() - data_to_show = A.name - to_chat(user, "You write '[data_to_write ? data_to_show : "NULL"]' to the '[io]' pin of \the [io.holder].") - - //If the pin can only be pulsed - else if(io.io_type == PULSE_CHANNEL) - io.holder.check_then_do_work(io.ord,ignore_power = TRUE) - to_chat(user, "You pulse \the [io.holder]'s [io].") - - io.holder.interact(user) // This is to update the UI. diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/detailer.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/detailer.dm deleted file mode 100644 index 262b24b4064..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/detailer.dm +++ /dev/null @@ -1,50 +0,0 @@ -/obj/item/integrated_electronics/detailer - name = "assembly detailer" - desc = "A combination autopainter and flash anodizer designed to give electronic assemblies a colorful, wear-resistant finish." - icon = 'modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/electronic_tools.dmi' - icon_state = "detailer" - flags_1 = CONDUCT_1 - item_flags = NOBLUDGEON - w_class = WEIGHT_CLASS_SMALL - custom_materials = list(/datum/material/iron=200) - var/data_to_write = null - var/accepting_refs = FALSE - var/detail_color = COLOR_ASSEMBLY_WHITE - var/list/color_list = list( - "black" = COLOR_ASSEMBLY_BLACK, - "gray" = COLOR_FLOORTILE_GRAY, - "machine gray" = COLOR_ASSEMBLY_BGRAY, - "white" = COLOR_ASSEMBLY_WHITE, - "red" = COLOR_ASSEMBLY_RED, - "orange" = COLOR_ASSEMBLY_ORANGE, - "beige" = COLOR_ASSEMBLY_BEIGE, - "brown" = COLOR_ASSEMBLY_BROWN, - "gold" = COLOR_ASSEMBLY_GOLD, - "yellow" = COLOR_ASSEMBLY_YELLOW, - "gurkha" = COLOR_ASSEMBLY_GURKHA, - "light green" = COLOR_ASSEMBLY_LGREEN, - "green" = COLOR_ASSEMBLY_GREEN, - "light blue" = COLOR_ASSEMBLY_LBLUE, - "blue" = COLOR_ASSEMBLY_BLUE, - "purple" = COLOR_ASSEMBLY_PURPLE - ) - -/obj/item/integrated_electronics/detailer/Initialize() - .=..() - update_icon() - -/obj/item/integrated_electronics/detailer/update_icon() - cut_overlays() - var/mutable_appearance/detail_overlay = mutable_appearance('modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/electronic_tools.dmi', "detailer-color") - detail_overlay.color = detail_color - add_overlay(detail_overlay) - ..() - -/obj/item/integrated_electronics/detailer/attack_self(mob/user) - var/color_choice = input(user, "Select color.", "Assembly Detailer") as null|anything in color_list - if(!color_list[color_choice]) - return - if(!in_range(src, user)) - return - detail_color = color_list[color_choice] - update_icon() diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/helpers.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/helpers.dm deleted file mode 100644 index e9cbb346458..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/helpers.dm +++ /dev/null @@ -1,142 +0,0 @@ -/obj/item/integrated_circuit/proc/setup_io(list/io_list, io_type, list/io_default_list, pin_type) - var/list/io_list_copy = io_list.Copy() - io_list.Cut() - for(var/i in 1 to io_list_copy.len) - var/io_entry = io_list_copy[i] - var/default_data = null - var/io_type_override = null - - // Override the default data. - if(length(io_default_list)) // List containing special pin types that need to be added. - default_data = io_default_list["[i]"] // This is deliberately text because the index is a number in text form. - - // Override the pin type. - if(io_list_copy[io_entry]) - io_type_override = io_list_copy[io_entry] - - if(io_type_override) - io_list.Add(new io_type_override(src, io_entry, default_data, pin_type,i)) - else - io_list.Add(new io_type(src, io_entry, default_data, pin_type,i)) - - -/obj/item/integrated_circuit/proc/set_pin_data(pin_type, pin_number, datum/new_data) - if(islist(new_data)) - for(var/i in 1 to length(new_data)) - if (istype(new_data) && !isweakref(new_data)) - new_data[i] = WEAKREF(new_data[i]) - if (istype(new_data) && !isweakref(new_data)) - new_data = WEAKREF(new_data) - var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number) - return pin.write_data_to_pin(new_data) - -/obj/item/integrated_circuit/proc/get_pin_data(pin_type, pin_number) - var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number) - return pin.get_data() - -/obj/item/integrated_circuit/proc/get_pin_data_as_type(pin_type, pin_number, as_type) - var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number) - return pin.data_as_type(as_type) - -/obj/item/integrated_circuit/proc/activate_pin(pin_number) - var/datum/integrated_io/activate/A = activators[pin_number] - A.push_data() - -/obj/item/integrated_circuit/proc/get_pin_ref(pin_type, pin_number) - switch(pin_type) - if(IC_INPUT) - if(pin_number > inputs.len) - return - return inputs[pin_number] - if(IC_OUTPUT) - if(pin_number > outputs.len) - return - return outputs[pin_number] - if(IC_ACTIVATOR) - if(pin_number > activators.len) - return - return activators[pin_number] - return - -/datum/integrated_io/proc/get_data() - if(islist(data)) - for(var/i in 1 to length(data)) - if(isweakref(data[i])) - data[i] = data[i].resolve() - if(isweakref(data)) - return data.resolve() - return data - - -// Returns a list of parameters necessary to locate a pin in the assembly: component number, pin type and pin number -// Components list can be supplied from the outside, for use in savefiles -/datum/integrated_io/proc/get_pin_parameters(list/components) - if(!holder) - return - - if(!components) - if(!holder.assembly) - return - components = holder.assembly.assembly_components - - var/component_number = components.Find(holder) - - var/list/pin_holder_list - switch(pin_type) - if(IC_INPUT) - pin_holder_list = holder.inputs - if(IC_OUTPUT) - pin_holder_list = holder.outputs - if(IC_ACTIVATOR) - pin_holder_list = holder.activators - else - return - - var/pin_number = pin_holder_list.Find(src) - - return list(component_number, pin_type, pin_number) - - -// Locates a pin in the assembly when given component number, pin type and pin number -// Components list can be supplied from the outside, for use in savefiles -/obj/item/electronic_assembly/proc/get_pin_ref(component_number, pin_type, pin_number, list/components) - if(!components) - components = assembly_components - - if(component_number > components.len) - return - - var/obj/item/integrated_circuit/component = components[component_number] - return component.get_pin_ref(pin_type, pin_number) - - -// Same as get_pin_ref, but takes in a list of 3 parameters (same format as get_pin_parameters) -// and performs extra sanity checks on parameters list and index numbers -/obj/item/electronic_assembly/proc/get_pin_ref_list(list/parameters, list/components) - if(!components) - components = assembly_components - - if(!islist(parameters) || parameters.len != 3) - return - - // Those are supposed to be list indexes, check them for sanity - if(!isnum_safe(parameters[1]) || parameters[1] % 1 || parameters[1] < 1) - return - - if(!isnum_safe(parameters[3]) || parameters[3] % 1 || parameters[3] < 1) - return - - return get_pin_ref(parameters[1], parameters[2], parameters[3], components) - - - - -// Used to obfuscate object refs imported/exported as strings. -// Not very secure, but if someone still finds a way to abuse refs, they deserve it. -/proc/XorEncrypt(string, key) - if(!string || !key ||!istext(string)||!istext(key)) - return - var/r - for(var/i = 1 to length(string)) - r += ascii2text(text2ascii(string,i) ^ text2ascii(key,((i-1)%length(string))+1)) - return r diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/integrated_circuit.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/integrated_circuit.dm deleted file mode 100644 index dbcdeca00e1..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/integrated_circuit.dm +++ /dev/null @@ -1,414 +0,0 @@ -/obj/item/integrated_circuit - name = "integrated circuit" - desc = "It's a tiny chip! This one doesn't seem to do much, however." - icon = 'modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/electronic_components.dmi' - icon_state = "template" - w_class = WEIGHT_CLASS_TINY - custom_materials = list(/datum/material/iron=200) - var/obj/item/electronic_assembly/assembly // Reference to the assembly holding this circuit, if any. - var/extended_desc - var/list/inputs = list() - var/list/inputs_default = list()// Assoc list which will fill a pin with data upon creation. e.g. "2" = 0 will set input pin 2 to equal 0 instead of null. - var/list/outputs = list() - var/list/outputs_default =list()// Ditto, for output. - var/list/activators = list() - var/next_use = 0 // Uses world.time - var/complexity = 1 // This acts as a limitation on building machines, more resource-intensive components cost more 'space'. - var/size = 1 // This acts as a limitation on building machines, bigger components cost more 'space'. -1 for size 0 - var/cooldown_per_use = 1 // Circuits are limited in how many times they can be work()'d by this variable. - var/ext_cooldown = 0 // Circuits are limited in how many times they can be work()'d with external world by this variable. - var/power_draw_per_use = 0 // How much power is drawn when work()'d. - var/power_draw_idle = 0 // How much power is drawn when doing nothing. - var/spawn_flags // Used for world initializing, see the #defines above. - var/action_flags = NONE // Used for telling circuits that can do certain actions from other circuits. - var/category_text = "NO CATEGORY THIS IS A BUG" // To show up on circuit printer, and perhaps other places. - var/removable = TRUE // Determines if a circuit is removable from the assembly. - var/displayed_name = "" - var/demands_object_input = FALSE - var/can_input_object_when_closed = FALSE - var/max_allowed = 0 // The maximum amount of components allowed inside an integrated circuit. - - -/* - Integrated circuits are essentially modular machines. Each circuit has a specific function, and combining them inside Electronic Assemblies allows -a creative player the means to solve many problems. Circuits are held inside an electronic assembly, and are wired using special tools. -*/ - -/obj/item/integrated_circuit/examine(mob/user) - interact(user) - external_examine(user) - . = ..() - -// Can be called via electronic_assembly/attackby() -/obj/item/integrated_circuit/proc/additem(var/obj/item/I, var/mob/living/user) - attackby(I, user) - -// This should be used when someone is examining while the case is opened. -/obj/item/integrated_circuit/proc/internal_examine(mob/user) - to_chat(user, "This board has [inputs.len] input pin\s, [outputs.len] output pin\s and [activators.len] activation pin\s.") - for(var/k in inputs) - var/datum/integrated_io/I = k - if(I.linked.len) - to_chat(user, "The '[I]' is connected to [I.get_linked_to_desc()].") - for(var/k in outputs) - var/datum/integrated_io/O = k - if(O.linked.len) - to_chat(user, "The '[O]' is connected to [O.get_linked_to_desc()].") - for(var/k in activators) - var/datum/integrated_io/activate/A = k - if(A.linked.len) - to_chat(user, "The '[A]' is connected to [A.get_linked_to_desc()].") - any_examine(user) - interact(user) - -// This should be used when someone is examining from an 'outside' perspective, e.g. reading a screen or LED. -/obj/item/integrated_circuit/proc/external_examine(mob/user) - any_examine(user) - -/obj/item/integrated_circuit/proc/any_examine(mob/user) - return - -/obj/item/integrated_circuit/proc/attackby_react(var/atom/movable/A,mob/user) - return - -/obj/item/integrated_circuit/proc/sense(var/atom/movable/A,mob/user,prox) - return - -/obj/item/integrated_circuit/proc/check_interactivity(mob/user) - if(assembly) - return assembly.check_interactivity(user) - else - return user.canUseTopic(src, BE_CLOSE) - -/obj/item/integrated_circuit/Initialize() - . = ..() - set_custom_materials(list(GET_MATERIAL_REF(/datum/material/iron)=w_class * SScircuit.cost_multiplier)) - displayed_name = name - setup_io(inputs, /datum/integrated_io, inputs_default, IC_INPUT) - setup_io(outputs, /datum/integrated_io, outputs_default, IC_OUTPUT) - setup_io(activators, /datum/integrated_io/activate, null, IC_ACTIVATOR) - - -/obj/item/integrated_circuit/proc/on_data_written() //Override this for special behaviour when new data gets pushed to the circuit. - return - -/obj/item/integrated_circuit/Destroy() - . = ..() - QDEL_LIST(inputs) - QDEL_LIST(outputs) - QDEL_LIST(activators) - - -/obj/item/integrated_circuit/emp_act(severity) - for(var/k in inputs) - var/datum/integrated_io/I = k - I.scramble() - for(var/k in outputs) - var/datum/integrated_io/O = k - O.scramble() - for(var/k in activators) - var/datum/integrated_io/activate/A = k - A.scramble() - - -/obj/item/integrated_circuit/verb/rename_component() - set name = "Rename Circuit" - set category = "Object" - set desc = "Rename your circuit, useful to stay organized." - - var/mob/M = usr - if(!check_interactivity(M)) - return - - var/input = reject_bad_name(stripped_input(M, "What do you want to name this?", "Rename", name), TRUE) - if(check_interactivity(M)) - if(!input) - input = name - if(CHAT_FILTER_CHECK(input)) - to_chat(M, "The circuit name contains prohibited words!") - return - to_chat(M, "The circuit '[name]' is now labeled '[input]'.") - displayed_name = input - -/obj/item/integrated_circuit/interact(mob/user) - ui_interact(user) - -/obj/item/integrated_circuit/ui_interact(mob/user) - . = ..() - if(!check_interactivity(user)) - return - - if(assembly) - assembly.ui_interact(user, src) - return - - var/table_edge_width = "30%" - var/table_middle_width = "40%" - - var/datum/browser/popup = new(user, "scannernew", name, 800, 630) // Set up the popup browser window - popup.add_stylesheet("scannernew", 'html/browser/assembly_ui.css') - - var/HTML = "[src.displayed_name] \ -

\ - " - - if(assembly) - HTML += "Return to Assembly
" - - HTML += "Refresh | \ - Rename | \ - Copy Ref" - - if(assembly && removable) - HTML += " | Remove" - - HTML += "
\ - \ - \ - \ - " - - var/column_width = 3 - var/row_height = max(inputs.len, outputs.len, 1) - - for(var/i = 1 to row_height) - HTML += "" - for(var/j = 1 to column_width) - var/datum/integrated_io/io = null - var/words - var/height = 1 - switch(j) - if(1) - io = get_pin_ref(IC_INPUT, i) - if(io) - words += "[io.display_pin_type()] [io.name] \ - [io.display_data(io.data)]
" - if(io.linked.len) - words += "" - - if(outputs.len > inputs.len) - height = 1 - if(2) - if(i == 1) - words += "[displayed_name]
[name != displayed_name ? "([name])":""]
[desc]" - height = row_height - else - continue - if(3) - io = get_pin_ref(IC_OUTPUT, i) - if(io) - words += "[io.display_pin_type()] [io.name] \ - [io.display_data(io.data)]
" - if(io.linked.len) - words += "" - - if(inputs.len > outputs.len) - height = 1 - HTML += "" - HTML += "" - - for(var/activator in activators) - var/datum/integrated_io/io = activator - var/words - - words += "[io] \ - [io.data?"\":"\"]
" - - if(io.linked.len) - words += "" - - HTML += "
[words]
[words]
\ -
Complexity: [complexity] \ -
Cooldown per use: [cooldown_per_use/10] sec \ - [max_allowed ? "
Maximum per circuit: [max_allowed]" : ""]" - - if(ext_cooldown) - HTML += "
External manipulation cooldown: [ext_cooldown/10] sec" - if(power_draw_idle) - HTML += "
Power Draw: [power_draw_idle] W (Idle)" - if(power_draw_per_use) - HTML += "
Power Draw: [power_draw_per_use] W (Active)" // Borgcode says that power cells' checked_use() takes joules as input. - - HTML += "
[extended_desc]" - - popup.set_content(HTML) - popup.open() - -/obj/item/integrated_circuit/Topic(href, href_list) - if(!check_interactivity(usr)) - return - if(..()) - return TRUE - - var/update = TRUE - var/update_to_assembly = FALSE - - var/obj/held_item = usr.get_active_held_item() - - if(href_list["rename"]) - rename_component(usr) - if(assembly) - assembly.add_allowed_scanner(usr.ckey) - - if(href_list["pin"]) - var/datum/integrated_io/pin = locate(href_list["pin"]) in inputs + outputs + activators - if(pin) - var/datum/integrated_io/linked - var/success = TRUE - if(href_list["link"]) - linked = locate(href_list["link"]) in pin.linked - - if(istype(held_item, /obj/item/integrated_electronics) || istype(held_item, /obj/item/multitool)) - update_to_assembly = pin.handle_wire(linked, held_item, href_list["act"], usr) - else - to_chat(usr, "You can't do a whole lot without the proper tools.") - success = FALSE - if(success && assembly) - assembly.add_allowed_scanner(usr.ckey) - - if(href_list["scan"]) - if(istype(held_item, /obj/item/integrated_electronics/debugger)) - var/obj/item/integrated_electronics/debugger/D = held_item - if(D.accepting_refs) - D.afterattack(src, usr, TRUE) - else - to_chat(usr, "The debugger's 'ref scanner' needs to be on.") - else - to_chat(usr, "You need a debugger set to 'ref' mode to do that.") - - if(href_list["return"]) - update_to_assembly = TRUE - - - if(update) - if(assembly && update_to_assembly) - assembly.interact(usr, src) - else - interact(usr) // To refresh the UI. - -/obj/item/integrated_circuit/proc/push_data() - for(var/k in outputs) - var/datum/integrated_io/O = k - O.push_data() - -/obj/item/integrated_circuit/proc/pull_data() - for(var/k in inputs) - var/datum/integrated_io/I = k - I.push_data() - -/obj/item/integrated_circuit/proc/draw_idle_power() - if(assembly) - return assembly.draw_power(power_draw_idle) - -// Override this for special behaviour when there's no power left. -/obj/item/integrated_circuit/proc/power_fail() - return - -// Returns true if there's enough power to work(). -/obj/item/integrated_circuit/proc/check_power() - if(!assembly) - return FALSE // Not in an assembly, therefore no power. - if(assembly.draw_power(power_draw_per_use)) - return TRUE // Battery has enough. - return FALSE // Not enough power. - -/obj/item/integrated_circuit/proc/check_then_do_work(ord,var/ignore_power = FALSE) - if(world.time < next_use) // All intergrated circuits have an internal cooldown, to protect from spam. - return FALSE - if(assembly && ext_cooldown && (world.time < assembly.ext_next_use)) // Some circuits have external cooldown, to protect from spam. - return FALSE - if(power_draw_per_use && !ignore_power) - if(!check_power()) - power_fail() - return FALSE - next_use = world.time + cooldown_per_use - if(assembly) - assembly.ext_next_use = world.time + ext_cooldown - do_work(ord) - return TRUE - -/obj/item/integrated_circuit/proc/do_work(ord) - return - -/obj/item/integrated_circuit/proc/disconnect_all() - var/datum/integrated_io/I - - for(var/i in inputs) - I = i - I.disconnect_all() - - for(var/i in outputs) - I = i - I.disconnect_all() - - for(var/i in activators) - I = i - I.disconnect_all() - -/obj/item/integrated_circuit/proc/ext_moved(oldLoc, dir) - return - - -// Returns the object that is supposed to be used in attack messages, location checks, etc. -/obj/item/integrated_circuit/proc/get_object() - // If the component is located in an assembly, let assembly determine it. - if(assembly) - return assembly.get_object() - else - return src // If not, the component is acting on its own. - - -// Returns the location to be used for dropping items. -// Same as the regular drop_location(), but with proc being run on assembly if there is any. -/obj/item/integrated_circuit/drop_location() - // If the component is located in an assembly, let the assembly figure that one out. - if(assembly) - return assembly.drop_location() - else - return ..() // If not, the component is acting on its own. - - -// Checks if the target object is reachable. Useful for various manipulators and manipulator-like objects. -/obj/item/integrated_circuit/proc/check_target(atom/target, exclude_contents = FALSE, exclude_components = FALSE, exclude_self = FALSE) - if(!target) - return FALSE - - var/atom/movable/acting_object = get_object() - - if(exclude_self && target == acting_object) - return FALSE - - if(exclude_components && assembly) - if(target in assembly.assembly_components) - return FALSE - - if(target == assembly.battery) - return FALSE - - if(target.Adjacent(acting_object) && isturf(target.loc)) - return TRUE - - if(!exclude_contents && (target in acting_object.GetAllContents())) - return TRUE - - if(target in acting_object.loc) - return TRUE - - return FALSE diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/pins.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/pins.dm deleted file mode 100644 index ad0f800b916..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/pins.dm +++ /dev/null @@ -1,216 +0,0 @@ -/* - Pins both hold data for circuits, as well move data between them. Some also cause circuits to do their function. DATA_CHANNEL pins are the data holding/moving kind, -where as PULSE_CHANNEL causes circuits to work() when their pulse hits them. -A visualization of how pins work is below. Imagine the below image involves an addition circuit. -When the bottom pin, the activator, receives a pulse, all the numbers on the left (input) get added, and the answer goes on the right side (output). -Inputs Outputs -A [2]\ /[8] result -B [1]-\|++|/ -C [4]-/|++| -D [1]/ || - || - Activator -*/ -/datum/integrated_io - var/name = "input/output" - var/obj/item/integrated_circuit/holder - var/datum/weakref/data // This is a weakref, to reduce typecasts. Note that oftentimes numbers and text may also occupy this. - var/list/linked = list() - var/io_type = DATA_CHANNEL - var/pin_type // IC_INPUT, IC_OUTPUT, IC_ACTIVATOR - used in saving assembly wiring - var/ord - -/datum/integrated_io/New(loc, _name, _data, _pin_type,_ord) - name = _name - if(!isnull(_data)) - data = _data - if(_pin_type) - pin_type = _pin_type - if(_ord) - ord = _ord - - holder = loc - - if(!istype(holder)) - message_admins("ERROR: An integrated_io ([name]) spawned without a valid holder! This is a bug.") - -/datum/integrated_io/Destroy() - disconnect_all() - data = null - holder = null - return ..() - -/datum/integrated_io/proc/data_as_type(var/as_type) - if(!isweakref(data)) - return - var/datum/weakref/w = data - var/output = w.resolve() - return istype(output, as_type) ? output : null - -/datum/integrated_io/proc/display_data(var/input) - if(isnull(input)) - return "(null)" // Empty data means nothing to show. - - if(istext(input)) - return "(\"[input]\")" // Wraps the 'string' in escaped quotes, so that people know it's a 'string'. - - if(islist(input)) - var/list/my_list = input - var/result = "list\[[my_list.len]\](" - if(my_list.len) - result += "
" - var/pos = 0 - for(var/line in my_list) - result += "[display_data(line)]" - pos++ - if(pos != my_list.len) - result += ",
" - result += "
" - result += ")" - return result - - if(isweakref(input)) - var/datum/weakref/w = input - var/atom/A = w.resolve() - return A ? "([A.name] \[Ref\])" : "(null)" // For refs, we want just the name displayed. - - return "([input])" // Nothing special needed for numbers or other stuff. - -/datum/integrated_io/activate/display_data() - return "(\[pulse\])" - -/datum/integrated_io/proc/display_pin_type() - return IC_FORMAT_ANY - -/datum/integrated_io/activate/display_pin_type() - return IC_FORMAT_PULSE - -/datum/integrated_io/proc/scramble() - if(isnull(data)) - return - if(isnum_safe(data)) - write_data_to_pin(rand(-10000, 10000)) - if(istext(data)) - write_data_to_pin("ERROR") - push_data() - -/datum/integrated_io/activate/scramble() - push_data() - -/datum/integrated_io/proc/handle_wire(datum/integrated_io/linked_pin, obj/item/tool, action, mob/living/user) - if(tool.tool_behaviour == TOOL_MULTITOOL) - if(!tool.multitool_check_buffer(user, tool)) - return - var/obj/item/multitool/multitool = tool - switch(action) - if("wire") - multitool.wire(src, user) - return TRUE - if("unwire") - if(linked_pin) - multitool.unwire(src, linked_pin, user) - return TRUE - if("data") - ask_for_pin_data(user) - return TRUE - - else if(istype(tool, /obj/item/integrated_electronics/wirer)) - var/obj/item/integrated_electronics/wirer/wirer = tool - if(linked_pin) - wirer.wire(linked_pin, user) - else - wirer.wire(src, user) - - else if(istype(tool, /obj/item/integrated_electronics/debugger)) - var/obj/item/integrated_electronics/debugger/debugger = tool - debugger.write_data(src, user) - return TRUE - - return FALSE - -/datum/integrated_io/proc/write_data_to_pin(new_data) - if(isnull(new_data) || isnum_safe(new_data) || istext(new_data) || isweakref(new_data)) - data = new_data - holder.on_data_written() - else if(islist(new_data)) - var/list/new_list = new_data - data = new_list.Copy(max(1,new_list.len - IC_MAX_LIST_LENGTH+1),0) - holder.on_data_written() - -/datum/integrated_io/proc/push_data() - for(var/k in 1 to linked.len) - var/datum/integrated_io/io = linked[k] - io.write_data_to_pin(data) - -/datum/integrated_io/activate/push_data() - for(var/k in 1 to linked.len) - var/datum/integrated_io/io = linked[k] - io.holder.check_then_do_work(io.ord) - -/datum/integrated_io/proc/pull_data() - for(var/k in 1 to linked.len) - var/datum/integrated_io/io = linked[k] - write_data_to_pin(io.data) - -/datum/integrated_io/proc/get_linked_to_desc() - if(linked.len) - return "the [english_list(linked)]" - return "nothing" - - -/datum/integrated_io/proc/connect_pin(datum/integrated_io/pin) - pin.linked |= src - linked |= pin - -// Iterates over every linked pin and disconnects them. -/datum/integrated_io/proc/disconnect_all() - for(var/pin in linked) - disconnect_pin(pin) - -/datum/integrated_io/proc/disconnect_pin(datum/integrated_io/pin) - pin.linked.Remove(src) - linked.Remove(pin) - - -/datum/integrated_io/proc/ask_for_data_type(mob/user, var/default, var/list/allowed_data_types = list("string","number","null")) - var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in allowed_data_types - if(!holder.check_interactivity(user)) - return - - var/new_data = null - switch(type_to_use) - if("string") - new_data = stripped_multiline_input(user, "Now type in a string.","[src] string writing", istext(default) ? default : null, no_trim = TRUE) - if(istext(new_data) && holder.check_interactivity(user) ) - to_chat(user, "You input "+new_data+" into the pin.") - return new_data - if("number") - new_data = input("Now type in a number.","[src] number writing", isnum_safe(default) ? default : null) as null|num - if(isnum_safe(new_data) && holder.check_interactivity(user) ) - to_chat(user, "You input [new_data] into the pin.") - return new_data - if("null") - if(holder.check_interactivity(user)) - to_chat(user, "You clear the pin's memory.") - return new_data - -// Basically a null check -/datum/integrated_io/proc/is_valid() - return !isnull(data) - -// This proc asks for the data to write, then writes it. -/datum/integrated_io/proc/ask_for_pin_data(mob/user) - var/new_data = ask_for_data_type(user) - write_data_to_pin(new_data) - -/datum/integrated_io/activate/ask_for_pin_data(mob/user) // This just pulses the pin. - holder.investigate_log(" was manually pulsed by [key_name(user)].", INVESTIGATE_CIRCUIT) - holder.check_then_do_work(ord,ignore_power = TRUE) - to_chat(user, "You pulse \the [holder]'s [src] pin.") - -/datum/integrated_io/activate - name = "activation pin" - io_type = PULSE_CHANNEL - -/datum/integrated_io/activate/out // All this does is just make the UI say 'out' instead of 'in' - data = 1 diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/printer.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/printer.dm deleted file mode 100644 index 69e32620b68..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/printer.dm +++ /dev/null @@ -1,384 +0,0 @@ -#define MAX_CIRCUIT_CLONE_TIME 3 MINUTES //circuit slow-clones can only take up this amount of time to complete - -/obj/item/integrated_circuit_printer - name = "integrated circuit printer" - desc = "A portable(ish) machine made to print tiny modular circuitry out of iron." - icon = 'modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/electronic_tools.dmi' - icon_state = "circuit_printer" - w_class = WEIGHT_CLASS_BULKY - var/upgraded = TRUE // When hit with an upgrade disk, will turn true, allowing it to print the higher tier circuits. - var/can_clone = TRUE // Allows the printer to clone circuits, either instantly or over time depending on upgrade. Set to FALSE to disable entirely. - var/fast_clone = TRUE // If this is false, then cloning will take an amount of deciseconds equal to the material cost divided by 100. - var/debug = FALSE // If it's upgraded and can clone, even without config settings. - var/current_category = null - var/cloning = FALSE // If the printer is currently creating a circuit - var/recycling = FALSE // If an assembly is being emptied into this printer - var/list/program // Currently loaded save, in form of list - var/datum/weakref/idlock = null - -/obj/item/integrated_circuit_printer/proc/check_interactivity(mob/user) - return user.canUseTopic(src, BE_CLOSE) - -/obj/item/integrated_circuit_printer/upgraded - upgraded = TRUE - can_clone = TRUE - fast_clone = TRUE - -/obj/item/integrated_circuit_printer/debug //translation: "integrated_circuit_printer/local_server" - name = "debug circuit printer" - debug = TRUE - upgraded = TRUE - can_clone = TRUE - fast_clone = TRUE - w_class = WEIGHT_CLASS_TINY - -/obj/item/integrated_circuit_printer/Initialize() - . = ..() - AddComponent(/datum/component/material_container, list(/datum/material/iron), MINERAL_MATERIAL_AMOUNT * 25, MATCONTAINER_ANY_INTENT | MATCONTAINER_SILENT) - //AddComponent(/datum/component/material_container, list(/datum/material/iron), MINERAL_MATERIAL_AMOUNT * 25, TRUE, list(/obj/item/stack, /obj/item/integrated_circuit, /obj/item/electronic_assembly)) - -/obj/item/integrated_circuit_printer/proc/print_program(mob/user) - if(!cloning) - return - - visible_message("[src] has finished printing its assembly!") - playsound(src, 'sound/items/poster_being_created.ogg', 50, TRUE) - var/obj/item/electronic_assembly/assembly = SScircuit.load_electronic_assembly(get_turf(src), program) - if(idlock) - assembly.idlock = idlock - assembly.creator = key_name(user) - assembly.investigate_log("was printed by [assembly.creator].", INVESTIGATE_CIRCUIT) - cloning = FALSE - -/obj/item/integrated_circuit_printer/attackby(obj/item/O, mob/user) - /* Skyrat port -- Upgade disks disabled for now - if(istype(O, /obj/item/disk/integrated_circuit/upgrade/advanced)) - if(upgraded) - to_chat(user, "[src] already has this upgrade. ") - return TRUE - to_chat(user, "You install [O] into [src]. ") - upgraded = TRUE - return TRUE - - if(istype(O, /obj/item/disk/integrated_circuit/upgrade/clone)) - if(fast_clone) - to_chat(user, "[src] already has this upgrade. ") - return TRUE - to_chat(user, "You install [O] into [src]. Circuit cloning will now be instant. ") - fast_clone = TRUE - return TRUE - */ - - if(istype(O, /obj/item/electronic_assembly)) - var/obj/item/electronic_assembly/EA = O //microtransactions not included - if(EA.assembly_components.len) - if(recycling) - return - if(!EA.opened) - to_chat(user, "You can't reach [EA]'s components to remove them!") - return - if(EA.battery) - to_chat(user, "Remove [EA]'s power cell first!") - return - for(var/V in EA.assembly_components) - var/obj/item/integrated_circuit/IC = V - if(!IC.removable) - to_chat(user, "[EA] has irremovable components in the casing, preventing you from emptying it.") - return - to_chat(user, "You begin recycling [EA]'s components...") - playsound(src, 'sound/items/electronic_assembly_emptying.ogg', 50, TRUE) - if(!do_after(user, 30, target = src) || recycling) //short channel so you don't accidentally start emptying out a complex assembly - return - recycling = TRUE - var/datum/component/material_container/mats = GetComponent(/datum/component/material_container) - for(var/V in EA.assembly_components) - var/obj/item/integrated_circuit/IC = V - if(!mats.has_space(mats.get_item_material_amount(IC))) - to_chat(user, "[src] can't hold any more materials!") - break - if(!do_after(user, 5, target = user)) - recycling = FALSE - return - playsound(src, 'sound/items/crowbar.ogg', 50, TRUE) - if(EA.try_remove_component(IC, user, TRUE)) - mats.user_insert(IC, user) - to_chat(user, "You recycle all the components[EA.assembly_components.len ? " you could " : " "]from [EA]!") - playsound(src, 'sound/items/electronic_assembly_empty.ogg', 50, TRUE) - recycling = FALSE - return TRUE - - if(istype(O, /obj/item/integrated_electronics/debugger)) - var/obj/item/integrated_electronics/debugger/debugger = O - if(!debugger.idlock) - return - - if(!idlock) - idlock = debugger.idlock - debugger.idlock = null - to_chat(user, "You set \the [src] to print out id-locked assemblies only.") - return - - if(debugger.idlock.resolve() == idlock.resolve()) - idlock = null - debugger.idlock = null - to_chat(user, "You reset \the [src]'s protection settings.") - return - - return ..() - -/obj/item/integrated_circuit_printer/attack_self(mob/user) - interact(user) - -/obj/item/integrated_circuit_printer/interact(mob/user) - if(!(in_range(src, user) || issilicon(user))) - return - - if(isnull(current_category)) - current_category = SScircuit.circuit_fabricator_recipe_list[1] - - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - - //Preparing the browser - var/datum/browser/popup = new(user, "printernew", "Integrated Circuit Printer", 800, 630) // Set up the popup browser window - - var/HTML = "

Integrated Circuit Printer


" - if(debug) - HTML += "

DEBUG PRINTER -- Infinite materials. Cloning available.

" - else - HTML += "Iron: [materials.total_amount]/[materials.max_amount].

" - - HTML += "Identity-lock: " - if(idlock) - var/obj/item/card/id = idlock.resolve() - HTML+= "[id.name] | Reset
" - else - HTML += "None | Reset
" - - HTML += "Assembly cloning: [can_clone ? (fast_clone ? "Instant" : "Available") : "Unavailable"].
" - - HTML += "Circuits available: [upgraded || debug ? "Advanced":"Regular"]." - if(!upgraded) - HTML += "
Crossed out circuits mean that the printer is not sufficiently upgraded to create that circuit." - - HTML += "
" - HTML += "Here you can load script for your assembly.
" - if(!cloning) - HTML += " Load Program " - else - HTML += " Load Program" - if(!program) - HTML += " [fast_clone ? "Print" : "Begin Printing"] Assembly
" - else if(cloning) - HTML += " Cancel Print" - else - HTML += " [fast_clone ? "Print" : "Begin Printing"] Assembly" - - HTML += "

" - HTML += "Categories:" - for(var/category in SScircuit.circuit_fabricator_recipe_list) - if(category != current_category) - HTML += " [category] " - else // Bold the button if it's already selected. - HTML += " [category] " - HTML += "
" - HTML += "

[current_category]

" - - var/list/current_list = SScircuit.circuit_fabricator_recipe_list[current_category] - for(var/path in current_list) - var/obj/O = path - var/can_build = TRUE - if(ispath(path, /obj/item/integrated_circuit)) - var/obj/item/integrated_circuit/IC = path - if((initial(IC.spawn_flags) & IC_SPAWN_RESEARCH) && (!(initial(IC.spawn_flags) & IC_SPAWN_DEFAULT)) && !upgraded) - can_build = FALSE - if(can_build) - HTML += "[initial(O.name)]: [initial(O.desc)]
" - else - HTML += "[initial(O.name)]: [initial(O.desc)]
" - - popup.set_content(HTML) - popup.open() - -/obj/item/integrated_circuit_printer/Topic(href, href_list) - if(!check_interactivity(usr)) - return - if(..()) - return TRUE - add_fingerprint(usr) - - if(href_list["id-lock"]) - idlock = null - - if(href_list["category"]) - current_category = href_list["category"] - - if(href_list["build"]) - var/build_type = text2path(href_list["build"]) - if(!build_type || !ispath(build_type)) - return TRUE - - var/cost = list(/datum/material/iron=400) - if(ispath(build_type, /obj/item/electronic_assembly)) - var/obj/item/electronic_assembly/E = SScircuit.cached_assemblies[build_type] - cost = E.custom_materials - else if(ispath(build_type, /obj/item/integrated_circuit)) - var/obj/item/integrated_circuit/IC = SScircuit.cached_components[build_type] - cost = IC.custom_materials - else if(!(build_type in SScircuit.circuit_fabricator_recipe_list["Tools"])) - return - - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - - if(!debug && !materials.has_materials(cost)) - to_chat(usr, "You need more materials to build that!") - to_chat(usr, "=== MATERIALS ===") - for(var/mat in cost) - var/datum/material/req_mat = mat - var/amount_required = cost[mat] - if(!istype(req_mat)) - req_mat = GET_MATERIAL_REF(req_mat) - to_chat(usr, "[req_mat]: [amount_required]") - return TRUE - materials.use_materials(cost) - - var/obj/item/built = new build_type(drop_location()) - usr.put_in_hands(built) - - if(istype(built, /obj/item/electronic_assembly)) - var/obj/item/electronic_assembly/E = built - E.creator = key_name(usr) - E.opened = TRUE - E.update_icon() - //reupdate diagnostic hud because it was put_in_hands() and not pickup()'ed - E.diag_hud_set_circuithealth() - E.diag_hud_set_circuitcell() - E.diag_hud_set_circuitstat() - E.diag_hud_set_circuittracking() - E.investigate_log("was printed by [E.creator].", INVESTIGATE_CIRCUIT) - - to_chat(usr, "[capitalize(built.name)] printed.") - playsound(src, 'sound/items/jaws_pry.ogg', 50, TRUE) - - if(href_list["print"]) - /* - if(!CONFIG_GET(flag/ic_printing) && !debug) - to_chat(usr, "CentCom has disabled printing of custom circuitry due to recent allegations of copyright infringement.") - return - */ - if(!can_clone) // Copying and printing ICs is cloning - to_chat(usr, "This printer does not have the cloning upgrade.") - return - switch(href_list["print"]) - if("load") - if(cloning) - return - - // We want this trimmed through stripped_multiline_input, but we don't want the result to be html encoded otherwise there will be json decode errors. - var/input = html_decode(stripped_multiline_input(usr, "Put your code there:", "loading", max_length = MAX_SIZE_CIRCUIT)) - if(!check_interactivity(usr) || cloning) - return - if(!input) - program = null - return - - var/validation = SScircuit.validate_electronic_assembly(input) - - // Validation error codes are returned as text. - if(istext(validation)) - to_chat(usr, "Error: [validation]") - return - else if(islist(validation)) - program = validation - to_chat(usr, "This is a valid program for [program["assembly"]["type"]].") - if(program["requires_upgrades"]) - if(upgraded) - to_chat(usr, "It uses advanced component designs.") - else - to_chat(usr, "It uses unknown component designs. Printer upgrade is required to proceed.") - if(program["unsupported_circuit"]) - to_chat(usr, "This program uses components not supported by the specified assembly. Please change the assembly type in the save file to a supported one.") - to_chat(usr, "Used space: [program["used_space"]]/[program["max_space"]].") - to_chat(usr, "Complexity: [program["complexity"]]/[program["max_complexity"]].") - to_chat(usr, "=== MATERIALS ===") - for(var/mat in program["material_costs"]) - var/datum/material/req_mat = mat - var/amount_required = program["material_costs"][mat] - if(!istype(req_mat)) - req_mat = GET_MATERIAL_REF(req_mat) - to_chat(usr, "[req_mat]: [amount_required]") - - if("print") - if(!program || cloning) - return - - if(program["requires_upgrades"] && !upgraded && !debug) - to_chat(usr, "This program uses unknown component designs. Printer upgrade is required to proceed.") - return - if(program["unsupported_circuit"] && !debug) - to_chat(usr, "This program uses components not supported by the specified assembly. Please change the assembly type in the save file to a supported one.") - return - else if(fast_clone) - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - if(materials.has_materials(program["material_costs"])) - materials.use_materials(program["material_costs"]) - cloning = TRUE - print_program(usr) - else - to_chat(usr, "The printer doesn't have sufficient materials to produce this circuit.") - else - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - if(!materials.has_materials(program["material_costs"])) - to_chat(usr, "The printer doesn't have sufficient materials to produce this circuit.") - return - materials.use_materials(program["material_costs"]) - var/total_cost = 0 - for(var/mat in program["material_costs"]) - total_cost += program["material_costs"][mat] - var/cloning_time = round(total_cost / 15) - cloning_time = min(cloning_time, MAX_CIRCUIT_CLONE_TIME) - cloning = TRUE - to_chat(usr, "You begin printing a custom assembly. This will take approximately [DisplayTimeText(cloning_time)]. You can still print \ - off normal parts during this time.") - playsound(src, 'sound/items/poster_being_created.ogg', 50, TRUE) - addtimer(CALLBACK(src, .proc/print_program, usr), cloning_time) - - if("cancel") - if(!cloning || !program) - return - - to_chat(usr, "Cloning has been canceled. Materials have been refunded.") - cloning = FALSE - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - for(var/mat in program["material_costs"]) - materials.use_amount_mat(-program["material_costs"][mat], mat) - //materials.use_amount_mat(-program["iron_cost"], /datum/material/iron) //use negative amount to regain the cost - - - interact(usr) - -/* SKYRAT PORT -- Upgrade Disks disabled for now -// FUKKEN UPGRADE DISKS -/obj/item/disk/integrated_circuit/upgrade - name = "integrated circuit printer upgrade disk" - desc = "Install this into your integrated circuit printer to enhance it." - icon = 'modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/electronic_tools.dmi' - icon_state = "upgrade_disk" - w_class = WEIGHT_CLASS_SMALL - -/obj/item/disk/integrated_circuit/upgrade/advanced - name = "integrated circuit printer upgrade disk - advanced designs" - desc = "Install this into your integrated circuit printer to enhance it. This one adds new, advanced designs to the printer." - -/obj/item/disk/integrated_circuit/upgrade/clone - name = "integrated circuit printer upgrade disk - instant cloner" - desc = "Install this into your integrated circuit printer to enhance it. This one allows the printer to duplicate assemblies instantaneously." - icon_state = "upgrade_disk_clone" -*/ - -/obj/item/integrated_circuit_printer/polychromic - name = "polychromic integrated circuit printer" - icon_state = "circuit_printer_poly" - -/obj/item/integrated_circuit_printer/polychromic/ComponentInitialize() - . = ..() - AddElement(/datum/element/polychromic, list("666", "CBA", "00F")) diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/saved_circuits.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/saved_circuits.dm deleted file mode 100644 index 089d855ee3d..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/saved_circuits.dm +++ /dev/null @@ -1,380 +0,0 @@ -// Helpers for saving/loading integrated circuits. - - -// Saves type, modified name and modified inputs (if any) to a list -// The list is converted to JSON down the line. -//"Special" is not verified at any point except for by the circuit itself. -/obj/item/integrated_circuit/proc/save() - var/list/component_params = list() - var/init_name = initial(name) - - // Save initial name used for differentiating assemblies - component_params["type"] = init_name - - // Save the modified name. - if(init_name != displayed_name) - component_params["name"] = displayed_name - - // Saving input values - if(length(inputs)) - var/list/saved_inputs = list() - - for(var/index in 1 to inputs.len) - var/datum/integrated_io/input = inputs[index] - - // Don't waste space saving the default values - if(input.data == inputs_default["[index]"]) - continue - if(input.data == initial(input.data)) - continue - - var/list/input_value = list(index, FALSE, input.data) - // Index, Type, Value - // FALSE is default type used for num/text/list/null - // TODO: support for special input types, such as internal refs and maybe typepaths - - if(islist(input.data) || isnum_safe(input.data) || istext(input.data) || isnull(input.data)) - saved_inputs.Add(list(input_value)) - - if(saved_inputs.len) - component_params["inputs"] = saved_inputs - - var/special = save_special() - if(!isnull(special)) - component_params["special"] = special - - return component_params - -/obj/item/integrated_circuit/proc/save_special() - return - -// Verifies a list of component parameters -// Returns null on success, error name on failure -/obj/item/integrated_circuit/proc/verify_save(list/component_params) - var/init_name = initial(name) - // Validate name - if(component_params["name"] && !reject_bad_name(component_params["name"], TRUE)) - return "Bad component name at [init_name]." - - // Validate input values - if(component_params["inputs"]) - var/list/loaded_inputs = component_params["inputs"] - if(!islist(loaded_inputs)) - return "Malformed input values list at [init_name]." - - var/inputs_amt = length(inputs) - - // Too many inputs? Inputs for input-less component? This is not good. - if(!inputs_amt || inputs_amt < length(loaded_inputs)) - return "Input values list out of bounds at [init_name]." - - for(var/list/input in loaded_inputs) - if(input.len != 3) - return "Malformed input data at [init_name]." - - var/input_id = input[1] - var/input_type = input[2] - //var/input_value = input[3] - - // No special type support yet. - if(input_type) - return "Unidentified input type at [init_name]!" - // TODO: support for special input types, such as typepaths and internal refs - - // Input ID is a list index, make sure it's sane. - if(!isnum_safe(input_id) || input_id % 1 || input_id > inputs_amt || input_id < 1) - return "Invalid input index at [init_name]." - - -// Loads component parameters from a list -// Doesn't verify any of the parameters it loads, this is the job of verify_save() -/obj/item/integrated_circuit/proc/load(list/component_params) - // Load name - if(component_params["name"]) - displayed_name = component_params["name"] - - // Load input values - if(component_params["inputs"]) - var/list/loaded_inputs = component_params["inputs"] - - for(var/list/input in loaded_inputs) - var/index = input[1] - //var/input_type = input[2] - var/input_value = input[3] - - var/datum/integrated_io/pin = inputs[index] - // The pins themselves validate the data. - pin.write_data_to_pin(input_value) - // TODO: support for special input types, such as internal refs and maybe typepaths - - if(!isnull(component_params["special"])) - load_special(component_params["special"]) - -/obj/item/integrated_circuit/proc/load_special(special_data) - return - -// Saves type and modified name (if any) to a list -// The list is converted to JSON down the line. -/obj/item/electronic_assembly/proc/save() - var/list/assembly_params = list() - - // Save initial name used for differentiating assemblies - assembly_params["type"] = initial(name) - - // Save modified name - if(initial(name) != name) - assembly_params["name"] = name - - // Save modified description - if(initial(desc) != desc) - assembly_params["desc"] = desc - - // Save modified color - if(initial(detail_color) != detail_color) - assembly_params["detail_color"] = detail_color - - return assembly_params - - -// Verifies a list of assembly parameters -// Returns null on success, error name on failure -/obj/item/electronic_assembly/proc/verify_save(list/assembly_params) - // Validate name and color - if(assembly_params["name"] && !reject_bad_name(assembly_params["name"], TRUE)) - return "Bad assembly name." - if(assembly_params["desc"] && !reject_bad_text(assembly_params["desc"])) - return "Bad assembly description." - -// Loads assembly parameters from a list -// Doesn't verify any of the parameters it loads, this is the job of verify_save() -/obj/item/electronic_assembly/proc/load(list/assembly_params) - // Load modified name, if any. - if(assembly_params["name"]) - name = assembly_params["name"] - - // Load modified description, if any. - if(assembly_params["desc"]) - desc = assembly_params["desc"] - - if(assembly_params["detail_color"]) - detail_color = assembly_params["detail_color"] - - update_icon() - - - -// Attempts to save an assembly into a save file format. -// Returns null if assembly is not complete enough to be saved. -/datum/controller/subsystem/processing/circuit/proc/save_electronic_assembly(obj/item/electronic_assembly/assembly) - // No components? Don't even try to save it. - if(!length(assembly.assembly_components)) - return - - - var/list/blocks = list() - - // Block 1. Assembly. - blocks["assembly"] = assembly.save() - // (implant assemblies are not yet supported) - - - // Block 2. Components. - var/list/components = list() - for(var/c in assembly.assembly_components) - var/obj/item/integrated_circuit/component = c - components.Add(list(component.save())) - blocks["components"] = components - - - // Block 3. Wires. - var/list/wires = list() - var/list/saved_wires = list() - - for(var/c in assembly.assembly_components) - var/obj/item/integrated_circuit/component = c - var/list/all_pins = component.inputs + component.outputs + component.activators - - for(var/p in all_pins) - var/datum/integrated_io/pin = p - var/list/params = pin.get_pin_parameters() - var/text_params = params.Join() - - for(var/p2 in pin.linked) - var/datum/integrated_io/pin2 = p2 - var/list/params2 = pin2.get_pin_parameters() - var/text_params2 = params2.Join() - - // Check if we already saved an opposite version of this wire - // (do not save the same wire twice) - if((text_params2 + "=" + text_params) in saved_wires) - continue - - // If not, add a wire "hash" for future checks and save it - saved_wires.Add(text_params + "=" + text_params2) - wires.Add(list(list(params, params2))) - - if(wires.len) - blocks["wires"] = wires - - return json_encode(blocks) - - - -// Checks assembly save and calculates some of the parameters. -// Returns assembly (type: list) if the save is valid. -// Returns error code (type: text) if loading has failed. -// The following parameters area calculated during validation and added to the returned save list: -// "requires_upgrades", "unsupported_circuit", "iron_cost", "complexity", "max_complexity", "used_space", "max_space" -/datum/controller/subsystem/processing/circuit/proc/validate_electronic_assembly(program) - // This regex was causing data to be parsed incorrectly, resulting in a situation where you can build a valid circuit - // in the server, save it and reimport it, and find some values not as they were supposed to be. Mostly interferes - // with special characters which are already safely handled to begin with. - //program = bad_regex.Replace(program, "") - - var/list/blocks = json_decode(program) - if(!blocks) - return "The program was empty or caused a parsing error." - - var/error - - // Block 1. Assembly. - var/list/assembly_params = blocks["assembly"] - - if(!islist(assembly_params) || !length(assembly_params)) - return "Invalid assembly data." // No assembly, damaged assembly or empty assembly - - // Validate type, get a temporary component - var/assembly_path = all_assemblies[assembly_params["type"]] - var/obj/item/electronic_assembly/assembly = cached_assemblies[assembly_path] - if(!assembly) - return "Invalid assembly type." - - // Check assembly save data for errors - error = assembly.verify_save(assembly_params) - if(error) - return error - - - // Read space & complexity limits and start keeping track of them - blocks["complexity"] = 0 - blocks["max_complexity"] = assembly.max_complexity - blocks["used_space"] = 0 - blocks["max_space"] = assembly.max_components - - // Start keeping track of total material costs - blocks["material_costs"] = list() - for(var/mat in assembly.custom_materials) - var/datum/material/req_mat = mat - var/amount_required = assembly.custom_materials[mat] - if(!istype(req_mat)) - req_mat = GET_MATERIAL_REF(req_mat) - if(req_mat in blocks["material_costs"]) - blocks["material_costs"][req_mat] += amount_required - else - blocks["material_costs"][req_mat] = amount_required - - - // Block 2. Components. - if(!islist(blocks["components"]) || !length(blocks["components"])) - return "Invalid components list." // No components or damaged components list - - var/list/assembly_components = list() - for(var/C in blocks["components"]) - var/list/component_params = C - - if(!islist(component_params) || !length(component_params)) - return "Invalid component data." - - // Validate type, get a temporary component - var/component_path = all_components[component_params["type"]] - var/obj/item/integrated_circuit/component = cached_components[component_path] - if(!component) - return "Invalid component type." - - // Add temporary component to assembly_components list, to be used later when verifying the wires - assembly_components.Add(component) - - // Check component save data for errors - error = component.verify_save(component_params) - if(error) - return error - - // Update estimated assembly complexity, taken space and material cost - blocks["complexity"] += component.complexity - blocks["used_space"] += component.size - for(var/mat in component.custom_materials) - var/datum/material/req_mat = mat - var/amount_required = component.custom_materials[mat] - if(!istype(req_mat)) - req_mat = GET_MATERIAL_REF(req_mat) - if(req_mat in blocks["material_costs"]) - blocks["material_costs"][req_mat] += amount_required - else - blocks["material_costs"][req_mat] = amount_required - - // Check if the assembly requires printer upgrades - if(!(component.spawn_flags & IC_SPAWN_DEFAULT)) - blocks["requires_upgrades"] = TRUE - - // Check if the assembly supports the circucit - if((component.action_flags & assembly.allowed_circuit_action_flags) != component.action_flags) - blocks["unsupported_circuit"] = TRUE - - - // Check complexity and space limitations - if(blocks["used_space"] > blocks["max_space"]) - return "Used space overflow." - if(blocks["complexity"] > blocks["max_complexity"]) - return "Complexity overflow." - - - // Block 3. Wires. - if(blocks["wires"]) - if(!islist(blocks["wires"])) - return "Invalid wiring list." // Damaged wires list - - for(var/w in blocks["wires"]) - var/list/wire = w - - if(!islist(wire) || wire.len != 2) - return "Invalid wire data." - - var/datum/integrated_io/IO = assembly.get_pin_ref_list(wire[1], assembly_components) - var/datum/integrated_io/IO2 = assembly.get_pin_ref_list(wire[2], assembly_components) - if(!IO || !IO2) - return "Invalid wire data." - - if(initial(IO.io_type) != initial(IO2.io_type)) - return "Wire type mismatch." - - return blocks - - -// Loads assembly (in form of list) into an object and returns it. -// No sanity checks are performed, save file is expected to be validated by validate_electronic_assembly -/datum/controller/subsystem/processing/circuit/proc/load_electronic_assembly(loc, list/blocks) - - // Block 1. Assembly. - var/list/assembly_params = blocks["assembly"] - var/obj/item/electronic_assembly/assembly_path = all_assemblies[assembly_params["type"]] - var/obj/item/electronic_assembly/assembly = new assembly_path(null) - assembly.load(assembly_params) - - // Block 2. Components. - for(var/component_params in blocks["components"]) - var/obj/item/integrated_circuit/component_path = all_components[component_params["type"]] - var/obj/item/integrated_circuit/component = new component_path(assembly) - assembly.add_component(component) - component.load(component_params) - - - // Block 3. Wires. - if(blocks["wires"]) - for(var/w in blocks["wires"]) - var/list/wire = w - var/datum/integrated_io/IO = assembly.get_pin_ref_list(wire[1]) - var/datum/integrated_io/IO2 = assembly.get_pin_ref_list(wire[2]) - IO.connect_pin(IO2) - - assembly.forceMove(loc) - return assembly diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/boolean_pin.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/boolean_pin.dm deleted file mode 100644 index da59434b653..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/boolean_pin.dm +++ /dev/null @@ -1,26 +0,0 @@ -// These pins only contain 0 or 1. Null is not allowed. -/datum/integrated_io/boolean - name = "boolean pin" - data = FALSE - -/datum/integrated_io/boolean/ask_for_pin_data(mob/user) // 'Ask' is a bit misleading, acts more like a toggle. - var/new_data = !data - to_chat(user, "You switch the data bit to [new_data ? "TRUE" : "FALSE"].") - write_data_to_pin(new_data) - -/datum/integrated_io/boolean/write_data_to_pin(var/new_data) - if(new_data == FALSE || new_data == TRUE) - data = new_data - holder.on_data_written() - -/datum/integrated_io/boolean/scramble() - write_data_to_pin(rand(FALSE,TRUE)) - push_data() - -/datum/integrated_io/boolean/display_pin_type() - return IC_FORMAT_BOOLEAN - -/datum/integrated_io/boolean/display_data(var/input) - if(data) - return "(TRUE)" - return "(FALSE)" diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/char_pin.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/char_pin.dm deleted file mode 100644 index 632ef695218..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/char_pin.dm +++ /dev/null @@ -1,27 +0,0 @@ -// These pins can only contain a 1 character string or null. -/datum/integrated_io/char - name = "char pin" - -/datum/integrated_io/char/ask_for_pin_data(mob/user) - var/new_data = stripped_input(user, "Please type in one character.","[src] char writing", no_trim = TRUE) - if(holder.check_interactivity(user) ) - to_chat(user, "You input [new_data ? "new_data" : "NULL"] into the pin.") - write_data_to_pin(new_data) - -/datum/integrated_io/char/write_data_to_pin(var/new_data) - if(isnull(new_data) || istext(new_data)) - if(length(new_data) > 1) - return - data = new_data - holder.on_data_written() - -// This makes the text go from "A" to "%". -/datum/integrated_io/char/scramble() - if(!is_valid()) - return - var/list/options = list("!","@","#","$","%","^","&","*","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z") - data = pick(options) - push_data() - -/datum/integrated_io/char/display_pin_type() - return IC_FORMAT_CHAR diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/color_pin.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/color_pin.dm deleted file mode 100644 index e2a09657dff..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/color_pin.dm +++ /dev/null @@ -1,49 +0,0 @@ -// These pins can only contain a color (in the form of #FFFFFF) or null. -/datum/integrated_io/color - name = "color pin" - -/datum/integrated_io/color/ask_for_pin_data(mob/user) - var/new_data = input("Please select a color.","[src] color writing") as color|null - if(holder.check_interactivity(user) ) - to_chat(user, "You input a new color into the pin.") - write_data_to_pin(new_data) - -/datum/integrated_io/color/write_data_to_pin(var/new_data) - // Since this is storing the color as a string hex color code, we need to make sure it's actually one. - if(isnull(new_data) || istext(new_data)) - if(istext(new_data)) - new_data = uppertext(new_data) - if(length(new_data) != 7) // We can hex if we want to, we can leave your strings behind - return // Cause your strings don't hex and if they don't hex - var/friends = copytext(new_data, 2, 8) // Well they're are no strings of mine - // I say, we can go where we want to, a place where they will never find - var/safety_dance = 1 - while(safety_dance >= 7) // And we can act like we come from out of this world.log - var/hex = copytext(friends, safety_dance, safety_dance+1) - if(!(hex in list("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"))) - return // Leave the fake one far behind, - safety_dance++ - - data = new_data // And we can hex - holder.on_data_written() - -// This randomizes the color. -/datum/integrated_io/color/scramble() - if(!is_valid()) - return - var/new_data - for(var/i=1;i<=3;i++) - var/temp_col = "[num2hex(rand(0,255), 2)]" - if(length(temp_col )<2) - temp_col = "0[temp_col]" - new_data += temp_col - data = new_data - push_data() - -/datum/integrated_io/color/display_pin_type() - return IC_FORMAT_COLOR - -/datum/integrated_io/color/display_data(var/input) - if(!isnull(data)) - return "([data])" - return ..() diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/dir_pin.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/dir_pin.dm deleted file mode 100644 index 8a2fb61a84f..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/dir_pin.dm +++ /dev/null @@ -1,31 +0,0 @@ -// These pins can only contain directions (1,2,4,8...) or null. -/datum/integrated_io/dir - name = "dir pin" - -/datum/integrated_io/dir/ask_for_pin_data(mob/user) - var/new_data = input("Please type in a valid dir number. \ - Valid dirs are;\n\ - North/Fore = [NORTH],\n\ - South/Aft = [SOUTH],\n\ - East/Starboard = [EAST],\n\ - West/Port = [WEST],\n\ - Northeast = [NORTHEAST],\n\ - Northwest = [NORTHWEST],\n\ - Southeast = [SOUTHEAST],\n\ - Southwest = [SOUTHWEST]","[src] dir writing") as null|num - if(isnum_safe(new_data) && holder.check_interactivity(user) ) - to_chat(user, "You input [new_data] into the pin.") - write_data_to_pin(new_data) - -/datum/integrated_io/dir/write_data_to_pin(var/new_data) - if(isnull(new_data) || (new_data in list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)/* + list(UP, DOWN)*/)) - data = new_data - holder.on_data_written() - -/datum/integrated_io/dir/display_pin_type() - return IC_FORMAT_DIR - -/datum/integrated_io/dir/display_data(var/input) - if(!isnull(data)) - return "([dir2text(data)])" - return ..() diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/index_pin.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/index_pin.dm deleted file mode 100644 index 5b2e4af11f8..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/index_pin.dm +++ /dev/null @@ -1,21 +0,0 @@ -// These pins can only contain integer numbers between 0 and IC_MAX_LIST_LENGTH. Null is allowed. -/datum/integrated_io/index - name = "index pin" - data = 1 - -/datum/integrated_io/index/ask_for_pin_data(mob/user) - var/new_data = input("Please type in an index.","[src] index writing") as num - if(isnum_safe(new_data) && holder.check_interactivity(user)) - to_chat(user, "You input [new_data] into the pin.") - write_data_to_pin(new_data) - -/datum/integrated_io/index/write_data_to_pin(new_data) - if(isnull(new_data)) - new_data = 0 - - if(isnum_safe(new_data)) - data = clamp(round(new_data), 0, IC_MAX_LIST_LENGTH) - holder.on_data_written() - -/datum/integrated_io/index/display_pin_type() - return IC_FORMAT_INDEX diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/list_pin.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/list_pin.dm deleted file mode 100644 index 6437d0869e7..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/list_pin.dm +++ /dev/null @@ -1,153 +0,0 @@ -// These pins contain a list. Null is not allowed. -/datum/integrated_io/lists - name = "list pin" - data = list() - -/datum/integrated_io/lists/ask_for_pin_data(mob/user) - interact(user) - -/datum/integrated_io/lists/proc/interact(mob/user) - var/list/my_list = data - var/t = "

[src]


" - t += "List length: [my_list.len]
" - t += "\[Refresh\] | " - t += "\[Add\] | " - t += "\[Remove\] | " - t += "\[Edit\] | " - t += "\[Swap\] | " - t += "\[Clear\]
" - t += "
" - var/i = 0 - for(var/line in my_list) - i++ - t += "#[i] | [display_data(line)] | " - t += "\[Edit\] | " - t += "\[Remove\]
" - user << browse(t, "window=list_pin_[REF(src)];size=500x400") - -/datum/integrated_io/lists/proc/add_to_list(mob/user, var/new_entry) - if(!new_entry && user) - new_entry = ask_for_data_type(user) - if(is_valid(new_entry)) - Add(new_entry) - -/datum/integrated_io/lists/proc/Add(var/new_entry) - var/list/my_list = data - if(my_list.len > IC_MAX_LIST_LENGTH) - my_list.Cut(Start=1,End=2) - my_list.Add(new_entry) - -/datum/integrated_io/lists/proc/remove_from_list_by_position(mob/user, var/position) - var/list/my_list = data - if(!my_list.len) - to_chat(user, "The list is empty, there's nothing to remove.") - return - if(!position) - return - var/target_entry = my_list[position] - if(target_entry) - my_list.Remove(target_entry) - -/datum/integrated_io/lists/proc/remove_from_list(mob/user, var/target_entry) - var/list/my_list = data - if(!my_list.len) - to_chat(user, "The list is empty, there's nothing to remove.") - return - if(!target_entry) - target_entry = input(user, "Which piece of data do you want to remove?", "Remove") as null|anything in my_list - if(holder.check_interactivity(user) && target_entry) - my_list.Remove(target_entry) - -/datum/integrated_io/lists/proc/edit_in_list(mob/user, var/target_entry) - var/list/my_list = data - if(!my_list.len) - to_chat(user, "The list is empty, there's nothing to modify.") - return - if(!target_entry) - target_entry = input(user, "Which piece of data do you want to edit?", "Edit") as null|anything in my_list - if(holder.check_interactivity(user) && target_entry) - var/edited_entry = ask_for_data_type(user, target_entry) - if(edited_entry) - my_list[my_list.Find(target_entry)] = edited_entry - -/datum/integrated_io/lists/proc/edit_in_list_by_position(mob/user, var/position) - var/list/my_list = data - if(!my_list.len) - to_chat(user, "The list is empty, there's nothing to modify.") - return - if(!position) - return - var/target_entry = my_list[position] - if(target_entry) - var/edited_entry = ask_for_data_type(user, target_entry) - if(edited_entry) - my_list[position] = edited_entry - -/datum/integrated_io/lists/proc/swap_inside_list(mob/user, var/first_target, var/second_target) - var/list/my_list = data - if(my_list.len <= 1) - to_chat(user, "The list is empty, or too small to do any meaningful swapping.") - return - if(!first_target) - first_target = input(user, "Which piece of data do you want to swap? (1)", "Swap") as null|anything in my_list - - if(holder.check_interactivity(user) && first_target) - if(!second_target) - second_target = input(user, "Which piece of data do you want to swap? (2)", "Swap") as null|anything in my_list - first_target - - if(holder.check_interactivity(user) && second_target) - var/first_pos = my_list.Find(first_target) - var/second_pos = my_list.Find(second_target) - my_list.Swap(first_pos, second_pos) - -/datum/integrated_io/lists/proc/clear_list(mob/user) - var/list/my_list = data - my_list.Cut() - -/datum/integrated_io/lists/scramble() - var/list/my_list = data - my_list = shuffle(my_list) - push_data() - -/datum/integrated_io/lists/write_data_to_pin(var/new_data) - if(islist(new_data)) - var/list/new_list = new_data - data = new_list.Copy(max(1,new_list.len - IC_MAX_LIST_LENGTH+1),0) - holder.on_data_written() - else if(isnull(new_data)) // Clear the list - var/list/my_list = data - my_list.Cut() - holder.on_data_written() - -/datum/integrated_io/lists/display_pin_type() - return IC_FORMAT_LIST - -/datum/integrated_io/lists/Topic(href, href_list) - if(!holder.check_interactivity(usr)) - return - if(..()) - return TRUE - - if(href_list["add"]) - add_to_list(usr) - - if(href_list["swap"]) - swap_inside_list(usr) - - if(href_list["clear"]) - clear_list(usr) - - if(href_list["remove"]) - if(href_list["pos"]) - remove_from_list_by_position(usr, text2num(href_list["pos"])) - else - remove_from_list(usr) - - if(href_list["edit"]) - if(href_list["pos"]) - edit_in_list_by_position(usr, text2num(href_list["pos"])) - else - edit_in_list(usr) - - holder.interact(usr) // Refresh the main UI, - interact(usr) // and the list UI. diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/number_pin.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/number_pin.dm deleted file mode 100644 index e4e02d33a10..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/number_pin.dm +++ /dev/null @@ -1,17 +0,0 @@ -// These pins can only contain numbers (int and floating point) or null. -/datum/integrated_io/number - name = "number pin" - -/datum/integrated_io/number/ask_for_pin_data(mob/user) - var/new_data = input("Please type in a number.","[src] number writing") as null|num - if(isnum_safe(new_data) && holder.check_interactivity(user) ) - to_chat(user, "You input [new_data] into the pin.") - write_data_to_pin(new_data) - -/datum/integrated_io/number/write_data_to_pin(var/new_data) - if(isnull(new_data) || isnum_safe(new_data)) - data = new_data - holder.on_data_written() - -/datum/integrated_io/number/display_pin_type() - return IC_FORMAT_NUMBER diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/ref_pin.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/ref_pin.dm deleted file mode 100644 index f64e15f2255..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/ref_pin.dm +++ /dev/null @@ -1,24 +0,0 @@ -// These pins only contain weakrefs or null. -/datum/integrated_io/ref - name = "ref pin" - -/datum/integrated_io/ref/ask_for_pin_data(mob/user) // This clears the pin. - write_data_to_pin(null) - -/datum/integrated_io/ref/write_data_to_pin(var/new_data) - if(isnull(new_data) || isweakref(new_data)) - data = new_data - holder.on_data_written() - -/datum/integrated_io/ref/display_pin_type() - return IC_FORMAT_REF - -/datum/integrated_io/ref/connect_pin(datum/integrated_io/pin) - ..(pin) - if(istype(pin,/datum/integrated_io/selfref)) - write_data_to_pin(pin.data) - -/datum/integrated_io/ref/disconnect_pin(datum/integrated_io/pin) - ..(pin) - if(istype(pin,/datum/integrated_io/selfref)) - write_data_to_pin(null) diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/selfref_pin.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/selfref_pin.dm deleted file mode 100644 index 79dcf9e6c8c..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/selfref_pin.dm +++ /dev/null @@ -1,27 +0,0 @@ -// This pin only contains its own weakref and can't be changed -/datum/integrated_io/selfref - name = "selfref pin" - -/datum/integrated_io/selfref/New() - ..() - write_data_to_pin(src) - -/datum/integrated_io/selfref/ask_for_pin_data(mob/user) // You can't clear it, it's self reference. - - -/datum/integrated_io/selfref/write_data_to_pin(var/new_data) // You can't write anything else but itself onto it - if(data) - return - data = WEAKREF(holder) - holder.on_data_written() - -/datum/integrated_io/selfref/display_pin_type() - return IC_FORMAT_REF - -/datum/integrated_io/selfref/connect_pin(datum/integrated_io/pin) - pin.write_data_to_pin(data) - ..(pin) - -/datum/integrated_io/selfref/disconnect_pin(datum/integrated_io/pin) - ..(pin) - pin.write_data_to_pin(null) diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/string_pin.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/string_pin.dm deleted file mode 100644 index 554ebf59487..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/special_pins/string_pin.dm +++ /dev/null @@ -1,30 +0,0 @@ -// These pins can only contain text and null. -/datum/integrated_io/string - name = "string pin" - -/datum/integrated_io/string/ask_for_pin_data(mob/user) - var/new_data = stripped_multiline_input(user, "Please type in a string.","[src] string writing", no_trim = TRUE) - if(holder.check_interactivity(user) ) - if(!isnull(new_data) && istext(new_data) && CHAT_FILTER_CHECK(new_data)) - to_chat(user, "Your input contains prohibited words.") - return - to_chat(user, "You input [new_data ? "[new_data]" : "NULL"] into the pin.") - write_data_to_pin(new_data) - -/datum/integrated_io/string/write_data_to_pin(var/new_data) - if(isnull(new_data) || istext(new_data)) - data = new_data - holder.on_data_written() - -// This makes the text go "from this" to "#G&*!HD$%L" -/datum/integrated_io/string/scramble() - if(!is_valid()) - return - var/list/options = list("!","@","#","$","%","^","&","*","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z") - var/new_data = "" - for(var/i in 1 to length(data)) - new_data += pick(options) - push_data() - -/datum/integrated_io/string/display_pin_type() - return IC_FORMAT_STRING diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/wirer.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/wirer.dm deleted file mode 100644 index f534487def1..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/core/wirer.dm +++ /dev/null @@ -1,103 +0,0 @@ -#define WIRE "wire" -#define WIRING "wiring" -#define UNWIRE "unwire" -#define UNWIRING "unwiring" - -/obj/item/integrated_electronics/wirer - name = "circuit wirer" - desc = "It's a small wiring tool, with a wire roll, electric soldering iron, wire cutter, and more in one package. \ - The wires used are generally useful for small electronics, such as circuitboards and breadboards, as opposed to larger wires \ - used for power or data transmission." - icon = 'modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/electronic_tools.dmi' - icon_state = "wirer-wire" - flags_1 = CONDUCT_1 - w_class = WEIGHT_CLASS_SMALL - custom_materials = list(/datum/material/iron=200) - var/datum/integrated_io/selected_io = null - var/mode = WIRE - -/obj/item/integrated_electronics/wirer/update_icon() - icon_state = "wirer-[mode]" - ..() - -/obj/item/integrated_electronics/wirer/proc/wire(var/datum/integrated_io/io, mob/user) - if(!io.holder.assembly) - to_chat(user, "\The [io.holder] needs to be secured inside an assembly first.") - return - switch(mode) - if(WIRE) - selected_io = io - to_chat(user, "You attach a data wire to \the [selected_io.holder]'s [selected_io.name] data channel.") - mode = WIRING - update_icon() - if(WIRING) - if(io == selected_io) - to_chat(user, "Wiring \the [selected_io.holder]'s [selected_io.name] into itself is rather pointless.") - return - if(io.io_type != selected_io.io_type) - to_chat(user, "Those two types of channels are incompatible. The first is a [selected_io.io_type], \ - while the second is a [io.io_type].") - return - if(io.holder.assembly && io.holder.assembly != selected_io.holder.assembly) - to_chat(user, "Both \the [io.holder] and \the [selected_io.holder] need to be inside the same assembly.") - return - selected_io.connect_pin(io) - - to_chat(user, "You connect \the [selected_io.holder]'s [selected_io.name] to \the [io.holder]'s [io.name].") - mode = WIRE - update_icon() - selected_io.holder.interact(user) // This is to update the UI. - selected_io = null - - if(UNWIRE) - selected_io = io - if(!io.linked.len) - to_chat(user, "There is nothing connected to \the [selected_io] data channel.") - selected_io = null - return - to_chat(user, "You prepare to detach a data wire from \the [selected_io.holder]'s [selected_io.name] data channel.") - mode = UNWIRING - update_icon() - return - - if(UNWIRING) - if(io == selected_io) - to_chat(user, "You can't wire a pin into each other, so unwiring \the [selected_io.holder] from \ - the same pin is rather moot.") - return - if(selected_io in io.linked) - selected_io.disconnect_pin(io) - to_chat(user, "You disconnect \the [selected_io.holder]'s [selected_io.name] from \ - \the [io.holder]'s [io.name].") - selected_io.holder.interact(user) // This is to update the UI. - selected_io = null - mode = UNWIRE - update_icon() - else - to_chat(user, "\The [selected_io.holder]'s [selected_io.name] and \the [io.holder]'s \ - [io.name] are not connected.") - return - -/obj/item/integrated_electronics/wirer/attack_self(mob/user) - switch(mode) - if(WIRE) - mode = UNWIRE - if(WIRING) - if(selected_io) - to_chat(user, "You decide not to wire the data channel.") - selected_io = null - mode = WIRE - if(UNWIRE) - mode = WIRE - if(UNWIRING) - if(selected_io) - to_chat(user, "You decide not to disconnect the data channel.") - selected_io = null - mode = UNWIRE - update_icon() - to_chat(user, "You set \the [src] to [mode].") - -#undef WIRE -#undef WIRING -#undef UNWIRE -#undef UNWIRING diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/passive/passive.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/passive/passive.dm deleted file mode 100644 index 7678d02ad5f..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/passive/passive.dm +++ /dev/null @@ -1,7 +0,0 @@ -// 'Passive' components do not have any pins, and instead contribute in some form to the assembly holding them. -/obj/item/integrated_circuit/passive - inputs = list() - outputs = list() - activators = list() - power_draw_idle = 0 - power_draw_per_use = 0 diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/passive/power.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/passive/power.dm deleted file mode 100644 index daca79cfd7a..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/passive/power.dm +++ /dev/null @@ -1,152 +0,0 @@ - -/obj/item/integrated_circuit/passive/power - name = "power thingy" - desc = "Does power stuff." - complexity = 5 - category_text = "Power - Passive" - -/obj/item/integrated_circuit/passive/power/proc/make_energy() - return - -// For calculators. -/obj/item/integrated_circuit/passive/power/solar_cell - name = "tiny photovoltaic cell" - desc = "It's a very tiny solar cell, generally used in calculators." - extended_desc = "This cell generates 1 W of power in optimal lighting conditions. Less light will result in less power being generated." - icon_state = "solar_cell" - complexity = 8 - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - var/max_power = 30 - -/obj/item/integrated_circuit/passive/power/solar_cell/make_energy() - var/turf/T = get_turf(src) - var/light_amount = T ? T.get_lumcount() : 0 - var/adjusted_power = max(max_power * light_amount, 0) - adjusted_power = round(adjusted_power, 0.1) - if(adjusted_power) - if(assembly) - assembly.give_power(adjusted_power) - -/obj/item/integrated_circuit/passive/power/starter - name = "starter" - desc = "This tiny circuit will send a pulse right after the device is turned on, or when power is restored to it." - icon_state = "led" - complexity = 1 - activators = list("pulse out" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - var/is_charge = FALSE - -/obj/item/integrated_circuit/passive/power/starter/make_energy() - if(assembly.battery) - if(assembly.battery.charge) - if(!is_charge) - activate_pin(1) - is_charge = TRUE - else - is_charge = FALSE - else - is_charge=FALSE - return FALSE - -// For fat machines that need fat power, like drones. -/obj/item/integrated_circuit/passive/power/relay - name = "tesla power relay" - desc = "An enigmatic device which wirelessly connects to nearby APCs to draw power." - w_class = WEIGHT_CLASS_SMALL - extended_desc = "Siphons 50 W of power from an APC in the same room so long as there is charge remaining. It will always drain \ - from the 'equipment' power channel." - icon_state = "power_relay" - complexity = 7 - spawn_flags = IC_SPAWN_RESEARCH - var/power_amount = 50 - - -/obj/item/integrated_circuit/passive/power/relay/make_energy() - if(!assembly) - return - var/area/A = get_area(src) - if(A && A.powered(AREA_USAGE_EQUIP) && assembly.give_power(power_amount)) - A.use_power(power_amount, AREA_USAGE_EQUIP) - // give_power() handles CELLRATE on its own. - - -// For really fat machines. -/obj/item/integrated_circuit/passive/power/relay/large - name = "large tesla power relay" - desc = "A bulky, enigmatic device which wirelessly connects to nearby APCs to draw power. Now industrial size!" - w_class = WEIGHT_CLASS_BULKY - extended_desc = "The siphon drains 2 kW of power from an APC in the same room as it as long as it has charge remaining. It will always drain \ - from the 'equipment' power channel." - icon_state = "power_relay" - complexity = 15 - spawn_flags = IC_SPAWN_RESEARCH - power_amount = 1000 - - -//fuel cell -/obj/item/integrated_circuit/passive/power/chemical_cell - name = "fuel cell" - desc = "Produces electricity from chemicals." - icon_state = "chemical_cell" - extended_desc = "This is effectively an internal beaker. It will consume and produce power from plasma, slime jelly, welding fuel, carbon,\ - ethanol, nutriment, and blood in order of decreasing efficiency. It will consume fuel only if the battery can take more energy." - complexity = 4 - inputs = list() - outputs = list("volume used" = IC_PINTYPE_NUMBER, "self reference" = IC_PINTYPE_SELFREF) - activators = list("push ref" = IC_PINTYPE_PULSE_IN) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - var/volume = 60 - var/list/fuel = list("plasma" = 50000, "slimejelly" = 22500, "welding_fuel" = 15000, "carbon" = 10000, "ethanol" = 10000, "nutriment" = 8000) - var/multi = 1 - var/lfwb =TRUE - -/obj/item/integrated_circuit/passive/power/chemical_cell/Initialize() - . = ..() - create_reagents(volume, OPENCONTAINER) - extended_desc +="But no fuel can be compared with blood of living human." - - -/obj/item/integrated_circuit/passive/power/chemical_cell/interact(mob/user) - set_pin_data(IC_OUTPUT, 2, WEAKREF(src)) - push_data() - ..() - -/obj/item/integrated_circuit/passive/power/chemical_cell/create_reagents(max_vol, flags) - . = ..() - RegisterSignal(reagents, list(COMSIG_REAGENTS_NEW_REAGENT, COMSIG_REAGENTS_ADD_REAGENT, COMSIG_REAGENTS_DEL_REAGENT, COMSIG_REAGENTS_REM_REAGENT), .proc/on_reagent_change) - RegisterSignal(reagents, COMSIG_PARENT_QDELETING, .proc/on_reagents_del) - -/// Handles properly detaching signal hooks. -/obj/item/integrated_circuit/passive/power/chemical_cell/proc/on_reagents_del(datum/reagents/reagents) - SIGNAL_HANDLER - UnregisterSignal(reagents, list(COMSIG_REAGENTS_NEW_REAGENT, COMSIG_REAGENTS_ADD_REAGENT, COMSIG_REAGENTS_DEL_REAGENT, COMSIG_REAGENTS_REM_REAGENT, COMSIG_PARENT_QDELETING)) - return NONE - -/obj/item/integrated_circuit/passive/power/chemical_cell/proc/on_reagent_change(datum/reagents/holder, ...) - SIGNAL_HANDLER - set_pin_data(IC_OUTPUT, 1, reagents.total_volume) - push_data() - return NONE - -/obj/item/integrated_circuit/passive/power/chemical_cell/make_energy() - if(assembly) - if(assembly.battery) - var/bp = 5000 - if(reagents.get_reagent_amount("blood")) //only blood is powerful enough to power the station(c) - var/datum/reagent/blood/B = locate() in reagents.reagent_list - if(lfwb) - if(B && B.data["cloneable"]) - var/mob/M = B.data["donor"] - if(M && (M.stat != DEAD) && (M.client)) - bp = 500000 - if((assembly.battery.maxcharge-assembly.battery.charge) / GLOB.CELLRATE > bp) - if(reagents.remove_reagent("blood", 1)) - assembly.give_power(bp) - for(var/I in fuel) - if((assembly.battery.maxcharge-assembly.battery.charge) / GLOB.CELLRATE > fuel[I]) - if(reagents.remove_reagent(I, 1)) - assembly.give_power(fuel[I]*multi) - -/obj/item/integrated_circuit/passive/power/chemical_cell/do_work() - set_pin_data(IC_OUTPUT, 2, WEAKREF(src)) - push_data() diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/access.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/access.dm deleted file mode 100644 index d60e829d38a..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/access.dm +++ /dev/null @@ -1,41 +0,0 @@ -// - card reader - // -/obj/item/integrated_circuit/input/card_reader - name = "ID card reader" //To differentiate it from the data card reader - desc = "A circuit that can read the registred name, assignment, and PassKey string from an ID card." - icon_state = "card_reader" - - complexity = 4 - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - outputs = list( - "registered name" = IC_PINTYPE_STRING, - "assignment" = IC_PINTYPE_STRING, - "passkey" = IC_PINTYPE_STRING - ) - activators = list( - "on read" = IC_PINTYPE_PULSE_OUT - ) - -/obj/item/integrated_circuit/input/card_reader/attackby_react(obj/item/I, mob/living/user) - var/obj/item/card/id/card = I.GetID() - var/list/access = I.GetAccess() - var/passkey = strtohex(XorEncrypt(json_encode(access), SScircuit.cipherkey)) - - if(assembly) - assembly.access_card.access |= access - - if(card) // An ID card. - set_pin_data(IC_OUTPUT, 1, card.registered_name) - set_pin_data(IC_OUTPUT, 2, card.assignment) - - else if(length(access)) // A non-card object that has access levels. - set_pin_data(IC_OUTPUT, 1, null) - set_pin_data(IC_OUTPUT, 2, null) - - else - return FALSE - - set_pin_data(IC_OUTPUT, 3, passkey) - - push_data() - activate_pin(1) - return TRUE diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/arithmetic.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/arithmetic.dm deleted file mode 100644 index 0799b4d2df7..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/arithmetic.dm +++ /dev/null @@ -1,344 +0,0 @@ -//These circuits do simple math. -/obj/item/integrated_circuit/arithmetic - complexity = 1 - inputs = list( - "A" = IC_PINTYPE_NUMBER, - "B" = IC_PINTYPE_NUMBER, - "C" = IC_PINTYPE_NUMBER, - "D" = IC_PINTYPE_NUMBER, - "E" = IC_PINTYPE_NUMBER, - "F" = IC_PINTYPE_NUMBER, - "G" = IC_PINTYPE_NUMBER, - "H" = IC_PINTYPE_NUMBER - ) - outputs = list("result" = IC_PINTYPE_NUMBER) - activators = list("compute" = IC_PINTYPE_PULSE_IN, "on computed" = IC_PINTYPE_PULSE_OUT) - category_text = "Arithmetic" - power_draw_per_use = 5 // Math is pretty cheap. - -// +Adding+ // - -/obj/item/integrated_circuit/arithmetic/addition - name = "addition circuit" - desc = "This circuit can add numbers together." - extended_desc = "The order that the calculation goes is;
\ - result = ((((A + B) + C) + D) ... ) and so on, until all pins have been added. \ - Null pins are ignored." - icon_state = "addition" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/arithmetic/addition/do_work() - var/result = 0 - for(var/k in 1 to inputs.len) - var/I = get_pin_data(IC_INPUT, k) - if(isnum_safe(I)) - result += I - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -// -Subtracting- // - -/obj/item/integrated_circuit/arithmetic/subtraction - name = "subtraction circuit" - desc = "This circuit can subtract numbers." - extended_desc = "The order that the calculation goes is;
\ - result = ((((A - B) - C) - D) ... ) and so on, until all pins have been subtracted. \ - Null pins are ignored. Pin A must be a number, or the circuit will not function." - icon_state = "subtraction" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/arithmetic/subtraction/do_work() - var/datum/integrated_io/A = inputs[1] - if(!isnum_safe(A.data)) - return - var/result = A.data - - for(var/k in 2 to inputs.len) - var/I = get_pin_data(IC_INPUT, k) - if(isnum_safe(I)) - result -= I - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -// *Multiply* // - -/obj/item/integrated_circuit/arithmetic/multiplication - name = "multiplication circuit" - desc = "This circuit can multiply numbers." - extended_desc = "The order that the calculation goes is;
\ - result = ((((A * B) * C) * D) ... ) and so on, until all pins have been multiplied. \ - Null pins are ignored. Pin A must be a number, or the circuit will not function." - icon_state = "multiplication" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - - -/obj/item/integrated_circuit/arithmetic/multiplication/do_work() - var/datum/integrated_io/A = inputs[1] - if(!isnum_safe(A.data)) - return - var/result = A.data - for(var/k in 2 to inputs.len) - var/I = get_pin_data(IC_INPUT, k) - if(isnum_safe(I)) - result *= I - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -// /Division/ // - -/obj/item/integrated_circuit/arithmetic/division - name = "division circuit" - desc = "This circuit can divide numbers. Don't even think about trying to divide by zero!" - extended_desc = "The order that the calculation goes is;
\ - result = ((((A / B) / C) / D) ... ) and so on, until all pins have been divided. \ - Null pins, and pins containing 0, are ignored. Pin A must be a number or the circuit will not function." - icon_state = "division" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/arithmetic/division/do_work() - var/datum/integrated_io/A = inputs[1] - if(!isnum_safe(A.data)) - return - var/result = A.data - - - for(var/k in 2 to inputs.len) - var/I = get_pin_data(IC_INPUT, k) - if(isnum_safe(I) && (I != 0)) - result /= I - - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -//^ Exponent ^// - -/obj/item/integrated_circuit/arithmetic/exponent - name = "exponent circuit" - desc = "Outputs A to the power of B." - icon_state = "exponent" - inputs = list("A" = IC_PINTYPE_NUMBER, "B" = IC_PINTYPE_NUMBER) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/arithmetic/exponent/do_work() - var/result = 0 - var/datum/integrated_io/A = inputs[1] - var/datum/integrated_io/B = inputs[2] - if(isnum_safe(A.data) && isnum_safe(B.data)) - result = A.data ** B.data - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -// +-Sign-+ // - -/obj/item/integrated_circuit/arithmetic/sign - name = "sign circuit" - desc = "This circuit can tell if a number is positive, negative, or zero." - extended_desc = "Will output 1, -1, or 0, depending on if A is a positive number, a negative number, or zero, respectively." - icon_state = "sign" - inputs = list("A" = IC_PINTYPE_NUMBER) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/arithmetic/sign/do_work() - var/result = 0 - var/datum/integrated_io/A = inputs[1] - if(isnum_safe(A.data)) - if(A.data > 0) - result = 1 - else if (A.data < 0) - result = -1 - else - result = 0 - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -// Round // - -/obj/item/integrated_circuit/arithmetic/round - name = "round circuit" - desc = "Rounds A to the nearest B multiple of A." - extended_desc = "If B is not given a number, it will output the floor of A instead." - icon_state = "round" - inputs = list("A" = IC_PINTYPE_NUMBER, "B" = IC_PINTYPE_NUMBER) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/arithmetic/round/do_work() - var/result = 0 - var/datum/integrated_io/A = inputs[1] - var/datum/integrated_io/B = inputs[2] - if(isnum_safe(A.data)) - if(isnum_safe(B.data) && B.data != 0) - result = round(A.data, B.data) - else - result = round(A.data) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -// Absolute // - -/obj/item/integrated_circuit/arithmetic/absolute - name = "absolute circuit" - desc = "This outputs a non-negative version of the number you put in. This may also be thought of as its distance from zero." - icon_state = "absolute" - inputs = list("A" = IC_PINTYPE_NUMBER) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/arithmetic/absolute/do_work() - var/result = 0 - for(var/k in 1 to inputs.len) - var/datum/integrated_io/I = inputs[k] - I.pull_data() - if(isnum_safe(I.data)) - result = abs(I.data) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -// Averaging // - -/obj/item/integrated_circuit/arithmetic/average - name = "average circuit" - desc = "This circuit is of average quality. It will compute the average of the numbers you give it." - extended_desc = "Note that null pins are ignored, whereas a pin containing 0 is included in the averaging calculation." - icon_state = "average" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/arithmetic/average/do_work() - var/result = 0 - var/inputs_used = 0 - for(var/k in 2 to inputs.len) - var/I = get_pin_data(IC_INPUT, k) - if(isnum_safe(I)) - inputs_used++ - result += I - - if(inputs_used) - result = result / inputs_used - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -// Pi, because why the hell not? // -/obj/item/integrated_circuit/arithmetic/pi - name = "pi constant circuit" - desc = "Not recommended for cooking. Outputs '3.14159' when it receives a pulse." - icon_state = "pi" - inputs = list() - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/arithmetic/pi/Initialize() - . = ..() - desc = "Not recommended for cooking. Outputs '[PI]' when it receives a pulse." - -/obj/item/integrated_circuit/arithmetic/pi/do_work() - set_pin_data(IC_OUTPUT, 1, PI) - push_data() - activate_pin(2) - -// Random // -/obj/item/integrated_circuit/arithmetic/random - name = "random number generator circuit" - desc = "This gives a random (integer) number between values A and B inclusive." - extended_desc = "'Inclusive' means that the upper bound is included in the range of numbers, e.g. L = 1 and H = 3 will allow \ - for outputs of 1, 2, or 3. H being the higher number is not strictly required." - icon_state = "random" - inputs = list("L" = IC_PINTYPE_NUMBER,"H" = IC_PINTYPE_NUMBER) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/arithmetic/random/do_work() - var/result = 0 - var/L = get_pin_data(IC_INPUT, 1) - var/H = get_pin_data(IC_INPUT, 2) - - if(isnum_safe(L) && isnum_safe(H)) - result = rand(L, H) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -// Square Root // - -/obj/item/integrated_circuit/arithmetic/square_root - name = "square root circuit" - desc = "This outputs the square root of the number you input." - icon_state = "square_root" - inputs = list("A" = IC_PINTYPE_NUMBER) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/arithmetic/square_root/do_work() - var/result = 0 - for(var/k in 2 to inputs.len) - var/I = get_pin_data(IC_INPUT, k) - if(isnum_safe(I)) - result += sqrt(I) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -// % Modulo % // - -/obj/item/integrated_circuit/arithmetic/modulo - name = "modulo circuit" - desc = "Gets the remainder of A / B." - icon_state = "modulo" - inputs = list("A" = IC_PINTYPE_NUMBER, "B" = IC_PINTYPE_NUMBER) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/arithmetic/modulo/do_work() - var/result = 0 - var/A = get_pin_data(IC_INPUT, 1) - var/B = get_pin_data(IC_INPUT, 2) - if(isnum_safe(A) && isnum_safe(B) && B != 0) - result = A % B - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -// -Max- // -/obj/item/integrated_circuit/arithmetic/max - name = "max circuit" - desc = "This circuit sends out the highest number." - extended_desc = "The highest number is put out. Null is ignored." - icon_state = "addition" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - var/min_comparision = FALSE - -/obj/item/integrated_circuit/arithmetic/max/do_work() - var/result - for(var/k in 1 to inputs.len) - var/I = get_pin_data(IC_INPUT, k) - if(!isnum_safe(I)) - continue - if(!isnum_safe(result) || (!min_comparision && I > result) || (min_comparision && I < result)) - result = I - if(!isnum_safe(result)) - result = 0 - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - - -// -Min- // -/obj/item/integrated_circuit/arithmetic/max/min - name = "min circuit" - desc = "This circuit sends out the smallest number." - extended_desc = "The smallest number is put out. Null is ignored. In case no number is found, 0 is given out." - min_comparision = TRUE diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/converters.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/converters.dm deleted file mode 100644 index ad2599f8cf4..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/converters.dm +++ /dev/null @@ -1,425 +0,0 @@ -//These circuits convert one variable to another. -/obj/item/integrated_circuit/converter - complexity = 2 - inputs = list("input") - outputs = list("output") - activators = list("convert" = IC_PINTYPE_PULSE_IN, "on convert" = IC_PINTYPE_PULSE_OUT) - category_text = "Converter" - power_draw_per_use = 10 - -/obj/item/integrated_circuit/converter/num2text - name = "number to string" - desc = "This circuit can convert a number variable into a string." - extended_desc = "Because of circuit limitations, null/false variables will output a '0' string." - icon_state = "num-string" - inputs = list("input" = IC_PINTYPE_NUMBER) - outputs = list("output" = IC_PINTYPE_STRING) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/converter/num2text/do_work() - var/result = null - pull_data() - var/incoming = get_pin_data(IC_INPUT, 1) - if(!isnull(incoming)) - result = num2text(incoming) - else if(!incoming) - result = "0" - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/converter/text2num - name = "string to number" - desc = "This circuit can convert a string variable into a number." - icon_state = "string-num" - inputs = list("input" = IC_PINTYPE_STRING) - outputs = list("output" = IC_PINTYPE_NUMBER) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/converter/text2num/do_work() - var/result = null - pull_data() - var/incoming = get_pin_data(IC_INPUT, 1) - if(!isnull(incoming)) - result = text2num(incoming) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/converter/ref2text - name = "reference to string" - desc = "This circuit can convert a reference to something else to a string, specifically the name of that reference." - icon_state = "ref-string" - inputs = list("input" = IC_PINTYPE_REF) - outputs = list("output" = IC_PINTYPE_STRING) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/converter/ref2text/do_work() - var/result = null - pull_data() - var/atom/A = get_pin_data(IC_INPUT, 1) - if(A && istype(A)) - result = A.name - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/converter/refcode - name = "reference encoder" - desc = "This circuit can encode a reference into a string, which can then be read by a reference decoder circuit." - icon_state = "ref-string" - inputs = list("input" = IC_PINTYPE_REF) - outputs = list("output" = IC_PINTYPE_STRING) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/converter/refcode/do_work() - var/result = null - pull_data() - var/atom/A = get_pin_data(IC_INPUT, 1) - if(A && istype(A)) - result = strtohex(XorEncrypt(REF(A), SScircuit.cipherkey)) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/converter/refdecode - name = "reference decoder" - desc = "This circuit can convert an encoded reference to an actual reference." - icon_state = "ref-string" - inputs = list("input" = IC_PINTYPE_STRING) - outputs = list("output" = IC_PINTYPE_REF) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - var/dec - -/obj/item/integrated_circuit/converter/refdecode/do_work() - pull_data() - dec = XorEncrypt(hextostr(get_pin_data(IC_INPUT, 1), TRUE), SScircuit.cipherkey) - set_pin_data(IC_OUTPUT, 1, WEAKREF(locate(dec))) - push_data() - activate_pin(2) - - -/obj/item/integrated_circuit/converter/radians2degrees - name = "radians to degrees converter" - desc = "Converts radians to degrees." - inputs = list("radian" = IC_PINTYPE_NUMBER) - outputs = list("degrees" = IC_PINTYPE_NUMBER) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/converter/radians2degrees/do_work() - var/result = null - pull_data() - var/incoming = get_pin_data(IC_INPUT, 1) - if(!isnull(incoming)) - result = TODEGREES(incoming) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/converter/degrees2radians - name = "degrees to radians converter" - desc = "Converts degrees to radians." - inputs = list("degrees" = IC_PINTYPE_NUMBER) - outputs = list("radians" = IC_PINTYPE_NUMBER) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/converter/degrees2radians/do_work() - var/result = null - pull_data() - var/incoming = get_pin_data(IC_INPUT, 1) - if(!isnull(incoming)) - result = TORADIANS(incoming) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - - -/obj/item/integrated_circuit/converter/abs_to_rel_coords - name = "abs to rel coordinate converter" - desc = "Easily convert absolute coordinates to relative coordinates with this." - extended_desc = "Keep in mind that both sets of input coordinates should be absolute." - complexity = 1 - inputs = list( - "X1" = IC_PINTYPE_NUMBER, - "Y1" = IC_PINTYPE_NUMBER, - "X2" = IC_PINTYPE_NUMBER, - "Y2" = IC_PINTYPE_NUMBER - ) - outputs = list( - "X" = IC_PINTYPE_NUMBER, - "Y" = IC_PINTYPE_NUMBER - ) - activators = list("compute rel coordinates" = IC_PINTYPE_PULSE_IN, "on convert" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/converter/abs_to_rel_coords/do_work() - var/x1 = get_pin_data(IC_INPUT, 1) - var/y1 = get_pin_data(IC_INPUT, 2) - - var/x2 = get_pin_data(IC_INPUT, 3) - var/y2 = get_pin_data(IC_INPUT, 4) - - if(!isnull(x1) && !isnull(y1) && !isnull(x2) && !isnull(y2)) - set_pin_data(IC_OUTPUT, 1, x1 - x2) - set_pin_data(IC_OUTPUT, 2, y1 - y2) - - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/converter/rel_to_abs_coords - name = "rel to abs coordinate converter" - desc = "Convert relative coordinates to absolute coordinates with this." - extended_desc = "Keep in mind that only one set of input coordinates should be absolute, and the other relative. \ - The output coordinates will be the absolute form of the input relative coordinates." - complexity = 1 - inputs = list( - "X1" = IC_PINTYPE_NUMBER, - "Y1" = IC_PINTYPE_NUMBER, - "X2" = IC_PINTYPE_NUMBER, - "Y2" = IC_PINTYPE_NUMBER - ) - outputs = list( - "X" = IC_PINTYPE_NUMBER, - "Y" = IC_PINTYPE_NUMBER - ) - activators = list("compute abs coordinates" = IC_PINTYPE_PULSE_IN, "on convert" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/converter/rel_to_abs_coords/do_work() - var/x1 = get_pin_data(IC_INPUT, 1) - var/y1 = get_pin_data(IC_INPUT, 2) - - var/x2 = get_pin_data(IC_INPUT, 3) - var/y2 = get_pin_data(IC_INPUT, 4) - - if(!isnull(x1) && !isnull(y1) && !isnull(x2) && !isnull(y2)) - set_pin_data(IC_OUTPUT, 1, x1 + x2) - set_pin_data(IC_OUTPUT, 2, y1 + y2) - - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/converter/adv_rel_to_abs_coords - name = "advanced rel to abs coordinate converter" - desc = "Easily convert relative coordinates to absolute coordinates with this." - extended_desc = "This circuit only requires a single set of relative inputs to output absolute coordinates." - complexity = 2 - inputs = list( - "X" = IC_PINTYPE_NUMBER, - "Y" = IC_PINTYPE_NUMBER, - ) - outputs = list( - "X" = IC_PINTYPE_NUMBER, - "Y" = IC_PINTYPE_NUMBER - ) - activators = list("compute abs coordinates" = IC_PINTYPE_PULSE_IN, "on convert" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/converter/adv_rel_to_abs_coords/do_work() - var/turf/T = get_turf(src) - - if(!T) - return - - var/x1 = get_pin_data(IC_INPUT, 1) - var/y1 = get_pin_data(IC_INPUT, 2) - - if(!isnull(x1) && !isnull(y1)) - set_pin_data(IC_OUTPUT, 1, T.x + x1) - set_pin_data(IC_OUTPUT, 2, T.y + y1) - - push_data() - activate_pin(2) - - -/obj/item/integrated_circuit/converter/hsv2hex - name = "hsv to hexadecimal" - desc = "This circuit can convert a HSV (Hue, Saturation, and Value) color to a Hexadecimal RGB color." - extended_desc = "The first pin controls tint (0-359), the second pin controls how intense the tint is (0-255), and the third controls how bright the tint is (0 for black, 127 for normal, 255 for white)." - icon_state = "hsv-hex" - inputs = list( - "hue" = IC_PINTYPE_NUMBER, - "saturation" = IC_PINTYPE_NUMBER, - "value" = IC_PINTYPE_NUMBER - ) - outputs = list("hexadecimal rgb" = IC_PINTYPE_COLOR) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/converter/hsv2hex/do_work() - var/result = null - pull_data() - var/hue = get_pin_data(IC_INPUT, 1) - var/saturation = get_pin_data(IC_INPUT, 2) - var/value = get_pin_data(IC_INPUT, 3) - if(isnum_safe(hue)&&isnum_safe(saturation)&&isnum_safe(value)) - result = HSVtoRGB(hsv(AngleToHue(hue),saturation,value)) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - - -/obj/item/integrated_circuit/converter/rgb2hex - name = "rgb to hexadecimal" - desc = "This circuit can convert a RGB (Red, Green, Blue) color to a Hexadecimal RGB color." - extended_desc = "The first pin controls red amount, the second pin controls green amount, and the third controls blue amount. They all go from 0-255." - icon_state = "rgb-hex" - inputs = list( - "red" = IC_PINTYPE_NUMBER, - "green" = IC_PINTYPE_NUMBER, - "blue" = IC_PINTYPE_NUMBER - ) - outputs = list("hexadecimal rgb" = IC_PINTYPE_COLOR) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/converter/rgb2hex/do_work() - var/result = null - pull_data() - var/red = get_pin_data(IC_INPUT, 1) - var/green = get_pin_data(IC_INPUT, 2) - var/blue = get_pin_data(IC_INPUT, 3) - if(isnum_safe(red)&&isnum_safe(green)&&isnum_safe(blue)) - result = rgb(red,green,blue) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - - -// - hsv to rgb - // -/obj/item/integrated_circuit/converter/hsv2rgb - name = "hsv to rgb" - desc = "This circuit can convert a HSV (Hue, Saturation, and Value) color to a RGB (red, blue and green) color." - extended_desc = "The first pin controls tint (0-359), the second pin controls how intense the tint is (0-255), and the third controls how bright the tint is (0 for black, 127 for normal, 255 for white)." - icon_state = "hsv-hex" - inputs = list( - "hue" = IC_PINTYPE_NUMBER, - "saturation" = IC_PINTYPE_NUMBER, - "value" = IC_PINTYPE_NUMBER - ) - outputs = list( - "red" = IC_PINTYPE_NUMBER, - "green" = IC_PINTYPE_NUMBER, - "blue" = IC_PINTYPE_NUMBER - ) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH -/obj/item/integrated_circuit/converter/hsv2rgb/do_work() - var/hue = get_pin_data(IC_INPUT, 1) - var/sat = get_pin_data(IC_INPUT, 2) - var/val = get_pin_data(IC_INPUT, 3) - if(!hue || !sat || !val) - set_pin_data(IC_OUTPUT, 1, 0) - set_pin_data(IC_OUTPUT, 2, 0) - set_pin_data(IC_OUTPUT, 3, 0) - else - var/list/RGB = ReadRGB(HSVtoRGB(hsv(hue,sat,val))) - - set_pin_data(IC_OUTPUT, 1, RGB[1]) - set_pin_data(IC_OUTPUT, 2, RGB[2]) - set_pin_data(IC_OUTPUT, 3, RGB[3]) - push_data() - activate_pin(2) - - -// - rgb to hsv - // -/obj/item/integrated_circuit/converter/rgb2hsv - name = "rgb to hsv" - desc = "This circuit can convert a RGB (Red, Blue, and Green) color to a HSV (Hue, Saturation and Value) color." - extended_desc = "All values for the RGB colors are situated between 0 and 255." - icon_state = "hsv-hex" - inputs = list( - "red" = IC_PINTYPE_NUMBER, - "green" = IC_PINTYPE_NUMBER, - "blue" = IC_PINTYPE_NUMBER - ) - outputs = list( - "hue" = IC_PINTYPE_NUMBER, - "saturation" = IC_PINTYPE_NUMBER, - "value" = IC_PINTYPE_NUMBER - ) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/converter/rgb2hsv/do_work() - var/red = get_pin_data(IC_INPUT, 1) - var/blue = get_pin_data(IC_INPUT, 2) - var/green = get_pin_data(IC_INPUT, 3) - if(!red || !blue || !green) - set_pin_data(IC_OUTPUT, 1, 0) - set_pin_data(IC_OUTPUT, 2, 0) - set_pin_data(IC_OUTPUT, 3, 0) - else - var/list/HSV = ReadHSV(RGBtoHSV(rgb(red,blue,green))) - - set_pin_data(IC_OUTPUT, 1, HSV[1]) - set_pin_data(IC_OUTPUT, 2, HSV[2]) - set_pin_data(IC_OUTPUT, 3, HSV[3]) - push_data() - activate_pin(2) - - -// - hexadecimal to hsv - // -/obj/item/integrated_circuit/converter/hex2hsv - name = "hexadecimal to hsv" - desc = "This circuit can convert a Hexadecimal RGB color into a HSV (Hue, Saturation and Value) color." - extended_desc = "Hexadecimal colors follow the format #RRBBGG, RR being the red value, BB the blue value and GG the green value. They are written in hexadecimal, giving each color a value from 0 (00) to 255 (FF)." - icon_state = "hsv-hex" - inputs = list("hexadecimal rgb" = IC_PINTYPE_COLOR) - outputs = list( - "hue" = IC_PINTYPE_NUMBER, - "saturation" = IC_PINTYPE_NUMBER, - "value" = IC_PINTYPE_NUMBER - ) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/converter/hex2hsv/do_work() - pull_data() - var/rgb = get_pin_data(IC_INPUT, 1) - if(!rgb) - set_pin_data(IC_OUTPUT, 1, 0) - set_pin_data(IC_OUTPUT, 2, 0) - set_pin_data(IC_OUTPUT, 3, 0) - return - else - var/list/hsv = ReadHSV(RGBtoHSV(rgb)) - set_pin_data(IC_OUTPUT, 1, hsv[1]) - set_pin_data(IC_OUTPUT, 2, hsv[2]) - set_pin_data(IC_OUTPUT, 3, hsv[3]) - push_data() - activate_pin(2) - - -// - hex 2 rgb - // -/obj/item/integrated_circuit/converter/hex2rgb - name = "hexadecimal to rgb" - desc = "This circuit can convert a Hexadecimal RGB color into a RGB (Red, Blue and Green color." - extended_desc = "Hexadecimal colors follow the format #RRBBGG, RR being the red value, BB the blue value and GG the green value. They are written in hexadecimal, giving each color a value from 0 (00) to 255 (FF)." - icon_state = "hsv-hex" - inputs = list("hexadecimal rgb" = IC_PINTYPE_COLOR) - outputs = list( - "red" = IC_PINTYPE_NUMBER, - "green" = IC_PINTYPE_NUMBER, - "blue" = IC_PINTYPE_NUMBER - ) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/converter/hex2rgb/do_work() - var/rgb = get_pin_data(IC_INPUT, 1) - if(!rgb) - set_pin_data(IC_OUTPUT, 1, 0) - set_pin_data(IC_OUTPUT, 2, 0) - set_pin_data(IC_OUTPUT, 3, 0) - else - var/list/RGB = ReadRGB(rgb) - - set_pin_data(IC_OUTPUT, 1, RGB[1]) - set_pin_data(IC_OUTPUT, 2, RGB[2]) - set_pin_data(IC_OUTPUT, 3, RGB[3]) - - push_data() - activate_pin(2) diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/data_transfer.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/data_transfer.dm deleted file mode 100644 index d1ec094305a..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/data_transfer.dm +++ /dev/null @@ -1,208 +0,0 @@ -/obj/item/integrated_circuit/transfer - category_text = "Data Transfer" - power_draw_per_use = 2 - -/obj/item/integrated_circuit/transfer/multiplexer - name = "two multiplexer" - desc = "This is what those in the business tend to refer to as a 'mux', or data selector. It moves data from one of the selected inputs to the output." - extended_desc = "The first input pin is used to select which of the other input pins which has its data moved to the output. \ - If the input selection is outside the valid range then no output is given." - complexity = 2 - icon_state = "mux2" - inputs = list("input selection" = IC_PINTYPE_NUMBER) - outputs = list("output" = IC_PINTYPE_ANY) - activators = list("select" = IC_PINTYPE_PULSE_IN, "on select" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 4 - var/number_of_pins = 2 - -/obj/item/integrated_circuit/transfer/multiplexer/Initialize() - for(var/i = 1 to number_of_pins) - inputs["input [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called. - - complexity = number_of_pins - . = ..() - desc += " It has [number_of_pins] input pins." - extended_desc += " This multiplexer has a range from 1 to [inputs.len - 1]." - -/obj/item/integrated_circuit/transfer/multiplexer/do_work() - var/input_index = get_pin_data(IC_INPUT, 1) - - if(!isnull(input_index) && (input_index >= 1 && input_index < inputs.len)) - set_pin_data(IC_OUTPUT, 1,get_pin_data(IC_INPUT, input_index + 1)) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/transfer/multiplexer/medium - name = "four multiplexer" - icon_state = "mux4" - number_of_pins = 4 - -/obj/item/integrated_circuit/transfer/multiplexer/large - name = "eight multiplexer" - w_class = WEIGHT_CLASS_SMALL - icon_state = "mux8" - number_of_pins = 8 - -/obj/item/integrated_circuit/transfer/multiplexer/huge - name = "sixteen multiplexer" - icon_state = "mux16" - w_class = WEIGHT_CLASS_SMALL - number_of_pins = 16 - -/obj/item/integrated_circuit/transfer/demultiplexer - name = "two demultiplexer" - desc = "This is what those in the business tend to refer to as a 'demux'. It moves data from the input to one of the selected outputs." - extended_desc = "The first input pin is used to select which of the output pins is given the data from the second input pin. \ - If the output selection is outside the valid range then no output is given." - complexity = 2 - icon_state = "dmux2" - inputs = list("output selection" = IC_PINTYPE_NUMBER, "input" = IC_PINTYPE_ANY) - outputs = list() - activators = list("select" = IC_PINTYPE_PULSE_IN, "on select" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 4 - var/number_of_pins = 2 - -/obj/item/integrated_circuit/transfer/demultiplexer/Initialize() - for(var/i = 1 to number_of_pins) - outputs["output [i]"] = IC_PINTYPE_ANY - complexity = number_of_pins - - . = ..() - desc += " It has [number_of_pins] output pins." - extended_desc += " This demultiplexer has a range from 1 to [outputs.len]." - -/obj/item/integrated_circuit/transfer/demultiplexer/do_work() - var/output_index = get_pin_data(IC_INPUT, 1) - if(!isnull(output_index) && (output_index >= 1 && output_index <= outputs.len)) - var/datum/integrated_io/O = outputs[output_index] - O.data = get_pin_data(IC_INPUT, 2) - O.push_data() - - activate_pin(2) - -/obj/item/integrated_circuit/transfer/demultiplexer/medium - name = "four demultiplexer" - icon_state = "dmux4" - number_of_pins = 4 - -/obj/item/integrated_circuit/transfer/demultiplexer/large - name = "eight demultiplexer" - icon_state = "dmux8" - w_class = WEIGHT_CLASS_SMALL - number_of_pins = 8 - -/obj/item/integrated_circuit/transfer/demultiplexer/huge - name = "sixteen demultiplexer" - icon_state = "dmux16" - w_class = WEIGHT_CLASS_SMALL - number_of_pins = 16 - -/obj/item/integrated_circuit/transfer/pulsedemultiplexer - name = "two pulse demultiplexer" - desc = "Selector switch to choose the pin to be activated by number." - extended_desc = "The first input pin is used to select which of the pulse out pins will be activated after activation of the circuit. \ - If the output selection is outside the valid range then no output is given." - complexity = 2 - icon_state = "dmux2" - inputs = list("output selection" = IC_PINTYPE_NUMBER) - outputs = list() - activators = list("select" = IC_PINTYPE_PULSE_IN) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 4 - var/number_of_pins = 2 - -/obj/item/integrated_circuit/transfer/pulsedemultiplexer/Initialize() - for(var/i = 1 to number_of_pins) - activators["output [i]"] = IC_PINTYPE_PULSE_OUT - complexity = number_of_pins - - . = ..() - desc += " It has [number_of_pins] output pins." - extended_desc += " This pulse demultiplexer has a range from 1 to [activators.len - 1]." - -/obj/item/integrated_circuit/transfer/pulsedemultiplexer/do_work() - var/output_index = get_pin_data(IC_INPUT, 1) - - if(output_index == clamp(output_index, 1, number_of_pins)) - activate_pin(round(output_index + 1 ,1)) - -/obj/item/integrated_circuit/transfer/pulsedemultiplexer/medium - name = "four pulse demultiplexer" - icon_state = "dmux4" - number_of_pins = 4 - -/obj/item/integrated_circuit/transfer/pulsedemultiplexer/large - name = "eight pulse demultiplexer" - icon_state = "dmux8" - w_class = WEIGHT_CLASS_SMALL - number_of_pins = 8 - -/obj/item/integrated_circuit/transfer/pulsedemultiplexer/huge - name = "sixteen pulse demultiplexer" - icon_state = "dmux16" - w_class = WEIGHT_CLASS_SMALL - number_of_pins = 16 - -/obj/item/integrated_circuit/transfer/pulsemultiplexer - name = "two pulse multiplexer" - desc = "Pulse in pins to choose the pin value to be sent." - extended_desc = "The input pulses are used to select which of the input pins has its data moved to the output." - complexity = 2 - icon_state = "dmux2" - inputs = list() - outputs = list("output" = IC_PINTYPE_ANY) - activators = list("on selected" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 4 - var/number_of_pins = 2 - -/obj/item/integrated_circuit/transfer/pulsemultiplexer/Initialize() - for(var/i = 1 to number_of_pins) - inputs["input [i]"] = IC_PINTYPE_ANY - for(var/i = 1 to number_of_pins) - activators["input [i]"] = IC_PINTYPE_PULSE_IN - complexity = number_of_pins - - . = ..() - desc += " It has [number_of_pins] pulse in pins and [number_of_pins] output pins." - extended_desc += " This pulse multiplexer has a range from 1 to [activators.len - 1]." - -/obj/item/integrated_circuit/transfer/pulsemultiplexer/do_work(ord) - var/input_index = ord - 2 - - if(!isnull(input_index) && (input_index >= 0 && input_index < inputs.len)) - set_pin_data(IC_OUTPUT, 1,get_pin_data(IC_INPUT, input_index + 1)) - push_data() - activate_pin(1) - -/obj/item/integrated_circuit/transfer/pulsemultiplexer/medium - name = "four pulse multiplexer" - icon_state = "dmux4" - number_of_pins = 4 - -/obj/item/integrated_circuit/transfer/pulsemultiplexer/large - name = "eight pulse multiplexer" - icon_state = "dmux8" - w_class = WEIGHT_CLASS_SMALL - number_of_pins = 8 - -/obj/item/integrated_circuit/transfer/pulsemultiplexer/huge - name = "sixteen pulse multiplexer" - icon_state = "dmux16" - w_class = WEIGHT_CLASS_SMALL - number_of_pins = 16 - -/obj/item/integrated_circuit/transfer/wire_node - name = "wire node" - desc = "Just a wire node to make wiring easier. Transfers the pulse from in to out." - icon_state = "wire_node" - activators = list("pulse in" = IC_PINTYPE_PULSE_IN, "pulse out" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 0 - complexity = 0 - size = 0.1 - -/obj/item/integrated_circuit/transfer/wire_node/do_work() - activate_pin(2) diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/input.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/input.dm deleted file mode 100644 index a04344b4954..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/input.dm +++ /dev/null @@ -1,1469 +0,0 @@ -/obj/item/integrated_circuit/input - var/can_be_asked_input = 0 - category_text = "Input" - power_draw_per_use = 5 - -/obj/item/integrated_circuit/input/proc/ask_for_input(mob/user) - return - -/obj/item/integrated_circuit/input/button - name = "button" - desc = "This tiny button must do something, right?" - icon_state = "button" - complexity = 1 - can_be_asked_input = 1 - inputs = list() - outputs = list() - activators = list("on pressed" = IC_PINTYPE_PULSE_IN) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/input/button/ask_for_input(mob/user) //Bit misleading name for this specific use. - to_chat(user, "You press the button labeled '[displayed_name]'.") - activate_pin(1) - -/obj/item/integrated_circuit/input/toggle_button - name = "toggle button" - desc = "It toggles on, off, on, off..." - icon_state = "toggle_button" - complexity = 1 - can_be_asked_input = 1 - inputs = list() - outputs = list("on" = IC_PINTYPE_BOOLEAN) - activators = list("on toggle" = IC_PINTYPE_PULSE_IN) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/input/toggle_button/ask_for_input(mob/user) // Ditto. - set_pin_data(IC_OUTPUT, 1, !get_pin_data(IC_OUTPUT, 1)) - push_data() - activate_pin(1) - to_chat(user, "You toggle the button labeled '[displayed_name]' [get_pin_data(IC_OUTPUT, 1) ? "on" : "off"].") - -/obj/item/integrated_circuit/input/numberpad - name = "number pad" - desc = "This small number pad allows someone to input a number into the system." - icon_state = "numberpad" - complexity = 2 - can_be_asked_input = 1 - inputs = list() - outputs = list("number entered" = IC_PINTYPE_NUMBER) - activators = list("on entered" = IC_PINTYPE_PULSE_IN) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 4 - -/obj/item/integrated_circuit/input/numberpad/ask_for_input(mob/user) - var/new_input = input(user, "Enter a number, please.",displayed_name) as null|num - if(isnum_safe(new_input) && ISADVANCEDTOOLUSER(user)) - set_pin_data(IC_OUTPUT, 1, new_input) - push_data() - activate_pin(1) - -/obj/item/integrated_circuit/input/textpad - name = "text pad" - desc = "This small text pad allows someone to input a string into the system." - icon_state = "textpad" - complexity = 2 - can_be_asked_input = 1 - inputs = list() - outputs = list("string entered" = IC_PINTYPE_STRING) - activators = list("on entered" = IC_PINTYPE_PULSE_IN) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 4 - -/obj/item/integrated_circuit/input/textpad/ask_for_input(mob/user) - var/new_input = stripped_multiline_input(user, "Enter some words, please.",displayed_name) - if(istext(new_input) && ISADVANCEDTOOLUSER(user)) - set_pin_data(IC_OUTPUT, 1, new_input) - push_data() - activate_pin(1) - -/obj/item/integrated_circuit/input/colorpad - name = "color pad" - desc = "This small color pad allows someone to input a hexadecimal color into the system." - icon_state = "colorpad" - complexity = 2 - can_be_asked_input = 1 - inputs = list() - outputs = list("color entered" = IC_PINTYPE_STRING) - activators = list("on entered" = IC_PINTYPE_PULSE_IN) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 4 - -/obj/item/integrated_circuit/input/colorpad/ask_for_input(mob/user) - var/new_color = input(user, "Enter a color, please.", "Color", "#ffffff") as color|null - if(new_color && ISADVANCEDTOOLUSER(user)) - set_pin_data(IC_OUTPUT, 1, new_color) - push_data() - activate_pin(1) - -/obj/item/integrated_circuit/input/med_scanner - name = "integrated medical analyser" - desc = "A very small version of the common medical analyser. This allows the machine to know how healthy someone is." - icon_state = "medscan" - complexity = 4 - inputs = list("target" = IC_PINTYPE_REF) - outputs = list( - "total health %" = IC_PINTYPE_NUMBER, - "total missing health" = IC_PINTYPE_NUMBER - ) - activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 40 - -/obj/item/integrated_circuit/input/med_scanner/do_work() - var/mob/living/H = get_pin_data_as_type(IC_INPUT, 1, /mob/living) - if(!istype(H)) //Invalid input - return - if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range. - var/total_health = round(H.health/H.getMaxHealth(), 0.01)*100 - var/missing_health = H.getMaxHealth() - H.health - - set_pin_data(IC_OUTPUT, 1, total_health) - set_pin_data(IC_OUTPUT, 2, missing_health) - - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/input/adv_med_scanner - name = "integrated adv. medical analyser" - desc = "A very small version of the medbot's medical analyser. This allows the machine to know how healthy someone is. \ - This type is much more precise, allowing the machine to know much more about the target than a normal analyzer." - icon_state = "medscan_adv" - complexity = 12 - inputs = list("target" = IC_PINTYPE_REF) - outputs = list( - "total health %" = IC_PINTYPE_NUMBER, - "total missing health" = IC_PINTYPE_NUMBER, - "brute damage" = IC_PINTYPE_NUMBER, - "burn damage" = IC_PINTYPE_NUMBER, - "tox damage" = IC_PINTYPE_NUMBER, - "oxy damage" = IC_PINTYPE_NUMBER, - "clone damage" = IC_PINTYPE_NUMBER - ) - activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 80 - -/obj/item/integrated_circuit/input/adv_med_scanner/do_work() - var/mob/living/H = get_pin_data_as_type(IC_INPUT, 1, /mob/living) - if(!istype(H)) //Invalid input - return - if(H in view(get_turf(src))) // Like medbot's analyzer it can be used in range.. - var/total_health = round(H.health/H.getMaxHealth(), 0.01)*100 - var/missing_health = H.getMaxHealth() - H.health - - set_pin_data(IC_OUTPUT, 1, total_health) - set_pin_data(IC_OUTPUT, 2, missing_health) - set_pin_data(IC_OUTPUT, 3, H.getBruteLoss()) - set_pin_data(IC_OUTPUT, 4, H.getFireLoss()) - set_pin_data(IC_OUTPUT, 5, H.getToxLoss()) - set_pin_data(IC_OUTPUT, 6, H.getOxyLoss()) - set_pin_data(IC_OUTPUT, 7, H.getCloneLoss()) - - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/input/slime_scanner - name = "slime scanner" - desc = "A very small version of the xenobio analyser. This allows the machine to know every needed properties of slime. Output mutation list is non-associative." - icon_state = "medscan_adv" - complexity = 12 - inputs = list("target" = IC_PINTYPE_REF) - outputs = list( - "colour" = IC_PINTYPE_STRING, - "adult" = IC_PINTYPE_BOOLEAN, - "nutrition" = IC_PINTYPE_NUMBER, - "charge" = IC_PINTYPE_NUMBER, - "health" = IC_PINTYPE_NUMBER, - "possible mutation" = IC_PINTYPE_LIST, - "genetic destability" = IC_PINTYPE_NUMBER, - "slime core amount" = IC_PINTYPE_NUMBER, - "Growth progress" = IC_PINTYPE_NUMBER, - ) - activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 80 - -/obj/item/integrated_circuit/input/slime_scanner/do_work() - var/mob/living/simple_animal/slime/T = get_pin_data_as_type(IC_INPUT, 1, /mob/living/simple_animal/slime) - if(!isslime(T)) //Invalid input - return - if(T in view(get_turf(src))) // Like medbot's analyzer it can be used in range.. - - set_pin_data(IC_OUTPUT, 1, T.colour) - set_pin_data(IC_OUTPUT, 2, T.is_adult) - set_pin_data(IC_OUTPUT, 3, T.nutrition/T.get_max_nutrition()) - set_pin_data(IC_OUTPUT, 4, T.powerlevel) - set_pin_data(IC_OUTPUT, 5, round(T.health/T.maxHealth,0.01)*100) - set_pin_data(IC_OUTPUT, 6, uniqueList(T.slime_mutation)) - set_pin_data(IC_OUTPUT, 7, T.mutation_chance) - set_pin_data(IC_OUTPUT, 8, T.cores) - set_pin_data(IC_OUTPUT, 9, T.amount_grown/SLIME_EVOLUTION_THRESHOLD) - - - push_data() - activate_pin(2) - - - -/obj/item/integrated_circuit/input/plant_scanner - name = "integrated plant analyzer" - desc = "A very small version of the plant analyser. This allows the machine to know all valuable parameters of plants in trays. \ - It can only scan plants, not seeds or fruits." - icon_state = "medscan_adv" - complexity = 12 - inputs = list("target" = IC_PINTYPE_REF) - outputs = list( - "plant type" = IC_PINTYPE_STRING, - "age" = IC_PINTYPE_NUMBER, - "potency" = IC_PINTYPE_NUMBER, - "yield" = IC_PINTYPE_NUMBER, - "Maturation speed" = IC_PINTYPE_NUMBER, - "Production speed" = IC_PINTYPE_NUMBER, - "Endurance" = IC_PINTYPE_NUMBER, - "Lifespan" = IC_PINTYPE_NUMBER, - "Weed Growth Rate" = IC_PINTYPE_NUMBER, - "Weed Vulnerability" = IC_PINTYPE_NUMBER, - "Weed level" = IC_PINTYPE_NUMBER, - "Pest level" = IC_PINTYPE_NUMBER, - "Toxicity level" = IC_PINTYPE_NUMBER, - "Water level" = IC_PINTYPE_NUMBER, - "Nutrition level" = IC_PINTYPE_NUMBER, - "harvest" = IC_PINTYPE_NUMBER, - "dead" = IC_PINTYPE_NUMBER, - "plant health" = IC_PINTYPE_NUMBER, - "self sustaining" = IC_PINTYPE_NUMBER - ) - activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 10 - -/obj/item/integrated_circuit/input/plant_scanner/do_work() - var/obj/machinery/hydroponics/H = get_pin_data_as_type(IC_INPUT, 1, /obj/machinery/hydroponics) - if(!istype(H)) //Invalid input - return - for(var/i=1, i<=outputs.len, i++) - set_pin_data(IC_OUTPUT, i, null) - if(H in view(get_turf(src))) // Like medbot's analyzer it can be used in range.. - if(H.myseed) - set_pin_data(IC_OUTPUT, 1, H.myseed.plantname) - set_pin_data(IC_OUTPUT, 2, H.age) - set_pin_data(IC_OUTPUT, 3, H.myseed.potency) - set_pin_data(IC_OUTPUT, 4, H.myseed.yield) - set_pin_data(IC_OUTPUT, 5, H.myseed.maturation) - set_pin_data(IC_OUTPUT, 6, H.myseed.production) - set_pin_data(IC_OUTPUT, 7, H.myseed.endurance) - set_pin_data(IC_OUTPUT, 8, H.myseed.lifespan) - set_pin_data(IC_OUTPUT, 9, H.myseed.weed_rate) - set_pin_data(IC_OUTPUT, 10, H.myseed.weed_chance) - set_pin_data(IC_OUTPUT, 11, H.weedlevel) - set_pin_data(IC_OUTPUT, 12, H.pestlevel) - set_pin_data(IC_OUTPUT, 13, H.toxic) - set_pin_data(IC_OUTPUT, 14, H.waterlevel) - set_pin_data(IC_OUTPUT, 15, H.reagents.total_volume) - set_pin_data(IC_OUTPUT, 16, H.harvest) - set_pin_data(IC_OUTPUT, 17, H.dead) - set_pin_data(IC_OUTPUT, 18, H.plant_health) - set_pin_data(IC_OUTPUT, 19, H.self_sustaining) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/input/gene_scanner - name = "gene scanner" - desc = "This circuit will scan the target plant for traits and reagent genes. Output is non-associative." - extended_desc = "This allows the machine to scan plants in trays for reagent and trait genes. \ - It can only scan plants, not seeds or fruits." - inputs = list( - "target" = IC_PINTYPE_REF - ) - outputs = list( - "traits" = IC_PINTYPE_LIST, - "reagents" = IC_PINTYPE_LIST - ) - activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) - icon_state = "medscan_adv" - spawn_flags = IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/input/gene_scanner/do_work() - var/list/gtraits = list() - var/list/greagents = list() - var/obj/machinery/hydroponics/H = get_pin_data_as_type(IC_INPUT, 1, /obj/machinery/hydroponics) - if(!istype(H)) //Invalid input - return - for(var/i=1, i<=outputs.len, i++) - set_pin_data(IC_OUTPUT, i, null) - if(H in view(get_turf(src))) // Like medbot's analyzer it can be used in range.. - if(H.myseed) - for(var/datum/plant_gene/reagent/G in H.myseed.genes) - greagents.Add(G.get_name()) - - for(var/datum/plant_gene/trait/G in H.myseed.genes) - gtraits.Add(G.get_name()) - - set_pin_data(IC_OUTPUT, 1, gtraits) - set_pin_data(IC_OUTPUT, 2, greagents) - push_data() - activate_pin(2) - - -/obj/item/integrated_circuit/input/examiner - name = "examiner" - desc = "It's a little machine vision system. It can return the name, description, distance, \ - relative coordinates, total amount of reagents, maximum amount of reagents, density, and opacity of the referenced object." - icon_state = "video_camera" - complexity = 6 - inputs = list( - "target" = IC_PINTYPE_REF - ) - outputs = list( - "name" = IC_PINTYPE_STRING, - "description" = IC_PINTYPE_STRING, - "X" = IC_PINTYPE_NUMBER, - "Y" = IC_PINTYPE_NUMBER, - "distance" = IC_PINTYPE_NUMBER, - "max reagents" = IC_PINTYPE_NUMBER, - "amount of reagents" = IC_PINTYPE_NUMBER, - "density" = IC_PINTYPE_BOOLEAN, - "opacity" = IC_PINTYPE_BOOLEAN, - "occupied turf" = IC_PINTYPE_REF - ) - activators = list( - "scan" = IC_PINTYPE_PULSE_IN, - "on scanned" = IC_PINTYPE_PULSE_OUT, - "not scanned" = IC_PINTYPE_PULSE_OUT - ) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 80 - -/obj/item/integrated_circuit/input/examiner/do_work() - var/atom/H = get_pin_data_as_type(IC_INPUT, 1, /atom) - var/turf/T = get_turf(src) - - if(!istype(H) || !(H in view(T))) - activate_pin(3) - else - set_pin_data(IC_OUTPUT, 1, H.name) - set_pin_data(IC_OUTPUT, 2, H.desc) - - if(istype(H, /mob/living)) - var/mob/living/M = H - var/msg = M.examine() - if(msg) - set_pin_data(IC_OUTPUT, 2, msg) - - set_pin_data(IC_OUTPUT, 3, H.x-T.x) - set_pin_data(IC_OUTPUT, 4, H.y-T.y) - set_pin_data(IC_OUTPUT, 5, sqrt((H.x-T.x)*(H.x-T.x)+ (H.y-T.y)*(H.y-T.y))) - var/mr = 0 - var/tr = 0 - if(H.reagents) - mr = H.reagents.maximum_volume - tr = H.reagents.total_volume - set_pin_data(IC_OUTPUT, 6, mr) - set_pin_data(IC_OUTPUT, 7, tr) - set_pin_data(IC_OUTPUT, 8, H.CanPass(assembly ? assembly : src, get_turf(H))) - set_pin_data(IC_OUTPUT, 9, H.opacity) - set_pin_data(IC_OUTPUT, 10, get_turf(H)) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/input/turfpoint - name = "Tile pointer" - desc = "This circuit will get a tile ref with the provided absolute coordinates." - extended_desc = "If the machine cannot see the target, it will not be able to calculate the correct direction.\ - This circuit only works while inside an assembly." - icon_state = "numberpad" - complexity = 5 - inputs = list("X" = IC_PINTYPE_NUMBER,"Y" = IC_PINTYPE_NUMBER) - outputs = list("tile" = IC_PINTYPE_REF) - activators = list("calculate dir" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT,"not calculated" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 40 - -/obj/item/integrated_circuit/input/turfpoint/do_work() - if(!assembly) - activate_pin(3) - return - var/turf/T = get_turf(assembly) - var/target_x = clamp(get_pin_data(IC_INPUT, 1), 0, world.maxx) - var/target_y = clamp(get_pin_data(IC_INPUT, 2), 0, world.maxy) - var/turf/A = locate(target_x, target_y, T.z) - set_pin_data(IC_OUTPUT, 1, null) - if(!A || !(A in view(T))) - activate_pin(3) - return - else - set_pin_data(IC_OUTPUT, 1, WEAKREF(A)) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/input/turfscan - name = "tile analyzer" - desc = "This circuit can analyze the contents of the scanned turf, and can read letters on the turf." - icon_state = "video_camera" - complexity = 5 - inputs = list( - "target" = IC_PINTYPE_REF - ) - outputs = list( - "located ref" = IC_PINTYPE_LIST, - "Written letters" = IC_PINTYPE_STRING, - "area" = IC_PINTYPE_STRING - ) - activators = list( - "scan" = IC_PINTYPE_PULSE_IN, - "on scanned" = IC_PINTYPE_PULSE_OUT, - "not scanned" = IC_PINTYPE_PULSE_OUT - ) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 40 - cooldown_per_use = 10 - -/obj/item/integrated_circuit/input/turfscan/do_work() - var/turf/scanned_turf = get_pin_data_as_type(IC_INPUT, 1, /turf) - var/turf/circuit_turf = get_turf(src) - var/area_name = get_area_name(scanned_turf) - if(!istype(scanned_turf)) //Invalid input - activate_pin(3) - return - - if(scanned_turf in view(circuit_turf)) // This is a camera. It can't examine things that it can't see. - var/list/turf_contents = new() - for(var/obj/U in scanned_turf) - turf_contents += WEAKREF(U) - for(var/mob/U in scanned_turf) - turf_contents += WEAKREF(U) - set_pin_data(IC_OUTPUT, 1, turf_contents) - set_pin_data(IC_OUTPUT, 3, area_name) - var/list/St = new() - for(var/obj/effect/decal/cleanable/crayon/I in scanned_turf) - St.Add(I.icon_state) - if(St.len) - set_pin_data(IC_OUTPUT, 2, jointext(St, ",", 1, 0)) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/input/turfpoint - name = "tile pointer" - desc = "This circuit will get tile ref with given absolute coorinates." - extended_desc = "If the machine cannot see the target, it will not be able to scan it.\ - This circuit will only work in an assembly." - icon_state = "numberpad" - complexity = 5 - inputs = list("X" = IC_PINTYPE_NUMBER,"Y" = IC_PINTYPE_NUMBER) - outputs = list("tile" = IC_PINTYPE_REF) - activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT,"not scanned" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 40 - -/obj/item/integrated_circuit/input/turfpoint/do_work() - if(!assembly) - activate_pin(3) - return - var/turf/T = get_turf(assembly) - var/target_x = clamp(get_pin_data(IC_INPUT, 1), 0, world.maxx) - var/target_y = clamp(get_pin_data(IC_INPUT, 2), 0, world.maxy) - var/turf/A = locate(target_x, target_y, T.z) - set_pin_data(IC_OUTPUT, 1, null) - if(!A || !(A in view(T))) - activate_pin(3) - return - else - set_pin_data(IC_OUTPUT, 1, WEAKREF(A)) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/input/turfscan - name = "tile analyzer" - desc = "This machine vision system can analyze contents of desired tile.And can read letters on floor." - icon_state = "video_camera" - complexity = 5 - inputs = list( - "target" = IC_PINTYPE_REF - ) - outputs = list( - "located ref" = IC_PINTYPE_LIST, - "Written letters" = IC_PINTYPE_STRING - ) - activators = list( - "scan" = IC_PINTYPE_PULSE_IN, - "on scanned" = IC_PINTYPE_PULSE_OUT, - "not scanned" = IC_PINTYPE_PULSE_OUT - ) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 40 - cooldown_per_use = 10 - -/obj/item/integrated_circuit/input/turfscan/do_work() - var/atom/movable/H = get_pin_data_as_type(IC_INPUT, 1, /atom) - var/turf/T = get_turf(src) - var/turf/E = get_turf(H) - if(!istype(H)) //Invalid input - return - - if(H in view(T)) // This is a camera. It can't examine thngs,that it can't see. - var/list/cont = new() - if(E.contents.len) - for(var/i = 1 to E.contents.len) - var/atom/U = E.contents[i] - cont += WEAKREF(U) - set_pin_data(IC_OUTPUT, 1, cont) - var/list/St = new() - for(var/obj/effect/decal/cleanable/crayon/I in E.contents) - St.Add(I.icon_state) - if(St.len) - set_pin_data(IC_OUTPUT, 2, jointext(St, ",", 1, 0)) - push_data() - activate_pin(2) - else - activate_pin(3) - -/obj/item/integrated_circuit/input/local_locator - name = "local locator" - desc = "This is needed for certain devices that demand a reference for a target to act upon. This type only locates something \ - that is holding the machine containing it." - inputs = list() - outputs = list("located ref" = IC_PINTYPE_REF, - "is ground" = IC_PINTYPE_BOOLEAN, - "is creature" = IC_PINTYPE_BOOLEAN) - activators = list("locate" = IC_PINTYPE_PULSE_IN, - "on scanned" = IC_PINTYPE_PULSE_OUT - ) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 20 - -/obj/item/integrated_circuit/input/local_locator/do_work() - var/datum/integrated_io/O = outputs[1] - O.data = null - if(assembly) - O.data = WEAKREF(assembly.loc) - set_pin_data(IC_OUTPUT, 2, isturf(assembly.loc)) - set_pin_data(IC_OUTPUT, 3, ismob(assembly.loc)) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/input/adjacent_locator - name = "adjacent locator" - desc = "This is needed for certain devices that demand a reference for a target to act upon. This type only locates something \ - that is standing up to a meter away from the machine." - extended_desc = "The first pin requires a ref to the kind of object that you want the locator to acquire. This means that it will \ - give refs to nearby objects that are similar. If more than one valid object is found nearby, it will choose one of them at \ - random." - inputs = list("desired type ref" = IC_PINTYPE_REF) - outputs = list("located ref" = IC_PINTYPE_REF) - activators = list("locate" = IC_PINTYPE_PULSE_IN,"found" = IC_PINTYPE_PULSE_OUT, - "not found" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 30 - -/obj/item/integrated_circuit/input/adjacent_locator/do_work() - var/datum/integrated_io/I = inputs[1] - var/datum/integrated_io/O = outputs[1] - O.data = null - - if(!isweakref(I.data)) - return - var/atom/A = I.data.resolve() - if(!A) - return - var/desired_type = A.type - - var/list/nearby_things = range(1, get_turf(src)) - var/list/valid_things = list() - for(var/atom/thing in nearby_things) - if(thing.type != desired_type) - continue - valid_things.Add(thing) - if(valid_things.len) - O.data = WEAKREF(pick(valid_things)) - activate_pin(2) - else - activate_pin(3) - O.push_data() - -/obj/item/integrated_circuit/input/advanced_locator_list - complexity = 6 - name = "list advanced locator" - desc = "This is needed for certain devices that demand list of names for a target to act upon. This type locates something \ - that is standing in given radius of up to 8 meters. Output is non-associative. Input will only consider keys if associative." - extended_desc = "The first pin requires a list of the kinds of objects that you want the locator to acquire. It will locate nearby objects by name and description, \ - and will then provide a list of all found objects which are similar. \ - The second pin is a radius." - inputs = list("desired type ref" = IC_PINTYPE_LIST, "radius" = IC_PINTYPE_NUMBER) - outputs = list("located ref" = IC_PINTYPE_LIST) - activators = list("locate" = IC_PINTYPE_PULSE_IN,"found" = IC_PINTYPE_PULSE_OUT,"not found" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 30 - var/radius = 1 - cooldown_per_use = 10 - -/obj/item/integrated_circuit/input/advanced_locator_list/on_data_written() - var/rad = get_pin_data(IC_INPUT, 2) - - if(isnum_safe(rad)) - rad = clamp(rad, 0, 8) - radius = rad - -/obj/item/integrated_circuit/input/advanced_locator_list/do_work() - var/datum/integrated_io/I = inputs[1] - var/datum/integrated_io/O = outputs[1] - O.data = null - var/list/input_list = list() - input_list = I.data - if(length(input_list)) //if there is no input don't do anything. - var/turf/T = get_turf(src) - var/list/nearby_things = view(radius,T) - var/list/valid_things = list() - for(var/item in input_list) - if(!isnull(item) && !isnum_safe(item)) - if(istext(item)) - for(var/i in nearby_things) - var/atom/thing = i - if(ismob(thing) && !isliving(thing)) - continue - if(findtext(addtext(thing.name," ",thing.desc), item, 1, 0) ) - valid_things.Add(WEAKREF(thing)) - else - var/atom/A = item - var/desired_type = A.type - for(var/i in nearby_things) - var/atom/thing = i - if(thing.type != desired_type) - continue - if(ismob(thing) && !isliving(thing)) - continue - valid_things.Add(WEAKREF(thing)) - if(valid_things.len) - O.data = valid_things - O.push_data() - activate_pin(2) - else - O.push_data() - activate_pin(3) - else - O.push_data() - activate_pin(3) - -/obj/item/integrated_circuit/input/advanced_locator - complexity = 6 - name = "advanced locator" - desc = "This is needed for certain devices that demand a reference for a target to act upon. This type locates something \ - that is standing in given radius of up to 8 meters" - extended_desc = "The first pin requires a ref to the kind of object that you want the locator to acquire. This means that it will \ - give refs to nearby objects which are similar. If this pin is a string, the locator will search for an \ - item matching the desired text in its name and description. If more than one valid object is found nearby, it will choose one of them at \ - random. The second pin is a radius." - inputs = list("desired type" = IC_PINTYPE_ANY, "radius" = IC_PINTYPE_NUMBER) - outputs = list("located ref" = IC_PINTYPE_REF) - activators = list("locate" = IC_PINTYPE_PULSE_IN,"found" = IC_PINTYPE_PULSE_OUT,"not found" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 30 - var/radius = 1 - -/obj/item/integrated_circuit/input/advanced_locator/on_data_written() - var/rad = get_pin_data(IC_INPUT, 2) - if(isnum_safe(rad)) - rad = clamp(rad, 0, 8) - radius = rad - -/obj/item/integrated_circuit/input/advanced_locator/do_work() - var/datum/integrated_io/I = inputs[1] - var/datum/integrated_io/O = outputs[1] - O.data = null - var/turf/T = get_turf(src) - var/list/nearby_things = view(radius,T) - var/list/valid_things = list() - if(isweakref(I.data)) - var/atom/A = I.data.resolve() - var/desired_type = A.type - if(desired_type) - for(var/i in nearby_things) - var/atom/thing = i - if(ismob(thing) && !isliving(thing)) - continue - if(thing.type == desired_type) - valid_things.Add(thing) - else if(istext(I.data)) - var/DT = I.data - for(var/i in nearby_things) - var/atom/thing = i - if(ismob(thing) && !isliving(thing)) - continue - if(findtext(addtext(thing.name," ",thing.desc), DT, 1, 0) ) - valid_things.Add(thing) - if(valid_things.len) - O.data = WEAKREF(pick(valid_things)) - O.push_data() - activate_pin(2) - else - O.push_data() - activate_pin(3) - -/obj/item/integrated_circuit/input/signaler - name = "integrated signaler" - desc = "Signals from a signaler can be received with this, allowing for remote control. It can also send signals." - extended_desc = "When a signal is received from another signaler, the 'on signal received' activator pin will be pulsed. \ - The two input pins are to configure the integrated signaler's settings. Note that the frequency should not have a decimal in it, \ - meaning the default frequency is expressed as 1457, not 145.7. To send a signal, pulse the 'send signal' activator pin." - icon_state = "signal" - complexity = 4 - inputs = list("frequency" = IC_PINTYPE_NUMBER,"code" = IC_PINTYPE_NUMBER) - outputs = list() - activators = list( - "send signal" = IC_PINTYPE_PULSE_IN, - "on signal sent" = IC_PINTYPE_PULSE_OUT, - "on signal received" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - action_flags = IC_ACTION_LONG_RANGE - power_draw_idle = 5 - power_draw_per_use = 40 - cooldown_per_use = 5 - var/frequency = FREQ_SIGNALER - var/code = DEFAULT_SIGNALER_CODE - var/datum/radio_frequency/radio_connection - var/hearing_range = 1 - -/obj/item/integrated_circuit/input/signaler/Initialize() - . = ..() - spawn(40) - set_frequency(frequency) - // Set the pins so when someone sees them, they won't show as null - set_pin_data(IC_INPUT, 1, frequency) - set_pin_data(IC_INPUT, 2, code) - -/obj/item/integrated_circuit/input/signaler/Destroy() - SSradio.remove_object(src,frequency) - - frequency = 0 - return ..() - -/obj/item/integrated_circuit/input/signaler/on_data_written() - var/new_freq = get_pin_data(IC_INPUT, 1) - var/new_code = get_pin_data(IC_INPUT, 2) - if(isnum_safe(new_freq) && new_freq > 0) - set_frequency(new_freq) - if(isnum_safe(new_code)) - code = new_code - - -/obj/item/integrated_circuit/input/signaler/do_work() // Sends a signal. - if(!radio_connection) - return - - var/datum/signal/signal = new(list("code" = code)) - radio_connection.post_signal(src, signal) - activate_pin(2) - -/obj/item/integrated_circuit/input/signaler/proc/set_frequency(new_frequency) - if(!frequency) - return - SSradio.remove_object(src, frequency) - frequency = new_frequency - radio_connection = SSradio.add_object(src, frequency, RADIO_SIGNALER) - -/obj/item/integrated_circuit/input/signaler/receive_signal(datum/signal/signal) - var/new_code = get_pin_data(IC_INPUT, 2) - var/code = 0 - - if(isnum_safe(new_code)) - code = new_code - if(!signal) - return 0 - if(signal.data["code"] != code) - return 0 - if(signal.source == src) // Don't trigger ourselves. - return 0 - - activate_pin(3) - audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*", null, hearing_range) - playsound(get_turf(src), 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE) - -/* SKYRAT PORT -- Disables NTNetworking for now, since tg changed completely how it works -/obj/item/integrated_circuit/input/ntnet_packet - name = "NTNet networking circuit" - desc = "Enables the sending and receiving of messages over NTNet via packet data protocol." - extended_desc = "Data can be sent or received using the second pin on each side, \ - with additonal data reserved for the third pin. When a message is received, the second activation pin \ - will pulse whatever is connected to it. Pulsing the first activation pin will send a message. Messages \ - can be sent to multiple recepients. Addresses must be separated with a semicolon, like this: Address1;Address2;Etc." - icon_state = "signal" - complexity = 2 - cooldown_per_use = 1 - inputs = list( - "target NTNet addresses"= IC_PINTYPE_STRING, - "data to send" = IC_PINTYPE_STRING, - "secondary text" = IC_PINTYPE_STRING, - "passkey" = IC_PINTYPE_STRING - ) - outputs = list( - "address received" = IC_PINTYPE_STRING, - "data received" = IC_PINTYPE_STRING, - "secondary text received" = IC_PINTYPE_STRING, - "passkey" = IC_PINTYPE_STRING, - "is_broadcast" = IC_PINTYPE_BOOLEAN - ) - activators = list("send data" = IC_PINTYPE_PULSE_IN, "on data received" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - action_flags = IC_ACTION_LONG_RANGE - power_draw_per_use = 50 - var/address - -/obj/item/integrated_circuit/input/ntnet_packet/Initialize() - . = ..() - var/datum/component/ntnet_interface/net = LoadComponent(/datum/component/ntnet_interface) - address = net.hardware_id - net.differentiate_broadcast = FALSE - desc += "
This circuit's NTNet hardware address is: [address]" - -/obj/item/integrated_circuit/input/ntnet_packet/do_work() - var/target_address = get_pin_data(IC_INPUT, 1) - var/message = get_pin_data(IC_INPUT, 2) - var/text = get_pin_data(IC_INPUT, 3) - - var/datum/netdata/data = new - data.recipient_ids = splittext(target_address, ";") - var/key = get_pin_data(IC_INPUT, 4) // hippie start -- adds passkey back in - data.standard_format_data(message, text, key) // hippie end - ntnet_send(data) - -/obj/item/integrated_circuit/input/ntnet_receive(datum/netdata/data) - set_pin_data(IC_OUTPUT, 1, data.sender_id) - set_pin_data(IC_OUTPUT, 2, data.data["data"]) - set_pin_data(IC_OUTPUT, 3, data.data["data_secondary"]) - set_pin_data(IC_OUTPUT, 4, data.data["encrypted_passkey"]) - set_pin_data(IC_OUTPUT, 5, data.broadcast) - - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/input/ntnet_advanced - name = "Low level NTNet transreceiver" - desc = "Enables the sending and receiving of messages over NTNet via packet data protocol. Allows advanced control of message contents and signalling. Must use associative lists. Outputs associative list. Has a slower transmission rate than normal NTNet circuits, due to increased data processing complexity." - extended_desc = "Data can be sent or received using the second pin on each side, \ - When a message is received, the second activation pin will pulse whatever is connected to it. \ - Pulsing the first activation pin will send a message. Messages can be sent to multiple recepients. \ - Addresses must be separated with a semicolon, like this: Address1;Address2;Etc." - icon_state = "signal" - complexity = 4 - cooldown_per_use = 10 - inputs = list( - "target NTNet addresses"= IC_PINTYPE_STRING, - "data" = IC_PINTYPE_LIST, - ) - outputs = list("received data" = IC_PINTYPE_LIST, "is_broadcast" = IC_PINTYPE_BOOLEAN) - activators = list("send data" = IC_PINTYPE_PULSE_IN, "on data received" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - action_flags = IC_ACTION_LONG_RANGE - power_draw_per_use = 50 - var/address - -/obj/item/integrated_circuit/input/ntnet_advanced/Initialize() - . = ..() - var/datum/component/ntnet_interface/net = LoadComponent(/datum/component/ntnet_interface) - address = net.hardware_id - net.differentiate_broadcast = FALSE - desc += "
This circuit's NTNet hardware address is: [address]" - -/obj/item/integrated_circuit/input/ntnet_advanced/do_work() - var/target_address = get_pin_data(IC_INPUT, 1) - var/list/message = get_pin_data(IC_INPUT, 2) - if(!islist(message)) - message = list() - var/datum/netdata/data = new - data.recipient_ids = splittext(target_address, ";") - data.data = message - //data.passkey = assembly.access_card.access - ntnet_send(data) - -/obj/item/integrated_circuit/input/ntnet_advanced/ntnet_receive(datum/netdata/data) - set_pin_data(IC_OUTPUT, 1, data.data) - set_pin_data(IC_OUTPUT, 2, data.broadcast) - push_data() - activate_pin(2) -*/ - -//This circuit gives information on where the machine is. -/obj/item/integrated_circuit/input/gps - name = "global positioning system" - desc = "This allows you to easily know the position of a machine containing this device." - extended_desc = "The coordinates that the GPS outputs are absolute, not relative. The full coords output has the coords separated by commas and is in string format." - icon_state = "gps" - complexity = 4 - inputs = list() - outputs = list("X"= IC_PINTYPE_NUMBER, "Y" = IC_PINTYPE_NUMBER, "Z" = IC_PINTYPE_NUMBER, "full coords" = IC_PINTYPE_STRING) - activators = list("get coordinates" = IC_PINTYPE_PULSE_IN, "on get coordinates" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 30 - -/obj/item/integrated_circuit/input/gps/do_work() - var/turf/T = get_turf(src) - - set_pin_data(IC_OUTPUT, 1, null) - set_pin_data(IC_OUTPUT, 2, null) - set_pin_data(IC_OUTPUT, 3, null) - set_pin_data(IC_OUTPUT, 4, null) - if(!T) - return - - set_pin_data(IC_OUTPUT, 1, T.x) - set_pin_data(IC_OUTPUT, 2, T.y) - set_pin_data(IC_OUTPUT, 3, T.z) - set_pin_data(IC_OUTPUT, 4, "[T.x],[T.y],[T.z]") - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/input/microphone - name = "microphone" - desc = "Useful for spying on people, or for voice-activated machines." - extended_desc = "This will automatically translate most languages it hears to Galactic Common. \ - The first activation pin is always pulsed when the circuit hears someone talk, while the second one \ - is only triggered if it hears someone speaking a language other than Galactic Common." - icon_state = "recorder" - complexity = 8 - inputs = list() - flags_1 = CONDUCT_1 | HEAR_1 - outputs = list( - "speaker" = IC_PINTYPE_STRING, - "message" = IC_PINTYPE_STRING - ) - activators = list("on message received" = IC_PINTYPE_PULSE_OUT, "on translation" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 5 - -/obj/item/integrated_circuit/input/microphone/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode) - . = ..() - var/translated = FALSE - if(speaker && message) - if(raw_message) - if(message_langs != get_selected_language()) - translated = TRUE - set_pin_data(IC_OUTPUT, 1, speaker.GetVoice()) - set_pin_data(IC_OUTPUT, 2, raw_message) - - push_data() - activate_pin(1) - if(translated) - activate_pin(2) - -/obj/item/integrated_circuit/input/sensor - name = "sensor" - desc = "Scans and obtains a reference for any objects or persons near you. All you need to do is shove the machine in their face." - extended_desc = "If the 'ignore storage' pin is set to true, the sensor will disregard scanning various storage containers such as backpacks." - icon_state = "recorder" - complexity = 12 - inputs = list("ignore storage" = IC_PINTYPE_BOOLEAN) - outputs = list("scanned" = IC_PINTYPE_REF) - activators = list("on scanned" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 120 - -/obj/item/integrated_circuit/input/sensor/sense(atom/A, mob/user, prox) - if(!prox || !A || (ismob(A) && !isliving(A))) - return FALSE - if(!check_then_do_work()) - return FALSE - var/ignore_bags = get_pin_data(IC_INPUT, 1) - if(ignore_bags) - var/datum/component/storage/STR = A.GetComponent(/datum/component/storage) - if(STR) - return FALSE - set_pin_data(IC_OUTPUT, 1, WEAKREF(A)) - push_data() - to_chat(user, "You scan [A] with [assembly].") - activate_pin(1) - return TRUE - -/obj/item/integrated_circuit/input/sensor/ranged - name = "ranged sensor" - desc = "Scans and obtains a reference for any objects or persons in range. All you need to do is point the machine towards the target." - extended_desc = "If the 'ignore storage' pin is set to true, the sensor will disregard scanning various storage containers such as backpacks." - icon_state = "recorder" - complexity = 36 - inputs = list("ignore storage" = IC_PINTYPE_BOOLEAN) - outputs = list("scanned" = IC_PINTYPE_REF) - activators = list("on scanned" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 120 - -/obj/item/integrated_circuit/input/sensor/ranged/sense(atom/A, mob/user) - if(!user || !A || (ismob(A) && !isliving(A))) - return FALSE - if(user.client) - if(!(A in view(user.client))) - return FALSE - else - if(!(A in view(user))) - return FALSE - if(!check_then_do_work()) - return FALSE - var/ignore_bags = get_pin_data(IC_INPUT, 1) - if(ignore_bags) - if(istype(A, /obj/item/storage)) - return FALSE - set_pin_data(IC_OUTPUT, 1, WEAKREF(A)) - push_data() - to_chat(user, "You scan [A] with [assembly].") - activate_pin(1) - return TRUE - -/obj/item/integrated_circuit/input/obj_scanner - name = "scanner" - desc = "Scans and obtains a reference for any objects you use on the assembly." - extended_desc = "If the 'put down' pin is set to true, the assembly will take the scanned object from your hands to its location. \ - Useful for interaction with the grabber. It only works on help intent." - icon_state = "recorder" - complexity = 4 - inputs = list("put down" = IC_PINTYPE_BOOLEAN) - outputs = list("scanned" = IC_PINTYPE_REF) - activators = list("on scanned" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 20 - -/obj/item/integrated_circuit/input/obj_scanner/attackby_react(var/atom/A,var/mob/living/user) - if(user.combat_mode) - return FALSE - if(!check_then_do_work()) - return FALSE - var/pu = get_pin_data(IC_INPUT, 1) - if(pu) - user.transferItemToLoc(A,drop_location()) - set_pin_data(IC_OUTPUT, 1, WEAKREF(A)) - push_data() - to_chat(user, "You let [assembly] scan [A].") - activate_pin(1) - return TRUE - -/obj/item/integrated_circuit/input/internalbm - name = "internal battery monitor" - desc = "This monitors the charge level of an internal battery." - icon_state = "internalbm" - extended_desc = "This circuit will give you the values of charge, max charge, and the current percentage of the internal battery on demand." - w_class = WEIGHT_CLASS_TINY - complexity = 1 - inputs = list() - outputs = list( - "cell charge" = IC_PINTYPE_NUMBER, - "max charge" = IC_PINTYPE_NUMBER, - "percentage" = IC_PINTYPE_NUMBER, - "refference to assembly" = IC_PINTYPE_REF, - "refference to cell" = IC_PINTYPE_REF - ) - activators = list("read" = IC_PINTYPE_PULSE_IN, "on read" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 1 - -/obj/item/integrated_circuit/input/internalbm/do_work() - set_pin_data(IC_OUTPUT, 1, null) - set_pin_data(IC_OUTPUT, 2, null) - set_pin_data(IC_OUTPUT, 3, null) - set_pin_data(IC_OUTPUT, 4, null) - set_pin_data(IC_OUTPUT, 5, null) - if(assembly) - set_pin_data(IC_OUTPUT, 4, WEAKREF(assembly)) - if(assembly.battery) - set_pin_data(IC_OUTPUT, 1, assembly.battery.charge) - set_pin_data(IC_OUTPUT, 2, assembly.battery.maxcharge) - set_pin_data(IC_OUTPUT, 3, 100*assembly.battery.charge/assembly.battery.maxcharge) - set_pin_data(IC_OUTPUT, 5, WEAKREF(assembly.battery)) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/input/externalbm - name = "external battery monitor" - desc = "This can read the battery state of any device in view." - icon_state = "externalbm" - extended_desc = "This circuit will give you the charge, max charge, and the current percentage values of any device or battery in view." - w_class = WEIGHT_CLASS_TINY - complexity = 2 - inputs = list("target" = IC_PINTYPE_REF) - outputs = list( - "cell charge" = IC_PINTYPE_NUMBER, - "max charge" = IC_PINTYPE_NUMBER, - "percentage" = IC_PINTYPE_NUMBER - ) - activators = list("read" = IC_PINTYPE_PULSE_IN, "on read" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 1 - -/obj/item/integrated_circuit/input/externalbm/do_work() - - var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) - set_pin_data(IC_OUTPUT, 1, null) - set_pin_data(IC_OUTPUT, 2, null) - set_pin_data(IC_OUTPUT, 3, null) - if(AM) - var/obj/item/stock_parts/cell/C = AM.get_cell() - if(C) - var/turf/A = get_turf(src) - if(get_turf(AM) in view(A)) - set_pin_data(IC_OUTPUT, 1, C.charge) - set_pin_data(IC_OUTPUT, 2, C.maxcharge) - set_pin_data(IC_OUTPUT, 3, C.percent()) - push_data() - activate_pin(2) - return - -/obj/item/integrated_circuit/input/ntnetsc - name = "NTNet scanner" - desc = "This can return the NTNet IDs of a component inside the given object, if there are any." - icon_state = "signalsc" - w_class = WEIGHT_CLASS_TINY - complexity = 2 - inputs = list("target" = IC_PINTYPE_REF) - outputs = list( - "id" = IC_PINTYPE_STRING - ) - activators = list("read" = IC_PINTYPE_PULSE_IN, "found" = IC_PINTYPE_PULSE_OUT,"not found" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 1 - -/obj/item/integrated_circuit/input/ntnetsc/do_work() - var/atom/AM = get_pin_data_as_type(IC_INPUT, 1, /atom) - var/datum/component/ntnet_interface/net - - if(AM) - var/list/processing_list = list(AM) - while(processing_list.len && !net) - var/atom/A = processing_list[1] - processing_list.Cut(1, 2) - //Byond does not allow things to be in multiple contents, or double parent-child hierarchies, so only += is needed - //This is also why we don't need to check against assembled as we go along - processing_list += A.contents - net = A.GetComponent(/datum/component/ntnet_interface) - - if(net) - set_pin_data(IC_OUTPUT, 1, net.hardware_id) - push_data() - activate_pin(2) - else - set_pin_data(IC_OUTPUT, 1, null) - push_data() - activate_pin(3) - -/obj/item/integrated_circuit/input/matscan - name = "material scanner" - desc = "This special module is designed to get information about material containers of different machinery, \ - like ORM, lathes, etc." - icon_state = "video_camera" - complexity = 6 - inputs = list( - "target" = IC_PINTYPE_REF - ) - outputs = list( - "Iron" = IC_PINTYPE_NUMBER, - "Glass" = IC_PINTYPE_NUMBER, - "Silver" = IC_PINTYPE_NUMBER, - "Gold" = IC_PINTYPE_NUMBER, - "Diamond" = IC_PINTYPE_NUMBER, - "Solid Plasma" = IC_PINTYPE_NUMBER, - "Uranium" = IC_PINTYPE_NUMBER, - "Bananium" = IC_PINTYPE_NUMBER, - "Titanium" = IC_PINTYPE_NUMBER, - "Bluespace Mesh" = IC_PINTYPE_NUMBER, - "Biomass" = IC_PINTYPE_NUMBER, - ) - activators = list( - "scan" = IC_PINTYPE_PULSE_IN, - "on scanned" = IC_PINTYPE_PULSE_OUT, - "not scanned" = IC_PINTYPE_PULSE_OUT - ) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 40 - var/list/mtypes = list(/datum/material/iron, /datum/material/glass, /datum/material/silver, /datum/material/gold, /datum/material/diamond, /datum/material/plasma, /datum/material/uranium, /datum/material/bananium, /datum/material/titanium, /datum/material/bluespace, /datum/material/biomass) - - -/obj/item/integrated_circuit/input/matscan/do_work() - var/atom/movable/H = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) - var/turf/T = get_turf(src) - var/datum/component/material_container/mt = H.GetComponent(/datum/component/material_container) - if(!mt) //Invalid input - return - if(H in view(T)) // This is a camera. It can't examine thngs,that it can't see. - for(var/I in 1 to mtypes.len) - var/amount = mt.materials - if(amount) - set_pin_data(IC_OUTPUT, I, amount) - else - set_pin_data(IC_OUTPUT, I, null) - push_data() - activate_pin(2) - else - activate_pin(3) - -/obj/item/integrated_circuit/input/atmospheric_analyzer - name = "atmospheric analyzer" - desc = "A miniaturized analyzer which can scan anything that contains gases. Leave target as NULL to scan the air around the assembly." - extended_desc = "The nth element of gas amounts is the number of moles of the \ - nth gas in gas list. \ - Pressure is in kPa, temperature is in Kelvin. \ - Due to programming limitations, scanning an object that does \ - not contain a gas will return the air around it instead." - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - inputs = list( - "target" = IC_PINTYPE_REF - ) - outputs = list( - "gas list" = IC_PINTYPE_LIST, - "gas amounts" = IC_PINTYPE_LIST, - "total moles" = IC_PINTYPE_NUMBER, - "pressure" = IC_PINTYPE_NUMBER, - "temperature" = IC_PINTYPE_NUMBER, - "volume" = IC_PINTYPE_NUMBER - ) - activators = list( - "scan" = IC_PINTYPE_PULSE_IN, - "on success" = IC_PINTYPE_PULSE_OUT, - "on failure" = IC_PINTYPE_PULSE_OUT - ) - power_draw_per_use = 5 - -/obj/item/integrated_circuit/input/atmospheric_analyzer/do_work() - for(var/i=1 to 6) - set_pin_data(IC_OUTPUT, i, null) - var/atom/target = get_pin_data_as_type(IC_INPUT, 1, /atom) - if(!target) - target = get_turf(src) - if( get_dist(get_turf(target),get_turf(src)) > 1 ) - activate_pin(3) - return - - var/datum/gas_mixture/air_contents = target.return_air() - if(!air_contents) - activate_pin(3) - return - - var/list/gases = air_contents.gases - var/list/gas_names = list() - var/list/gas_amounts = list() - for(var/id in gases) - var/name = gases[id][GAS_META][META_GAS_NAME] - var/amt = round(gases[id], 0.001) - gas_names.Add(name) - gas_amounts.Add(amt) - - set_pin_data(IC_OUTPUT, 1, gas_names) - set_pin_data(IC_OUTPUT, 2, gas_amounts) - set_pin_data(IC_OUTPUT, 3, round(air_contents.total_moles(), 0.001)) - set_pin_data(IC_OUTPUT, 4, round(air_contents.return_pressure(), 0.001)) - set_pin_data(IC_OUTPUT, 5, round(air_contents.temperature, 0.001)) - set_pin_data(IC_OUTPUT, 6, round(air_contents.return_volume(), 0.001)) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/input/data_card_reader - name = "data card reader" - desc = "A circuit that can read from and write to data cards." - extended_desc = "Setting the \"write mode\" boolean to true will cause any data cards that are used on the assembly to replace\ - their existing function and data strings with the given strings, if it is set to false then using a data card on the assembly will cause\ - the function and data strings stored on the card to be written to the output pins." - icon_state = "card_reader" - complexity = 4 - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - inputs = list( - "function" = IC_PINTYPE_STRING, - "data to store" = IC_PINTYPE_STRING, - "write mode" = IC_PINTYPE_BOOLEAN - ) - outputs = list( - "function" = IC_PINTYPE_STRING, - "stored data" = IC_PINTYPE_STRING - ) - activators = list( - "on write" = IC_PINTYPE_PULSE_OUT, - "on read" = IC_PINTYPE_PULSE_OUT - ) - -/obj/item/integrated_circuit/input/data_card_reader/attackby_react(obj/item/I, mob/living/user) - if(!istype(I, /obj/item/card/data)) - return FALSE - var/obj/item/card/data/card = I - var/write_mode = get_pin_data(IC_INPUT, 3) - if(card) - if(write_mode == TRUE) - card.function = get_pin_data(IC_INPUT, 1) - card.data = get_pin_data(IC_INPUT, 2) - push_data() - activate_pin(1) - else - set_pin_data(IC_OUTPUT, 1, card.function) - set_pin_data(IC_OUTPUT, 2, card.data) - push_data() - activate_pin(2) - else - return FALSE - return TRUE - -//Adding some color to cards aswell, because why not -/obj/item/card/data/attackby(obj/item/I, mob/living/user) - if(istype(I, /obj/item/integrated_electronics/detailer)) - var/obj/item/integrated_electronics/detailer/D = I - detail_color = D.detail_color - update_icon() - return ..() - -/* SKYRAT PORT -- Commented out because we don't have the backend code for this (yet) -//Interceptor -//Intercepts a telecomms signal, aka a radio message (;halp getting griff) -//Inputs: -//On (Boolean): If on, the circuit intercepts radio signals. Otherwise it does not. This doesn't affect no pass! -//No pass (Boolean): Decides if the signal will be silently intercepted -// (false) or also blocked from being sent on the radio (true) -//Outputs: -//Source: name of the mob -//Job: job of the mob -//content: the actual message -//spans: a list of spans, there's not much info about this but stuff like robots will have "robot" span -/obj/item/integrated_circuit/input/tcomm_interceptor - name = "telecommunication interceptor" - desc = "This circuit allows for telecomms signals \ - to be fetched prior to being broadcasted." - extended_desc = "Similar \ - to the old NTSL system of realtime signal modification, \ - the circuit connects to telecomms and fetches data \ - for each signal, which can be sent normally or blocked, \ - for cases such as other circuits modifying certain data. \ - Beware, this cannot stop signals from unreachable areas, such \ - as space or zlevels other than station's one." - complexity = 30 - cooldown_per_use = 0.1 - w_class = WEIGHT_CLASS_SMALL - inputs = list( - "intercept" = IC_PINTYPE_BOOLEAN, - "no pass" = IC_PINTYPE_BOOLEAN - ) - outputs = list( - "source" = IC_PINTYPE_STRING, - "job" = IC_PINTYPE_STRING, - "content" = IC_PINTYPE_STRING, - "spans" = IC_PINTYPE_LIST, - "frequency" = IC_PINTYPE_NUMBER - ) - activators = list( - "on intercept" = IC_PINTYPE_PULSE_OUT - ) - power_draw_idle = 0 - spawn_flags = IC_SPAWN_RESEARCH - var/obj/machinery/telecomms/receiver/circuit/receiver - var/list/freq_blacklist = list(FREQ_CENTCOM,FREQ_SYNDICATE,FREQ_CTF_RED,FREQ_CTF_BLUE) - -/obj/item/integrated_circuit/input/tcomm_interceptor/Initialize() - . = ..() - receiver = new(src) - receiver.holder = src - -/obj/item/integrated_circuit/input/tcomm_interceptor/Destroy() - qdel(receiver) - GLOB.ic_jammers -= src - ..() - -/obj/item/integrated_circuit/input/tcomm_interceptor/receive_signal(datum/signal/signal) - if((signal.transmission_method == TRANSMISSION_SUBSPACE) && get_pin_data(IC_INPUT, 1)) - if(signal.frequency in freq_blacklist) - return - set_pin_data(IC_OUTPUT, 1, signal.data["name"]) - set_pin_data(IC_OUTPUT, 2, signal.data["job"]) - set_pin_data(IC_OUTPUT, 3, signal.data["message"]) - set_pin_data(IC_OUTPUT, 4, signal.data["spans"]) - set_pin_data(IC_OUTPUT, 5, signal.frequency) - push_data() - activate_pin(1) - -/obj/item/integrated_circuit/input/tcomm_interceptor/on_data_written() - if(get_pin_data(IC_INPUT, 2)) - GLOB.ic_jammers |= src - if(get_pin_data(IC_INPUT, 1)) - power_draw_idle = 200 - else - power_draw_idle = 100 - else - GLOB.ic_jammers -= src - if(get_pin_data(IC_INPUT, 1)) - power_draw_idle = 100 - else - power_draw_idle = 0 - -/obj/item/integrated_circuit/input/tcomm_interceptor/power_fail() - set_pin_data(IC_INPUT, 1, 0) - set_pin_data(IC_INPUT, 2, 0) - -/obj/item/integrated_circuit/input/tcomm_interceptor/disconnect_all() - set_pin_data(IC_INPUT, 1, 0) - set_pin_data(IC_INPUT, 2, 0) - ..() -*/ - -// -Inputlist- // -/obj/item/integrated_circuit/input/selection - name = "selection circuit" - desc = "This circuit lets you choose between different strings from a selection." - extended_desc = "This circuit lets you choose between up to 4 different values from selection of up to 8 strings that you can set. Null values are ignored and the chosen value is put out in selected." - icon_state = "addition" - can_be_asked_input = 1 - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - inputs = list( - "A" = IC_PINTYPE_STRING, - "B" = IC_PINTYPE_STRING, - "C" = IC_PINTYPE_STRING, - "D" = IC_PINTYPE_STRING, - "E" = IC_PINTYPE_STRING, - "F" = IC_PINTYPE_STRING, - "G" = IC_PINTYPE_STRING, - "H" = IC_PINTYPE_STRING - ) - activators = list( - "on selected" = IC_PINTYPE_PULSE_OUT - ) - outputs = list( - "selected" = IC_PINTYPE_STRING - ) - -/obj/item/integrated_circuit/input/selection/ask_for_input(mob/user) - var/list/selection = list() - for(var/k in 1 to inputs.len) - var/I = get_pin_data(IC_INPUT, k) - if(istext(I)) - selection.Add(I) - var/selected = input(user,"Choose input.","Selection") in selection - if(!selected) - return - set_pin_data(IC_OUTPUT, 1, selected) - push_data() - activate_pin(1) - - -// -storage examiner- // **works** -/obj/item/integrated_circuit/input/storage_examiner - name = "storage examiner circuit" - desc = "This circuit lets you scan a storage's content. (backpacks, toolboxes etc.)" - extended_desc = "The items are put out as reference, which makes it possible to interact with them. Additionally also gives the amount of items." - icon_state = "grabber" - can_be_asked_input = 1 - complexity = 6 - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - inputs = list( - "storage" = IC_PINTYPE_REF - ) - activators = list( - "examine" = IC_PINTYPE_PULSE_IN, - "on examined" = IC_PINTYPE_PULSE_OUT - ) - outputs = list( - "item amount" = IC_PINTYPE_NUMBER, - "item list" = IC_PINTYPE_LIST - ) - power_draw_per_use = 85 - -/obj/item/integrated_circuit/input/storage_examiner/do_work() - var/obj/item/storage = get_pin_data_as_type(IC_INPUT, 1, /obj/item) - if(!istype(storage,/obj/item/storage)) - return - - set_pin_data(IC_OUTPUT, 1, storage.contents.len) - - var/list/regurgitated_contents = list() - for(var/obj/o in storage.contents) - regurgitated_contents.Add(WEAKREF(o)) - - - set_pin_data(IC_OUTPUT, 2, regurgitated_contents) - push_data() - activate_pin(2) diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/lists.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/lists.dm deleted file mode 100644 index adc79e748b4..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/lists.dm +++ /dev/null @@ -1,462 +0,0 @@ -//These circuits do things with lists, and use special list pins for stability. -/obj/item/integrated_circuit/lists - complexity = 1 - inputs = list( - "input" = IC_PINTYPE_LIST - ) - outputs = list( - "result" = IC_PINTYPE_STRING - ) - activators = list( - "compute" = IC_PINTYPE_PULSE_IN, - "on computed" = IC_PINTYPE_PULSE_OUT - ) - category_text = "Lists" - power_draw_per_use = 20 - cooldown_per_use = 10 - -/obj/item/integrated_circuit/lists/pick - name = "pick circuit" - desc = "This circuit will pick a random element from the input list, and output that element." - extended_desc = "The input list is not modified." - icon_state = "addition" - outputs = list( - "result" = IC_PINTYPE_ANY - ) - activators = list( - "compute" = IC_PINTYPE_PULSE_IN, - "on success" = IC_PINTYPE_PULSE_OUT, - "on failure" = IC_PINTYPE_PULSE_OUT, - ) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - cooldown_per_use = 1 - -/obj/item/integrated_circuit/lists/pick/do_work() - var/list/input_list = get_pin_data(IC_INPUT, 1) // List pins guarantee that there is a list inside, even if just an empty one. - if(input_list.len) - set_pin_data(IC_OUTPUT, 1, pick(input_list)) - push_data() - activate_pin(2) - else - activate_pin(3) - - -/obj/item/integrated_circuit/lists/append - name = "append circuit" - desc = "This circuit will add an element to a list." - extended_desc = "The new element will always be at the bottom of the list." - inputs = list( - "list to append" = IC_PINTYPE_LIST, - "input" = IC_PINTYPE_ANY - ) - outputs = list( - "appended list" = IC_PINTYPE_LIST - ) - icon_state = "addition" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/lists/append/do_work() - var/list/input_list = get_pin_data(IC_INPUT, 1) - var/list/output_list = list() - var/new_entry = get_pin_data(IC_INPUT, 2) - output_list = input_list.Copy() - output_list.Add(new_entry) - - set_pin_data(IC_OUTPUT, 1, output_list) - push_data() - activate_pin(2) - - -/obj/item/integrated_circuit/lists/search - name = "search circuit" - desc = "This circuit will get the index location of the desired element in a list." - extended_desc = "Search will start at position 1 and will return the first matching position." - inputs = list( - "list" = IC_PINTYPE_LIST, - "item" = IC_PINTYPE_ANY - ) - outputs = list( - "index" = IC_PINTYPE_NUMBER - ) - activators = list( - "compute" = IC_PINTYPE_PULSE_IN, - "on success" = IC_PINTYPE_PULSE_OUT, - "on failure" = IC_PINTYPE_PULSE_OUT, - ) - icon_state = "addition" - complexity = 2 - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - cooldown_per_use = 1 - -/obj/item/integrated_circuit/lists/search/do_work() - var/list/input_list = get_pin_data(IC_INPUT, 1) - var/output = input_list.Find(get_pin_data(IC_INPUT, 2)) - - set_pin_data(IC_OUTPUT, 1, output) - push_data() - - if(output) - activate_pin(2) - else - activate_pin(3) - - -/obj/item/integrated_circuit/lists/filter - name = "filter circuit" - desc = "This circuit will search through a list for anything matching the desired element(s) and outputs two lists: \ - one containing only the matching elements, and one with the matching elements filtered out." - extended_desc = "Sample accepts lists. If no match is found, the original list is sent to output 1." - inputs = list( - "input list" = IC_PINTYPE_LIST, - "sample" = IC_PINTYPE_ANY - ) - outputs = list( - "list filtered" = IC_PINTYPE_LIST, - "list matched" = IC_PINTYPE_LIST - ) - activators = list( - "compute" = IC_PINTYPE_PULSE_IN, - "on match" = IC_PINTYPE_PULSE_OUT, - "on no match" = IC_PINTYPE_PULSE_OUT - ) - complexity = 6 - icon_state = "addition" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/lists/filter/do_work() - var/list/input_list = get_pin_data(IC_INPUT, 1) - var/sample = get_pin_data(IC_INPUT, 2) - var/list/sample_list = islist(sample) ? uniqueList(sample) : null - var/list/output_list1 = input_list.Copy() - var/list/output_list2 = list() - var/list/output = list() - - for(var/input_item in input_list) - if(sample_list) - for(var/sample_item in sample_list) - if(!isnull(sample_item)) - if(istext(input_item) && istext(sample_item) && findtext(input_item, sample_item)) - output += input_item - if(istype(input_item, /atom) && istext(sample_item)) - var/atom/input_item_atom = input_item - if(istext(sample_item) && findtext(input_item_atom.name, sample_item)) - output += input_item - if(!istext(input_item)) - if(input_item == sample_item) - output += input_item - else - if(!isnull(sample)) - if(istext(input_item) && istext(sample) && findtext(input_item, sample)) - output += input_item - continue - if(istype(input_item, /atom) && istext(sample)) - var/atom/input_itema = input_item - if(findtext(input_itema.name, sample)) - output += input_item - if(!istext(input_item)) - if(input_item == sample) - output += input_item - - output_list1.Remove(output) - output_list2.Add(output) - set_pin_data(IC_OUTPUT, 1, output_list1) - set_pin_data(IC_OUTPUT, 2, output_list2) - push_data() - - output_list1 ~! input_list ? activate_pin(2) : activate_pin(3) - -/obj/item/integrated_circuit/lists/listset - name = "list set circuit" - desc = "This circuit will remove any duplicate entries from a list." - extended_desc = "If there are no duplicate entries, the output list will be unchanged." - inputs = list( - "list" = IC_PINTYPE_LIST - ) - outputs = list( - "list filtered" = IC_PINTYPE_LIST - ) - icon_state = "addition" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/lists/listset/do_work() - var/list/input_list = get_pin_data(IC_INPUT, 1) - input_list = uniqueList(input_list) - - set_pin_data(IC_OUTPUT, 1, input_list) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/lists/at - name = "at circuit" - desc = "This circuit will pick an element from a list by the input index." - extended_desc = "If there is no element at the given index, the result will be null." - inputs = list( - "list" = IC_PINTYPE_LIST, - "index" = IC_PINTYPE_INDEX - ) - outputs = list( - "item" = IC_PINTYPE_ANY - ) - activators = list( - "compute" = IC_PINTYPE_PULSE_IN, - "on success" = IC_PINTYPE_PULSE_OUT, - "on failure" = IC_PINTYPE_PULSE_OUT - ) - icon_state = "addition" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - cooldown_per_use = 1 - -/obj/item/integrated_circuit/lists/at/do_work() - var/list/input_list = get_pin_data(IC_INPUT, 1) - var/index = get_pin_data(IC_INPUT, 2) - - // Check if index is valid - if(index > input_list.len) - set_pin_data(IC_OUTPUT, 1, null) - push_data() - activate_pin(3) - return - - set_pin_data(IC_OUTPUT, 1, input_list[index]) - push_data() - activate_pin(2) - - -/obj/item/integrated_circuit/lists/delete - name = "delete circuit" - desc = "This circuit will remove an element from a list by the index." - extended_desc = "If there is no element at the given index, the result list will be unchanged." - inputs = list( - "list" = IC_PINTYPE_LIST, - "index" = IC_PINTYPE_INDEX - ) - outputs = list( - "item" = IC_PINTYPE_LIST - ) - icon_state = "addition" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/lists/delete/do_work() - var/list/input_list = get_pin_data(IC_INPUT, 1) - var/list/red_list = list() - var/index = get_pin_data(IC_INPUT, 2) - - if(length(input_list)) - for(var/j in 1 to input_list.len) - var/I = input_list[j] - if(j != index) - red_list.Add(I) - set_pin_data(IC_OUTPUT, 1, red_list) - push_data() - activate_pin(2) - - -/obj/item/integrated_circuit/lists/write - name = "write circuit" - desc = "This circuit will write an element to a list at the given index location." - extended_desc = "If there is no element at the given index, it will output the same list as before." - inputs = list( - "list" = IC_PINTYPE_LIST, - "index" = IC_PINTYPE_INDEX, - "item" = IC_PINTYPE_ANY - ) - outputs = list( - "redacted list" = IC_PINTYPE_LIST - ) - activators = list( - "compute" = IC_PINTYPE_PULSE_IN, - "on success" = IC_PINTYPE_PULSE_OUT, - "on failure" = IC_PINTYPE_PULSE_OUT, - ) - icon_state = "addition" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/lists/write/do_work() - var/list/input_list = get_pin_data(IC_INPUT, 1) - var/index = get_pin_data(IC_INPUT, 2) - var/item = get_pin_data(IC_INPUT, 3) - - // Check if index is valid - if(index > input_list.len) - set_pin_data(IC_OUTPUT, 1, input_list) - push_data() - activate_pin(3) - return - - if(!islist(item)) - var/list/red_list = input_list.Copy() //crash proof - red_list[index] = item - set_pin_data(IC_OUTPUT, 1, red_list) - push_data() - activate_pin(2) - - -/obj/item/integrated_circuit/lists/len - name = "len circuit" - desc = "This circuit will return the length of the list." - inputs = list( - "list" = IC_PINTYPE_LIST, - ) - outputs = list( - "item" = IC_PINTYPE_NUMBER - ) - icon_state = "addition" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/lists/len/do_work() - var/list/input_list = get_pin_data(IC_INPUT, 1) - set_pin_data(IC_OUTPUT, 1, input_list.len) - push_data() - activate_pin(2) - cooldown_per_use = 1 - - -/obj/item/integrated_circuit/lists/jointext - name = "join text circuit" - desc = "This circuit will combine two lists into one, and output it as a string." - extended_desc = "Default settings will encode the entire list into a string." - icon_state = "join" - inputs = list( - "list to join" = IC_PINTYPE_LIST,// - "delimiter" = IC_PINTYPE_STRING, - "start" = IC_PINTYPE_INDEX, - "end" = IC_PINTYPE_NUMBER - ) - inputs_default = list( - "2" = ", ", - "4" = 0 - ) - outputs = list( - "joined text" = IC_PINTYPE_STRING - ) - icon_state = "addition" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - cooldown_per_use = 1 - -/obj/item/integrated_circuit/lists/jointext/do_work() - var/list/input_list = get_pin_data(IC_INPUT, 1) - var/delimiter = get_pin_data(IC_INPUT, 2) - var/start = get_pin_data(IC_INPUT, 3) - var/end = get_pin_data(IC_INPUT, 4) - - var/result = null - - if(input_list.len && delimiter && !isnull(start) && !isnull(end)) - result = jointext(input_list, delimiter, start, end) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - - -/obj/item/integrated_circuit/lists/constructor - name = "large list constructor" - desc = "This circuit will build a list out of up to sixteen input values." - icon_state = "constr8" - inputs = list() - outputs = list( - "result" = IC_PINTYPE_LIST - ) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - var/number_of_pins = 16 - -/obj/item/integrated_circuit/lists/constructor/Initialize() - for(var/i = 1 to number_of_pins) - inputs["input [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called. - complexity = number_of_pins / 2 - . = ..() - -/obj/item/integrated_circuit/lists/constructor/do_work() - var/list/output_list = list() - for(var/i = 1 to number_of_pins) - var/data = get_pin_data(IC_INPUT, i) - - // No nested lists - if(!islist(data)) - output_list += data - else - output_list += null - - set_pin_data(IC_OUTPUT, 1, output_list) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/lists/constructor/small - name = "list constructor" - desc = "This circuit will build a list out of up to four input values." - icon_state = "constr" - number_of_pins = 4 - -/obj/item/integrated_circuit/lists/constructor/medium - name = "medium list constructor" - desc = "This circuit will build a list out of up to eight input values." - icon_state = "constr8" - number_of_pins = 8 - - -/obj/item/integrated_circuit/lists/deconstructor - name = "large list deconstructor" - desc = "This circuit will write the first sixteen entries of its input list, starting with the index, into the output values." - icon_state = "deconstr8" - inputs = list( - "input" = IC_PINTYPE_LIST, - "index" = IC_PINTYPE_INDEX - ) - outputs = list() - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - var/number_of_pins = 16 - -/obj/item/integrated_circuit/lists/deconstructor/Initialize() - for(var/i = 1 to number_of_pins) - outputs["output [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called. - complexity = number_of_pins / 2 - . = ..() - -/obj/item/integrated_circuit/lists/deconstructor/do_work() - var/list/input_list = get_pin_data(IC_INPUT, 1) - var/start_index = get_pin_data(IC_INPUT, 2) - - for(var/i = 1 to number_of_pins) - var/list_index = i + start_index - 1 - if(list_index > input_list.len) - set_pin_data(IC_OUTPUT, i, null) - else - set_pin_data(IC_OUTPUT, i, input_list[list_index]) - - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/lists/deconstructor/small - name = "list deconstructor" - desc = "This circuit will write the first four entries of its input list, starting with the index, into the output values." - icon_state = "deconstr" - number_of_pins = 4 - -/obj/item/integrated_circuit/lists/deconstructor/medium - name = "medium list deconstructor" - desc = "This circuit will write the first eight entries of its input list, starting with the index, into the output values." - number_of_pins = 8 - - -// - Join circuit - // -/obj/item/integrated_circuit/lists/join - name = "join circuit" - desc = "This circuit is a huge fan of shipping. It joins 2 lists together." - extended_desc = "Elements found in both lists will not be removed and can be found twice in the list." - inputs = list( - "first list" = IC_PINTYPE_LIST, - "second list" = IC_PINTYPE_LIST - ) - outputs = list( - "joined list" = IC_PINTYPE_LIST - ) - icon_state = "addition" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/lists/join/do_work() - var/list/input_list = get_pin_data(IC_INPUT, 1) - var/list/input_list2 = get_pin_data(IC_INPUT, 2) - - set_pin_data(IC_OUTPUT, 1, input_list+input_list2) - push_data() - activate_pin(2) diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/logic.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/logic.dm deleted file mode 100644 index a6144eec406..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/logic.dm +++ /dev/null @@ -1,223 +0,0 @@ -/obj/item/integrated_circuit/logic - name = "logic gate" - desc = "This tiny chip will decide for you!" - extended_desc = "Logic circuits will treat a null, 0, and a \"\" string value as FALSE and anything else as TRUE." - complexity = 1 - outputs = list("result" = IC_PINTYPE_BOOLEAN) - activators = list("compare" = IC_PINTYPE_PULSE_IN) - category_text = "Logic" - power_draw_per_use = 1 - -/obj/item/integrated_circuit/logic/do_work() - push_data() - -/obj/item/integrated_circuit/logic/binary - inputs = list("A" = IC_PINTYPE_ANY,"B" = IC_PINTYPE_ANY) - activators = list("compare" = IC_PINTYPE_PULSE_IN, "on true result" = IC_PINTYPE_PULSE_OUT, "on false result" = IC_PINTYPE_PULSE_OUT) - -/obj/item/integrated_circuit/logic/binary/do_work() - var/datum/integrated_io/A = inputs[1] - var/datum/integrated_io/B = inputs[2] - var/datum/integrated_io/O = outputs[1] - O.data = do_compare(A, B) ? TRUE : FALSE - - if(get_pin_data(IC_OUTPUT, 1)) - activate_pin(2) - else - activate_pin(3) - ..() - -/obj/item/integrated_circuit/logic/binary/proc/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) - return FALSE - -/obj/item/integrated_circuit/logic/binary/proc/comparable(var/datum/integrated_io/A, var/datum/integrated_io/B) - return (isnum_safe(A.data) && isnum_safe(B.data)) || (istext(A.data) && istext(B.data)) - -/obj/item/integrated_circuit/logic/unary - inputs = list("A" = IC_PINTYPE_ANY) - activators = list("compare" = IC_PINTYPE_PULSE_IN, "on compare" = IC_PINTYPE_PULSE_OUT) - -/obj/item/integrated_circuit/logic/unary/do_work() - var/datum/integrated_io/A = inputs[1] - var/datum/integrated_io/O = outputs[1] - O.data = do_check(A) ? TRUE : FALSE - ..() - activate_pin(2) - -/obj/item/integrated_circuit/logic/unary/proc/do_check(var/datum/integrated_io/A) - return FALSE - -/obj/item/integrated_circuit/logic/binary/equals - name = "equal gate" - desc = "This gate compares two values, and outputs TRUE if both are the same." - icon_state = "equal" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/logic/binary/equals/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) - return A.data == B.data - -/obj/item/integrated_circuit/logic/binary/jklatch - name = "JK latch" - desc = "This gate is a synchronized JK latch." - icon_state = "jklatch" - inputs = list("J" = IC_PINTYPE_ANY,"K" = IC_PINTYPE_ANY) - outputs = list("Q" = IC_PINTYPE_BOOLEAN,"!Q" = IC_PINTYPE_BOOLEAN) - activators = list("pulse in C" = IC_PINTYPE_PULSE_IN, "pulse out Q" = IC_PINTYPE_PULSE_OUT, "pulse out !Q" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - var/lstate=FALSE - -/obj/item/integrated_circuit/logic/binary/jklatch/do_work() - var/datum/integrated_io/A = inputs[1] - var/datum/integrated_io/B = inputs[2] - var/datum/integrated_io/O = outputs[1] - var/datum/integrated_io/Q = outputs[2] - if(A.data) - if(B.data) - lstate=!lstate - else - lstate = TRUE - else - if(B.data) - lstate=FALSE - O.data = lstate ? TRUE : FALSE - Q.data = !lstate ? TRUE : FALSE - if(get_pin_data(IC_OUTPUT, 1)) - activate_pin(2) - else - activate_pin(3) - push_data() - -/obj/item/integrated_circuit/logic/binary/rslatch - name = "RS latch" - desc = "This gate is a synchronized RS latch. If both R and S are true, its state will not change." - icon_state = "sr_nor" - inputs = list("S" = IC_PINTYPE_ANY,"R" = IC_PINTYPE_ANY) - outputs = list("Q" = IC_PINTYPE_BOOLEAN,"!Q" = IC_PINTYPE_BOOLEAN) - activators = list("pulse in C" = IC_PINTYPE_PULSE_IN, "pulse out Q" = IC_PINTYPE_PULSE_OUT, "pulse out !Q" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - var/lstate=FALSE - -/obj/item/integrated_circuit/logic/binary/rslatch/do_work() - var/datum/integrated_io/A = inputs[1] - var/datum/integrated_io/B = inputs[2] - var/datum/integrated_io/O = outputs[1] - var/datum/integrated_io/Q = outputs[2] - if(A.data) - if(!B.data) - lstate=TRUE - else - if(B.data) - lstate=FALSE - O.data = lstate ? TRUE : FALSE - Q.data = !lstate ? TRUE : FALSE - if(get_pin_data(IC_OUTPUT, 1)) - activate_pin(2) - else - activate_pin(3) - push_data() - -/obj/item/integrated_circuit/logic/binary/gdlatch - name = "gated D latch" - desc = "This gate is a synchronized gated D latch." - icon_state = "gated_d" - inputs = list("D" = IC_PINTYPE_ANY,"E" = IC_PINTYPE_ANY) - outputs = list("Q" = IC_PINTYPE_BOOLEAN,"!Q" = IC_PINTYPE_BOOLEAN) - activators = list("pulse in C" = IC_PINTYPE_PULSE_IN, "pulse out Q" = IC_PINTYPE_PULSE_OUT, "pulse out !Q" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - var/lstate=FALSE - -/obj/item/integrated_circuit/logic/binary/gdlatch/do_work() - var/datum/integrated_io/A = inputs[1] - var/datum/integrated_io/B = inputs[2] - var/datum/integrated_io/O = outputs[1] - var/datum/integrated_io/Q = outputs[2] - if(B.data) - if(A.data) - lstate=TRUE - else - lstate=FALSE - - O.data = lstate ? TRUE : FALSE - Q.data = !lstate ? TRUE : FALSE - if(get_pin_data(IC_OUTPUT, 1)) - activate_pin(2) - else - activate_pin(3) - push_data() - -/obj/item/integrated_circuit/logic/binary/not_equals - name = "not equal gate" - desc = "This gate compares two values, and outputs TRUE if both are different." - icon_state = "not_equal" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/logic/binary/not_equals/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) - return A.data != B.data - -/obj/item/integrated_circuit/logic/binary/and - name = "and gate" - desc = "This gate will output TRUE if both inputs evaluate to true." - icon_state = "and" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/logic/binary/and/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) - return A.data && B.data - -/obj/item/integrated_circuit/logic/binary/or - name = "or gate" - desc = "This gate will output TRUE if one of the inputs evaluate to true." - icon_state = "or" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/logic/binary/or/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) - return A.data || B.data - -/obj/item/integrated_circuit/logic/binary/less_than - name = "less than gate" - desc = "This will output TRUE if the first input is less than the second input." - icon_state = "less_than" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/logic/binary/less_than/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) - if(comparable(A, B)) - return A.data < B.data - -/obj/item/integrated_circuit/logic/binary/less_than_or_equal - name = "less than or equal gate" - desc = "This will output TRUE if the first input is less than, or equal to the second input." - icon_state = "less_than_or_equal" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/logic/binary/less_than_or_equal/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) - if(comparable(A, B)) - return A.data <= B.data - -/obj/item/integrated_circuit/logic/binary/greater_than - name = "greater than gate" - desc = "This will output TRUE if the first input is greater than the second input." - icon_state = "greater_than" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/logic/binary/greater_than/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) - if(comparable(A, B)) - return A.data > B.data - -/obj/item/integrated_circuit/logic/binary/greater_than_or_equal - name = "greater than or equal gate" - desc = "This will output TRUE if the first input is greater than, or equal to the second input." - icon_state = "greater_than_or_equal" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/logic/binary/greater_than_or_equal/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) - if(comparable(A, B)) - return A.data >= B.data - -/obj/item/integrated_circuit/logic/unary/not - name = "not gate" - desc = "This gate inverts what's fed into it." - icon_state = "not" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - activators = list("invert" = IC_PINTYPE_PULSE_IN, "on inverted" = IC_PINTYPE_PULSE_OUT) - -/obj/item/integrated_circuit/logic/unary/not/do_check(var/datum/integrated_io/A) - return !A.data diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/manipulation.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/manipulation.dm deleted file mode 100644 index 39f0a385ece..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/manipulation.dm +++ /dev/null @@ -1,752 +0,0 @@ -/obj/item/integrated_circuit/manipulation - category_text = "Manipulation" - -/* SKYRAT PORT -- Comments out weapon firing mechanism -/obj/item/integrated_circuit/manipulation/weapon_firing - name = "weapon firing mechanism" - desc = "This somewhat complicated system allows one to slot in a gun, direct it towards a position, and remotely fire it." - extended_desc = "The firing mechanism can slot in any energy weapon. \ - The first and second inputs need to be numbers which correspond to coordinates for the gun to fire at relative to the machine itself. \ - The 'fire' activator will cause the mechanism to attempt to fire the weapon at the coordinates, if possible. Mode will switch between \ - lethal (TRUE) or stun (FALSE) modes. It uses the internal battery of the weapon itself, not the assembly. If you wish to fire the gun while the circuit is in \ - hand, you will need to use an assembly that is a gun." - complexity = 20 - max_allowed = 1 - w_class = WEIGHT_CLASS_SMALL - size = 3 - inputs = list( - "target X rel" = IC_PINTYPE_NUMBER, - "target Y rel" = IC_PINTYPE_NUMBER, - "mode" = IC_PINTYPE_BOOLEAN - ) - outputs = list("reference to gun" = IC_PINTYPE_REF) - activators = list( - "fire" = IC_PINTYPE_PULSE_IN - - ) - var/obj/item/gun/energy/installed_gun = null - spawn_flags = IC_SPAWN_RESEARCH - action_flags = IC_ACTION_COMBAT - power_draw_per_use = 0 - ext_cooldown = 1 - var/mode = FALSE - - var/stun_projectile = null //stun mode projectile type - var/stun_projectile_sound - var/lethal_projectile = null //lethal mode projectile type - var/lethal_projectile_sound - - demands_object_input = TRUE // You can put stuff in once the circuit is in assembly,passed down from additem and handled by attackby() - - - -/obj/item/integrated_circuit/manipulation/weapon_firing/Destroy() - qdel(installed_gun) - return ..() - -/obj/item/integrated_circuit/manipulation/weapon_firing/attackby(var/obj/O, var/mob/user) - if(istype(O, /obj/item/gun/energy)) - var/obj/item/gun/gun = O - if(installed_gun) - to_chat(user, "There's already a weapon installed.") - return - user.transferItemToLoc(gun,src) - installed_gun = gun - var/list/gun_properties = gun.get_turret_properties() - to_chat(user, "You slide \the [gun] into the firing mechanism.") - playsound(src, 'sound/items/Crowbar.ogg', 50, 1) - stun_projectile = gun_properties["stun_projectile"] - stun_projectile_sound = gun_properties["stun_projectile_sound"] - lethal_projectile = gun_properties["lethal_projectile"] - lethal_projectile_sound = gun_properties["lethal_projectile_sound"] - if(gun_properties["shot_delay"]) - cooldown_per_use = gun_properties["shot_delay"]*10 - if(cooldown_per_use<30) - cooldown_per_use = 30 - if(gun_properties["reqpower"]) - power_draw_per_use = gun_properties["reqpower"] - set_pin_data(IC_OUTPUT, 1, WEAKREF(installed_gun)) - push_data() - else - ..() - -/obj/item/integrated_circuit/manipulation/weapon_firing/attack_self(var/mob/user) - if(installed_gun) - installed_gun.forceMove(drop_location()) - to_chat(user, "You slide \the [installed_gun] out of the firing mechanism.") - size = initial(size) - playsound(src, 'sound/items/Crowbar.ogg', 50, 1) - installed_gun = null - set_pin_data(IC_OUTPUT, 1, WEAKREF(null)) - push_data() - else - to_chat(user, "There's no weapon to remove from the mechanism.") - -/obj/item/integrated_circuit/manipulation/weapon_firing/do_work() - if(!installed_gun || !installed_gun.handle_pins()) - return - if(!isturf(assembly.loc) && !(assembly.can_fire_equipped && ishuman(assembly.loc))) - return - set_pin_data(IC_OUTPUT, 1, WEAKREF(installed_gun)) - push_data() - var/datum/integrated_io/xo = inputs[1] - var/datum/integrated_io/yo = inputs[2] - var/datum/integrated_io/mode1 = inputs[3] - - mode = mode1.data - if(assembly) - if(isnum_safe(xo.data)) - xo.data = round(xo.data, 1) - if(isnum_safe(yo.data)) - yo.data = round(yo.data, 1) - - var/turf/T = get_turf(assembly) - var/target_x = clamp(T.x + xo.data, 0, world.maxx) - var/target_y = clamp(T.y + yo.data, 0, world.maxy) - - assembly.visible_message("[assembly] fires [installed_gun]!") - shootAt(locate(target_x, target_y, T.z)) - -/obj/item/integrated_circuit/manipulation/weapon_firing/proc/shootAt(turf/target) - var/turf/T = get_turf(src) - var/turf/U = target - if(!istype(T) || !istype(U)) - return - if(!installed_gun.cell) - return - if(!installed_gun.cell.charge) - return - var/obj/item/ammo_casing/energy/shot = installed_gun.ammo_type[mode?2:1] - if(installed_gun.cell.charge < shot.e_cost) - return - if(!shot) - return - update_icon() - var/obj/item/projectile/A - if(!mode) - A = new stun_projectile(T) - playsound(loc, stun_projectile_sound, 75, 1) - else - A = new lethal_projectile(T) - playsound(loc, lethal_projectile_sound, 75, 1) - installed_gun.cell.use(shot.e_cost) - //Shooting Code: - A.preparePixelProjectile(target, src) - A.ignore_source_check = TRUE //needed else writing into firer will mess with the projectile collision - A.firer = !usr ? "[assembly]/[REF(assembly)] circuit made by [assembly.creator]" : "[assembly]/[REF(assembly)] circuit activated by [usr.ckey]/[usr] and made by [assembly.creator]" - A.log_override = TRUE //Only resoves a runtime that would be caused on call. - A.fire() - log_attack("[assembly] [REF(assembly)] made by [assembly.creator] has fired [installed_gun].") - return A -*/ - -/obj/item/integrated_circuit/manipulation/locomotion - name = "locomotion circuit" - desc = "This allows a machine to move in a given direction." - icon_state = "locomotion" - extended_desc = "The circuit accepts a 'dir' number as a direction to move towards.
\ - Pulsing the 'step towards dir' activator pin will cause the machine to move one step in that direction, assuming it is not \ - being held, or anchored in some way. It should be noted that the ability to move is dependant on the type of assembly that this circuit inhabits; only drone assemblies can move." - w_class = WEIGHT_CLASS_SMALL - complexity = 10 - max_allowed = 4 - cooldown_per_use = 1 SECONDS - ext_cooldown = 1 SECONDS - inputs = list("direction" = IC_PINTYPE_DIR) - outputs = list("obstacle" = IC_PINTYPE_REF) - activators = list("step towards dir" = IC_PINTYPE_PULSE_IN,"on step"=IC_PINTYPE_PULSE_OUT,"blocked"=IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_RESEARCH - action_flags = IC_ACTION_MOVEMENT - power_draw_per_use = 100 - -/obj/item/integrated_circuit/manipulation/locomotion/do_work() - ..() - var/turf/T = get_turf(src) - if(T && assembly) - if(assembly.anchored || !assembly.can_move()) - return - if(assembly.loc == T) // Check if we're held by someone. If the loc is the floor, we're not held. - var/datum/integrated_io/wanted_dir = inputs[1] - if(isnum_safe(wanted_dir.data)) - if(step(assembly, wanted_dir.data)) - activate_pin(2) - return - else - set_pin_data(IC_OUTPUT, 1, WEAKREF(assembly.collw)) - push_data() - activate_pin(3) - return FALSE - return FALSE - -/obj/item/integrated_circuit/manipulation/grenade - name = "grenade primer" - desc = "This circuit comes with the ability to attach most types of grenades and prime them at will." - extended_desc = "The time between priming and detonation is limited to between 1 to 12 seconds, but is optional. \ - If the input is not set, not a number, or a number less than 1, the grenade's built-in timing will be used. \ - Beware: Once primed, there is no aborting the process!" - icon_state = "grenade" - complexity = 30 - max_allowed = 1 - cooldown_per_use = 10 - inputs = list("detonation time" = IC_PINTYPE_NUMBER) - outputs = list("reference to grenade" = IC_PINTYPE_REF) - activators = list("prime grenade" = IC_PINTYPE_PULSE_IN) - spawn_flags = IC_SPAWN_RESEARCH - action_flags = IC_ACTION_COMBAT - var/obj/item/grenade/attached_grenade - var/pre_attached_grenade_type - demands_object_input = TRUE // You can put stuff in once the circuit is in assembly,passed down from additem and handled by attackby() - -/obj/item/integrated_circuit/manipulation/grenade/Initialize() - . = ..() - if(pre_attached_grenade_type) - var/grenade = new pre_attached_grenade_type(src) - attach_grenade(grenade) - -/obj/item/integrated_circuit/manipulation/grenade/Destroy() - if(attached_grenade && !attached_grenade.active) - attached_grenade.forceMove(loc) - detach_grenade() - return ..() - -/obj/item/integrated_circuit/manipulation/grenade/attackby(var/obj/item/grenade/G, var/mob/user) - if(istype(G)) - if(attached_grenade) - to_chat(user, "There is already a grenade attached!") - else if(user.transferItemToLoc(G,src)) - user.visible_message("\The [user] attaches \a [G] to \the [src]!", "You attach \the [G] to \the [src].") - attach_grenade(G) - G.forceMove(src) - else - return ..() - -/obj/item/integrated_circuit/manipulation/grenade/attack_self(var/mob/user) - if(attached_grenade) - user.visible_message("\The [user] removes \an [attached_grenade] from \the [src]!", "You remove \the [attached_grenade] from \the [src].") - user.put_in_hands(attached_grenade) - detach_grenade() - else - return ..() - -/obj/item/integrated_circuit/manipulation/grenade/do_work() - if(attached_grenade && !attached_grenade.active) - var/datum/integrated_io/detonation_time = inputs[1] - var/dt - if(isnum_safe(detonation_time.data) && detonation_time.data > 0) - dt = clamp(detonation_time.data, 1, 12)*10 - else - dt = 15 - addtimer(CALLBACK(attached_grenade, /obj/item/grenade.proc/detonate), dt) - var/atom/holder = loc - message_admins("activated a grenade assembly. Last touches: Assembly: [holder.fingerprintslast] Circuit: [fingerprintslast] Grenade: [attached_grenade.fingerprintslast]") - -// These procs do not relocate the grenade, that's the callers responsibility -/obj/item/integrated_circuit/manipulation/grenade/proc/attach_grenade(var/obj/item/grenade/G) - attached_grenade = G - G.forceMove(src) - desc += " \An [attached_grenade] is attached to it!" - set_pin_data(IC_OUTPUT, 1, WEAKREF(G)) - -/obj/item/integrated_circuit/manipulation/grenade/proc/detach_grenade() - if(!attached_grenade) - return - attached_grenade.forceMove(drop_location()) - set_pin_data(IC_OUTPUT, 1, WEAKREF(null)) - attached_grenade = null - desc = initial(desc) - -/obj/item/integrated_circuit/manipulation/plant_module - name = "plant manipulation module" - desc = "Used to uproot weeds and harvest/plant trays." - icon_state = "plant_m" - extended_desc = "The circuit accepts a reference to a hydroponic tray or an item on an adjacent tile. \ - Mode input (0-harvest, 1-uproot weeds, 2-uproot plant, 3-plant seed) determines action. \ - Harvesting outputs a list of the harvested plants." - w_class = WEIGHT_CLASS_TINY - complexity = 10 - inputs = list("tray" = IC_PINTYPE_REF,"mode" = IC_PINTYPE_NUMBER,"item" = IC_PINTYPE_REF) - outputs = list("result" = IC_PINTYPE_LIST) - activators = list("pulse in" = IC_PINTYPE_PULSE_IN,"pulse out" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 50 - -/obj/item/integrated_circuit/manipulation/plant_module/do_work() - ..() - var/obj/acting_object = get_object() - var/obj/OM = get_pin_data_as_type(IC_INPUT, 1, /obj) - var/obj/O = get_pin_data_as_type(IC_INPUT, 3, /obj/item) - - if(!check_target(OM)) - push_data() - activate_pin(2) - return - - if(istype(OM,/obj/structure/spacevine) && check_target(OM) && get_pin_data(IC_INPUT, 2) == 2) - qdel(OM) - push_data() - activate_pin(2) - return - - var/obj/machinery/hydroponics/TR = OM - if(istype(TR)) - switch(get_pin_data(IC_INPUT, 2)) - if(0) - var/list/harvest_output = TR.attack_hand() - for(var/i in 1 to length(harvest_output)) - harvest_output[i] = WEAKREF(harvest_output[i]) - - if(length(harvest_output)) - set_pin_data(IC_OUTPUT, 1, harvest_output) - push_data() - if(1) - TR.weedlevel = 0 - TR.update_icon() - if(2) - if(TR.myseed) //Could be that they're just using it as a de-weeder - TR.age = 0 - TR.plant_health = 0 - if(TR.harvest) - TR.harvest = FALSE //To make sure they can't just put in another seed and insta-harvest it - qdel(TR.myseed) - TR.myseed = null - TR.weedlevel = 0 //Has a side effect of cleaning up those nasty weeds - TR.dead = 0 - TR.update_icon() - if(3) - if(!check_target(O)) - activate_pin(2) - return FALSE - - else if(istype(O, /obj/item/seeds) && !istype(O, /obj/item/seeds/sample)) - if(!TR.myseed) - if(istype(O, /obj/item/seeds/kudzu)) - investigate_log("had Kudzu planted in it by [acting_object] at [AREACOORD(src)]","kudzu") - acting_object.visible_message("[acting_object] plants [O].") - TR.dead = 0 - TR.myseed = O - TR.age = 1 - TR.plant_health = TR.myseed.endurance - TR.lastcycle = world.time - O.forceMove(TR) - TR.update_icon() - activate_pin(2) - -/obj/item/integrated_circuit/manipulation/seed_extractor - name = "seed extractor module" - desc = "Used to extract seeds from grown produce." - icon_state = "plant_m" - extended_desc = "The circuit accepts a reference to a plant item and extracts seeds from it, outputting the results to a list." - complexity = 8 - inputs = list("target" = IC_PINTYPE_REF) - outputs = list("result" = IC_PINTYPE_LIST) - activators = list("pulse in" = IC_PINTYPE_PULSE_IN,"pulse out" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 50 - -/obj/item/integrated_circuit/manipulation/seed_extractor/do_work() - ..() - var/obj/O = get_pin_data_as_type(IC_INPUT, 1, /obj/item) - if(!check_target(O)) - push_data() - activate_pin(2) - return - - var/list/seed_output = seedify(O, -1) - for(var/i in 1 to length(seed_output)) - seed_output[i] = WEAKREF(seed_output[i]) - - if(seed_output.len) - set_pin_data(IC_OUTPUT, 1, seed_output) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/manipulation/grabber - name = "grabber" - desc = "A circuit with its own inventory for items. Used to grab and store things." - icon_state = "grabber" - extended_desc = "This circuit accepts a reference to an object to be grabbed, and can store up to 10 objects. Modes: 1 to grab, 0 to eject the first object, -1 to eject all objects, and -2 to eject the target. If you throw something from a grabber's inventory with a thrower, the grabber will update its outputs accordingly." - w_class = WEIGHT_CLASS_SMALL - size = 3 - cooldown_per_use = 5 - complexity = 10 - max_allowed = 1 - inputs = list("target" = IC_PINTYPE_REF,"mode" = IC_PINTYPE_NUMBER) - outputs = list("first" = IC_PINTYPE_REF, "last" = IC_PINTYPE_REF, "amount" = IC_PINTYPE_NUMBER,"contents" = IC_PINTYPE_LIST) - activators = list("pulse in" = IC_PINTYPE_PULSE_IN,"pulse out" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_RESEARCH - action_flags = IC_ACTION_COMBAT - power_draw_per_use = 50 - var/max_items = 10 - -/obj/item/integrated_circuit/manipulation/grabber/do_work() - //There shouldn't be any target required to eject all contents - var/mode = get_pin_data(IC_INPUT, 2) - switch(mode) - if(-1) - drop_all() - if(0) - if(contents.len) - drop(contents[1]) - - var/obj/item/AM = get_pin_data_as_type(IC_INPUT, 1, /obj/item) - if(!QDELETED(AM) && !istype(AM, /obj/item/electronic_assembly) && !istype(AM, /obj/item/transfer_valve) && !istype(assembly.loc, /obj/item/implant/storage)) - switch(mode) - if(1) - grab(AM) - if(-2) - drop(AM) - update_outputs() - activate_pin(2) - -/obj/item/integrated_circuit/manipulation/grabber/proc/grab(obj/item/AM) - var/max_w_class = assembly.w_class - if(check_target(AM)) - if(contents.len < max_items && AM.w_class <= max_w_class) - var/atom/A = get_object() - A.investigate_log("picked up ([AM]) with [src].", INVESTIGATE_CIRCUIT) - AM.forceMove(src) - -/obj/item/integrated_circuit/manipulation/grabber/proc/drop(obj/item/AM, turf/T = drop_location()) - if(!(AM in contents)) - return - var/atom/A = get_object() - A.investigate_log("dropped ([AM]) from [src].", INVESTIGATE_CIRCUIT) - AM.forceMove(T) - -/obj/item/integrated_circuit/manipulation/grabber/proc/drop_all() - if(contents.len) - var/turf/T = drop_location() - var/obj/item/U - for(U in src) - drop(U, T) - -/obj/item/integrated_circuit/manipulation/grabber/proc/update_outputs() - if(contents.len) - set_pin_data(IC_OUTPUT, 1, WEAKREF(contents[1])) - set_pin_data(IC_OUTPUT, 2, WEAKREF(contents[contents.len])) - else - set_pin_data(IC_OUTPUT, 1, null) - set_pin_data(IC_OUTPUT, 2, null) - set_pin_data(IC_OUTPUT, 3, contents.len) - set_pin_data(IC_OUTPUT, 4, contents) - push_data() - -/obj/item/integrated_circuit/manipulation/grabber/attack_self(var/mob/user) - drop_all() - update_outputs() - push_data() - -/obj/item/integrated_circuit/manipulation/claw - name = "pulling claw" - desc = "Circuit which can pull things.." - icon_state = "pull_claw" - extended_desc = "This circuit accepts a reference to a thing to be pulled. Modes: 0 for release. 1 for pull." - w_class = WEIGHT_CLASS_SMALL - size = 3 - cooldown_per_use = 5 - max_allowed = 1 - complexity = 10 - inputs = list("target" = IC_PINTYPE_REF,"mode" = IC_PINTYPE_INDEX,"dir" = IC_PINTYPE_DIR) - outputs = list("is pulling" = IC_PINTYPE_BOOLEAN) - activators = list("pulse in" = IC_PINTYPE_PULSE_IN,"pulse out" = IC_PINTYPE_PULSE_OUT,"released" = IC_PINTYPE_PULSE_OUT,"pull to dir" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 50 - ext_cooldown = 1 - var/max_grab = GRAB_PASSIVE - -/obj/item/integrated_circuit/manipulation/claw/do_work(ord) - var/obj/acting_object = get_object() - var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) - var/mode = get_pin_data(IC_INPUT, 2) - switch(ord) - if(1) - mode = clamp(mode, GRAB_PASSIVE, max_grab) - if(AM) - if(check_target(AM, exclude_contents = TRUE)) - acting_object.investigate_log("grabbed ([AM]) using [src].", INVESTIGATE_CIRCUIT) - acting_object.start_pulling(AM,mode) - if(acting_object.pulling) - set_pin_data(IC_OUTPUT, 1, TRUE) - else - set_pin_data(IC_OUTPUT, 1, FALSE) - push_data() - - if(4) - if(acting_object.pulling) - var/dir = get_pin_data(IC_INPUT, 3) - var/turf/G =get_step(get_turf(acting_object),dir) - var/atom/movable/pullee = acting_object.pulling - var/turf/Pl = get_turf(pullee) - var/turf/F = get_step_towards(Pl,G) - if(acting_object.Adjacent(F)) - if(!step_towards(pullee, F)) - F = get_step_towards2(Pl,G) - if(acting_object.Adjacent(F)) - step_towards(pullee, F) - activate_pin(2) - -/obj/item/integrated_circuit/manipulation/claw/stop_pulling() - set_pin_data(IC_OUTPUT, 1, FALSE) - activate_pin(3) - push_data() - ..() - - - -/* -/obj/item/integrated_circuit/manipulation/matman - name = "material manager" - desc = "This circuit is designed for automatic storage and distribution of materials." - extended_desc = "The first input takes a ref of a machine with a material container. \ - Second input is used for inserting material stacks into the internal material storage. \ - Inputs 3-13 are used to transfer materials between target machine and circuit storage. \ - Positive values will take that number of materials from another machine. \ - Negative values will fill another machine from internal storage. Outputs show current stored amounts of mats." - icon_state = "grabber" - complexity = 16 - inputs = list( - "target" = IC_PINTYPE_REF, - "sheets to insert" = IC_PINTYPE_NUMBER, - "Iron" = IC_PINTYPE_NUMBER, - "Glass" = IC_PINTYPE_NUMBER, - "Silver" = IC_PINTYPE_NUMBER, - "Gold" = IC_PINTYPE_NUMBER, - "Diamond" = IC_PINTYPE_NUMBER, - "Uranium" = IC_PINTYPE_NUMBER, - "Solid Plasma" = IC_PINTYPE_NUMBER, - "Bluespace Mesh" = IC_PINTYPE_NUMBER, - "Bananium" = IC_PINTYPE_NUMBER, - "Titanium" = IC_PINTYPE_NUMBER, - ) - outputs = list( - "self ref" = IC_PINTYPE_REF, - "Total amount" = IC_PINTYPE_NUMBER, - "Iron" = IC_PINTYPE_NUMBER, - "Glass" = IC_PINTYPE_NUMBER, - "Silver" = IC_PINTYPE_NUMBER, - "Gold" = IC_PINTYPE_NUMBER, - "Diamond" = IC_PINTYPE_NUMBER, - "Uranium" = IC_PINTYPE_NUMBER, - "Solid Plasma" = IC_PINTYPE_NUMBER, - "Bluespace Mesh" = IC_PINTYPE_NUMBER, - "Bananium" = IC_PINTYPE_NUMBER, - "Titanium" = IC_PINTYPE_NUMBER - ) - activators = list( - "insert sheet" = IC_PINTYPE_PULSE_IN, - "transfer mats" = IC_PINTYPE_PULSE_IN, - "on success" = IC_PINTYPE_PULSE_OUT, - "on failure" = IC_PINTYPE_PULSE_OUT, - "push ref" = IC_PINTYPE_PULSE_IN, - "on push ref" = IC_PINTYPE_PULSE_IN - ) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 40 - ext_cooldown = 1 - cooldown_per_use = 10 - var/list/mtypes = list(/datum/material/iron, /datum/material/glass, /datum/material/silver, /datum/material/gold, /datum/material/diamond, /datum/material/plasma, /datum/material/uranium, /datum/material/bananium, /datum/material/titanium, /datum/material/bluespace) - -/obj/item/integrated_circuit/manipulation/matman/Initialize() - var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, - list(/datum/material/iron, /datum/material/glass, /datum/material/silver, /datum/material/gold, /datum/material/diamond, /datum/material/plasma, /datum/material/uranium, /datum/material/bananium, /datum/material/titanium, /datum/material/bluespace), 0, - FALSE, /obj/item/stack, CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert)) - materials.max_amount =100000 - materials.precise_insertion = TRUE - .=..() - -/obj/item/integrated_circuit/manipulation/matman/proc/AfterMaterialInsert(type_inserted, id_inserted, amount_inserted) - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - set_pin_data(IC_OUTPUT, 2, materials.total_amount) - for(var/I in 1 to mtypes.len) - var/amount = materials.materials[mtypes[I]] - if(amount) - set_pin_data(IC_OUTPUT, I+2, amount) - push_data() - -/obj/item/integrated_circuit/manipulation/matman/proc/is_insertion_ready(mob/user) - return TRUE - -/obj/item/integrated_circuit/manipulation/matman/do_work(ord) - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - var/atom/movable/H = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) - if(!check_target(H)) - activate_pin(4) - return - var/turf/T = get_turf(H) - switch(ord) - if(1) - var/obj/item/stack/sheet/S = H - if(!S) - activate_pin(4) - return - if(materials.insert_stack(S, clamp(get_pin_data(IC_INPUT, 2),0,100), multiplier = 1) ) - AfterMaterialInsert() - activate_pin(3) - else - activate_pin(4) - if(2) - var/datum/component/material_container/mt = H.GetComponent(/datum/component/material_container) - var/suc - for(var/I in 1 to mtypes.len) - var/datum/material/M = materials.materials[mtypes[I]] - if(M) - var/U = clamp(get_pin_data(IC_INPUT, I+2),-100000,100000) - if(!U) - continue - if(!mt) //Invalid input - if(U>0) - if(materials.retrieve_sheets(materials.amount2sheet(U), mtypes[I], T)) - suc = TRUE - else - if(mt.transer_amt_to(materials, U, mtypes[I])) - suc = TRUE - if(suc) - AfterMaterialInsert() - activate_pin(3) - else - activate_pin(4) - if(5) - set_pin_data(IC_OUTPUT, 1, WEAKREF(src)) - AfterMaterialInsert() - activate_pin(6) - -/obj/item/integrated_circuit/manipulation/matman/Destroy() - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - materials.retrieve_all() - .=..() -*/ - - - -// - inserter circuit - // -/obj/item/integrated_circuit/manipulation/inserter - name = "inserter" - desc = "A nimble circuit that puts stuff inside a storage like a backpack and can take it out aswell." - icon_state = "grabber" - extended_desc = "This circuit accepts a reference to an object to be inserted or extracted depending on mode. If a storage is given for extraction, the extracted item will be put in the new storage. Modes: 1 insert, 0 to extract." - w_class = WEIGHT_CLASS_SMALL - size = 3 - cooldown_per_use = 5 - complexity = 10 - inputs = list("target object" = IC_PINTYPE_REF, "target container" = IC_PINTYPE_REF,"mode" = IC_PINTYPE_NUMBER) - activators = list("pulse in" = IC_PINTYPE_PULSE_IN,"pulse out" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_RESEARCH - action_flags = IC_ACTION_COMBAT - power_draw_per_use = 20 - var/max_items = 10 - -/obj/item/integrated_circuit/manipulation/inserter/do_work() - //There shouldn't be any target required to eject all contents - var/obj/item/target_obj = get_pin_data_as_type(IC_INPUT, 1, /obj/item) - if(!target_obj) - return - - var/distance = get_dist(get_turf(src),get_turf(target_obj)) - if(distance > 1 || distance < 0) - return - - var/obj/item/storage/container = get_pin_data_as_type(IC_INPUT, 2, /obj/item) - var/mode = get_pin_data(IC_INPUT, 3) - switch(mode) - if(1) //Not working - if(!container || !istype(container,/obj/item/storage) || !Adjacent(container)) - return - - var/datum/component/storage/STR = container.GetComponent(/datum/component/storage) - if(!STR) - return - - STR.attackby(src, target_obj) - - else - var/datum/component/storage/STR = target_obj.loc.GetComponent(/datum/component/storage) - if(!STR) - return - - if(!container || !istype(container,/obj/item/storage) || !Adjacent(container)) - STR.remove_from_storage(target_obj,drop_location()) - else - STR.remove_from_storage(target_obj,container) - -// Renamer circuit. Renames the assembly it is in. Useful in cooperation with telecomms-based circuits. -/obj/item/integrated_circuit/manipulation/renamer - name = "renamer" - desc = "A small circuit that renames the assembly it is in. Useful paired with speech-based circuits." - icon_state = "internalbm" - extended_desc = "This circuit accepts a string as input, and can be pulsed to rewrite the current assembly's name with said string. On success, it pulses the default pulse-out wire." - inputs = list("name" = IC_PINTYPE_STRING) - outputs = list("current name" = IC_PINTYPE_STRING) - activators = list("rename" = IC_PINTYPE_PULSE_IN,"get name" = IC_PINTYPE_PULSE_IN,"pulse out" = IC_PINTYPE_PULSE_OUT) - power_draw_per_use = 1 - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/manipulation/renamer/do_work(var/n) - if(!assembly) - return - switch(n) - if(1) - var/new_name = get_pin_data(IC_INPUT, 1) - if(new_name) - assembly.name = new_name - - else - set_pin_data(IC_OUTPUT, 1, assembly.name) - push_data() - - activate_pin(3) - - - -// - redescribing circuit - // -/obj/item/integrated_circuit/manipulation/redescribe - name = "redescriber" - desc = "Takes any string as an input and will set it as the assembly's description." - extended_desc = "Strings should can be of any length." - icon_state = "speaker" - cooldown_per_use = 10 - complexity = 3 - inputs = list("text" = IC_PINTYPE_STRING) - outputs = list("description" = IC_PINTYPE_STRING) - activators = list("redescribe" = IC_PINTYPE_PULSE_IN,"get description" = IC_PINTYPE_PULSE_IN,"pulse out" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/manipulation/redescribe/do_work(var/n) - if(!assembly) - return - - switch(n) - if(1) - assembly.desc = get_pin_data(IC_INPUT, 1) - - else - set_pin_data(IC_OUTPUT, 1, assembly.desc) - push_data() - - activate_pin(3) - -// - repainting circuit - // -/obj/item/integrated_circuit/manipulation/repaint - name = "auto-repainter" - desc = "There's an oddly high amount of spraying cans fitted right inside this circuit." - extended_desc = "Takes a value in hexadecimal and uses it to repaint the assembly it is in." - cooldown_per_use = 10 - complexity = 3 - inputs = list("color" = IC_PINTYPE_COLOR) - outputs = list("current color" = IC_PINTYPE_COLOR) - activators = list("repaint" = IC_PINTYPE_PULSE_IN,"get color" = IC_PINTYPE_PULSE_IN,"pulse out" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/manipulation/repaint/do_work(var/n) - if(!assembly) - return - - switch(n) - if(1) - assembly.detail_color = get_pin_data(IC_INPUT, 1) - assembly.update_icon() - - else - set_pin_data(IC_OUTPUT, 1, assembly.detail_color) - push_data() - - activate_pin(3) diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/memory.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/memory.dm deleted file mode 100644 index 97b1944ae2e..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/memory.dm +++ /dev/null @@ -1,140 +0,0 @@ -/obj/item/integrated_circuit/memory - name = "memory chip" - desc = "This tiny chip can store one piece of data." - icon_state = "memory" - complexity = 1 - inputs = list() - outputs = list() - activators = list("set" = IC_PINTYPE_PULSE_IN, "on set" = IC_PINTYPE_PULSE_OUT) - category_text = "Memory" - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 1 - var/number_of_pins = 1 - -/obj/item/integrated_circuit/memory/Initialize() - for(var/i = 1 to number_of_pins) - inputs["input [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called. - outputs["output [i]"] = IC_PINTYPE_ANY - complexity = number_of_pins - . = ..() - -/obj/item/integrated_circuit/memory/examine(mob/user) - ..() - var/i - for(i = 1, i <= outputs.len, i++) - var/datum/integrated_io/O = outputs[i] - var/data = "nothing" - if(isweakref(O.data)) - var/datum/d = O.data_as_type(/datum) - if(d) - data = "[d]" - else if(!isnull(O.data)) - data = O.data - to_chat(user, "\The [src] has [data] saved to address [i].") - -/obj/item/integrated_circuit/memory/do_work() - for(var/i = 1 to inputs.len) - var/datum/integrated_io/I = inputs[i] - var/datum/integrated_io/O = outputs[i] - O.data = I.data - O.push_data() - activate_pin(2) - -/obj/item/integrated_circuit/memory/tiny - name = "small memory circuit" - desc = "This circuit can store two pieces of data." - icon_state = "memory4" - power_draw_per_use = 2 - number_of_pins = 2 - -/obj/item/integrated_circuit/memory/medium - name = "medium memory circuit" - desc = "This circuit can store four pieces of data." - icon_state = "memory4" - power_draw_per_use = 2 - number_of_pins = 4 - -/obj/item/integrated_circuit/memory/large - name = "large memory circuit" - desc = "This big circuit can store eight pieces of data." - icon_state = "memory8" - power_draw_per_use = 4 - number_of_pins = 8 - -/obj/item/integrated_circuit/memory/huge - name = "large memory stick" - desc = "This stick of memory can store up up to sixteen pieces of data." - icon_state = "memory16" - w_class = WEIGHT_CLASS_SMALL - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 8 - number_of_pins = 16 - -/obj/item/integrated_circuit/memory/constant - name = "constant chip" - desc = "This tiny chip can store one piece of data, which cannot be overwritten without disassembly." - icon_state = "memory" - inputs = list() - outputs = list("output pin" = IC_PINTYPE_ANY) - activators = list("push data" = IC_PINTYPE_PULSE_IN) - var/accepting_refs = FALSE - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - number_of_pins = 0 - -/obj/item/integrated_circuit/memory/constant/do_work() - var/datum/integrated_io/O = outputs[1] - O.push_data() - -/obj/item/integrated_circuit/memory/constant/emp_act() - for(var/i in 1 to activators.len) - var/datum/integrated_io/activate/A = activators[i] - A.scramble() - -/obj/item/integrated_circuit/memory/constant/save_special() - var/datum/integrated_io/O = outputs[1] - if(istext(O.data) || isnum_safe(O.data)) - return O.data - -/obj/item/integrated_circuit/memory/constant/load_special(special_data) - var/datum/integrated_io/O = outputs[1] - if(istext(special_data) || isnum_safe(special_data)) - O.data = special_data - -/obj/item/integrated_circuit/memory/constant/attack_self(mob/user) - var/datum/integrated_io/O = outputs[1] - if(!ISADVANCEDTOOLUSER(user)) - return - var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref", "null") - - var/new_data = null - switch(type_to_use) - if("string") - accepting_refs = FALSE - new_data = input("Now type in a string.","[src] string writing") as null|text - if(istext(new_data) && ISADVANCEDTOOLUSER(user)) - O.data = new_data - to_chat(user, "You set \the [src]'s memory to [O.display_data(O.data)].") - if("number") - accepting_refs = FALSE - new_data = input("Now type in a number.","[src] number writing") as null|num - if(isnum_safe(new_data) && ISADVANCEDTOOLUSER(user)) - O.data = new_data - to_chat(user, "You set \the [src]'s memory to [O.display_data(O.data)].") - if("ref") - accepting_refs = TRUE - to_chat(user, "You turn \the [src]'s ref scanner on. Slide it across \ - an object for a ref of that object to save it in memory.") - if("null") - O.data = null - to_chat(user, "You set \the [src]'s memory to absolutely nothing.") - -/obj/item/integrated_circuit/memory/constant/afterattack(atom/target, mob/living/user, proximity) - . = ..() - if(accepting_refs && proximity) - var/datum/integrated_io/O = outputs[1] - O.data = WEAKREF(target) - visible_message("[user] slides \a [src]'s over \the [target].") - to_chat(user, "You set \the [src]'s memory to a reference to [O.display_data(O.data)]. The ref scanner is \ - now off.") - accepting_refs = FALSE - diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/mining.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/mining.dm deleted file mode 100644 index 3dc9a45118c..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/mining.dm +++ /dev/null @@ -1,105 +0,0 @@ -/obj/item/integrated_circuit/mining/ore_analyzer - name = "ore analyzer" - desc = "Analyzes a rock for its ore type." - extended_desc = "Takes a reference for an object and checks if it is a rock first. If that is the case, it outputs the mineral \ - inside the rock." - category_text = "Mining" - ext_cooldown = 1 - complexity = 20 - cooldown_per_use = 1 SECONDS - inputs = list( - "rock" = IC_PINTYPE_REF - ) - outputs = list( - "ore type" = IC_PINTYPE_STRING, - "amount" = IC_PINTYPE_NUMBER - ) - activators = list( - "analyze" = IC_PINTYPE_PULSE_IN, - "on analyzed" = IC_PINTYPE_PULSE_OUT, - "on found" = IC_PINTYPE_PULSE_OUT - ) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 20 - var/turf/closed/mineral/rock - var/mineral - - -/obj/item/integrated_circuit/mining/ore_analyzer/do_work() - rock = get_pin_data(IC_INPUT, 1) - if(!istype(rock,/turf/closed/mineral)) - mineral = null - set_pin_data(IC_OUTPUT, 1, null) - set_pin_data(IC_OUTPUT, 2, null) - - push_data() - activate_pin(2) - return - - if(rock.mineralType) - mineral = "[rock.mineralType]" - mineral = copytext(mineral, findlasttextEx(mineral, "/")+1) - else - mineral = "rock" - - set_pin_data(IC_OUTPUT, 1, mineral) - set_pin_data(IC_OUTPUT, 2, rock.mineralAmt) - push_data() - - activate_pin(2) - activate_pin(3) - - -/obj/item/integrated_circuit/mining/mining_drill - name = "mining drill" - desc = "A mining drill that can drill through rocks." - extended_desc = "A mining drill that activates on sensing a mineable rock. It takes some time to get the job done and \ - has to not be moved during that time." - category_text = "Mining" - ext_cooldown = 1 - complexity = 20 - cooldown_per_use = 3 SECONDS - inputs = list( - "rock" = IC_PINTYPE_REF - ) - outputs = list() - activators = list( - "mine" = IC_PINTYPE_PULSE_IN, - "on success" = IC_PINTYPE_PULSE_OUT, - "on failure" = IC_PINTYPE_PULSE_OUT - ) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 100 - - var/busy = FALSE - var/usedx - var/usedy - var/turf/closed/mineral/rock - -/obj/item/integrated_circuit/mining/mining_drill/do_work() - rock = get_pin_data(IC_INPUT, 1) - - if(!rock) - activate_pin(3) - return - if(!(ismineralturf(rock) && rock.Adjacent(assembly)) || busy) - activate_pin(3) - return - - busy = TRUE - usedx = assembly.loc.x - usedy = assembly.loc.y - playsound(src, 'sound/items/drill_use.ogg',50,1) - addtimer(CALLBACK(src, .proc/drill), 50) - - -/obj/item/integrated_circuit/mining/mining_drill/proc/drill() - busy = FALSE - // The assembly was moved, hence stopping the mining OR the rock was mined before - if(usedx != assembly.loc.x || usedy != assembly.loc.y || !rock) - activate_pin(3) - return FALSE - - activate_pin(2) - rock.gets_drilled() - return(TRUE) diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/output.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/output.dm deleted file mode 100644 index f07dbd5af28..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/output.dm +++ /dev/null @@ -1,496 +0,0 @@ -/obj/item/integrated_circuit/output - category_text = "Output" - speech_span = SPAN_ROBOT - -/obj/item/integrated_circuit/output/screen - name = "small screen" - extended_desc = " use <br> to start a new line" - desc = "Takes any data type as an input, and displays it to the user upon examining." - icon_state = "screen" - inputs = list("displayed data" = IC_PINTYPE_ANY) - outputs = list() - activators = list("load data" = IC_PINTYPE_PULSE_IN) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 10 - var/eol = "<br>" - var/stuff_to_display = null - -/obj/item/integrated_circuit/output/screen/disconnect_all() - ..() - stuff_to_display = null - -/obj/item/integrated_circuit/output/screen/any_examine(mob/user) - var/shown_label = "" - if(displayed_name && displayed_name != name) - shown_label = " labeled '[displayed_name]'" - - to_chat(user, "There is \a [src][shown_label], which displays [!isnull(stuff_to_display) ? "'[stuff_to_display]'" : "nothing"].") - -/obj/item/integrated_circuit/output/screen/do_work() - var/datum/integrated_io/I = inputs[1] - if(isweakref(I.data)) - var/datum/d = I.data_as_type(/datum) - if(d) - stuff_to_display = "[d]" - else - stuff_to_display = replacetext("[I.data]", eol , "
") - -/obj/item/integrated_circuit/output/screen/large - name = "large screen" - desc = "Takes any data type as an input and displays it to anybody near the device when pulsed. \ - It can also be examined to see the last thing it displayed." - icon_state = "screen_medium" - power_draw_per_use = 20 - -/obj/item/integrated_circuit/output/screen/large/do_work() - ..() - - if(isliving(assembly.loc))//this whole block just returns if the assembly is neither in a mobs hands or on the ground - var/mob/living/H = assembly.loc - if(H.get_active_held_item() != assembly && H.get_inactive_held_item() != assembly) - return - else - if(!isturf(assembly.loc)) - return - - var/list/nearby_things = range(0, get_turf(src)) - for(var/mob/M in nearby_things) - var/obj/O = assembly ? assembly : src - to_chat(M, "[icon2html(O.icon, world, O.icon_state)] [stuff_to_display]") - if(assembly) - assembly.investigate_log("displayed \"[html_encode(stuff_to_display)]\" with [type].", INVESTIGATE_CIRCUIT) - else - investigate_log("displayed \"[html_encode(stuff_to_display)]\" as [type].", INVESTIGATE_CIRCUIT) - -/obj/item/integrated_circuit/output/light - name = "light" - desc = "A basic light which can be toggled on/off when pulsed." - icon_state = "light" - complexity = 4 - max_allowed = 4 - inputs = list() - outputs = list() - activators = list("toggle light" = IC_PINTYPE_PULSE_IN) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - var/light_toggled = 0 - var/light_brightness = 3 - var/light_rgb = "#FFFFFF" - power_draw_idle = 0 // Adjusted based on brightness. - -/obj/item/integrated_circuit/output/light/do_work() - light_toggled = !light_toggled - update_lighting() - -/obj/item/integrated_circuit/output/light/proc/update_lighting() - if(light_toggled) - if(assembly) - assembly.set_light(l_range = light_brightness, l_power = 1, l_color = light_rgb) - else - if(assembly) - assembly.set_light(0) - power_draw_idle = light_toggled ? light_brightness * 2 : 0 - -/obj/item/integrated_circuit/output/light/power_fail() // Turns off the flashlight if there's no power left. - light_toggled = FALSE - update_lighting() - -/obj/item/integrated_circuit/output/light/advanced - name = "advanced light" - desc = "A light that takes a hexadecimal color value and a brightness value, and can be toggled on/off by pulsing it." - icon_state = "light_adv" - complexity = 8 - inputs = list( - "color" = IC_PINTYPE_COLOR, - "brightness" = IC_PINTYPE_NUMBER - ) - outputs = list() - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/output/light/advanced/on_data_written() - update_lighting() - -/obj/item/integrated_circuit/output/light/advanced/update_lighting() - var/new_color = get_pin_data(IC_INPUT, 1) - var/brightness = get_pin_data(IC_INPUT, 2) - - if(new_color && isnum_safe(brightness)) - brightness = clamp(brightness, 0, 4) - light_rgb = new_color - light_brightness = brightness - - ..() - -/obj/item/integrated_circuit/output/sound - name = "speaker circuit" - desc = "A miniature speaker is attached to this component." - icon_state = "speaker" - complexity = 8 - cooldown_per_use = 4 SECONDS - inputs = list( - "sound ID" = IC_PINTYPE_STRING, - "volume" = IC_PINTYPE_NUMBER, - "frequency" = IC_PINTYPE_BOOLEAN - ) - max_allowed = 5 - outputs = list() - activators = list("play sound" = IC_PINTYPE_PULSE_IN) - power_draw_per_use = 10 - var/list/sounds = list() - -/obj/item/integrated_circuit/output/sound/Initialize() - .= ..() - extended_desc = list() - extended_desc += "The first input pin determines which sound is used. The choices are; " - extended_desc += jointext(sounds, ", ") - extended_desc += ". The second pin determines the volume of sound that is played" - extended_desc += ", and the third determines if the frequency of the sound will vary with each activation." - extended_desc = jointext(extended_desc, null) - -/obj/item/integrated_circuit/output/sound/do_work() - var/ID = get_pin_data(IC_INPUT, 1) - var/vol = get_pin_data(IC_INPUT, 2) - var/freq = get_pin_data(IC_INPUT, 3) - if(!isnull(ID) && !isnull(vol)) - var/selected_sound = sounds[ID] - if(!selected_sound) - return - vol = clamp(vol ,0 , 100) - playsound(get_turf(src), selected_sound, vol, freq, -1) - var/atom/A = get_object() - A.investigate_log("played a sound ([selected_sound]) as [type].", INVESTIGATE_CIRCUIT) - -/obj/item/integrated_circuit/output/sound/on_data_written() - power_draw_per_use = get_pin_data(IC_INPUT, 2) * 15 - -/obj/item/integrated_circuit/output/sound/beeper - name = "beeper circuit" - desc = "Takes a sound name as an input, and will play said sound when pulsed. This circuit has a variety of beeps, boops, and buzzes to choose from." - sounds = list( - "beep" = 'sound/machines/twobeep.ogg', - "chime" = 'sound/machines/chime.ogg', - "buzz sigh" = 'sound/machines/buzz-sigh.ogg', - "buzz twice" = 'sound/machines/buzz-two.ogg', - "ping" = 'sound/machines/ping.ogg', - "synth yes" = 'sound/machines/synth_yes.ogg', - "synth no" = 'sound/machines/synth_no.ogg', - "warning buzz" = 'sound/machines/warning-buzzer.ogg' - ) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/output/sound/beepsky - name = "securitron sound circuit" - desc = "Takes a sound name as an input, and will play said sound when pulsed. This circuit is similar to those used in Securitrons." - sounds = list( - "creep" = 'sound/voice/beepsky/creep.ogg', - "criminal" = 'sound/voice/beepsky/criminal.ogg', - "freeze" = 'sound/voice/beepsky/freeze.ogg', - "god" = 'sound/voice/beepsky/god.ogg', - "i am the law" = 'sound/voice/beepsky/iamthelaw.ogg', - "insult" = 'sound/voice/beepsky/insult.ogg', - "radio" = 'sound/voice/beepsky/radio.ogg', - "secure day" = 'sound/voice/beepsky/secureday.ogg', - ) - spawn_flags = IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/output/sound/medbot - name = "medbot sound circuit" - desc = "Takes a sound name as an input, and will play said sound when pulsed. This circuit is often found in medical robots." - sounds = list( - "surgeon" = 'sound/voice/medbot/surgeon.ogg', - "radar" = 'sound/voice/medbot/radar.ogg', - "feel better" = 'sound/voice/medbot/feelbetter.ogg', - "patched up" = 'sound/voice/medbot/patchedup.ogg', - "injured" = 'sound/voice/medbot/injured.ogg', - "insult" = 'sound/voice/medbot/insult.ogg', - "coming" = 'sound/voice/medbot/coming.ogg', - "help" = 'sound/voice/medbot/help.ogg', - "live" = 'sound/voice/medbot/live.ogg', - "lost" = 'sound/voice/medbot/lost.ogg', - "flies" = 'sound/voice/medbot/flies.ogg', - "catch" = 'sound/voice/medbot/catch.ogg', - "delicious" = 'sound/voice/medbot/delicious.ogg', - "apple" = 'sound/voice/medbot/apple.ogg', - "no" = 'sound/voice/medbot/no.ogg', - ) - spawn_flags = IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/output/sound/vox - name = "ai vox sound circuit" - desc = "Takes a sound name as an input, and will play said sound when pulsed. This circuit is often found in AI announcement systems." - spawn_flags = IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/output/sound/vox/Initialize() - .= ..() - sounds = GLOB.vox_sounds - extended_desc = "The first input pin determines which sound is used. It uses the AI Vox Broadcast word list. So either experiment to find words that work, or ask the AI to help in figuring them out. The second pin determines the volume of sound that is played, and the third determines if the frequency of the sound will vary with each activation." - -/obj/item/integrated_circuit/output/text_to_speech - name = "text-to-speech circuit" - desc = "Takes any string as an input and will make the device say the string when pulsed." - extended_desc = "This unit is more advanced than the plain speaker circuit, able to transpose any valid text to speech." - icon_state = "speaker" - cooldown_per_use = 10 - complexity = 12 - inputs = list("text" = IC_PINTYPE_STRING) - outputs = list() - activators = list("to speech" = IC_PINTYPE_PULSE_IN) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 60 - -/obj/item/integrated_circuit/output/text_to_speech/do_work() - text = get_pin_data(IC_INPUT, 1) - if(!isnull(text)) - var/atom/movable/A = get_object() - var/sanitized_text = sanitize(text) - A.say(sanitized_text) - if (assembly) - log_say("[assembly] [REF(assembly)] : [sanitized_text]") - else - log_say("[name] ([type]) : [sanitized_text]") - -/obj/item/integrated_circuit/output/video_camera - name = "video camera circuit" - desc = "Takes a string as a name and a boolean to determine whether it is on, and uses this to be a camera linked to a list of networks you choose." - extended_desc = "The camera is linked to a list of camera networks of your choosing. Common choices are 'rd' for the research network, 'ss13' for the main station network (visible to AI), 'mine' for the mining network, and 'thunder' for the thunderdome network (viewable from bar)." - icon_state = "video_camera" - w_class = WEIGHT_CLASS_TINY - complexity = 10 - inputs = list( - "camera name" = IC_PINTYPE_STRING, - "camera active" = IC_PINTYPE_BOOLEAN, - "camera network" = IC_PINTYPE_LIST - ) - inputs_default = list("1" = "video camera circuit", "3" = list("rd")) - outputs = list() - activators = list() - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - action_flags = IC_ACTION_LONG_RANGE - power_draw_idle = 0 // Raises to 20 when on. - var/obj/machinery/camera/camera - var/updating = FALSE - -/obj/item/integrated_circuit/output/video_camera/New() - ..() - camera = new(src) - camera.network = list("rd") - on_data_written() - -/obj/item/integrated_circuit/output/video_camera/Destroy() - QDEL_NULL(camera) - return ..() - -/obj/item/integrated_circuit/output/video_camera/proc/set_camera_status(var/status) - if(camera) - camera.status = status - GLOB.cameranet.updatePortableCamera(camera) - power_draw_idle = camera.status ? 20 : 0 - if(camera.status) // Ensure that there's actually power. - if(!draw_idle_power()) - power_fail() - -/obj/item/integrated_circuit/output/video_camera/on_data_written() - if(camera) - var/cam_name = get_pin_data(IC_INPUT, 1) - var/cam_active = get_pin_data(IC_INPUT, 2) - var/list/new_network = get_pin_data(IC_INPUT, 3) - if(!isnull(cam_name)) - camera.c_tag = cam_name - if(!isnull(new_network)) - camera.network = new_network - set_camera_status(cam_active) - -/obj/item/integrated_circuit/output/video_camera/power_fail() - if(camera) - set_camera_status(0) - set_pin_data(IC_INPUT, 2, FALSE) - -/obj/item/integrated_circuit/output/video_camera/ext_moved(oldLoc, dir) - . = ..() - update_camera_location(oldLoc) - -#define VIDEO_CAMERA_BUFFER 10 -/obj/item/integrated_circuit/output/video_camera/proc/update_camera_location(oldLoc) - oldLoc = get_turf(oldLoc) - if(!QDELETED(camera) && !updating && oldLoc != get_turf(src)) - updating = TRUE - addtimer(CALLBACK(src, .proc/do_camera_update, oldLoc), VIDEO_CAMERA_BUFFER) -#undef VIDEO_CAMERA_BUFFER - -/obj/item/integrated_circuit/output/video_camera/proc/do_camera_update(oldLoc) - if(!QDELETED(camera) && oldLoc != get_turf(src)) - GLOB.cameranet.updatePortableCamera(camera) - updating = FALSE - -/obj/item/integrated_circuit/output/led - name = "light-emitting diode" - desc = "RGB LED. Takes a boolean value in, and if the boolean value is 'true-equivalent', the LED will be marked as lit on examine." - extended_desc = "TRUE-equivalent values are: Non-empty strings, non-zero numbers, and valid refs." - complexity = 0.1 - max_allowed = 4 - icon_state = "led" - inputs = list( - "lit" = IC_PINTYPE_BOOLEAN, - "color" = IC_PINTYPE_COLOR - ) - outputs = list() - activators = list() - inputs_default = list( - "2" = "#FF0000" - ) - power_draw_idle = 0 // Raises to 1 when lit. - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - var/led_color = "#FF0000" - -/obj/item/integrated_circuit/output/led/on_data_written() - power_draw_idle = get_pin_data(IC_INPUT, 1) ? 1 : 0 - led_color = get_pin_data(IC_INPUT, 2) - -/obj/item/integrated_circuit/output/led/power_fail() - set_pin_data(IC_INPUT, 1, FALSE) - -/obj/item/integrated_circuit/output/led/external_examine(mob/user) - var/text_output = "There is " - - if(name == displayed_name) - text_output += "\an [name]" - else - text_output += "\an ["\improper[name]"] labeled '[displayed_name]'" - text_output += " which is currently [get_pin_data(IC_INPUT, 1) ? "lit *" : "unlit"]." - to_chat(user, text_output) - -/obj/item/integrated_circuit/output/diagnostic_hud - name = "AR interface" - desc = "Takes an icon name as an input, and will update the status hud when data is written to it." - extended_desc = "Takes an icon name as an input, and will update the status hud when data is written to it, this means it can change the icon and have the icon stay that way even if the circuit is removed. The acceptable inputs are 'alert', 'move', 'working', 'patrol', 'called', and 'heart'. Any input other than that will return the icon to its default state." - var/list/icons = list( - "alert" = "hudalert", - "move" = "hudmove", - "working" = "hudworkingleft", - "patrol" = "hudpatrolleft", - "called" = "hudcalledleft", - "heart" = "hudsentientleft" - ) - complexity = 1 - icon_state = "led" - inputs = list( - "icon" = IC_PINTYPE_STRING - ) - outputs = list() - activators = list() - power_draw_idle = 0 - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/output/diagnostic_hud/on_data_written() - var/ID = get_pin_data(IC_INPUT, 1) - var/selected_icon = icons[ID] - if(assembly) - if(selected_icon) - assembly.prefered_hud_icon = selected_icon - else - assembly.prefered_hud_icon = "hudstat" - //update the diagnostic hud - assembly.diag_hud_set_circuitstat() - - -//Text to radio -//Outputs a simple string into radio (good to couple with the interceptor) -//Input: -//Text: the actual string to output -//Frequency: what channel to output in. This is a STRING, not a number, due to how comms work. It has to be the frequency without the dot, aka for common you need to put "1459" -/obj/item/integrated_circuit/output/text_to_radio - name = "text-to-radio circuit" - desc = "Takes any string as an input and will make the device output it in the radio with the frequency chosen as input." - extended_desc = "Similar to the text-to-speech circuit, except the fact that the text is converted into a subspace signal and broadcasted to the desired frequency, or 1459 as default.\ - The frequency is a number, and doesn't need the dot. Example: Common frequency is 145.9, so the result is 1459 as a number." - icon_state = "speaker" - complexity = 15 - inputs = list("text" = IC_PINTYPE_STRING, "frequency" = IC_PINTYPE_NUMBER) - outputs = list("encryption keys" = IC_PINTYPE_LIST) - activators = list("broadcast" = IC_PINTYPE_PULSE_IN) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 100 - cooldown_per_use = 0.1 - var/list/whitelisted_freqs = list() // special freqs can be used by inserting encryption keys - var/list/encryption_keys = list() - var/obj/item/radio/headset/integrated/radio - -/obj/item/integrated_circuit/output/text_to_radio/Initialize() - . = ..() - radio = new(src) - radio.frequency = FREQ_COMMON - //GLOB.ic_speakers += src - -/obj/item/integrated_circuit/output/text_to_radio/Destroy() - qdel(radio) - //GLOB.ic_speakers -= src - ..() - -/obj/item/integrated_circuit/output/text_to_radio/on_data_written() - var/freq = get_pin_data(IC_INPUT, 2) - if(!(freq in whitelisted_freqs)) - freq = sanitize_frequency(get_pin_data(IC_INPUT, 2), radio.freerange) - radio.set_frequency(freq) - -/obj/item/integrated_circuit/output/text_to_radio/do_work() - text = get_pin_data(IC_INPUT, 1) - if(!isnull(text)) - var/atom/movable/A = get_object() - var/sanitized_text = sanitize(text) - radio.talk_into(A, sanitized_text, ) - if (assembly) - log_say("[assembly] [REF(assembly)] : [sanitized_text]") - -/obj/item/integrated_circuit/output/text_to_radio/attackby(obj/O, mob/user) - if(istype(O, /obj/item/encryptionkey)) - user.transferItemToLoc(O,src) - encryption_keys += O - recalculate_channels() - to_chat(user, "You slide \the [O] inside the circuit.") - else - ..() - -/obj/item/integrated_circuit/output/text_to_radio/proc/recalculate_channels() - whitelisted_freqs.Cut() - set_pin_data(IC_INPUT, 2, 1459) - radio.set_frequency(FREQ_COMMON) //reset it - var/list/weakreffd_ekeys = list() - for(var/o in encryption_keys) - var/obj/item/encryptionkey/K = o - weakreffd_ekeys += WEAKREF(K) - for(var/i in K.channels) - whitelisted_freqs |= GLOB.radiochannels[i] - set_pin_data(IC_OUTPUT, 1, weakreffd_ekeys) - - -/obj/item/integrated_circuit/output/text_to_radio/attack_self(mob/user) - if(encryption_keys.len) - for(var/i in encryption_keys) - var/obj/O = i - O.forceMove(drop_location()) - encryption_keys.Cut() - set_pin_data(IC_OUTPUT, 1, WEAKREF(null)) - to_chat(user, "You slide the encryption keys out of the circuit.") - recalculate_channels() - else - to_chat(user, "There are no encryption keys to remove from the mechanism.") - -/obj/item/radio/headset/integrated - -/obj/item/integrated_circuit/output/screen/large - name = "medium screen" - -/obj/item/integrated_circuit/output/screen/extralarge // the subtype is called "extralarge" because tg brought back medium screens and they named the subtype /screen/large - name = "large screen" - desc = "Takes any data type as an input and displays it to the user upon examining, and to all nearby beings when pulsed." - icon_state = "screen_large" - power_draw_per_use = 40 - cooldown_per_use = 10 - -/obj/item/integrated_circuit/output/screen/extralarge/do_work() - ..() - var/obj/O = assembly ? get_turf(assembly) : loc - O.visible_message("[icon2html(O.icon, world, O.icon_state)] [stuff_to_display]") - if(assembly) - assembly.investigate_log("displayed \"[html_encode(stuff_to_display)]\" with [type].", INVESTIGATE_CIRCUIT) - else - investigate_log("displayed \"[html_encode(stuff_to_display)]\" as [type].", INVESTIGATE_CIRCUIT) diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/power.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/power.dm deleted file mode 100644 index eace78faecf..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/power.dm +++ /dev/null @@ -1,208 +0,0 @@ -/obj/item/integrated_circuit/power/ - category_text = "Power - Active" - -/obj/item/integrated_circuit/power/transmitter - name = "power transmission circuit" - desc = "This can wirelessly transmit electricity from an assembly's battery towards a nearby machine." - icon_state = "power_transmitter" - extended_desc = "This circuit transmits 5 kJ of electricity every time the activator pin is pulsed. The input pin must be \ - a reference to a machine to send electricity to. This can be a battery, or anything containing a battery. The machine can exist \ - inside the assembly, or adjacent to it. The power is sourced from the assembly's power cell. If the target is outside of the assembly, \ - some power is lost due to ineffiency." - w_class = WEIGHT_CLASS_SMALL - complexity = 16 - inputs = list("target" = IC_PINTYPE_REF) - outputs = list( - "target cell charge" = IC_PINTYPE_NUMBER, - "target cell max charge" = IC_PINTYPE_NUMBER, - "target cell percentage" = IC_PINTYPE_NUMBER - ) - activators = list("transmit" = IC_PINTYPE_PULSE_IN, "on transmit" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 500 // Inefficency has to come from somewhere. - var/amount_to_move = 5000 - -/obj/item/integrated_circuit/power/transmitter/large - name = "large power transmission circuit" - desc = "This can wirelessly transmit a lot of electricity from an assembly's battery towards a nearby machine. Warning: Do not operate in flammable environments." - extended_desc = "This circuit transmits 20 kJ of electricity every time the activator pin is pulsed. The input pin must be \ - a reference to a machine to send electricity to. This can be a battery, or anything containing a battery. The machine can exist \ - inside the assembly, or adjacent to it. The power is sourced from the assembly's power cell. If the target is outside of the assembly, \ - some power is lost due to ineffiency. Warning! Don't stack more than 1 power transmitter, as it becomes less efficient for every other \ - transmission circuit in its own assembly and other nearby ones." - w_class = WEIGHT_CLASS_BULKY - complexity = 32 - power_draw_per_use = 2000 - amount_to_move = 20000 - -/obj/item/integrated_circuit/power/transmitter/do_work() - - var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) - if(!AM) - return FALSE - if(istype(AM, /obj/item/gun/energy)) - return FALSE - if(!assembly) - return FALSE // Pointless to do everything else if there's no battery to draw from. - var/obj/item/stock_parts/cell/cell = AM.get_cell() - if(cell) - var/transfer_amount = amount_to_move - var/turf/A = get_turf(src) - var/turf/B = get_turf(AM) - if(A.Adjacent(B)) - if(AM.loc != assembly) - transfer_amount *= 0.8 // Losses due to distance. - var/list/U=A.GetAllContents(/obj/item/integrated_circuit/power/transmitter) - transfer_amount *= 1 / U.len - set_pin_data(IC_OUTPUT, 1, cell.charge) - set_pin_data(IC_OUTPUT, 2, cell.maxcharge) - set_pin_data(IC_OUTPUT, 3, cell.percent()) - activate_pin(2) - push_data() - if(cell.charge == cell.maxcharge) - return FALSE - if(transfer_amount && assembly.draw_power(amount_to_move)) // CELLRATE is already handled in draw_power() - cell.give(transfer_amount * GLOB.CELLRATE) - if(istype(AM, /obj/item)) - var/obj/item/I = AM - I.update_icon() - return TRUE - else - set_pin_data(IC_OUTPUT, 1, null) - set_pin_data(IC_OUTPUT, 2, null) - set_pin_data(IC_OUTPUT, 3, null) - activate_pin(2) - push_data() - return FALSE - -/obj/item/integrated_circuit/power/transmitter/large/do_work() - if(..()) // If the above code succeeds, do this below. - var/atom/movable/acting_object = get_object() - if(prob(20)) - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(12, 1, src) - s.start() - acting_object.visible_message("\The [acting_object] makes some sparks!") - return TRUE - - -// - wire connector - // -/obj/item/integrated_circuit/power/transmitter/wire_connector - name = "wire connector" - desc = "Connects to a wire and allows to read the power, charge it or charge itself from the wire's power." - extended_desc = "This circuit will automatically attempt to locate and connect to wires on the floor beneath it when pulsed. \ - You must set a target before connecting. It can also transfer energy up to 2kJ from the assembly \ - to a wire and backwards if negative values are set for energy transfer." - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - inputs = list( - "charge" = IC_PINTYPE_NUMBER - ) - activators = list( - "toggle connection" = IC_PINTYPE_PULSE_IN, - "transfer power" = IC_PINTYPE_PULSE_IN, - "on connected" = IC_PINTYPE_PULSE_OUT, - "on connection failed" = IC_PINTYPE_PULSE_OUT, - "on disconnected" = IC_PINTYPE_PULSE_OUT - ) - outputs = list( - "connected cable" = IC_PINTYPE_REF, - "powernet power" = IC_PINTYPE_NUMBER, - "powernet load" = IC_PINTYPE_NUMBER - ) - complexity = 35 - power_draw_per_use = 100 - amount_to_move = 0 - - var/obj/structure/cable/connected_cable - -/obj/item/integrated_circuit/power/transmitter/wire_connector/Destroy() - connected_cable = null - return ..() - -/obj/item/integrated_circuit/power/transmitter/wire_connector/Initialize() - START_PROCESSING(SSobj, src) - . = ..() - -//Does wire things -/obj/item/integrated_circuit/power/transmitter/wire_connector/process() - ..() - update_cable() - push_data() - -//If the assembly containing this is moved from the tile the wire is in, the connection breaks -/obj/item/integrated_circuit/power/transmitter/wire_connector/ext_moved() - if(connected_cable) - if(get_dist(get_object(), connected_cable) > 0) - // The connected cable is removed - connected_cable = null - set_pin_data(IC_OUTPUT, 1, null) - push_data() - activate_pin(5) - - -/obj/item/integrated_circuit/power/transmitter/wire_connector/on_data_written() - var/charge_num = get_pin_data(IC_INPUT, 1) - //In case someone sets that pin to null - if(!charge_num) - amount_to_move = 0 - return - - amount_to_move = clamp(charge_num,-2000, 2000) - -/obj/item/integrated_circuit/power/transmitter/wire_connector/do_work(var/n) - if(n == 1) - // If there is a connection, disconnect - if(connected_cable) - connected_cable = null - set_pin_data(IC_OUTPUT, 1, null) - push_data() - activate_pin(5) - return - - var/obj/structure/cable/foundcable = locate() in get_turf(src) - // If no connector can't connect - if(!foundcable || foundcable.invisibility != 0) - set_pin_data(IC_OUTPUT, 1, null) - push_data() - activate_pin(4) - return - connected_cable = foundcable - update_cable() - push_data() - activate_pin(3) - return - - - if(!connected_cable || !assembly) - return - - if(!assembly.battery) - return - - //No charge transfer, no need to syphon tickrates with scripts - if(!amount_to_move || amount_to_move == 0) - return - - //Second clamp: set the number between what the battery and powernet allows - var/obj/item/stock_parts/cell/battery = assembly.battery - amount_to_move = clamp(amount_to_move, -connected_cable.powernet.avail, battery.charge) - - if(amount_to_move > 0) - connected_cable.powernet.newavail += battery.use(amount_to_move) - return - connected_cable.powernet.avail -= battery.give(-amount_to_move) - -/obj/item/integrated_circuit/power/transmitter/wire_connector/proc/update_cable() - if(get_dist(get_object(), connected_cable) > 0) - connected_cable = null - - if(!connected_cable || connected_cable.invisibility != 0) - set_pin_data(IC_OUTPUT, 1, null) - set_pin_data(IC_OUTPUT, 2, null) - set_pin_data(IC_OUTPUT, 3, null) - return - - var/datum/powernet/analyzed_net = connected_cable.powernet - set_pin_data(IC_OUTPUT, 1, WEAKREF(connected_cable)) - set_pin_data(IC_OUTPUT, 2, analyzed_net.viewavail) - set_pin_data(IC_OUTPUT, 3, analyzed_net.viewload) diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/reagents.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/reagents.dm deleted file mode 100644 index 40a363978ac..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/reagents.dm +++ /dev/null @@ -1,849 +0,0 @@ -#define IC_SMOKE_REAGENTS_MINIMUM_UNITS 10 - -/obj/item/integrated_circuit/reagent - category_text = "Reagent" - resistance_flags = UNACIDABLE | FIRE_PROOF - cooldown_per_use = 10 - var/volume = 0 - var/reagent_flags = OPENCONTAINER - -/obj/item/integrated_circuit/reagent/Initialize() - . = ..() - if(volume) - create_reagents(volume, reagent_flags) - push_vol() - -/obj/item/integrated_circuit/reagent/proc/push_vol() - set_pin_data(IC_OUTPUT, 1, reagents.total_volume) - push_data() - -/obj/item/integrated_circuit/reagent/create_reagents(max_vol, flags) - . = ..() - RegisterSignal(reagents, list(COMSIG_REAGENTS_NEW_REAGENT, COMSIG_REAGENTS_ADD_REAGENT, COMSIG_REAGENTS_DEL_REAGENT, COMSIG_REAGENTS_REM_REAGENT), .proc/on_reagent_change) - RegisterSignal(reagents, COMSIG_PARENT_QDELETING, .proc/on_reagents_del) - -/// Handles properly detaching signal hooks. -/obj/item/integrated_circuit/reagent/proc/on_reagents_del(datum/reagents/reagents) - SIGNAL_HANDLER - UnregisterSignal(reagents, list(COMSIG_REAGENTS_NEW_REAGENT, COMSIG_REAGENTS_ADD_REAGENT, COMSIG_REAGENTS_DEL_REAGENT, COMSIG_REAGENTS_REM_REAGENT, COMSIG_PARENT_QDELETING)) - return NONE - -/obj/item/integrated_circuit/reagent/proc/on_reagent_change(datum/reagents/holder, ...) - SIGNAL_HANDLER - push_vol() - return NONE - -// Hydroponics trays have no reagents holder and handle reagents in their own snowflakey way. -// This is a dirty hack to make injecting reagents into them work. -// TODO: refactor that. -/* SKYRAT PORT -- TODO make it work with new hydro -/obj/item/integrated_circuit/reagent/proc/inject_tray(obj/machinery/hydroponics/tray, atom/movable/source, amount) - var/atom/movable/acting_object = get_object() - var/list/trays = list(tray) - var/visi_msg = "[acting_object] transfers fluid into [tray]" - - if(amount > 30 && source.reagents.total_volume >= 30 && tray.using_irrigation) - trays = tray.FindConnected() - if (trays.len > 1) - visi_msg += ", setting off the irrigation system" - - acting_object.visible_message("[visi_msg].") - playsound(loc, 'sound/effects/slosh.ogg', 25, 1) - - var/split = round(amount/trays.len) - - for(var/obj/machinery/hydroponics/H in trays) - var/datum/reagents/temp_reagents = new /datum/reagents() - temp_reagents.my_atom = H - - source.reagents.trans_to(temp_reagents, split) - H.applyChemicals(temp_reagents) - - temp_reagents.clear_reagents() - qdel(temp_reagents) -*/ - -/obj/item/integrated_circuit/reagent/injector - name = "integrated hypo-injector" - desc = "This scary looking thing is able to pump liquids into, or suck liquids out of, whatever it's pointed at." - icon_state = "injector" - extended_desc = "This autoinjector can push up to 30 units of reagents into another container or someone else outside of the machine. The target \ - must be adjacent to the machine, and if it is a person, they cannot be wearing thick clothing. Negative given amounts makes the injector suck out reagents instead." - - volume = 30 - - complexity = 20 - max_allowed = 1 - cooldown_per_use = 6 SECONDS - inputs = list( - "target" = IC_PINTYPE_REF, - "injection amount" = IC_PINTYPE_NUMBER - ) - inputs_default = list( - "2" = 5 - ) - outputs = list( - "volume used" = IC_PINTYPE_NUMBER, - "self reference" = IC_PINTYPE_SELFREF - ) - activators = list( - "inject" = IC_PINTYPE_PULSE_IN, - "on injected" = IC_PINTYPE_PULSE_OUT, - "on fail" = IC_PINTYPE_PULSE_OUT, - "push ref" = IC_PINTYPE_PULSE_IN - - ) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 15 - var/direction_mode = CIRCUIT_SYRINGE_INJECT - var/transfer_amount = 10 - var/busy = FALSE - - -/obj/item/integrated_circuit/reagent/injector/on_data_written() - var/new_amount = get_pin_data(IC_INPUT, 2) - if(new_amount < 0) - new_amount = -new_amount - direction_mode = CIRCUIT_SYRINGE_DRAW - else - direction_mode = CIRCUIT_SYRINGE_INJECT - if(isnum_safe(new_amount)) - new_amount = clamp(new_amount, 0, volume) - transfer_amount = new_amount - - -/obj/item/integrated_circuit/reagent/injector/do_work(ord) - switch(ord) - if(1) - inject() - if(4) - set_pin_data(IC_OUTPUT, 2, WEAKREF(src)) - push_data() - -/obj/item/integrated_circuit/reagent/injector/proc/inject() - set waitfor = FALSE // Don't sleep in a proc that is called by a processor without this set, otherwise it'll delay the entire thing - var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) - var/atom/movable/acting_object = get_object() - - if(busy || !check_target(AM)) - activate_pin(3) - return - - if(!AM.reagents) - // SKYRAT PORT -- TODO make hydro work again - //if(istype(AM, /obj/machinery/hydroponics) && direction_mode == CIRCUIT_SYRINGE_INJECT && reagents.total_volume && transfer_amount)//injection into tray. - //inject_tray(AM, src, transfer_amount) - //activate_pin(2) - //return - activate_pin(3) - return - - if(direction_mode == CIRCUIT_SYRINGE_INJECT) - if(!reagents.total_volume || !AM.is_injectable() || AM.reagents.holder_full()) - activate_pin(3) - return - - if(isliving(AM)) - var/mob/living/L = AM - if(!L.can_inject(null, 0)) - activate_pin(3) - return - - //Always log attemped injections for admins - var/contained = reagents.log_list() - log_combat(src, L, "attempted to inject", addition="which had [contained]") - L.visible_message("[acting_object] is trying to inject [L]!", \ - "[acting_object] is trying to inject you!") - busy = TRUE - if(do_atom(src, L, extra_checks=CALLBACK(L, /mob/living/proc/can_inject,null,0))) - reagents.trans_to(L, transfer_amount) - log_combat(src, L, "injected", addition="which had [contained]") - L.visible_message("[acting_object] injects [L] with its needle!", \ - "[acting_object] injects you with its needle!") - else - busy = FALSE - activate_pin(3) - return - busy = FALSE - - else - reagents.trans_to(AM, transfer_amount) - - if(direction_mode == CIRCUIT_SYRINGE_DRAW) - if(reagents.total_volume >= reagents.maximum_volume) - acting_object.visible_message("[acting_object] tries to draw from [AM], but the injector is full.") - activate_pin(3) - return - - var/tramount = abs(transfer_amount) - - if(isliving(AM)) - var/mob/living/L = AM - L.visible_message("[acting_object] is trying to take a blood sample from [L]!", \ - "[acting_object] is trying to take a blood sample from you!") - busy = TRUE - if(do_atom(src, L, extra_checks=CALLBACK(L, /mob/living/proc/can_inject,null,0))) - if(L.transfer_blood_to(src, tramount)) - L.visible_message("[acting_object] takes a blood sample from [L]!", \ - "[acting_object] takes a blood sample from you!") - else - L.visible_message("[acting_object] fails to take a blood sample from [L].", \ - "[acting_object] fails to take a blood sample from you!") - busy = FALSE - activate_pin(3) - return - busy = FALSE - - else - if(!AM.reagents.total_volume) - acting_object.visible_message("[acting_object] tries to draw from [AM], but it is empty!") - activate_pin(3) - return - - if(!AM.is_drawable()) - activate_pin(3) - return - tramount = min(tramount, AM.reagents.total_volume) - AM.reagents.trans_to(src, tramount) - activate_pin(2) - - - -/obj/item/integrated_circuit/reagent/pump - name = "reagent pump" - desc = "Moves liquids safely inside a machine, or even nearby it." - icon_state = "reagent_pump" - extended_desc = "This is a pump which will move liquids from the source ref to the target ref. The third pin determines \ - how much liquid is moved per pulse, between 0 and 50. The pump can move reagents to any open container inside the machine, or \ - outside the machine if it is adjacent to the machine." - - complexity = 8 - inputs = list("source" = IC_PINTYPE_REF, "target" = IC_PINTYPE_REF, "injection amount" = IC_PINTYPE_NUMBER) - inputs_default = list("3" = 5) - outputs = list() - activators = list("transfer reagents" = IC_PINTYPE_PULSE_IN, "on transfer" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - var/transfer_amount = 10 - var/direction_mode = CIRCUIT_SYRINGE_INJECT - power_draw_per_use = 10 - -/obj/item/integrated_circuit/reagent/pump/on_data_written() - var/new_amount = get_pin_data(IC_INPUT, 3) - if(new_amount < 0) - new_amount = -new_amount - direction_mode = CIRCUIT_SYRINGE_DRAW - else - direction_mode = CIRCUIT_SYRINGE_INJECT - if(isnum_safe(new_amount)) - new_amount = clamp(new_amount, 0, 50) - transfer_amount = new_amount - -/obj/item/integrated_circuit/reagent/pump/do_work() - var/atom/movable/source = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) - var/atom/movable/target = get_pin_data_as_type(IC_INPUT, 2, /atom/movable) - - // Check for invalid input. - if(!check_target(source) || !check_target(target)) - return - - // If the pump is pumping backwards, swap target and source. - if(!direction_mode) - var/temp_source = source - source = target - target = temp_source - - if(!source.reagents) - return - - if(!target.reagents) - // Hydroponics trays have no reagents holder and handle reagents in their own snowflakey way. - // This is a dirty hack to make injecting reagents into them work. - /* SKYRAT PORT -- hydro tray injecting disabled for now - if(istype(target, /obj/machinery/hydroponics) && source.reagents.total_volume) - inject_tray(target, source, transfer_amount) - activate_pin(2) - */ - return - - if(!source.is_drainable() || !target.is_refillable()) - return - - source.reagents.trans_to(target, transfer_amount) - activate_pin(2) - -/obj/item/integrated_circuit/reagent/storage - cooldown_per_use = 1 - name = "reagent storage" - desc = "Stores liquid inside the device away from electrical components. It can store up to 60u." - icon_state = "reagent_storage" - extended_desc = "This is effectively an internal beaker." - - volume = 60 - - complexity = 4 - inputs = list() - outputs = list( - "volume used" = IC_PINTYPE_NUMBER, - "self reference" = IC_PINTYPE_SELFREF - ) - activators = list("push ref" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - - - -/obj/item/integrated_circuit/reagent/storage/do_work() - set_pin_data(IC_OUTPUT, 2, WEAKREF(src)) - push_data() - -/obj/item/integrated_circuit/reagent/storage/big - name = "big reagent storage" - icon_state = "reagent_storage_big" - desc = "Stores liquid inside the device away from electrical components. Can store up to 180u." - - volume = 180 - - complexity = 16 - spawn_flags = IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/reagent/storage/cryo - name = "cryo reagent storage" - desc = "Stores liquid inside the device away from electrical components. It can store up to 60u. This will also prevent reactions." - icon_state = "reagent_storage_cryo" - extended_desc = "This is effectively an internal cryo beaker." - - complexity = 8 - spawn_flags = IC_SPAWN_RESEARCH - reagent_flags = OPENCONTAINER | NO_REACT - -/obj/item/integrated_circuit/reagent/storage/grinder - name = "reagent grinder" - desc = "This is a reagent grinder. It accepts a ref to something, and refines it into reagents. It can store up to 100u." - icon_state = "blender" - extended_desc = "" - inputs = list( - "target" = IC_PINTYPE_REF, - ) - outputs = list( - "volume used" = IC_PINTYPE_NUMBER, - "self reference" = IC_PINTYPE_SELFREF - ) - activators = list( - "grind" = IC_PINTYPE_PULSE_IN, - "on grind" = IC_PINTYPE_PULSE_OUT, - "on fail" = IC_PINTYPE_PULSE_OUT, - "push ref" = IC_PINTYPE_PULSE_IN - ) - volume = 100 - power_draw_per_use = 150 - complexity = 16 - spawn_flags = IC_SPAWN_RESEARCH - - -/obj/item/integrated_circuit/reagent/storage/grinder/do_work(ord) - switch(ord) - if(1) - grind() - if(4) - set_pin_data(IC_OUTPUT, 2, WEAKREF(src)) - push_data() - -/obj/item/integrated_circuit/reagent/storage/grinder/proc/grind() - if(reagents.total_volume >= reagents.maximum_volume) - activate_pin(3) - return FALSE - var/obj/item/I = get_pin_data_as_type(IC_INPUT, 1, /obj/item) - if(istype(I)&&(I.grind_results)&&check_target(I)&&(I.on_grind(src) != -1)) - reagents.add_reagent_list(I.grind_results) - if(I.reagents) - I.reagents.trans_to(src, I.reagents.total_volume) - qdel(I) - activate_pin(2) - return TRUE - activate_pin(3) - return FALSE - -/obj/item/integrated_circuit/reagent/storage/juicer - name = "reagent juicer" - desc = "This is a reagent juicer. It accepts a ref to something and refines it into reagents. It can store up to 100u." - icon_state = "blender" - extended_desc = "" - inputs = list( - "target" = IC_PINTYPE_REF, - ) - outputs = list( - "volume used" = IC_PINTYPE_NUMBER, - "self reference" = IC_PINTYPE_SELFREF - ) - activators = list( - "juice" = IC_PINTYPE_PULSE_IN, - "on juice" = IC_PINTYPE_PULSE_OUT, - "on fail" = IC_PINTYPE_PULSE_OUT, - "push ref" = IC_PINTYPE_PULSE_IN - ) - volume = 100 - power_draw_per_use = 150 - complexity = 16 - spawn_flags = IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/reagent/storage/juicer/do_work(ord) - switch(ord) - if(1) - juice() - if(4) - set_pin_data(IC_OUTPUT, 2, WEAKREF(src)) - push_data() - -/obj/item/integrated_circuit/reagent/storage/juicer/proc/juice() - if(reagents.total_volume >= reagents.maximum_volume) - activate_pin(3) - return FALSE - var/obj/item/I = get_pin_data_as_type(IC_INPUT, 1, /obj/item) - if(istype(I)&&check_target(I)&&(I.juice_results)&&(I.on_juice() != -1)) - reagents.add_reagent_list(I.juice_results) - qdel(I) - activate_pin(2) - return TRUE - activate_pin(3) - return FALSE - - - -/obj/item/integrated_circuit/reagent/storage/scan - name = "reagent scanner" - desc = "Stores liquid inside the device away from electrical components. It can store up to 60u. On pulse this beaker will send list of contained reagents." - icon_state = "reagent_scan" - extended_desc = "Mostly useful for filtering reagents." - - complexity = 8 - outputs = list( - "volume used" = IC_PINTYPE_NUMBER, - "self reference" = IC_PINTYPE_SELFREF, - "list of reagents" = IC_PINTYPE_LIST - ) - activators = list( - "scan" = IC_PINTYPE_PULSE_IN, - "push ref" = IC_PINTYPE_PULSE_IN - ) - spawn_flags = IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/reagent/storage/scan/do_work(ord) - switch(ord) - if(1) - var/cont[0] - for(var/datum/reagent/RE in reagents.reagent_list) - cont += RE - set_pin_data(IC_OUTPUT, 3, cont) - push_data() - if(2) - set_pin_data(IC_OUTPUT, 2, WEAKREF(src)) - push_data() - -/obj/item/integrated_circuit/reagent/filter - name = "reagent filter" - desc = "Filters liquids by list of desired or unwanted reagents." - icon_state = "reagent_filter" - extended_desc = "This is a filter which will move liquids from the source to its target. \ - If the amount in the fourth pin is positive, it will move all reagents except those in the unwanted list. \ - If the amount in the fourth pin is negative, it will only move the reagents in the wanted list. \ - The third pin determines how many reagents are moved per pulse, between 0 and 50. Amount is given for each separate reagent." - - complexity = 8 - inputs = list( - "source" = IC_PINTYPE_REF, - "target" = IC_PINTYPE_REF, - "injection amount" = IC_PINTYPE_NUMBER, - "list of reagents" = IC_PINTYPE_LIST - ) - inputs_default = list( - "3" = 5 - ) - outputs = list() - activators = list( - "transfer reagents" = IC_PINTYPE_PULSE_IN, - "on transfer" = IC_PINTYPE_PULSE_OUT - ) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - var/transfer_amount = 10 - var/direction_mode = CIRCUIT_SYRINGE_INJECT - power_draw_per_use = 10 - -/obj/item/integrated_circuit/reagent/filter/on_data_written() - var/new_amount = get_pin_data(IC_INPUT, 3) - if(new_amount < 0) - new_amount = -new_amount - direction_mode = CIRCUIT_SYRINGE_DRAW - else - direction_mode = CIRCUIT_SYRINGE_INJECT - if(isnum_safe(new_amount)) - new_amount = clamp(new_amount, 0, 50) - transfer_amount = new_amount - -/obj/item/integrated_circuit/reagent/filter/do_work() - var/atom/movable/source = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) - var/atom/movable/target = get_pin_data_as_type(IC_INPUT, 2, /atom/movable) - var/list/demand = get_pin_data(IC_INPUT, 4) - - // Check for invalid input. - if(!check_target(source) || !check_target(target)) - return - - if(!source.reagents || !target.reagents) - return - - // FALSE in those procs makes mobs invalid targets. - if(!source.is_drawable(FALSE) || !target.is_injectable(FALSE)) - return - - if(target.reagents.maximum_volume - target.reagents.total_volume <= 0) - return - - for(var/datum/reagent/G in source.reagents.reagent_list) - if(!direction_mode) - if(G in demand) - source.reagents.trans_id_to(target, G.type, transfer_amount) - else - if(!(G in demand)) - source.reagents.trans_id_to(target, G.type, transfer_amount) - activate_pin(2) - push_data() - -/obj/item/integrated_circuit/reagent/storage/heater - name = "chemical heater" - desc = "Stores liquid inside the device away from electrical components. It can store up to 60u. It will heat or cool the reagents \ - to the target temperature when turned on." - icon_state = "heater" - complexity = 8 - inputs = list( - "target temperature" = IC_PINTYPE_NUMBER, - "on" = IC_PINTYPE_BOOLEAN - ) - inputs_default = list("1" = 300) - outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_SELFREF,"temperature" = IC_PINTYPE_NUMBER) - spawn_flags = IC_SPAWN_RESEARCH - var/heater_coefficient = 0.1 - -/obj/item/integrated_circuit/reagent/storage/heater/on_data_written() - if(get_pin_data(IC_INPUT, 2)) - power_draw_idle = 30 - else - power_draw_idle = 0 - -/obj/item/integrated_circuit/reagent/storage/heater/Initialize() - .=..() - START_PROCESSING(SScircuit, src) - -/obj/item/integrated_circuit/reagent/storage/heater/Destroy() - STOP_PROCESSING(SScircuit, src) - return ..() - -/obj/item/integrated_circuit/reagent/storage/heater/process() - if(!power_draw_idle) - return - var/target_temperature = clamp(get_pin_data(IC_INPUT, 1), 0, 3000) - if(reagents.chem_temp > target_temperature) - reagents.chem_temp += min(-1, (target_temperature - reagents.chem_temp) * heater_coefficient) - if(reagents.chem_temp < target_temperature) - reagents.chem_temp += max(1, (target_temperature - reagents.chem_temp) * heater_coefficient) - - reagents.chem_temp = round(reagents.chem_temp) - reagents.handle_reactions() - set_pin_data(IC_OUTPUT, 3, reagents.chem_temp) - push_data() - - -/obj/item/integrated_circuit/reagent/smoke - name = "smoke generator" - desc = "Unlike most electronics, creating smoke is completely intentional." - icon_state = "smoke" - extended_desc = "This smoke generator creates clouds of smoke on command. It can also hold liquids inside, which will go \ - into the smoke clouds when activated. The reagents are consumed when the smoke is made." - ext_cooldown = 1 - volume = 100 - complexity = 20 - cooldown_per_use = 1 SECONDS - inputs = list() - outputs = list( - "volume used" = IC_PINTYPE_NUMBER, - "self reference" = IC_PINTYPE_SELFREF - ) - activators = list( - "create smoke" = IC_PINTYPE_PULSE_IN, - "on smoked" = IC_PINTYPE_PULSE_OUT, - "push ref" = IC_PINTYPE_PULSE_IN - ) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 20 - var/smoke_radius = 5 - var/notified = FALSE - -/obj/item/integrated_circuit/reagent/smoke/do_work(ord) - switch(ord) - if(1) - if(!reagents || (reagents.total_volume < IC_SMOKE_REAGENTS_MINIMUM_UNITS)) - return - var/location = get_turf(src) - var/datum/effect_system/smoke_spread/chem/S = new - S.attach(location) - playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3) - if(S) - S.set_up(reagents, smoke_radius, location, notified) - if(!notified) - notified = TRUE - S.start() - reagents.clear_reagents() - activate_pin(2) - if(3) - set_pin_data(IC_OUTPUT, 2, WEAKREF(src)) - push_data() - -// - Integrated extinguisher - // -/obj/item/integrated_circuit/reagent/extinguisher - name = "integrated extinguisher" - desc = "This circuit sprays any of its contents out like an extinguisher." - icon_state = "injector" - extended_desc = "This circuit can hold up to 30 units of any given chemicals. On each use, it sprays these reagents like a fire extinguisher." - - volume = 30 - - complexity = 20 - cooldown_per_use = 6 SECONDS - inputs = list( - "target X rel" = IC_PINTYPE_NUMBER, - "target Y rel" = IC_PINTYPE_NUMBER - ) - outputs = list( - "volume" = IC_PINTYPE_NUMBER, - "self reference" = IC_PINTYPE_SELFREF - ) - activators = list( - "spray" = IC_PINTYPE_PULSE_IN, - "on sprayed" = IC_PINTYPE_PULSE_OUT, - "on fail" = IC_PINTYPE_PULSE_OUT, - "push ref" = IC_PINTYPE_PULSE_IN - ) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 15 - max_allowed = 2 - var/busy = FALSE - -/obj/item/integrated_circuit/reagent/extinguisher/Initialize() - .=..() - set_pin_data(IC_OUTPUT,2, src) - -/obj/item/integrated_circuit/reagent/extinguisher/do_work() - //Check if enough volume - set_pin_data(IC_OUTPUT, 1, reagents.total_volume) - if(!reagents || reagents.total_volume < 5 || busy) - push_data() - activate_pin(3) - return - - playsound(loc, 'sound/effects/extinguish.ogg', 75, 1, -3) - //Get the tile on which the water particle spawns - var/turf/Spawnpoint = get_turf(src) - if(!Spawnpoint) - push_data() - activate_pin(3) - return - - //Get direction and target turf for each water particle - var/turf/T = locate(Spawnpoint.x + get_pin_data(IC_INPUT, 1),Spawnpoint.y + get_pin_data(IC_INPUT, 2),Spawnpoint.z) - if(!T) - push_data() - activate_pin(3) - return - var/direction = get_dir(Spawnpoint, T) - var/turf/T1 = get_step(T,turn(direction, 90)) - var/turf/T2 = get_step(T,turn(direction, -90)) - var/list/the_targets = list(T,T1,T2) - busy = TRUE - - // Create list with particles and their targets - var/list/water_particles=list() - for(var/a=0, a<5, a++) - var/obj/effect/particle_effect/water/W = new /obj/effect/particle_effect/water(get_turf(src)) - water_particles[W] = pick(the_targets) - var/datum/reagents/R = new/datum/reagents(5) - W.reagents = R - R.my_atom = W - reagents.trans_to(W,1) - - //Make em move dat ass, hun - addtimer(CALLBACK(src, /obj/item/integrated_circuit/reagent/extinguisher/proc/move_particles, water_particles), 2) - -//This whole proc is a loop -/obj/item/integrated_circuit/reagent/extinguisher/proc/move_particles(var/list/particles, var/repetitions=0) - //Check if there's anything in here first - if(!particles || particles.len == 0) - return - // Second loop: Get all the water particles and make them move to their target - for(var/obj/effect/particle_effect/water/W in particles) - var/turf/my_target = particles[W] - if(!W) - continue - step_towards(W,my_target) - if(!W.reagents) - continue - if(W.loc == my_target) - break - if(repetitions < 4) - repetitions++ //Can't have math operations in addtimer(CALLBACK()) - addtimer(CALLBACK(src, /obj/item/integrated_circuit/reagent/extinguisher/proc/move_particles, particles, repetitions), 2) - else - push_data() - activate_pin(2) - busy = FALSE - - -// - Drain circuit - // -/obj/item/integrated_circuit/reagent/drain - name = "chemical drain circuit" - desc = "This circuit either eliminates reagents by creating a puddle or can suck up chemicals on tiles." - icon_state = "injector" - extended_desc = "Set mode to FALSE to eliminate reagents and TRUE to drain." - - volume = 20 - - complexity = 10 - inputs = list( - "mode" = IC_PINTYPE_BOOLEAN - ) - outputs = list( - "volume" = IC_PINTYPE_NUMBER, - "self reference" = IC_PINTYPE_SELFREF - ) - activators = list( - "drain" = IC_PINTYPE_PULSE_IN, - "on drained" = IC_PINTYPE_PULSE_OUT, - "on fail" = IC_PINTYPE_PULSE_OUT, - "push ref" = IC_PINTYPE_PULSE_IN - ) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 15 - - -/obj/item/integrated_circuit/reagent/drain/Initialize() - .=..() - set_pin_data(IC_OUTPUT,2, src) - - -/obj/item/integrated_circuit/reagent/drain/do_work() - if(get_pin_data(IC_OUTPUT, 1, reagents.total_volume)) - if(!reagents || !reagents.total_volume) - push_data() - activate_pin(3) - return - // Put the reagents on the floortile the assembly is on - reagents.clear_reagents() - push_data() - activate_pin(2) - return - - else - if(reagents) - if(reagents.total_volume >= volume) - push_data() - activate_pin(3) - return - // Favorably, drain it from a chemicals pile, else, try something different - var/obj/effect/decal/cleanable/drainedchems = locate(/obj/effect/decal/cleanable) in get_turf(src) - if(!drainedchems || !drainedchems.reagents || drainedchems.reagents.total_volume == 0) - push_data() - activate_pin(3) - return - drainedchems.reagents.trans_to(src, 30, 0.5) - if(drainedchems.reagents.total_volume == 0) - qdel(drainedchems) - push_data() - activate_pin(2) - -// - Beaker Connector - // -/obj/item/integrated_circuit/input/beaker_connector - category_text = "Reagent" - cooldown_per_use = 1 - name = "beaker slot" - desc = "Lets you add a beaker to your assembly and remove it even when the assembly is closed." - icon_state = "reagent_storage" - extended_desc = "It can help you extract reagents easier." - complexity = 4 - - inputs = list() - outputs = list( - "volume used" = IC_PINTYPE_NUMBER, - "current beaker" = IC_PINTYPE_REF - ) - activators = list( - "on insert" = IC_PINTYPE_PULSE_OUT, - "on remove" = IC_PINTYPE_PULSE_OUT, - "push ref" = IC_PINTYPE_PULSE_OUT - ) - - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - can_be_asked_input = TRUE - demands_object_input = TRUE - can_input_object_when_closed = TRUE - - var/obj/item/reagent_containers/glass/beaker/current_beaker - - -/obj/item/integrated_circuit/input/beaker_connector/attackby(var/obj/item/reagent_containers/I, var/mob/living/user) - //Check if it truly is a reagent container - if(!istype(I,/obj/item/reagent_containers/glass/beaker)) - to_chat(user,"The [I.name] doesn't seem to fit in here.") - return - - //Check if there is no other beaker already inside - if(current_beaker) - to_chat(user,"There is already a reagent container inside.") - return - - //The current beaker is the one we just attached, its location is inside the circuit - current_beaker = I - user.transferItemToLoc(I,src) - - to_chat(user,"You put the [I.name] inside the beaker connector.") - - //Set the pin to a weak reference of the current beaker - push_vol() - set_pin_data(IC_OUTPUT, 2, WEAKREF(current_beaker)) - push_data() - activate_pin(1) - activate_pin(3) - - -/obj/item/integrated_circuit/input/beaker_connector/ask_for_input(mob/user) - attack_self(user) - - -/obj/item/integrated_circuit/input/beaker_connector/attack_self(mob/user) - //Check if no beaker attached - if(!current_beaker) - to_chat(user, "There is currently no beaker attached.") - return - - //Remove beaker and put in user's hands/location - to_chat(user, "You take [current_beaker] out of the beaker connector.") - user.put_in_hands(current_beaker) - current_beaker = null - //Remove beaker reference - push_vol() - set_pin_data(IC_OUTPUT, 2, null) - push_data() - activate_pin(2) - activate_pin(3) - - -/obj/item/integrated_circuit/input/beaker_connector/proc/push_vol() - var/beakerVolume = 0 - if(current_beaker) - beakerVolume = current_beaker.reagents.total_volume - - set_pin_data(IC_OUTPUT, 1, beakerVolume) - push_data() - - -/obj/item/reagent_containers/glass/beaker/on_reagent_change() - ..() - if(istype(loc,/obj/item/integrated_circuit/input/beaker_connector)) - var/obj/item/integrated_circuit/input/beaker_connector/current_circuit = loc - current_circuit.push_vol() diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/smart.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/smart.dm deleted file mode 100644 index 4a9e4ff3dd1..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/smart.dm +++ /dev/null @@ -1,370 +0,0 @@ -/obj/item/integrated_circuit/smart - category_text = "Smart" - -/obj/item/integrated_circuit/smart/basic_pathfinder - name = "basic pathfinder" - desc = "This complex circuit is able to determine what direction a given target is." - extended_desc = "This circuit uses a miniturized integrated camera to determine where the target is. If the machine \ - cannot see the target, it will not be able to calculate the correct direction." - icon_state = "numberpad" - complexity = 5 - inputs = list("target" = IC_PINTYPE_REF,"ignore obstacles" = IC_PINTYPE_BOOLEAN) - outputs = list("dir" = IC_PINTYPE_DIR) - activators = list("calculate dir" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT,"not calculated" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 40 - -/obj/item/integrated_circuit/smart/basic_pathfinder/do_work() - var/datum/integrated_io/I = inputs[1] - set_pin_data(IC_OUTPUT, 1, null) - if(!isweakref(I.data)) - activate_pin(3) - return - var/atom/A = I.data.resolve() - if(!A) - activate_pin(3) - return - if(!(A in view(get_turf(src)))) - push_data() - activate_pin(3) - return // Can't see the target. - - if(get_pin_data(IC_INPUT, 2)) - set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_turf(A))) - else - set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_step_towards2(get_turf(src),A))) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/smart/coord_basic_pathfinder - name = "coordinate pathfinder" - desc = "This complex circuit is able to determine what direction a given target is." - extended_desc = "This circuit uses absolute coordinates to determine where the target is. If the machine \ - cannot see the target, it will not be able to calculate the correct direction. \ - This circuit will only work while inside an assembly." - icon_state = "numberpad" - complexity = 5 - inputs = list("X" = IC_PINTYPE_NUMBER,"Y" = IC_PINTYPE_NUMBER,"ignore obstacles" = IC_PINTYPE_BOOLEAN) - outputs = list( "dir" = IC_PINTYPE_DIR, - "distance" = IC_PINTYPE_NUMBER - ) - activators = list("calculate dir" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT,"not calculated" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 40 - -/obj/item/integrated_circuit/smart/coord_basic_pathfinder/do_work() - if(!assembly) - activate_pin(3) - return - var/turf/T = get_turf(assembly) - var/target_x = clamp(get_pin_data(IC_INPUT, 1), 0, world.maxx) - var/target_y = clamp(get_pin_data(IC_INPUT, 2), 0, world.maxy) - var/turf/A = locate(target_x, target_y, T.z) - set_pin_data(IC_OUTPUT, 1, null) - if(!A||A==T) - activate_pin(3) - return - if(get_pin_data(IC_INPUT, 2)) - set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_turf(A))) - else - set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_step_towards2(get_turf(src),A))) - set_pin_data(IC_OUTPUT, 2, sqrt((A.x-T.x)*(A.x-T.x)+ (A.y-T.y)*(A.y-T.y))) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/smart/advanced_pathfinder - name = "advanced pathfinder" - desc = "This circuit uses a complex processor for long-range pathfinding." - extended_desc = "This circuit uses absolute coordinates to find its target. A path will be generated to the target, taking obstacles into account, \ - and pathing around any instances of said input. The passkey provided from a card reader is used to calculate a valid path through airlocks." - icon_state = "numberpad" - complexity = 40 - cooldown_per_use = 50 - inputs = list("X target" = IC_PINTYPE_NUMBER,"Y target" = IC_PINTYPE_NUMBER,"obstacle" = IC_PINTYPE_REF,"access" = IC_PINTYPE_STRING) - outputs = list("X" = IC_PINTYPE_LIST,"Y" = IC_PINTYPE_LIST) - activators = list("calculate path" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT,"not calculated" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 80 - var/obj/item/card/id/idc - -/obj/item/integrated_circuit/smart/advanced_pathfinder/Initialize() - .=..() - idc = new(src) - -/obj/item/integrated_circuit/smart/advanced_pathfinder/do_work() - if(!assembly) - activate_pin(3) - return - //idc.access = assembly.access_card.access // hippie start -- readded xor decryption - hippie_xor_decrypt() // hippie end - var/turf/a_loc = get_turf(assembly) - var/list/P = get_path_to(assembly, locate(get_pin_data(IC_INPUT, 1),get_pin_data(IC_INPUT, 2),a_loc.z), id=idc, exclude=get_turf(get_pin_data_as_type(IC_INPUT,3, /atom)), simulated_only = FALSE) - - if(!P) - activate_pin(3) - return - - var/list/Xn = new/list(P.len) - var/list/Yn = new/list(P.len) - var/turf/T - for(var/i =1 to P.len) - T=P[i] - Xn[i] = T.x - Yn[i] = T.y - set_pin_data(IC_OUTPUT, 1, Xn) - set_pin_data(IC_OUTPUT, 2, Yn) - push_data() - activate_pin(2) - - -// - MMI Tank - // -/obj/item/integrated_circuit/input/mmi_tank - name = "man-machine interface tank" - desc = "This circuit is just a jar filled with an artificial liquid mimicking the cerebrospinal fluid." - extended_desc = "This jar can hold 1 man-machine interface and let it take control of some basic functions of the assembly." - complexity = 29 - inputs = list("laws" = IC_PINTYPE_LIST) - outputs = list( - "man-machine interface" = IC_PINTYPE_REF, - "direction" = IC_PINTYPE_DIR, - "click target" = IC_PINTYPE_REF - ) - activators = list( - "move" = IC_PINTYPE_PULSE_OUT, - "left" = IC_PINTYPE_PULSE_OUT, - "right" = IC_PINTYPE_PULSE_OUT, - "up" = IC_PINTYPE_PULSE_OUT, - "down" = IC_PINTYPE_PULSE_OUT, - "leftclick" = IC_PINTYPE_PULSE_OUT, - "shiftclick" = IC_PINTYPE_PULSE_OUT, - "altclick" = IC_PINTYPE_PULSE_OUT, - "ctrlclick" = IC_PINTYPE_PULSE_OUT - ) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 150 - can_be_asked_input = TRUE - demands_object_input = TRUE - - var/obj/item/mmi/installed_brain - -/obj/item/integrated_circuit/input/mmi_tank/attackby(var/obj/item/mmi/O, var/mob/user) - if(!istype(O,/obj/item/mmi)) - to_chat(user,"You can't put that inside.") - return - if(installed_brain) - to_chat(user,"There's already a brain inside.") - return - user.transferItemToLoc(O,src) - installed_brain = O - can_be_asked_input = FALSE - to_chat(user, "You gently place \the man-machine interface inside the tank.") - to_chat(O, "You are slowly being placed inside the man-machine-interface tank.") - O.brainmob.remote_control=src - set_pin_data(IC_OUTPUT, 1, O) - -/obj/item/integrated_circuit/input/mmi_tank/attack_self(var/mob/user) - if(installed_brain) - RemoveBrain() - to_chat(user, "You slowly lift [installed_brain] out of the MMI tank.") - playsound(src, 'sound/items/Crowbar.ogg', 50, 1) - installed_brain = null - push_data() - else - to_chat(user, "You don't see any brain swimming in the tank.") - -/obj/item/integrated_circuit/input/mmi_tank/Destroy() - RemoveBrain() - ..() - -/obj/item/integrated_circuit/input/mmi_tank/relaymove(var/n,var/dir) - set_pin_data(IC_OUTPUT, 2, dir) - do_work(1) - switch(dir) - if(8) activate_pin(2) - if(4) activate_pin(3) - if(1) activate_pin(4) - if(2) activate_pin(5) - -/obj/item/integrated_circuit/input/mmi_tank/do_work(var/n) - push_data() - activate_pin(n) - -/obj/item/integrated_circuit/input/mmi_tank/proc/RemoveBrain() - if(installed_brain) - can_be_asked_input = TRUE - installed_brain.forceMove(drop_location()) - set_pin_data(IC_OUTPUT, 1, WEAKREF(null)) - if(installed_brain.brainmob) - installed_brain.brainmob.remote_control = null - - -//Brain changes -/mob/living/brain/var/check_bot_self = FALSE - -/mob/living/brain/ClickOn(atom/A, params) - ..() - if(!istype(remote_control,/obj/item/integrated_circuit/input/mmi_tank)) - return - var/obj/item/integrated_circuit/input/mmi_tank/brainholder=remote_control - brainholder.set_pin_data(IC_OUTPUT, 3, A) - var/list/modifiers = params2list(params) - - if(modifiers["shift"]) - brainholder.do_work(7) - return - if(modifiers["alt"]) - brainholder.do_work(8) - return - if(modifiers["ctrl"]) - brainholder.do_work(9) - return - - if(istype(A,/obj/item/electronic_assembly)) - var/obj/item/electronic_assembly/CheckedAssembly = A - - if(brainholder in CheckedAssembly.assembly_components) - var/obj/item/electronic_assembly/holdingassembly=A - check_bot_self=TRUE - - if(holdingassembly.opened) - holdingassembly.ui_interact(src) - holdingassembly.attack_self(src) - check_bot_self=FALSE - return - - brainholder.do_work(6) - -/mob/living/brain/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) - return check_bot_self - -/obj/item/integrated_circuit/smart/advanced_pathfinder/proc/hippie_xor_decrypt() - var/Ps = get_pin_data(IC_INPUT, 4) - if(!Ps) - return - var/list/Pl = json_decode(XorEncrypt(hextostr(Ps, TRUE), SScircuit.cipherkey)) - if(Pl&&islist(Pl)) - idc.access = Pl - -// - pAI connector circuit - // -/obj/item/integrated_circuit/input/pAI_connector - name = "pAI connector circuit" - desc = "This circuit lets you fit in a personal artificial intelligence to give it some form of control over the bot." - extended_desc = "You can wire various functions to it." - complexity = 29 - inputs = list("laws" = IC_PINTYPE_LIST) - outputs = list( - "personal artificial intelligence" = IC_PINTYPE_REF, - "direction" = IC_PINTYPE_DIR, - "click target" = IC_PINTYPE_REF - ) - activators = list( - "move" = IC_PINTYPE_PULSE_OUT, - "left" = IC_PINTYPE_PULSE_OUT, - "right" = IC_PINTYPE_PULSE_OUT, - "up" = IC_PINTYPE_PULSE_OUT, - "down" = IC_PINTYPE_PULSE_OUT, - "leftclick" = IC_PINTYPE_PULSE_OUT, - "shiftclick" = IC_PINTYPE_PULSE_OUT, - "altclick" = IC_PINTYPE_PULSE_OUT, - "ctrlclick" = IC_PINTYPE_PULSE_OUT, - "shiftctrlclick" = IC_PINTYPE_PULSE_OUT - ) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 150 - can_be_asked_input = TRUE - demands_object_input = TRUE - - var/obj/item/paicard/installed_pai - -/obj/item/integrated_circuit/input/pAI_connector/attackby(var/obj/item/paicard/O, var/mob/user) - if(!istype(O,/obj/item/paicard)) - to_chat(user,"You can't put that inside.") - return - if(installed_pai) - to_chat(user,"There's already a pAI connected to this.") - return - user.transferItemToLoc(O,src) - installed_pai = O - can_be_asked_input = FALSE - to_chat(user, "You slowly connect the circuit's pins to the [installed_pai].") - to_chat(O, "You are slowly being connected to the pAI connector.") - O.pai.remote_control=src - set_pin_data(IC_OUTPUT, 1, O) - -/obj/item/integrated_circuit/input/pAI_connector/attack_self(var/mob/user) - if(installed_pai) - RemovepAI() - to_chat(user, "You slowly disconnect the circuit's pins from the [installed_pai].") - playsound(src, 'sound/items/Crowbar.ogg', 50, 1) - installed_pai = null - push_data() - else - to_chat(user, "The connection port is empty.") - -/obj/item/integrated_circuit/input/pAI_connector/relaymove(var/n,var/dir) - set_pin_data(IC_OUTPUT, 2, dir) - do_work(1) - switch(dir) - if(8) activate_pin(2) - if(4) activate_pin(3) - if(1) activate_pin(4) - if(2) activate_pin(5) - -/obj/item/integrated_circuit/input/pAI_connector/do_work(var/n) - push_data() - activate_pin(n) - - -/obj/item/integrated_circuit/input/pAI_connector/Destroy() - RemovepAI() - ..() - -/obj/item/integrated_circuit/input/pAI_connector/proc/RemovepAI() - if(installed_pai) - can_be_asked_input = TRUE - installed_pai.forceMove(drop_location()) - set_pin_data(IC_OUTPUT, 1, WEAKREF(null)) - installed_pai.pai.remote_control = null - - -//pAI changes -/mob/living/silicon/pai/var/check_bot_self = FALSE - -/mob/living/silicon/pai/ClickOn(atom/A, params) - ..() - if(!istype(remote_control,/obj/item/integrated_circuit/input/pAI_connector)) - return - var/obj/item/integrated_circuit/input/pAI_connector/paiholder=remote_control - paiholder.set_pin_data(IC_OUTPUT, 3, A) - var/list/modifiers = params2list(params) - - if(modifiers["shift"] && modifiers["ctrl"]) - paiholder.do_work(10) - return - if(modifiers["shift"]) - paiholder.do_work(7) - return - if(modifiers["alt"]) - paiholder.do_work(8) - return - if(modifiers["ctrl"]) - paiholder.do_work(9) - return - - if(istype(A,/obj/item/electronic_assembly)) - var/obj/item/electronic_assembly/CheckedAssembly = A - - if(paiholder in CheckedAssembly.assembly_components) - var/obj/item/electronic_assembly/holdingassembly=A - check_bot_self=TRUE - - if(holdingassembly.opened) - holdingassembly.ui_interact(src) - holdingassembly.attack_self(src) - check_bot_self=FALSE - return - - paiholder.do_work(6) - -/mob/living/silicon/pai/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) - return check_bot_self diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/text.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/text.dm deleted file mode 100644 index a2c84934102..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/text.dm +++ /dev/null @@ -1,271 +0,0 @@ -/obj/item/integrated_circuit/text - name = "text thingy" - desc = "Does text-processing related things." - category_text = "Text" - complexity = 1 - - -/obj/item/integrated_circuit/text/lowercase - name = "lowercase string converter" - desc = "this circuit will cause a string to come out in all lowercase." - icon_state = "lowercase" - inputs = list("input" = IC_PINTYPE_STRING) - outputs = list("output" = IC_PINTYPE_STRING) - activators = list("to lowercase" = IC_PINTYPE_PULSE_IN, "on converted" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/text/lowercase/do_work() - var/result = null - pull_data() - var/incoming = get_pin_data(IC_INPUT, 1) - if(!isnull(incoming)) - result = lowertext(incoming) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/text/uppercase - name = "uppercase string converter" - desc = "THIS WILL CAUSE A STRING TO COME OUT IN ALL UPPERCASE." - icon_state = "uppercase" - inputs = list("input" = IC_PINTYPE_STRING) - outputs = list("output" = IC_PINTYPE_STRING) - activators = list("to uppercase" = IC_PINTYPE_PULSE_IN, "on converted" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/text/uppercase/do_work() - var/result = null - pull_data() - var/incoming = get_pin_data(IC_INPUT, 1) - if(!isnull(incoming)) - result = uppertext(incoming) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/text/concatenator - name = "concatenator" - desc = "This can join up to 8 strings together to get a string with a maximum of 512 characters." - complexity = 4 - inputs = list() - outputs = list("result" = IC_PINTYPE_STRING) - activators = list("concatenate" = IC_PINTYPE_PULSE_IN, "on concatenated" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - var/number_of_pins = 8 - var/max_string_length = 512 - -/obj/item/integrated_circuit/text/concatenator/Initialize() - for(var/i = 1 to number_of_pins) - inputs["input [i]"] = IC_PINTYPE_STRING - . = ..() - -/obj/item/integrated_circuit/text/concatenator/do_work() - var/result = null - var/spamprotection - for(var/k in 1 to inputs.len) - var/I = get_pin_data(IC_INPUT, k) - if(!isnull(I)) - if((result ? length(result) : 0) + length(I) > max_string_length) - spamprotection = (result ? length(result) : 0) + length(I) - break - result = result + I - - if(spamprotection >= max_string_length*1.75 && assembly) - if(assembly.fingerprintslast) - var/mob/M = get_mob_by_ckey(assembly.fingerprintslast) - var/more = "" - if(M) - more = "[ADMIN_LOOKUPFLW(M)] " - message_admins("A concatenator circuit has greatly exceeded its [max_string_length] character limit with a total of [spamprotection] characters, and has been deleted. Assembly last touched by [more ? more : assembly.fingerprintslast].") - investigate_log("A concatenator circuit has greatly exceeded its [max_string_length] character limit with a total of [spamprotection] characters, and has been deleted. Assembly last touched by [assembly.fingerprintslast].", INVESTIGATE_CIRCUIT) - else - message_admins("A concatenator circuit has greatly exceeded its [max_string_length] character limit with a total of [spamprotection] characters, and has been deleted. No associated key.") - investigate_log("A concatenator circuit has greatly exceeded its [max_string_length] character limit with a total of [spamprotection] characters, and has been deleted. No associated key.", INVESTIGATE_CIRCUIT) - qdel(assembly) - return - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/text/concatenator/small - name = "small concatenator" - desc = "This can join up to 4 strings together to get a string with a maximum of 256 characters." - complexity = 2 - number_of_pins = 4 - max_string_length = 256 - -/obj/item/integrated_circuit/text/concatenator/large - name = "large concatenator" - desc = "This can join up to 16 strings together to get a string with a maximum of 1024 characters." - complexity = 6 - number_of_pins = 16 - max_string_length = 1024 - -/obj/item/integrated_circuit/text/separator - name = "separator" - desc = "This splits a single string into two at the relative split point." - extended_desc = "This circuit splits a given string into two, based on the string and the index value. \ - The index splits the string after the given index, including spaces. So 'a person' with an index of '3' \ - will split into 'a p' and 'erson'." - icon_state = "split" - complexity = 4 - inputs = list( - "string to split" = IC_PINTYPE_STRING, - "index" = IC_PINTYPE_NUMBER, - ) - outputs = list( - "before split" = IC_PINTYPE_STRING, - "after split" = IC_PINTYPE_STRING - ) - activators = list("separate" = IC_PINTYPE_PULSE_IN, "on separated" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/text/separator/do_work() - var/text = get_pin_data(IC_INPUT, 1) - var/index = get_pin_data(IC_INPUT, 2) - - var/split = min(index+1, length(text)) - - var/before_text = copytext(text, 1, split) - var/after_text = copytext(text, split, 0) - - set_pin_data(IC_OUTPUT, 1, before_text) - set_pin_data(IC_OUTPUT, 2, after_text) - push_data() - - activate_pin(2) - -/obj/item/integrated_circuit/text/indexer - name = "indexer" - desc = "This circuit takes a string and an index value, then returns the character found at in the string at the given index." - extended_desc = "Make sure the index is not longer or shorter than the string length. If you don't, the circuit will return empty." - icon_state = "split" - complexity = 4 - inputs = list( - "string to index" = IC_PINTYPE_STRING, - "index" = IC_PINTYPE_NUMBER, - ) - outputs = list( - "found character" = IC_PINTYPE_STRING - ) - activators = list("index" = IC_PINTYPE_PULSE_IN, "on indexed" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/text/indexer/do_work() - var/strin = get_pin_data(IC_INPUT, 1) - var/ind = get_pin_data(IC_INPUT, 2) - if(ind > 0 && ind <= length(strin)) - set_pin_data(IC_OUTPUT, 1, strin[ind]) - else - set_pin_data(IC_OUTPUT, 1, "") - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/text/findstring - name = "find text" - desc = "This outputs the position of the sample in the string, or returns 0." - extended_desc = "The first pin is the string to be examined. The second pin is the sample to be found. \ - For example, inputting 'my wife has caught on fire' with 'has' as the sample will give you position 9. \ - This circuit isn't case sensitive, and it does not ignore spaces." - complexity = 4 - inputs = list( - "string" = IC_PINTYPE_STRING, - "sample" = IC_PINTYPE_STRING, - ) - outputs = list( - "position" = IC_PINTYPE_NUMBER - ) - activators = list("search" = IC_PINTYPE_PULSE_IN, "after search" = IC_PINTYPE_PULSE_OUT, "found" = IC_PINTYPE_PULSE_OUT, "not found" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - - -/obj/item/integrated_circuit/text/findstring/do_work() - var/position = findtext(get_pin_data(IC_INPUT, 1),get_pin_data(IC_INPUT, 2)) - - set_pin_data(IC_OUTPUT, 1, position) - push_data() - - activate_pin(2) - if(position) - activate_pin(3) - else - activate_pin(4) - -/obj/item/integrated_circuit/text/stringlength - name = "get length" - desc = "This circuit will return the number of characters in a string." - complexity = 1 - inputs = list( - "string" = IC_PINTYPE_STRING - ) - outputs = list( - "length" = IC_PINTYPE_NUMBER - ) - activators = list("get length" = IC_PINTYPE_PULSE_IN, "on acquisition" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/text/stringlength/do_work() - set_pin_data(IC_OUTPUT, 1, length(get_pin_data(IC_INPUT, 1))) - push_data() - - activate_pin(2) - -/obj/item/integrated_circuit/text/exploders - name = "string exploder" - desc = "This splits a single string into a list of strings." - extended_desc = "This circuit splits a given string into a list of strings based on the string and given delimiter. \ - For example, 'eat this burger' will be converted to list('eat','this','burger'). Leave the delimiter null to get a list \ - of every individual character." - icon_state = "split" - complexity = 4 - inputs = list( - "string to split" = IC_PINTYPE_STRING, - "delimiter" = IC_PINTYPE_STRING, - ) - outputs = list( - "list" = IC_PINTYPE_LIST - ) - activators = list("separate" = IC_PINTYPE_PULSE_IN, "on separated" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/text/exploders/do_work() - var/strin = get_pin_data(IC_INPUT, 1) - var/delimiter = get_pin_data(IC_INPUT, 2) - if(delimiter == null) - set_pin_data(IC_OUTPUT, 1, string2charlist(strin)) - else - set_pin_data(IC_OUTPUT, 1, splittext(strin, delimiter)) - push_data() - - activate_pin(2) - - -// - Text Replacer - // -/obj/item/integrated_circuit/text/text_replacer - name = "replace circuit" - desc = "Replaces all of one bit of text with another" - extended_desc = "Takes a string(haystack) and puts out the string while having a certain word(needle) replaced with another. Maximum 512 characters." - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - inputs = list( - "haystack" = IC_PINTYPE_STRING, - "needle" = IC_PINTYPE_STRING, - "replacement" = IC_PINTYPE_STRING - ) - activators = list( - "replace" = IC_PINTYPE_PULSE_IN, - "on replaced" = IC_PINTYPE_PULSE_OUT - ) - outputs = list( - "replaced string" = IC_PINTYPE_STRING - ) - cooldown_per_use = (10 SECONDS) - complexity = 6 - var/max_len = MAX_MESSAGE_LEN / 2 - -/obj/item/integrated_circuit/text/text_replacer/do_work() - set_pin_data(IC_OUTPUT, 1, replacetext(copytext(get_pin_data(IC_INPUT, 1), 1, max_len), copytext(get_pin_data(IC_INPUT, 2), 1, max_len), copytext(get_pin_data(IC_INPUT, 3), 1, max_len))) - push_data() - activate_pin(2) diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/time.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/time.dm deleted file mode 100644 index d3443ab74c8..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/time.dm +++ /dev/null @@ -1,187 +0,0 @@ -/obj/item/integrated_circuit/time - name = "time circuit" - desc = "Now you can build your own clock!" - complexity = 1 - inputs = list() - outputs = list() - category_text = "Time" - -/obj/item/integrated_circuit/time/delay - name = "two-sec delay circuit" - desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ - This circuit is set to send a pulse after a delay of two seconds." - icon_state = "delay-20" - var/delay = 2 SECONDS - activators = list("incoming"= IC_PINTYPE_PULSE_IN,"outgoing" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 2 - -/obj/item/integrated_circuit/time/delay/do_work() - addtimer(CALLBACK(src, .proc/activate_pin, 2), delay) - -/obj/item/integrated_circuit/time/delay/five_sec - name = "five-sec delay circuit" - desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ - This circuit is set to send a pulse after a delay of five seconds." - icon_state = "delay-50" - delay = 5 SECONDS - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/time/delay/one_sec - name = "one-sec delay circuit" - desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ - This circuit is set to send a pulse after a delay of one second." - icon_state = "delay-10" - delay = 1 SECONDS - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/time/delay/half_sec - name = "half-sec delay circuit" - desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ - This circuit is set to send a pulse after a delay of half a second." - icon_state = "delay-5" - delay = 0.5 SECONDS - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/time/delay/tenth_sec - name = "tenth-sec delay circuit" - desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ - This circuit is set to send a pulse after a delay of 1/10th of a second." - icon_state = "delay-1" - delay = 0.1 SECONDS - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/time/delay/custom - name = "custom delay circuit" - desc = "This sends a pulse signal out after a delay defined in tenths of a second, critical for ensuring proper control \ - flow in a complex machine. This circuit's delay can be customized, between 1/10th of a second to one hour. \ - The delay is updated upon receiving a pulse." - extended_desc = "The delay is defined in tenths of a second. For instance, 4 will be a delay of 0.4 seconds, or 15 for 1.5 seconds." - icon_state = "delay" - inputs = list("delay time" = IC_PINTYPE_NUMBER) - spawn_flags = IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/time/delay/custom/on_data_written() - ..() - var/delay_input = get_pin_data(IC_INPUT, 1) - if(!isnum_safe(delay_input)) - return - if(delay_input < 1 || delay_input > 1 HOURS) // Value had to be clamped, update the pin. Check's here to avoid infinitely setting the pin. - set_pin_data(IC_INPUT, 1, clamp(delay_input ,1 ,1 HOURS)) - return - delay = delay_input - -/obj/item/integrated_circuit/time/ticker - name = "ticker circuit" - desc = "This circuit sends an automatic pulse every four seconds." - icon_state = "tick-m" - complexity = 4 - var/delay = 4 SECONDS - var/next_fire = 0 - var/is_running = FALSE - inputs = list("enable ticking" = IC_PINTYPE_BOOLEAN) - activators = list("outgoing pulse" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 4 - -/obj/item/integrated_circuit/time/ticker/Destroy() - STOP_PROCESSING(SSfastprocess, src) - return ..() - -/obj/item/integrated_circuit/time/ticker/on_data_written() - var/do_tick = get_pin_data(IC_INPUT, 1) - if(do_tick && !is_running) - is_running = TRUE - START_PROCESSING(SSfastprocess, src) - else if(!do_tick && is_running) - is_running = FALSE - STOP_PROCESSING(SSfastprocess, src) - -/obj/item/integrated_circuit/time/ticker/process() - if(world.time > next_fire) - next_fire = world.time + delay - activate_pin(1) - - -/obj/item/integrated_circuit/time/ticker/custom - name = "custom ticker" - desc = "This advanced circuit sends an automatic pulse every given interval, defined in tenths of a second." - extended_desc ="This advanced circuit sends an automatic pulse every given interval, defined in tenths of a second. \ - For example, setting the time pin to 4 will send a pulse every 0.4 seconds, or 15 for every 1.5 seconds." - icon_state = "tick-f" - complexity = 8 - delay = 2 SECONDS - inputs = list("enable ticking" = IC_PINTYPE_BOOLEAN,"delay time" = IC_PINTYPE_NUMBER) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 8 - -/obj/item/integrated_circuit/time/ticker/custom/on_data_written() - ..() - var/delay_input = get_pin_data(IC_INPUT, 2) - if(!isnum_safe(delay_input)) - return - if(delay_input < 1 || delay_input > 1 HOURS) - set_pin_data(IC_INPUT, 2, clamp(delay_input ,1 ,1 HOURS)) - return - delay = delay_input - -/obj/item/integrated_circuit/time/ticker/fast - name = "fast ticker" - desc = "This advanced circuit sends an automatic pulse every two seconds." - icon_state = "tick-f" - complexity = 6 - delay = 2 SECONDS - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 8 - -/obj/item/integrated_circuit/time/ticker/slow - name = "slow ticker" - desc = "This simple circuit sends an automatic pulse every six seconds." - icon_state = "tick-s" - complexity = 2 - delay = 6 SECONDS - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 2 - -/obj/item/integrated_circuit/time/clock - name = "integrated clock (NT Common Time)" - desc = "Tells you what the time is, in Nanotrasen Common Time." //round time - icon_state = "clock" - inputs = list() - outputs = list( - "time" = IC_PINTYPE_STRING, - "hours" = IC_PINTYPE_NUMBER, - "minutes" = IC_PINTYPE_NUMBER, - "seconds" = IC_PINTYPE_NUMBER, - "absolute decisecond elapsed time" = IC_PINTYPE_NUMBER - ) - activators = list("get time" = IC_PINTYPE_PULSE_IN, "on time got" = IC_PINTYPE_PULSE_OUT) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 2 - -/obj/item/integrated_circuit/time/clock/proc/get_time() - return world.time - -/obj/item/integrated_circuit/time/clock/do_work() - var/current_time = get_time() - set_pin_data(IC_OUTPUT, 1, time2text(current_time, "hh:mm:ss") ) - set_pin_data(IC_OUTPUT, 2, text2num(time2text(current_time, "hh") ) ) - set_pin_data(IC_OUTPUT, 3, text2num(time2text(current_time, "mm") ) ) - set_pin_data(IC_OUTPUT, 4, text2num(time2text(current_time, "ss") ) ) - set_pin_data(IC_OUTPUT, 5, current_time) - push_data() - activate_pin(2) - -/obj/item/integrated_circuit/time/clock/station - name = "integrated clock (Station Time)" - desc = "Tells you what the time is, in terms and adjusted for your local station or planet" - -/obj/item/integrated_circuit/time/clock/station/get_time() - return station_time() - -/obj/item/integrated_circuit/time/clock/bluespace - name = "integrated clock (Bluespace Absolute Time)" - desc = "Tells you what the time is, in Bluespace Absolute Time, unaffected by local time dilation or other phenomenon." - -/obj/item/integrated_circuit/time/clock/bluespace/get_time() - return REALTIMEOFDAY diff --git a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/trig.dm b/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/trig.dm deleted file mode 100644 index 75580911c31..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/integrated_electronics/subtypes/trig.dm +++ /dev/null @@ -1,138 +0,0 @@ -//These circuits do not-so-simple math. -/obj/item/integrated_circuit/trig - complexity = 1 - inputs = list( - "A" = IC_PINTYPE_NUMBER, - "B" = IC_PINTYPE_NUMBER, - "C" = IC_PINTYPE_NUMBER, - "D" = IC_PINTYPE_NUMBER, - "E" = IC_PINTYPE_NUMBER, - "F" = IC_PINTYPE_NUMBER, - "G" = IC_PINTYPE_NUMBER, - "H" = IC_PINTYPE_NUMBER - ) - outputs = list("result" = IC_PINTYPE_NUMBER) - activators = list("compute" = IC_PINTYPE_PULSE_IN, "on computed" = IC_PINTYPE_PULSE_OUT) - category_text = "Trig" - extended_desc = "Input and output are in degrees." - power_draw_per_use = 1 // Still cheap math. - -// Sine // - -/obj/item/integrated_circuit/trig/sine - name = "sin circuit" - desc = "Only evil if you're allergic to math. Takes a degree and outputs the sine of said degree." - icon_state = "sine" - inputs = list("A" = IC_PINTYPE_NUMBER) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/trig/sine/do_work() - pull_data() - var/result = null - var/A = get_pin_data(IC_INPUT, 1) - if(!isnull(A)) - result = sin(A) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -// Cosine // - -/obj/item/integrated_circuit/trig/cosine - name = "cos circuit" - desc = "Takes a degree and outputs the cosine of said degree." - icon_state = "cosine" - inputs = list("A" = IC_PINTYPE_NUMBER) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/trig/cosine/do_work() - pull_data() - var/result = null - var/A = get_pin_data(IC_INPUT, 1) - if(!isnull(A)) - result = cos(A) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -// Tangent // - -/obj/item/integrated_circuit/trig/tangent - name = "tan circuit" - desc = "Takes a degree and outputs the tangent of said degree." - icon_state = "tangent" - inputs = list("A" = IC_PINTYPE_NUMBER) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/trig/tangent/do_work() - pull_data() - var/result = null - var/A = get_pin_data(IC_INPUT, 1) - if(!isnull(A)) - result = tan(A) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -// Cosecant // - -/obj/item/integrated_circuit/trig/cosecant - name = "cosecant (CSC) circuit" - desc = "Takes a degree and outputs the cosecant of said degree." - icon_state = "cosecant" - inputs = list("A" = IC_PINTYPE_NUMBER) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/trig/cosecant/do_work() - pull_data() - var/result = null - var/A = get_pin_data(IC_INPUT, 1) - if(!isnull(A)) - result = CSC(A) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -// Secant // - -/obj/item/integrated_circuit/trig/secant - name = "secant (SEC) circuit" - desc = "Takes a degree and outputs the secant of said degree." - icon_state = "secant" - inputs = list("A" = IC_PINTYPE_NUMBER) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/trig/secant/do_work() - pull_data() - var/result = null - var/A = get_pin_data(IC_INPUT, 1) - if(!isnull(A)) - result = SEC(A) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) - -// Cotangent // - -/obj/item/integrated_circuit/trig/cotangent - name = "cotangent (COT) circuit" - desc = "Takes a degree and outputs the cotangent of said degree." - icon_state = "cotangent" - inputs = list("A" = IC_PINTYPE_NUMBER) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - -/obj/item/integrated_circuit/trig/cotangent/do_work() - pull_data() - var/result = null - var/A = get_pin_data(IC_INPUT, 1) - if(!isnull(A)) - result = COT(A) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) diff --git a/modular_skyrat/modules/integrated_circuits/code/research/designs/integrated_circuit_designs.dm b/modular_skyrat/modules/integrated_circuits/code/research/designs/integrated_circuit_designs.dm deleted file mode 100644 index dfcdb81704b..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/research/designs/integrated_circuit_designs.dm +++ /dev/null @@ -1,87 +0,0 @@ -/datum/design/integrated_circuit_printer - name = "Integrated Circuit Printer" - desc = "The printer for various integrated circuits and electronics." - id = "integrated_circuit_printer" - build_type = PROTOLATHE | AWAY_LATHE - materials = list (/datum/material/iron = 13500, /datum/material/glass = 4500) - construction_time = 100 - build_path = /obj/item/integrated_circuit_printer - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/integrated_circuit_uniform - name = "Integrated Circuit Jumpsuit" - desc = "A uniform that contains a built in electronic assembly." - id = "integrated_circuit_uniform" - build_type = PROTOLATHE | AWAY_LATHE - materials = list (/datum/material/iron = 10000, /datum/material/glass = 4000) - construction_time = 100 - build_path = /obj/item/clothing/under/circuitry - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/integrated_circuit_suit - name = "Integrated Circuit Chestpiece" - desc = "A chestpiece that contains a built in electronic assembly." - id = "integrated_circuit_suit" - build_type = PROTOLATHE | AWAY_LATHE - materials = list (/datum/material/iron = 12000, /datum/material/glass = 5000) - construction_time = 100 - build_path = /obj/item/clothing/suit/circuitry - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/integrated_circuit_shoes - name = "Integrated Circuit Boots" - desc = "A pair of boots that contain a built in electronic assembly." - id = "integrated_circuit_shoes" - build_type = PROTOLATHE | AWAY_LATHE - materials = list (/datum/material/iron = 4000, /datum/material/glass = 1000) - construction_time = 100 - build_path = /obj/item/clothing/shoes/circuitry - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/integrated_circuit_head - name = "Integrated Circuit Headwear" - desc = "A piece of headwear that contains a built in electronic assembly." - id = "integrated_circuit_head" - build_type = PROTOLATHE | AWAY_LATHE - materials = list (/datum/material/iron = 5000, /datum/material/glass = 1200) - construction_time = 100 - build_path = /obj/item/clothing/head/circuitry - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/integrated_circuit_gloves - name = "Integrated Circuit Gloves" - desc = "A pair of gloves that contain a built in electronic assembly." - id = "integrated_circuit_gloves" - build_type = PROTOLATHE | AWAY_LATHE - materials = list (/datum/material/iron = 3000, /datum/material/glass = 1000) - construction_time = 100 - build_path = /obj/item/clothing/gloves/circuitry - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/integrated_circuit_glasses - name = "Integrated Circuit Goggles" - desc = "Goggles that contain a built in electronic assembly." - id = "integrated_circuit_glasses" - build_type = PROTOLATHE | AWAY_LATHE - materials = list (/datum/material/iron = 2500, /datum/material/glass = 800) - construction_time = 100 - build_path = /obj/item/clothing/glasses/circuitry - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/integrated_circuit_ears - name = "Integrated Circuit Earpiece" - desc = "An earpiece that contains a built in electronic assembly. The wiring interferes with standard encryption keys." - id = "integrated_circuit_ears" - build_type = PROTOLATHE | AWAY_LATHE - materials = list (/datum/material/iron = 2500, /datum/material/glass = 800) - construction_time = 100 - build_path = /obj/item/clothing/ears/circuitry - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE diff --git a/modular_skyrat/modules/integrated_circuits/code/research/designs/integrated_circuit_nodes.dm b/modular_skyrat/modules/integrated_circuits/code/research/designs/integrated_circuit_nodes.dm deleted file mode 100644 index 19f84a3cb5a..00000000000 --- a/modular_skyrat/modules/integrated_circuits/code/research/designs/integrated_circuit_nodes.dm +++ /dev/null @@ -1,14 +0,0 @@ -/datum/techweb_node/integrated_circuitry - id = "integrated_circuitry" - starting_node = TRUE // Starting node for now, can be unlockable later - display_name = "Integrated Electronics" - description = "The technology to produce various types of integrated electronics and their respective tools." - design_ids = list("integrated_circuit_printer") - -/datum/techweb_node/integrated_circuitry_clothing - id = "integrated_circuitry_clothing" - starting_node = TRUE // Starting node for now, can be unlockable later - display_name = "Integrated Electronic Clothing" - description = "The technology to produce various types of clothing with integrated electronics." - design_ids = list("integrated_circuit_uniform", "integrated_circuit_suit", "integrated_circuit_shoes", "integrated_circuit_head", "integrated_circuit_gloves", \ - "integrated_circuit_glasses", "integrated_circuit_ears") diff --git a/modular_skyrat/modules/integrated_circuits/icons/mob/clothing/circuit_ears.dmi b/modular_skyrat/modules/integrated_circuits/icons/mob/clothing/circuit_ears.dmi deleted file mode 100644 index 376a5e340738c61802fc8dc18f7344d9c03b08da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 374 zcmV-+0g3*JP)V=-0C=2JR&a84_w-Y6@%7{?OD!tS z%+FJ>RWQ*r;NmRLOex6#a*U0*I5Sc+(=$pSoZ^zil2jm5DLJz!xiqt+s8WfGGbOXA z7^IPlGp#5wHxYCm4FJLF8|=;=3~m4b0C!15K~z|U?bb^UfFKM6P<~ZG zQ0{+P35kgdTQF>hnMc@kTEY&L`WtPmm|LU8+?7p2PRqKv<}JuGfv5Ix6`1-iU;lAH zd@ZM=b6%y7bpQZ>i8Y_ER>LW_q}m|LWr;EOdAJ+0IA0pL&qJ>ehff%s2LOPnT>{ww Uv`QRNo&W#<07*qoM6N<$g8OKbZvX%Q diff --git a/modular_skyrat/modules/integrated_circuits/icons/mob/clothing/circuit_glasses.dmi b/modular_skyrat/modules/integrated_circuits/icons/mob/clothing/circuit_glasses.dmi deleted file mode 100644 index a33db9b1c4833d9c4b5083b7b1060c9537cd2cdb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 405 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeE3?v1%WpM*3l>na**8>L*XlZH5$jBHO8m65w z&i(IVJkvNUE2}UsFUZf&+1VMWz{Izx2B@B~B*-tA!Qt7BG$5z4DkP%BCAB!YD6^m> zGe3`kp<+&OSV2+g_b_bQ+xW_h|ehD5X`CrFqz1O`l)Aml1C&$D0?W8K#?N+)c} zjMI&aRqT$h307pHIMUI}z1gQu&X%Q~loCIEKxl%)Uw diff --git a/modular_skyrat/modules/integrated_circuits/icons/mob/clothing/circuit_gloves.dmi b/modular_skyrat/modules/integrated_circuits/icons/mob/clothing/circuit_gloves.dmi deleted file mode 100644 index 7ff9713cf1acd82b8c7afd893d3616fb7d72ee58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 393 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0J3?w7mbKU|el>na**8>L*gslPckBGu zVOYnIpP$cghQZg@HzXt^C@84DzCKnUc^^V$7mXi0(mC&=d6J>1r+0^iaggz4 zV=sj{k0u?N6rvEUX}MWrr^)6eD}p+^ja4_VkXSOY+jy;pp}FW0vnN4e1z(F9rFj_+ zzLI`(PL2m?4Z}=N7sn8f&g29MR%KxhO-D%|FQy1lgPAN25{hm&d=tFdwK)8pCO>?^ zBCWZ_hw)H&G|MyZvI8Ooes>ranQ1wSYG^wBFizx>Sjy`#Wvc?89rNKdgOht0#p^|S zngSh68BVX92B`&GO$wiq3C7Jno3=9=> zRF50-H5>4-Ua+(~D*k3gK$yM;M{0w$%LFsI1(T9j?5J(u_x7s9F-@Hh#S64EC!S|? zyKi%%Hgz-4vCYcUC-2$(H&`c%X>pY6^s`!kIaNbPi>y`N2vC`h-vQq>Fd{qXs+)xd^Bfg0{4cC3^|NuQVzeE-q%jE zu~SVxBf|ROUV1Xmymfa!y}hRU`+1MyWcLsEo(nkX9S>js(!jW7LiV$GuX%HVnhe>_ z&o68|`|@*e&^`N>3Bg_!8I5|XEdrnNwy&Ob-{U{K#q*+`jgr59+^~4QX{*=)JCFZ6 z()L+6OnkvV`}L#cGvY-T@aP^dj{9>Xg#Cy9i~kJU7^Ha*h$Sp$yup-X!Vuli%LaE~ zgYE%0<_)YjGO#F`u&-ewyTKGG^NVXY7Ww~seecmT<-IxEj~C~1-^qRCq-7vhyZvgG z>5sUj74{Dnvfg7X;gwtame+ctz5)Ba-!XZUx7+__5^}L;%+}rYY{v?N<6$S_r}T;@ zyuV^<@rIknRb)ZUt<)1$d&PKXH$4iNqY_{5@I#oP?mg3&?<~)jm1!^Of5(o)X;|Gq ddo%wB-j35-_Q);`U;!p522WQ%mvv4FO#qHj7f}EJ diff --git a/modular_skyrat/modules/integrated_circuits/icons/mob/clothing/circuit_shoes.dmi b/modular_skyrat/modules/integrated_circuits/icons/mob/clothing/circuit_shoes.dmi deleted file mode 100644 index 2ce1a326a9d5b391dd1d94ba1ba59d8aba5e5b63..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 396 zcmV;70dxL|P)DIyg8T9UUAT96vulHa0dSBO^1J0E2;nBqStEOiXZXZCqSjLW`cr00001 zbW%=J06^y0W&i*HZhBN$bVOxyV{&P5bZKvH004NLQ&wKp9N9t>^(0059lL_t(oh3%Hh3dA4~1gDL*#=QRj zZ)03`PmZwH&;`LmjRl@EWf@xK>B2qE4G7%OK3tdZ_|@B|_`50L(T@dOepH{Wkfr)hxu q5z6W5vxH-xKH>B8zdU^nmV+BjlmjOWDWv=W0000f7gbeNYHDg`{{R3=06t1hOKp9N9t>^(009a~L_t(YiS3jzZo)tiMgOj3*WL&$r88?{p}2~LDCq1& z)Fcv?(iy_0NJ+&tk|GCy8*sub2*DqubWsZAFS&T5=b7DN2Waz`Q4wH>wdWfa(h}-1 z`JJJCp<*^rqC>DW9miaoc*a6FoIH(~7wgqK3wr351#@k)7ZzM^^l;alx$8T)h=lCb z+}3pJ?91A3af^?^{epS3UTwq~cGm8gt&b4$LCytz{KPM4)8@Kj4EUu%?JE?W^drTE zNL4x^o*^iu(3yf4M1!!3S(x{IiP(1&8wPbL-`*7AGjABYbsGd?gm#}S?6<|mhKp9N9t>^( z00G`fL_t(oh3%G6Z`&{ogzZo~kG5iUcH8{_f4YA%Eg;!x!yRCSzogx+07WzrjA(bl82|tP07*qoM6N<$f{DU8+W-In diff --git a/modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/electronic_components.dmi b/modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/electronic_components.dmi deleted file mode 100644 index 1b87735d8745b8c261ed6b6ac5112fccb67b782d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10498 zcmaKSbzIZ$_V}2aBS(h{f*{=@Fycc=2vX9`=nyGM$uSTqL1{thZb_v!Qb`eMfsrC5 zBZR?VzkTlg-TS@wkMH;Wdhe+d&vVXs;=IqZIDK6WD)O7;004kW^P#E%06>Bv{!paX zh%Gv$k6r@+*9M;(nfa+YJ#+AN^Y(M|@&o{aa?`U$eOF~^VrC8)YO`w!fOjiAX0@HR zO_(I=^4%Y?St^@6v7k$7?M_IsQaRXr4>VK?3;XfLQbTb$hh32ne7-1u_5AJc*NtVf z9ytpeqoDx@wUnbRbJaf^Nx~GA;p`8~(1!1KCaQCRo*fYIAiDlGw$P;T&P|Ss?s{VPCe=5eB>*cQhibeEVAPq4J-Pwkzr(p zn0+$u&R+y(EKfHgzc;nDPQG(5rjoz^uY1S$GCOi_sA?2hk-+G>1sW{5PxIGJPJKHG z6*Q^>2I8{!;A5qf9LY)VX~{o8uTmuYhP1~{P98rN2Pr>((|1S%r)QiU7Ex+I{;=WO zO3XDkee{^cuAqzBHO;TuAvRa3D-7*0;hh1j03pX^mEkTd=z zR{dG!!OSZQ5VRT^jAFgx_rWvo(0?;r;Ta32c}^;DZ*XU1^DCWRz}#NML{-34?Yth- z`UhjmJ$e_^UR~qP5re2Rrh>NfDs9$WTV>XbJW?p>erMCH)qT80@t1IIyH#;rirvl! z_n6cj^@WhHo=_EMnQuQ9ulZhNuj^A;ohu+*HZ=T;ZkRu4ZprrZu<;ZAP0pE#Tcxf5 z0r0Z2`G=r(OL@ZL0pHR-6TRnQiM>lAgnco+T{mcSk-0U?paHR~+mhS<=Q3a1)nc*z%q*roQq4`%i; z_*Pv6Y_D~AmgXMrl1!zg2s>s|`su%Ec$Hu^J809A+@tU(p*(9aw!@Y(C@qjStZePT zJcrwH=h9Y+?8C`n2JcyT%AUkoINxL=u1sAyxgpDFu=qt@7+*Zuk3r@pwT6!Hnb8;{ z%U+5lKb!rHVV2=K`dA>fsql8APFT5{iD_{0qH58V7uFfV+8F~Ex*j~4#t+!}stR#5 zWU;>;HX;9|mGphfiNv28*vP|oOl;evuRA(^C}O{Nx<0nmmx@14L_-w{SBo(WDHNub z0>j`C@_I?;{$RC%tT-yO1d?p^@A8F)DW<7$zxbpX9UpDq;DUXm|D-R@TYsp3_TidV zqKv6}k=$Ni(R0HL$cMM1568dylY2&Q8B*mpbTV)-6~Vfrwo-rHm-rQ#e{)?W%eC~}^7{*$rPf}x_(la$NaEXPkw};OuS+R*LynG49gfa++^$4Z3aiVj z<8^fa0N@RMZ6h@l3Z<^DzS#yKi~s;y0DvxPAHCEJIP!fj#e%S>n%!~g zrQ=Xqiu4eb>RV^tG%{X(=DdAevoQJBUz3ZU@*KZt*c$5vhMgE2o6hXfMWNwhER@%g ze`krEZElRjl6lWwXU$>C&}gMtMJ#le97%)Q9MpVEdlS|w>86pQmr z-RC=KdgxeeTdtLl*U8qgfxy*i+Wz&Xksol?z|4)vPZU;x5Itlv;4#DZBnZTu>6zF; z*0tgF8UTno(-g|y@57+s!|DKLwUl}_8JubuF({s)h%0@SC)n*nLz*Zvn+uPW`6?Q@ z;!le^8oVN>xe$2y<-JJChQk>^8_w?4CvKYsFb~$w=fnN^nY`-y18>e&txa`Eri2Yg zbTB@oWmI)T)O3q2ZD*Qd`p{{SSxDnmn{Jd3EyBSz+*_Xk{KmW9PcSlveT^Q`A)jH( z$6w;ZG4O~CdOK53AWM4)vVx9~RTH2F_J!L}Bw`

esGa%gN}5hKcn*Dx^+t34hMU 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 NXsYR|))GH6{vTeNN9F(k diff --git a/modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/electronic_misc.dmi b/modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/electronic_misc.dmi deleted file mode 100644 index e2607ab869ce9e91ee52f7fffbb83a63257aabe9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2511 zcmZWr2UOGN7XO1HJf>Bd3b9lXP-JgOz`{eUm8GBrV;Hg_G(m=h1Vm6HOF)?+$WpLu zkwjLIWy=T%8deDclE@Gt!4R@ue0`@qr|+Ko-Sdq*zWbfuz302{a?w#vT1^@N06C{~ z_HF!`$fL!K&95>?f6=a1QsnqT1xrE_<~la)<*jX!E96a5`#9p( z=1v7}&w53A|4-F8rRw01zI(;GpN)hpygE_c=@d{i`Q2Scf=6FT_ku%LKZZj)KN_ty zeYKl>tk&U)m3rqrm`UUr5@^KeT>nJHZ`8wEsmHC|mW;aPgOS%DMp;64F6?uuo)=}H z+GLbfm5yjKyIkT=)QR-TEOw19SWtapcfw~HKQY(Wmei;5@KQ{5BH~0ga7~cs$;~z0>BU;@+_j|eR4x03$ZA-i|&B!@}$U#l)RI@-KE&+b^I7|#^Qj(Si^^R z{;y+8!vf9Ttn-DGV#(~w2Oo|8{4hXUhYhY=kusS|JbND;QPFE4+hZ`)?0EWz*G;@O zFvrNU`K&zWkSy3KzP=NK`!_D zO$MG^zLlHJP~pU%8a00;yyo$JVUpKVhbwmj7n$_lVuyZg!uTND)nrfgNMFwCi7%7h zTWpWc)~)gvypEQw#U@+V6!)4k6;GdG>tC3bQTip>OCDYvm{%~V1yos`d+KIziu?H% z=|tK2-4jDzeTiWt@aqJj>2yoEhEK>aM#a#u?Y zrCoM7Hmq0}VDKt2Emd6S)#LJl!P+OHKt`juuf$0!%=w;{JRw$hP|rBcP5ROcrlsjZ zNaZ1@HTYjhI~|*nUhxd?H8lv{O`j?=Q6%F?+|LNfZjWf+g~M{>9}px1=yjj7)We~83*GuH;n;o$|`LfvB?|N#8m!EcUbKB{HkptK&I&DH1mzLHMtJo5Re#zLGvKAJPHG8_%IE7V0 zj8RLe9u1Elgdc$*nZ&q7Q*+i*nhAdkQ-oc-X4~uTQhH;c6_yn6Ih`s?)^jmKt*3{5 zi9_*0GO;EaBvTZ>G<<;I>2h_IYL9*>Z0-ZSHp6N!Bz0u(1%}RG_W`#A7YjEI*nnv% z?VADM%znfo0DK%Tc~tD9BFg$tUY>e=;w&qfAvvZ{2C|3T!|dlD-L+#S*D0U7{4;ge zn9@DGooo`g$}xNhVHzGGcg~_C3@8dne*Qx!`4>8Ro%8e%$MB#z;qVX$bcANpeSCHr zHjv57Pnk8#=%N!q9K$Ya(K2&BARu~Tr?%Kx6wC0hx0YqLr8wXDzvv9fYx-F=x&Vc6 zpXg;WSGEYvq;zr4;5=QI(q!wgnUsgk5@*yhXJ;V4O83i=zb^P{5Mr?6vjVH{5K8H- zjGYJ}h`a&vS7Irj9qoEHFupU$ZA`eZkzD0P9xD`?D%1-V=Gh83V!;gLO(HD0>eJq* zif@^Lk0T%SL!;0rK7O9=ID1MB(LsQ0Q|*#wgaaS7`@}WU9Sx~8yLool$K_qS@oOP6 ztwHS$1Feaxb?tP}aq#*R(0?1u|A4fi1a7>)#So0td)a2LZLD?N28rMlp8|f>)y$So zh{6VLDDH}m=T5T5`1lS_Mmg6yzJ7Ep)9?XL)fmOy*vrja|BVfM(jt9|9u~?k)-6QI z?@F%sVf&;@_ysMPky&mTm2hJCd14Ix0*^m>1`ZS00y` zUZGxyDJb7TC(X&n=}ms9GY8uw(~{vSjbvBV)GJPX36(b;ssSRc{Z;3qiMP8~vs!uyhIx+r3d2n%H8a*? zh&bX$nB=c7hU)JV%UYJz0%}diTNZyfEoJ2&zVH*T@Lrp8!<~2uZzIh09=$C;P4M-^ zx{s)&_ZiB7fP+{Z+6HPrL&xld$ z8{g491s;~QFE!H$w=)t5DeS_?HbQaq51 z#nr_G5N*N88>+@J`hbXvcd zCw8hWId>T*Q(q9TN6Zd-DVkLdur0kydV#L43J=}M#(7W!n6XQ{`pRII?i62x_9CK_3^@@ZU9t3f)Pts-cW=?}p>M zJL3F3XSuSUhjZH7JHHWY4Htja){$eb^V{IeH+nD|nk4@fq1m=@S~sc!dvHq8ksc(} zYC4%QGA8)h-}4B*oL_Xwf$~}4<4A`Kt2`_T6b>59jt;c4$|3lL@(a@2wZ@uh-b)Pg z{GgErGOgRIOKahwIx!XnkyQhSMog^hT)dI)eIDEh^^ zNmy7owE?fpKB~R_VDIJR@zKfM4GYUJ=SL>ot56s#as>IvAkf>lva!GOprL-E_wsSh zqq;0}tsIU$^d&uj!{Wt#{z<5C&^3ycP}?u(Ht6Q!Uc~?IF7K$w``^yr#J_7d{Q8%? zSNpItIm6_}R~3ylzBx2Dk=-Bz^x?Z*ofnTlPG9-aCd zFSEnC;un4KMp!8T@tpBDE%A$=Si7uW8z0$yEMI)|RmqViPiT!`e?Fu8fdlEn9V_hS z6_z(*jx-YhT}JpkLipuSZbC&`?A;T|3>wv3B7`xjcOYACoBH zSrI>8j%FUK&uTLKi{(6UDm4R-x z*FG;P!hE(s=*z@)4qoE4%HSP?Liaw_xT>7!`!>`10?e$8`(ranS(g;5kpQ^Le$cA$u&oScs>*4j+2GPMu47pX=1a#w{&iX)v{N`x@EDDov%*@2ZBr7W`Cnxvn)vKAAncdyphK7cShzQX^talhJW3`9L z@K9o5GO;jw4+Rz-9UTb?iG+m2J1i`DdHLAb*s7|k-rnBa+}zsQ+AmmGTP;|a2ibS; zN=r)v0s=&_urjf*1|QTs6rxxdjOg0hT4Q4)FE6j8q$C&&Ha0f)@$nHC7l%L~oSd9G zIyxE}8ls}2N=ix$3=9GS0z5oC-rn9&D72!Y0);|-`}S>WY6=dA|NHkZH8u4?aa>&7 z(a{kjBO?(JQTyL^1qB5V2$Y_lPWy!U&6_tbUc3+$eK7l>5t&$`nGYS}=;)YeJUj9r ziT&}Vff1I{*6c%L6pXahlwbMf90tcg7A3w4&MK(<pjO?@(F=sK+FR!Cd{Zfd>kKJxq0m#eeUo13hGFLmrvmWZ^e=l5SD$Yl?`&n;8Q+ zQDc98DMJ|GR=Aua;s>gbfP+-T>o;rm7f(k1Q9to4zxJAXtt~8Og2D3G0MO9!K&Kxr z%{^wUOFbkz<1Y$-*k}3*Ap)IjB8eY_^J4$#vk;zW{bwKVsx2u}630MI!g}pc)$=$_ z_3P5WR+7zqZo7W{Yye8RG+}=8F5P#8ATZsVw0O6XE%-&oL3%~{BDSwJt643;L*FepnvjcEm&@3aUvku=}jG( zPMIKp_pglO`mPEsdfM+K38{!X&H3*W<_S!2?7L=u!ni~GDOedv4%#vgGu0fmTyuA_ z*$is!tKi$QUOoQT@vp6Gw4yaNvRa7HXM#MY=P~(Kx&m}__4=Qtu%fIj2k~gXHgm$N zW+8Ewj|ZVe^*lAn@C2)0k;1|YdaLk&!b z!%sB1!EKEX+J)Lox)p+pLvr!YJzo?8)0PGtmDGvDnOgR2o+ShpvPE(=PxSN7>#;}C zRgN7K{d>0!$ZuxSBVR=F)zNCfdI+GRq#IHuxYA_!lc@C>2bBFj@lrHUh@C0NiD{5` zCOrL4&hO)6YoV`Mm4&+5;ClL;8a4p&9bOBvB)aNi^;~E9R<2kEeH~l76~*vQdz0<} zH(2>hUd0xy{xK|{E<39k>*k&o~z7)w(GyP}WH+7>V#!gbP>ef{tPuvlAjK~O zV9vL}L*ephC@Z6ZfFSMo>hPoZ$^6;y)s!hLfz6}m0#QaLxDEP8WK()~<@9HsI{DuA z3jN{os?pOpBjklq3X-eEZm+k|`UOD6AdLVR|G91r&=;KmR6O5lzy5#|R`07P{HTD& z^@knb*L3A`0Db^6yai~OxZY~bL%>ut(@?+)ddC63JMU-P6;{jLHLHWtKhn#s_lVTd$lLeDKM{R5m?82%4^6+| zz@8D>s80Nqp$sNbIJTMzze{!~U!veFZJFZT*W_>wdh=PRh2@hq&C=2fgN-_7v-*l@ z*`$HUzCCB^M;mj^wW+!&L^VHS1q8vuAO&V`+^CHs;j^QFF*3Ftu=Se22xiUGWejW$ zS%-99yZWX7eAmjRNBh8ypb=7-Iav{mCht;mj3CKQs?FteAXD`(!ATM&Q>CRbZZ3FX zxxe1#BZo^OC_o6EPrbO#sv>}joPJY~m8CB}M*krl_&}eA{v8JyN2&Y<_id z=}T*Ao0scN7mCrDe^#If&xs<8sWB3X2nZrS}mBzi6X_9^SeJ z`|7vheh1aNw@zSXCrXzR1b;>7f3}lS<96-<`sVU`tbS97^F#LV(h>A&Hn`N(u*qJp zy%`G~_-|otax44zbF8~ulH_@V=}WW~emeCJzrVsp*(_a-o5U|e>Krd< zif%uS6?eln_jWDzrz|u~wj+V2e?W591Q#OlsT{M+ka9&FAX~=)mf;pA#32)E3ATj=76LL~6q8stN0zz!&(fV#Hod(g3( zmBg^k=9at2WsuxH)iayFe&_m=m&5*|HuZgKSqXzuyf^OqXJqHjK{$!F`KwfZJi*n4 zka{+w{2T+M&1P$?piOo9Uh-JX=RHXY^txffs34o%Pl7|XpL`GhX)1&E);A@g;NSB@ zoJM#>emu-QRO1c`!8WtP6<>k}&KgPig2W4JUY-OZOS46W-tT_vN{z_wwgDEES*q`Q z_h@9}IX+`9H#9#sgSktK=*{cc{-BIeWQ=BX{UHpCC|ev_YkW&6Pt5~bzDP)Ml2p~+ z@+hOOMNNcd5Gp+SwPpx>&4mKP^0yqgP=7?If;Jw=UV828R&4i`5OAUZi9{C#>DqDh%3apLCEdv-Nbf_!FKk1|Nog$HCpP zxCkCN#M4iACK=uTXRDUq)g#mEL-g!PRfH>n)sX@7#B*YY?5Xy<{TV^L&S(z@$k)YL zI{eF?zf*JcM@g?I!SJY*^Dn2 zHqENt*2g*#Sf*1g$)wP#Wgi$k8{f+@`z&q%6+qCV5QVZTV_u;z;%w0qV5Xi5Dx>IN zOED#d=b`1D2reg&1>u=vfGclBcEWA3N{*a~=a=bR@G^!-vArxSO05A|X!GQVX&O+p zeq1%Ul7{9hxXhhg5BF7V*s%12*gqLee1nv6-DKx&6EW9fuXQcD$w)LkX(>~}qKxzdoS=Z&3Yw=B!=Z^$WI>{5|1D#uMR92wAJ&Ef?jVIS_` zu_7>_+ju`8wF2CG&&iXMi zkZKvf{G}ruIO8Br*|B4Y)L^Hb1(4|9c%d2v>aM-d_uI$@ z&mGY@iW5O3jwvS{M78~m+;%+4aianE57cd*GeD)y2BO$w}q(mIpNeUO*kswCm_g^e4$+ z0Z+ePbNBnpo75xbvK3GtWa%iEQNG)~bv@W;pS=+Zh*BO_-*rG_#;I5v-YxG1$eRr) z@+GAAj(EN8U5(JiL>k)Q^)#ryX$M(Ck;{pc~3!Npb<%z zrH+jc_mv-%7Ss)oZy7YHEPY2Cl%H@jVPNk5BrhGFK{Y3jUD@vERk_A1q6bP2UWEh~ z7fbO3pPuRe#cctOu&Lz65G?<;_?%l%4Sa}0wD^@WN&dJhEKw-Qj<9ZUfw~tv9zMy( z`a8e%4P3V4s~>D3iJiC1cSHkPO|l}HN5c(|tJK46uGwBTnV++= zjt4PE0T)_SnSy}GP~__WXYci}38TOlf6_6bjG-8m{N?7aCjipl>0dMKSM9cL)$-fa zBLv>dl1PaJU0N^2Y#NXhc0CuOgtXzl@>wM|K+Ep=>^ACp9HdQ}1;3u^@LuqF-`ZQ? zV=6}tX(MiM{tuiKbJ`e*m?wYa}1E>~-wvV8UPi%4iZ{B0EbmFKJ#!sGTSfA}6ww{V+Eb;5hf z=BwI&Q}d+;j5{tt%@Un6#?7o%6Q&Ua$YH!6-so8J=+0fMFVn}JLRc^>wGCPK-{Rbm#io0aG8hAKDA zm7dQ(Rz!UgAB4AA%Ioc|OF*!LAMMc4+Jjj31mqPJ4Xtrxu8o5qr_5k1fSVY!JBBU= zv#<{Nu;IFs3%2NR*Mkln1}vc_8b+sc*z};1?+q8+;w;0#`iyyWVa5$6z@5D%X(#Vc z*k2E2bM;+-(ZLRY3LTUr7Dn380Og9qmDWtM#mC|I)@JabD|}w0?3dqx zhJGiQJ=K~qK5_0_)6mbYpRd9dyXZKv?j*y44$=YEZkpL=$F{YN%cD~K2qo5%=|H?= z;e1fUK>)1L<#D?hl66y`#(Jet#{Km*K(!9@)V8(4W~#jR zJ5^;_Gb2+jI67hc2FvX8z-RD#Cvi(}KzNq|NtD*p*^)Naj7bM-xc-w1|JjDqOKj?F z1tu3EeW>I9BgKr*qwmEUJ>4XJM+8iu_q;=^mjhrXz*5wP2q0Y$K8o+IihSV@d)yhx zRBH95jm%ZJnvqhe)YO0xT-NTbMAcnvTDw4buoEXCwGfG@bi#cr%s)n$^@{1}&F?kC z?4w6RHJf2%{N5#Gu*oHv&{*4rG%!%^X}wI5JH6*X;MlvCNOg}1?bBbc8ge<%yY1{# z#*eethS&GFm%3t`F8p&{HDRJ;;#X0*W(M)$l35;&uZxp>kg1~04otaJ9|C2K(mN5a z&QwlDraK)iS7?DZ270nU2ev^r@atBpu+o!-U-|f8@A5@H<)PtY19>Au+EF>-38siG zRP{?oU(Ft_Yy*Z#A+X6H_o`kfv*^^WGGoYhx1Hm#Q7xb5~XW zGC~`F^G}ac%W^t6HKx9FaqbF3Bc*l*Lpsu{xy!%FTAl3Be?C18i2!eL&u;by?9}uo zGA@egVEQsR~{ODYxy<&+*`Rkqe~Uejc}F zqQfqj5s$;8uK(okATiG2xi$?|4*`)MD->^BY^?rM0H`ua1Mc61b1m%HKVDisWVTXY z*mpa$>F7N2nK(Fb_$|aj=0SaO=Nl;Wis6BzMONd zZTW!^l*E_l=_yUw;Ly4rwi8Tmw$=F+knM4yKZ|C9=1NRnDz%eNUjgM;G??@5_&=xN z+U*#LM%hWpNa#^=BVWFH-5oZhZQB_Tdm@AnH}Oa|Kx#W&B~#KcRTyu@e(U^~EAeqE z;2Q^Rx?1{><WdVJbP81@IqE3&dri(+)Ox$>oQ%c%c z$T2G=st8%a`8?K8?(_wk2^1+~Liq+%#~o;bXA(fWgVY<~hu$1=e(}K1RoJhY23zE)18Gm!=+KwtzBNGl??wF!fgZZT=Ud0F zWh)%GfDejr|C=o=s5h37I(G%7al<-1%ph%ABTr*~bZNleRX91`COXNMt^a3nm#**} zes;UjI>7)^>4Wck2D>LrmFJ$-wU_$?d(%^<=PJ0kPJTPaB2sTY4Na+%0pL@=x4lbg zhC%|f1IFTQvD8*H+`8ZI-^gWT8aK#lzYqBK-wifiK2>9wUuJ7*`!WU2lSh9O`{a>; zh+0Zl*%Fzg?K|VF=|*3M!88&!ss%^G4>{L^r?8Y`%cFREQqUvrr^IdoHV@-55e*D1 zv2ShtR4Z!z{!nD4eCl6ZFj~*Qwp~-+O@(-~u*jj_gKA#fe*dv__K(M7L~&V)_m6aG zo!1O^J>QiHvV44h$yd@}%cuTDSWLQNIoB6FRC`jX*^sGxDb73o?K?m0t+HAjd|7}{I{@l{EStzb(_Pky#I}!e< zvhrtG^miCQ$iRSFmB2(@kA$r$QIXW|!FB1+vpwc`>2J5;P#C@z;&w4qveb_58>{Zp z0{~6@m^RK_yco>>-ZxvqxtIEWF3g2+BPySqDvCr;H_Q212B#7oXFbtb7I@1_q_qxT za0uiUUc9FGj0^hs&1}nL1uh3{twqKM_ptcwC1=(K4g#2^<6n$Va*Nu7Mz^Gk6;dgp zy;Y;lqjUF0kgU@c`@Yhx^7d~^URP)P+8=8?5bY$#oG+z*GVMw?Pvo@Et)DxfVA(t3 z&VoIxe_|Cq2*(N4ck5%bXD?TNu~ITb+f1z16#A-o(6rU(Dn#|h z9T}Hyf|i`N`-CWqqgJSIb7;H;?zxcJU(kaU?yKa4Ztv_CmY^9t0_EZ6#5+XteVcW$>9wujFUcz9f!N zSHO1!19FHS*A0L9HsOekqI25WzysL1Q%<^6);yVRk2QN}(BYBDF=jNG#MEAsJK_sjHb!Gy44{TQ_=dqN+J|kshEK6V-;D*2w0pucdgN9`hd7Z> zP~&7pw8F#%rv(UyNgKNQ&(=>KC4ejmn$(18-B!>buUvb=mu_n#r6QL4OZ9A~gFX5=0axf@!VmzS1xyAw=khDV9)_4AxapaU`AGi0>$mggsNodVr8$3? zAPr^?&@FlvSn{zu4YFdBJ)d-oz30OUT9hQ|+56+BNxtX2pB72Jc$7%0tXBdBcP6V* zRQlHSgnQpbO_`t%u5YeJ4h<&H>Rf7sL#R(j8YO7GWeA|M0D}7?Xa8tr4}M6*TH{f> zc?w~pJa}DE($J$mxX$Y*6Vo6Gbn1*WrHdtFrt@OX;qCRD*qeXMLYY+fNro zwGIwP9G*8acKrY<2sFDt*a>{FQ;Q|AAaInpm?}EIrWoojiie06^UTZ9xHcBm%NEeGnymn=4k_W0K{pp_7>CQ1OLmCjOIXtQHMJ zI*?!#c@EdSlwT20@oDpeR*RYL?zi-nayu9GGc+_c>eqhyfiMHuA^ZRx{_PM_I&%XO zgfoks+<>^?yqHhikhjGi@CF+W<2{HP7MY2}F9Fqw7<`JwGIxECttPmz`P>j^I{+?a zw!+#WF%N!`7~|=ol)sDS555v?lqcx2Z(BSCTa&figF{(nL;o8eC(d7qG*XclifrHn zd$TnPY^Bi&PbU8SO_FX^0tq>k2)WB5saK`>7J7+88CDGe5s>YPTIYA(9JTxU(4&r` znCIU;QnZECtXk|j`rT(@Co_airqIi8nB9--WE|1nMu(obA_?xQiB}TBMFj}*xLQOX zqA2v}2asYH?I&_*Q)$2wbYI;5B(&2pE_8bn85~1!~$X9zJ7c zl1DEcGu>7D3%NpdS+O$%FsrSK0y2h=l?8=apgFWaOXsW{PnRy)U{~#T`_KR(70a)4 zRRfC!At^mf00NMNZ3K{BXdztnT9+>g0g$2VC6Kt~4ygyHqldq0wfm9J{!j?qwz55I z&tSlauQD-xxzfr{2vQ3br#Y;&Y~CvLty26B?2}{b5yTh}5~gApcSd&b$^*t%yE`uH zU2rCHKMu2BI2_Q2Q6FfWJN(}$*O45Vu#ZEZpvVPYo($%D|0Ipy-fbe2ku9R^Off(& zIILtCLtcA~nvzY$6uizqsqp2+#0Z<;?lJzwTq#O`74K1jk{AdkJQCtNh2iO$WqzE4 zdw-XRA5BsmYum|pjX7D*=TN9iWX9}lVfqv4tgaJLohanVy5U+cv&%K}uXIIm)DD-T z-G3^(*@cy0ytoiHLh4`lk639Tzah+!B9a{5kPEks6+dAc$X76Vgd8o3D(dzTSB3~m zm69awMi5b7~@2OM0pYf#D&8THpN1>Q$9b?z|ZcJ92$_#ad98UB|%VZVo(vLAu`{~*l& zu*@gLWaBOS*T;-T^nNpEE3(BB$m;EGUp-fZ^$6rRW4@<753?-deS7dfuQDN*54GHS zjEaE|%pY!%=O^{e5|C?xcLJEWkn8X?pPsz+sFK9|&d%!+d;`&_+snzILc1WTsCC7ttYwf7`iyT($=$nhS{(9&3967#-DdTHE4UpellZPqfF9& zYrJBvlADwYG42dDT6MhI-y2#euRBY(nAiUGI-QLmGW|7S*tMv(midaXT=BxM17XG^6+#6_;A^0p#vC34l|vnZVbI`V_fi)&NKzGD)60L0RpX)xzs{maJ$O*HiEy@LY(OzF)EM2KYS@y})cmj}=rDJuW5-{bspt@C*P?Aoh!k-4|uP4O5Z&%t-| zT&C{0f5X-Os5O)}? zy^q#~G85lC*A%y{dy6|x01Ilg_#~(lxFeGoq?~g`F=v?ns_*3B6KPu*Sn_tDHULVQ z^W#a@tX9UvH-Z5on^323Gq+Td4KEF94ioR?*Qh*YBMuvue^SW{suUZshS* zb^+{&ntO46ZF{f@`vXRx{h`SU_yX$v<^NPUuXxqFZ0H4Xecn+DgoX5+%rUP(Oz6z! z@t-*{3mKuhw1{DRsh{c_L0`Nbc||%&>p&iKGERtp4v6=-D>ahNcHdAgGCW_Jt=@|> zjN#J*H;!1FXG4_0n7J)}c<7dCvXVRp5jYILSUnb>dbCtb{85w5+I+*efTw0xPyeiE zhkFh6Y|VT@^o!HAn7fZE^{UohP|g(NZ5BS%M~4^W$x`1?+}}B5d+nrwpN7q=KWd%i zfjKX@`RarpY zyYC2&@9PWi(o5DGly%tJL*;%i1F^F5QU>x~e_-voBx?vmW4{f2td7wfUu{rMP`j^( zF9VfmGjwqm>Og=R*-^kguyVe_4{+%VNWK~Q8S^v0IwI{YZy+h&%!c*jUft@yxcGan zUq*V0Ra1O9KQ_MH7CJOKt&V+LPUhyvppK-NU7^%FR;qVpP@qBRPMWg4 zsN;hB*QTgn$yg=5F2T<1rLoY9`I1!Rw9-2r7igJHLps9q@_TOYfvI?pV_DZ_p|pu+N-RG& zqKag69ekGI1Ct&Ok(Ob4*RAmVSzky5BxCZDve6)POxL9?C4gHwcvEMRCzKaH{DKRQ zzKZJ2Ic0X*G%fI&gCKyxg?Wlx?q5jW)W!3gdJA^Hh&uwzWzqYbbUI_L_wi>No=(7e zP=W5t%BoUNmX=8WB6v?vYw_nt?WU zDK`jHPT2|N;^1Tveps2bQ8=);>W&OPuRE#v#1{w^9;JDl>RIZErVm&8ikJ?GLJVA{ z3eEV5EDo?QPwTFa3LF|zYv=Os)z{a5NIH2qsM=jW*G7xU z>*xQtwBlpp!M`3FI6-U`8M*u>`qzV_jxN}`Rt0|dPZE9n`pZfO1ISH_DukuW%m|F!|1(#b0T;P0Hl~&5*RhGnp_VD(cWuQAnNI?HtU8DP?`S^*_xRdQzKTZ)_SM}UW<>jPjs05g?_wuVFCJ9%@3*Fea1b*&&c1RJa9>pFy)(^t(KpU72pJl z$IeHw_DKu!IbPb{G6Jkj+m;E|C9}nAFa2x0oI4XHNGymY zazE9uUxb8*=Gjtca=1N^<2^ zwG0MJY2%*~V>fW?i#94#RRX;$CHQ%00KS5+$i4VvRmtFRxv-eXiR1_)rqU@t=}q{z zZY}EV%|eDkTUx+^@p&oAJhU>umVNtbwK{w)x~Qu(Z{k(Q^?5ER^5X}ufI25@FEXxBLi)28yj08`)J=E|V)HT6btgO!65fqS^H#^As_~t8D=_vUMEQ>{Y%!aheoMx6`0$^`jpde&;dJnKQ_CCe#P6S)9?T#? zq=+@%F1&Z$fxhT=L(ODtO-N+ZFJ|g&lhb4(y;^S5LA+)n_Kf#ruU>a+f(Af@xf2Te zrRi~%Xn@q1jJKGwAtW%|BWNnWG74-kub|V4{lcd97cn ziA^wm`o~_!V2;_+Lc;(`7n8%&XWXvb1J(1{8w8-~fUzSN*lyUc+9xpe0{5TnaY?H0 zOsk1-!17dz`x zt{!+^OX$eGKBJLK`(;7==AF@MBG>V_l5{V#?A`qp^iND^n(ZpQg9!a?+dyEt zfPwpm>U=L8)3;f_taf)QIif_(oTj}T?{cvpt#G!x?HtJa?3lgT*=MY|l=mRE;Z%_H zDGfx{-}ip#6DLy-h30mT3Ix&h^QO8mQ-X%kN{n){h8=y*ubJMmqVL#hT~Bo?NT}jQ z2M(FVp@YXWbHQa*@551lOMH6wTx<#zcc7> z_MukiAECgWFWel7bH2BiQKVYzz;9A4wweaQyon53S#47@Mr6%=LPEIeAHDrEfh6&Bz6X~B^eU{l(#unzKdUy~wjqSZB*ae$IEBFo z&UjT-FO3yGHv=Jx%WIRM+K|gY)A+w6UsanFZJ=R@394=@0#*F2dD*A^lnk`aml@xP z7@=`_P(c5op^CG@C*+rhojQx5p@HGu>BL0xsMtS0T%q1z^014y(clit_4F&4Eyrql z+$3l=ge0J+lyK$gzn=8xr_U7nKKLAJSf4))y?xmcF-Q=I%uG@rO%2Fu@({*6Pk4v4~TsRhWt{G*Qh;pu6&)tG2oOLa)Xo!ZD# zXwc(5dnF)K)=`oCIQmJ>OYZu z_dZO%oKb&VzoIxPFpukaBa|AP9&$4m`}^PuB5*u6>ILh%TmW@$=eLX{)3u|vz`EAR+4#U+)BB`%j78K-|59(GZM00 z4f6OpzA(})+VIun-nHli!&y~9p2dg-M8X3!Tqa|!1tq*mx$_>pmx8n2*w4Z;?!pV! zbd6dWLVb)r->MT{DvsV$5|RvVsBO3a;6DqqOdsDqzudi?!MQA90@7hGK_$tORCls#TWAimC~8?r{p_^s#v`|BzH9$XHL)5t(v3KM&5 ziNlQS*j30E7w(1O*f+JI^$EV^WhHmY(1l(X0#0${oH;^vKDBP zh)xexrxImQANJyptIX)vl|qpeUH%LbpTSQQ`9gTvLVW0N*a1<8QFJavcesRUCqLAA zS32q&Yt@?z*iReTW<_(!K4dyyQ%jv8e`=%zY)NOK=3*P%B`-}yZf4dFE*%xm=0_$w zA2D_0v#CD6`#UjKroZf*lW?&t1P^?g4!?OSl|aP+1iEENp46v8_J7x2ng$81Fzxc1kjWK-Fi>}}?FsLnA5poy zig6{hV3ud;FMA2WPWWp+8<436R*$F~p>LO5zAsO_yMOU3@9>z)b}zfwbrViEh>6Y# z@ydxKp{LFIo3d@E$&4=JG09=wfBaEl~;qi^&LHKdd2}zn4|=XdzPY zxk+5^X*cjlM2&~6gA@7t@j0#}*st@2gfN4Mp@l(IY9Ir7eIh3FLsGY2_MZ^{8nceW zfqRuy4~XVd>Y#tP`;1<#)YzKuH?lYyS+GB!em)QW_l~LH!&%lt5TfLCqm|(}kcLSiI!Zcf*u%-(O7TaAKY+PyAja{0~Sh);>4 zxL^Aw&QTkpvTdO1K?soEu`uggo6u#`@KNmdpn#q$Z!EaVaaTAt(>SS}J|&AZY+``6 zLWnBnBkAi;_VM=-fPHCtl7Ux?9fPk1b7=DFg?YUSFD2-3oJ}jOckJo#IFkHTaZklL zYOT;*_L{rQ@^JKWpvhr^({A9gcw;xft*if{^GfS(v1BDT+(oYxVUQW=60fy1hSoIn zXm%!;`wPnhA2$#mb}8l=Xz1A%vkoh59L5bB>DYw7wHJGi*&&?1T>efXc6lcv+W8Q$ z2GM40w;Hb0rL?pZf6WK`bHz&UdfGzxeCjWqKXZ9_|EwjU;M&tSl8hr7^ z(^Z|kNaQUrC_;&1u_e!guL7#;v$g1F2?r<1B_k>Tcs@D&%a!omcW$$VZl-3bW)+d$ju2$uoM!Zmc$E(Q4aJ#!FM9_kXQ>TaIWIfYUC~MQt^pdYaU=D1d znl4AN)wjErA*OE<>$&G94#Wbv2zry1(^FZf@F_+BAQ(faZ6A)j1hP@mN7%oRGl_v;8P za2stwg;Uo=|Z%n3i6^ea1_uDxdI8nf8Hr@FyGn`oI0d1 zG^E`6V&7TDE0 z9#j<#3-i&s=MF1XpcQ!zA$KE%$89Wk9z)JXx-&l`#N_2kMMw@JXmyf*mpBmqY8fXv z&a>)qW%WzqzrVr>d2QU#O?vUCig&&yUxB)WhOH&|Y)6PvS-6k%`oi~f9w1v(Ul98y zjlCPub1#8P1@mmc75vWx{`4~4zTtrX3|C|{@W_hHj!q=l-Vb>=a0n;Ep7>`;LXYpg z5_vIEVlVF}(id)s!6(>Aydr0a45V~f9`Yp2c(rU-Bg(j2U&|y{9&4~d0I>4A0AkO4 zx*1Ymp@v??j^$S3y&CJ4HBaKr@-N@fx_t`X<8ASM-0845Z1fdfJC?*+Jg|O_; zYib^M!?Q_6147L{HsgXAEOEtd?|UKjc70%S*9{>_{`4!NmAib*4d&sKNb(4*?Pf>` z>eG^1e=d6fe*Hi~ZFUmgpbZ4_MW~H5$%d0Y{l5p${zGs6_ek1Df|`E#A^hFq>!RHS zmR|pRkwGL-NjMDITiCzHEZZjoMqlcGS-o9fQ6+((Lg|P7p8op~r1Is8zi*FOUPG2e z7ej4_(hpq)9p1qBRr6)YAgHlH$LO@ja&}a$l6_EjuX~El1Ff^cTCVH&x?j5#>-e-M)1rvP7k+F|pIRgig-{NIpI`g?K!8fYOo z9JV@EL#+6)>}2;yLF(J;eCyNr~O|0^&7&;H1sLKPbzxK|Y&Ab5Ng z4YA2!p%--gX^RwghaKg?p(?tE2jfZnEjm^ z((eN>FWEl+wA05eF9QU_^G(A9kE^2PS)2w54qqMF(+Vql8P1*|!K4FY9jn?n4N`CLu0(jQ^4BCVnVjc>pukMySp7IK`X?aA_~8-hhk^4r0r^jWz2&|W zeDF*&Hi+FT7^@$_J8+-?!)vIa_sH;!JtM^(r2Pbc#9s7F@U6wWNEN-_Zxuab#*7&= hX3Ur|W5(^k{|7nO@MsNHFt-2z002ovPDHLkV1hGS8jP!NI|TA~kVPTU%QK02+<1udg2*94ss>oSB)asHo`m z^qeaDo>dxK76-d`5%8Yd)5_B`%a89V#2leL_6Wa~8huHl{4M|l08jt~0g!IibyBkh zg!DteL4cheiq$yE?BK(sJwFp;2nl#nLTU;Cne^(?zGEHE>nME5!E#CKZz{t#UQV}e zt-N^bx%5-t7wHRCD8rdoeBbD=uhzBeX<2r^vGhO}$zCQ<|sUlWuw){1PsHKBTzdVmcx(;S{n! zzxo)09rbgKuid^4MrEi3<;ekGdg;xs(BfCqb&>e7{FiYs%OcL4wVviQ|$6JPpGUNieur3BM`^>=l{d`zvo z@GVQS*6p3-rAy^6PXN%R`R?%u&ZI9~O(4G8x&HLpwnJ9Cpx#|RKj0dPE6bNhGq?dN zHPue<7^c>G{$U+7vUsGd)G5na|FC29F#Kp7ZSRf#`0bm{@72DrHI~o)3hFZVb$Of5 zyij-|Eea-)NSmn6b}n_|a*r%6olMF0ZxF>j=DL}j0~SUZ+PSK~hUnPfMO{>)us<|j zYirgf9p_j#m(3Umk}q;?H$4uwV5BZ%@G9$+{Bp!!1|=M;uZRWqqepWfjB4(>=Qjc$ zctIq}FBsV1Q5gR6IMj+DN+M5FrzNCeIwgj9+J&koa_v-lnNb%I#m|-C-C7=_t@jCH z9Z@Cofbj*0m9r}ndlX`ctCc*p)ZFBoxb-9 z4<>G4yRJM7^9fW3bHs$mIq)cDWzE`d=sSaRj+7+b;`o9saCV+PV*Y`L=Z~OOo04b7 zZ`WXlrd6L;>nkS~n*mgj)8-@jPmHUuaP6||cpcl@;gsIrjz2dok!c-p>AVL@lk>0J zhC|NGIBJy&DY2@vR?T`<%3PAVGEHY+c;s1eQ$yoDnajR6DfT$(Rr ze$LSpE0@uyv*4IJHqVl(EF|!HQ#^^Dty?1C505!n%u#MC|M*qT(&G9&#pOTMa2H{L zpVX~t-NvYuw2gOr9y0HQQCcGg7RL$=mfq9Qo5Lxc6S&24Jj8Ddf{1|b*Nl$X_h^fc zZc!`!u)EJUzb5rjs;?Z#P^s<|{8r%}N6olOoKVPWh_|tH_px-IQL#wS#*=9|t8xcr zgcb;PRBjRA__pvRT$mKPuw)r#KG*Do^P zN4LG5krh@7di|YP5bt9$bZ)W8X#u$#qZG2Ctgcm2E%8ky^=h3ecb+a5 z#0Z$~=IFSEnIYFXK9@Iv1AU=nx8sajO&SxUlnu3PE=|Q+^i9F=AJ#xup!L9tClkT) zlsZVtK+6ET!^NW;CEzEFD#$r!lgN8!M|=h#J+BScZ}hw3a`8{Cmph<+b#996=Q)(t zrSFWfvx7=mkIoTJVapIJZW&fU;L+<9+mdhN~6UQGRcZFWF%P&{gDe#FO&dehC47Y`D#P4=90>^w}y zuwB2v&tfnBSom1$2leeYS)idXn%^ z`!Cgrk`VeFNI8F9-$E>`@eZdJYBV`Yg*9GRjD|xrr0<*RE04S{O%v3kqm~m8YhKO+ zmU#Gei2pM3N@T6#+%#^x4cA60yv1_fN~v#or2XaK7}HER0Zo`oJw)vZENNE7iknx{ zb8Fg7l2cjjCJ~hG3~b}ky3Jyj$d6oR%MCKKJu*X-2a0AuwE<%nuCuC92$dj zUP+`MvL;n|fYHpR_Tr`s-*9h+&7GQ(7&8^F4f*4y$+(<}W~GiP+TwW8`21EOfA^iH z@+H0il|uI5+HYv{!pjW~lSj`VG`;jHhs2Q^WVaTzz%2Bkqme)=iiiCl7?0T0-EPg5 zK12;f>lOw5n3Eb+gGV#b_Kj_%lxE#3<)aZ{X-mt5{evkwuWw5jsIN4ZpV;P-L4v%< zijSg!>IRm6pl8yw=LVw}^9* znia~HVC+#!;G~K%>7RTI2b~@K2H!5vf}{?_c{zko;7#UwXC$I+qw(-Y(3CL{=J7!w zye2o;B8m=>9J9nRf~7E#II;JjlMZrNCF7 zb2?0ZU)iT}oS{5b?(RsQL1UMiULTZ7dp|Oj9jXNNB@$L6e&Rk$Yr;P&Nz;gD)yj9O z81+UH7~%Jz*y?=v+s`(7zF!Id-^Hw^hVnTkrbMrR{X zmpg9gya=NY6>%}Stx_LiPHR#Cr`ENj!lzJ1pIrI~X+%6y z|4lGwM3sy9a6+bAWmV+OrpWdj2-)GqP8d~I|7oANshrCV!bAVQIUNFbos!{}<=qwL Qn%@fW^$yrm;~7=(59+$-od5s; diff --git a/modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/new_assemblies.dmi b/modular_skyrat/modules/integrated_circuits/icons/obj/assemblies/new_assemblies.dmi deleted file mode 100644 index e7697cb44fbbda3b56748fba7b9cb575884735e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12639 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 diff --git a/modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_ears.dmi b/modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_ears.dmi deleted file mode 100644 index 17a92c22135f9c36277435a415e54eb436550092..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 477 zcmV<30V4j1P)P)t-sz`(!& z{{S8y9sqyw0004WQchCV=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex6#a*U0*I5Sc+(=$pS zoZ^zil2jm5DLJz!xiqt+s8WfGGbOXA7$|1Q#hF%=n41b=W2)56FG$V9rCeFT)z1a& z5&(q0DnypB`4j*E0KQ2?K~zYI?U2h7gCGn5(-%mF{GQIC4*?}X;{e2ce+?)JpM0nZ%x}FMU_KT;+-n6B{q&f;7+^jY zE(Kx^pcsfbfMOsifush=h^@fFt3MGirDu%N^E%HvlG(s{N2{-MfY(O8&mYbkcUufS TZsfp$00000NkvXXu0mjf&%wHq diff --git a/modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_glasses.dmi b/modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_glasses.dmi deleted file mode 100644 index 5d0c0b000440592fc81a615df6d483335af12421..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 514 zcmV+d0{#7oP)fFDZ*Bkpc$`yKaB_9`^iy#0_2eo`Eh^5;&r`5fFwryM z;w;ZhDainGjE%TBGg33tGfE(w;*!LYR3K9+IkPCaG_$0rQi+Q*C9|j)C}zmTnO2mT zn+joLs?^OdNX^5gTv@@@&jsuf0EE6OM3%7m6aWAL1W80eR5*>jlR;|3Fc3w*1PXL# z853w%a(aU#CumL9E>zQW=atn9B;*1DZ@VezDj`S6A_q|KQa25bQjoH0g*H$BGk*p~ zz~7zhip~;}ykf|ZEASGNxaEF|@_`pBrt@m9%ACu%p{NvBn8fEO^HVbyorNXTky-G_ zet9mLL1=0l7Gq#+x{lUul(D3ZElk&hjDUrm87qy|1H*h@Js6%J7aO9Lu1{QJ6f(q9 zwdgZm8W9*Q2JTBrLsk;%a|Bro47Q{d-gK)2b^#+3ecI?eRnM>PqfKlCZk==QiKSyV zM?<{CkCG)a?sj{>O|2z9y+5$z;(NbMe+<7rB=vtiU)9J#zra&;m;e9(07*qoM6N<$ Ef~`x^^Z)<= diff --git a/modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_gloves.dmi b/modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_gloves.dmi deleted file mode 100644 index 240cfe7000f3c31bd821a8c1b6cff82e8c91c1ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 556 zcmV+{0@MA8P)I#E-q&O098Z)8X6itK0Z@ZQzj-RKR-V+nE)I)08&y?Gt2<7i9HDb z0004WQchCV=-0C=2JR&a84_w-Y6@%7{?OD!tS z%+FJ>RWQ*r;NmRLOex6#a*U0*I5Sc+(=$pSoZ^zil2jm5DLJz!xiqt+s8WfGGbOXA z7$|1Q#hF%=n41b=W2)56FG$V9rCeFT)z1a&5&(q0DnypB`4j*E0VPR9K~zYI?Udb? zgCGoq4MLS92=D*2J3)5qwpi)eo4sf*{NbA!Aab0he^^A_VRymremD0N&bI^#U4HQ2 zdI`?^J%PgVG6DWuC&BzR0sduukx>252?zhWuFLrv?*2%9zw-zP54_{&-vamT_s%)n z0iOiStpo9q@85uCtiXj1Z+^0by8b8b8V^2nxs_;SBp6qbGak;kP)y8FfNyvbdW(xN zr!6NmCsN|PaZdCOPnoyO2u6F@?obyQ=Ou5ca#nD|TvRiS@~m3eHf92~TZzD$Wr$PO zT~hgkDNF;QD2;G@9%0)V#tTN!BeH2o2e~P1XG+A@St*QZszSy%-l#3E&Y;|`G|26Y u8lU#7?BIA>ulUa^o&N5w_@_Sg$NB;w7!!%TzB7mb0000V=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex7wuvIWN;^NFm z%}mcIfpCgT5=&AQY!#G}GmDZ-GfRppmAE)lGK-28Y!wW-IMa#}b5kK~OqII%1*v(s zlq)N^`nf2$_GA|#e@t`m3laiK zl|D^?^mMww?>Hb`gnK}KAwYM{Jt1^2z9FSj*z549wZx?*M?$8tXo;NN<#4%V(KHSI zXT18?2BcuOH{EV;x;e&Pd;oTP)7{@T#rG|(2hRdwmu$E(QW5th=UKD>KJtBrFc<)m84W_tlcQmVjo(q9 zoWymGKSq1k9%dgnDB!OslKDqZgP{@eEXPWqAWY#r$KONbG(p0jd>W)AqqXkMHa$=6 zJjb7kRDRKMI1B=ZxtyPqKkGi=+-%I{_?-N!x)7NIi@y_$5#JR6FY6F#&9V49!4Ty9 zP#q#YIj$-Ik~$<6t6BnF9TI|qAi=5>K&M1PeAds&0e=8;o7nz+w1VaU0000V=-0C=2JR&a84_w-Y6@%7{?OD!tS z%+FJ>RWQ*r;NmRLOex6#a*U0*I5Sc+(=$pSoZ^zil2jm5DLJz!xiqt+s8WfGGbOXA z7$|1Q#hF%=n41b=W2)56FG$V9rCeFT)z1a&5&(q0DnypB`4j*E0H;YrK~zYI?ULIL zgCGz@(FKWwmeYdYDGWM$AiYapu+c$G`-b-cvn}O Y-dU9h{}`pzod5s;07*qoM6N<$f}HBA@c;k- diff --git a/modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_suit.dmi b/modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_suit.dmi deleted file mode 100644 index 79b5e0e1c2abf6d5b8b0ce2997683fe993c07e66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 557 zcmV+|0@D47P)DiO1>y*CwUm~KX!#n(xm~-xc za%O&)qe2!r3UC}b>%%|;gT!K)&Jbmjpn&&tk zcL&|M#{CHqi!6&2M8wb{uA+D*JTVfu0TOV?k-!Z+LCBe`6p>Plq9Hj)J1k<3A)>-C zA@FF3xcAOg2aH9*>k6k@$y+@WOHU$dhVaH))NpYgLVgj5h1) z35E(!AhK=0*PdW>;3~WuutX8LdIAv`)QICZ*TbM%WMDAZ#1n*kcj%gOzA5IYpxQ+< vek7c5uh=!^H-i~}sgDhOo#QqB>LdLDMVJblm&ZlE00000NkvXXu0mjfM{wom diff --git a/modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_under.dmi b/modular_skyrat/modules/integrated_circuits/icons/obj/clothing/circuit_under.dmi deleted file mode 100644 index 6ffe6efb1cc3fc30db4f0221202490d903f8f64f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 490 zcmVAMeE-0A>JeY-~-D z02db*92^`fDk?=b6|evR00DGTPE!Ct=GbNc004G+R9JLGWpiV4X>fFDZ*Bkpc$`yK zaB_9`^iy#0_2eo`Eh^5;&r`5fFwryM;w;ZhDainGjE%TBGg33tGfE(w;*!LYR3K9+ zIkPCaG_$0rQi+Q*C9|j)C}zmTnO2mTn+joLs?^OdNX^5gTv@@@&jsuf0EE6OM3%7m z6aWAK)Ja4^R7i>KkwFrKAPfYJ(SVXDqW=G@3wT)3Q0{FnPL&?)(8a{2dGn?Ww3yPu z54=mc@}7*b#!#;t3f>LFa1$VoabQHO2+mv)I7;_BUQRh*a-{-eOL>4=WJU1A8zc~7 zW)dKL=GMkC5MvK(aup0?C4dd+!%t8Xyj&NVUR= z&r9&(B3L&>CPv&=RdD9E@gam|E-I|B3+*HV6~T$yRKfe}K>W)lK2^b&TYZAXIVY^2 gFS%}b^X6~)02Mq6M_RjtbpQYW07*qoM6N<$g3-gpDF6Tf diff --git a/tgstation.dme b/tgstation.dme index 02a7a6dc625..64a4d24a423 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -149,6 +149,7 @@ #include "code\__DEFINES\vehicles.dm" #include "code\__DEFINES\vv.dm" #include "code\__DEFINES\wall_dents.dm" +#include "code\__DEFINES\wiremod.dm" #include "code\__DEFINES\wires.dm" #include "code\__DEFINES\wounds.dm" #include "code\__DEFINES\dcs\flags.dm" @@ -246,7 +247,6 @@ #include "code\__HELPERS\sorts\InsertSort.dm" #include "code\__HELPERS\sorts\MergeSort.dm" #include "code\__HELPERS\sorts\TimSort.dm" -#include "code\__HELPERS\~skyrat_helpers\integrated_circuits.dm" #include "code\__HELPERS\~skyrat_helpers\is_helpers.dm" #include "code\__HELPERS\~skyrat_helpers\logging.dm" #include "code\__HELPERS\~skyrat_helpers\unsorted.dm" @@ -348,6 +348,7 @@ #include "code\controllers\subsystem\communications.dm" #include "code\controllers\subsystem\dbcore.dm" #include "code\controllers\subsystem\dcs.dm" +#include "code\controllers\subsystem\delay_component.dm" #include "code\controllers\subsystem\discord.dm" #include "code\controllers\subsystem\disease.dm" #include "code\controllers\subsystem\economy.dm" @@ -408,6 +409,7 @@ #include "code\controllers\subsystem\processing\acid.dm" #include "code\controllers\subsystem\processing\ai_controllers.dm" #include "code\controllers\subsystem\processing\ai_movement.dm" +#include "code\controllers\subsystem\processing\clock_component.dm" #include "code\controllers\subsystem\processing\fastprocess.dm" #include "code\controllers\subsystem\processing\fields.dm" #include "code\controllers\subsystem\processing\fluids.dm" @@ -580,6 +582,7 @@ #include "code\datums\components\remote_materials.dm" #include "code\datums\components\rot.dm" #include "code\datums\components\rotation.dm" +#include "code\datums\components\shell.dm" #include "code\datums\components\shielded.dm" #include "code\datums\components\shrink.dm" #include "code\datums\components\shy.dm" @@ -3222,6 +3225,7 @@ #include "code\modules\research\designs\telecomms_designs.dm" #include "code\modules\research\designs\tool_designs.dm" #include "code\modules\research\designs\weapon_designs.dm" +#include "code\modules\research\designs\wiremod_designs.dm" #include "code\modules\research\machinery\_production.dm" #include "code\modules\research\machinery\circuit_imprinter.dm" #include "code\modules\research\machinery\departmental_circuit_imprinter.dm" @@ -3571,6 +3575,42 @@ #include "code\modules\vending\toys.dm" #include "code\modules\vending\wardrobes.dm" #include "code\modules\vending\youtool.dm" +#include "code\modules\wiremod\component.dm" +#include "code\modules\wiremod\component_printer.dm" +#include "code\modules\wiremod\integrated_circuit.dm" +#include "code\modules\wiremod\marker.dm" +#include "code\modules\wiremod\port.dm" +#include "code\modules\wiremod\components\arithmetic.dm" +#include "code\modules\wiremod\components\clock.dm" +#include "code\modules\wiremod\components\comparison.dm" +#include "code\modules\wiremod\components\concat.dm" +#include "code\modules\wiremod\components\contains.dm" +#include "code\modules\wiremod\components\delay.dm" +#include "code\modules\wiremod\components\dummy.dm" +#include "code\modules\wiremod\components\hear.dm" +#include "code\modules\wiremod\components\index.dm" +#include "code\modules\wiremod\components\length.dm" +#include "code\modules\wiremod\components\light.dm" +#include "code\modules\wiremod\components\logic.dm" +#include "code\modules\wiremod\components\not.dm" +#include "code\modules\wiremod\components\radio.dm" +#include "code\modules\wiremod\components\ram.dm" +#include "code\modules\wiremod\components\random.dm" +#include "code\modules\wiremod\components\self.dm" +#include "code\modules\wiremod\components\species.dm" +#include "code\modules\wiremod\components\speech.dm" +#include "code\modules\wiremod\components\textcase.dm" +#include "code\modules\wiremod\components\tostring.dm" +#include "code\modules\wiremod\components\typecheck.dm" +#include "code\modules\wiremod\components\abstract\compare.dm" +#include "code\modules\wiremod\preset\hello_world.dm" +#include "code\modules\wiremod\preset\speech_relay.dm" +#include "code\modules\wiremod\shell\bot.dm" +#include "code\modules\wiremod\shell\compact_remote.dm" +#include "code\modules\wiremod\shell\controller.dm" +#include "code\modules\wiremod\shell\drone.dm" +#include "code\modules\wiremod\shell\server.dm" +#include "code\modules\wiremod\shell\shell_items.dm" #include "code\modules\zombie\items.dm" #include "code\modules\zombie\organs.dm" #include "interface\interface.dm" @@ -3586,7 +3626,6 @@ #include "modular_skyrat\master_files\code\_globalvars\lists\ambience.dm" #include "modular_skyrat\master_files\code\_onclick\cyborg.dm" #include "modular_skyrat\master_files\code\controllers\configuration\entries\skryat_config_entries.dm" -#include "modular_skyrat\master_files\code\controllers\processing\circuit.dm" #include "modular_skyrat\master_files\code\controllers\subsystem\statpanel.dm" #include "modular_skyrat\master_files\code\datums\ert.dm" #include "modular_skyrat\master_files\code\datums\components\fullauto.dm" @@ -4104,57 +4143,6 @@ #include "modular_skyrat\modules\implants\code\research\designs\medical_designs.dm" #include "modular_skyrat\modules\implants\code\research\techweb\medical_nodes.dm" #include "modular_skyrat\modules\inflatables\code\inflatable.dm" -#include "modular_skyrat\modules\integrated_circuits\code\game\data_huds.dm" -#include "modular_skyrat\modules\integrated_circuits\code\game\objects\items\devices\multitool.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\analyzer.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\assemblies.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\debugger.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\detailer.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\helpers.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\integrated_circuit.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\pins.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\printer.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\saved_circuits.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\wirer.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\clothing\circuit_ears.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\clothing\circuit_glasses.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\clothing\circuit_gloves.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\clothing\circuit_head.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\clothing\circuit_shoes.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\clothing\circuit_suit.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\clothing\circuit_under.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\clothing\clothing.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\special_pins\boolean_pin.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\special_pins\char_pin.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\special_pins\color_pin.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\special_pins\dir_pin.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\special_pins\index_pin.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\special_pins\list_pin.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\special_pins\number_pin.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\special_pins\ref_pin.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\special_pins\selfref_pin.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\core\special_pins\string_pin.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\passive\passive.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\passive\power.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\subtypes\access.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\subtypes\arithmetic.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\subtypes\converters.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\subtypes\data_transfer.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\subtypes\input.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\subtypes\lists.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\subtypes\logic.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\subtypes\manipulation.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\subtypes\memory.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\subtypes\mining.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\subtypes\output.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\subtypes\power.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\subtypes\reagents.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\subtypes\smart.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\subtypes\text.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\subtypes\time.dm" -#include "modular_skyrat\modules\integrated_circuits\code\integrated_electronics\subtypes\trig.dm" -#include "modular_skyrat\modules\integrated_circuits\code\research\designs\integrated_circuit_designs.dm" -#include "modular_skyrat\modules\integrated_circuits\code\research\designs\integrated_circuit_nodes.dm" #include "modular_skyrat\modules\jukebox\code\controllers\subsystem\jukeboxes.dm" #include "modular_skyrat\modules\jukebox\code\controllers\subsystem\game\machinery\dance_machine.dm" #include "modular_skyrat\modules\jungle\code\game\objects\structures\flora.dm" diff --git a/tgui/packages/tgui/components/InfinitePlane.js b/tgui/packages/tgui/components/InfinitePlane.js new file mode 100644 index 00000000000..55273137bbe --- /dev/null +++ b/tgui/packages/tgui/components/InfinitePlane.js @@ -0,0 +1,169 @@ +import { computeBoxProps } from "./Box"; +import { Stack } from "./Stack"; +import { ProgressBar } from "./ProgressBar"; +import { Button } from "./Button"; +import { Component } from 'inferno'; + +const ZOOM_MIN_VAL = 0.5; +const ZOOM_MAX_VAL = 1.5; + +const ZOOM_INCREMENT = 0.1; + +export class InfinitePlane extends Component { + constructor() { + super(); + + this.state = { + mouseDown: false, + + left: 0, + top: 0, + + lastLeft: 0, + lastTop: 0, + + zoom: 1, + }; + + this.handleMouseDown = this.handleMouseDown.bind(this); + this.handleMouseMove = this.handleMouseMove.bind(this); + this.onMouseUp = this.onMouseUp.bind(this); + + this.doOffsetMouse = this.doOffsetMouse.bind(this); + } + + componentDidMount() { + window.addEventListener("mouseup", this.onMouseUp); + + window.addEventListener("mousedown", this.doOffsetMouse); + window.addEventListener("mousemove", this.doOffsetMouse); + window.addEventListener("mouseup", this.doOffsetMouse); + } + + componentWillUnmount() { + window.removeEventListener("mouseup", this.onMouseUp); + + window.removeEventListener("mousedown", this.doOffsetMouse); + window.removeEventListener("mousemove", this.doOffsetMouse); + window.removeEventListener("mouseup", this.doOffsetMouse); + } + + doOffsetMouse(event) { + const { zoom } = this.state; + event.screenZoomX = event.screenX * Math.pow(zoom, -1); + event.screenZoomY = event.screenY * Math.pow(zoom, -1); + } + + handleMouseDown(event) { + this.setState((state) => { + return { + mouseDown: true, + lastLeft: event.clientX - state.left, + lastTop: event.clientY - state.top, + }; + }); + } + + onMouseUp() { + this.setState({ + mouseDown: false, + }); + } + + handleMouseMove(event) { + if (this.state.mouseDown) { + this.setState((state) => { + return { + left: event.clientX - state.lastLeft, + top: event.clientY - state.lastTop, + }; + }); + } + } + + render() { + const { + children, + backgroundImage, + imageWidth, + ...rest + } = this.props; + const { + left, + top, + zoom, + } = this.state; + + return ( +

+
+
+ {children} +
+ + + +
+ ); + } +} diff --git a/tgui/packages/tgui/components/index.js b/tgui/packages/tgui/components/index.js index 605bc61bab6..3833d1a69ab 100644 --- a/tgui/packages/tgui/components/index.js +++ b/tgui/packages/tgui/components/index.js @@ -20,6 +20,7 @@ export { Dropdown } from './Dropdown'; export { Flex } from './Flex'; export { Grid } from './Grid'; export { Icon } from './Icon'; +export { InfinitePlane } from './InfinitePlane'; export { Input } from './Input'; export { Knob } from './Knob'; export { LabeledControls } from './LabeledControls'; diff --git a/tgui/packages/tgui/interfaces/ComponentPrinter.tsx b/tgui/packages/tgui/interfaces/ComponentPrinter.tsx new file mode 100644 index 00000000000..9fefbbb9479 --- /dev/null +++ b/tgui/packages/tgui/interfaces/ComponentPrinter.tsx @@ -0,0 +1,169 @@ +import { createSearch } from 'common/string'; +import { useBackend, useLocalState } from '../backend'; +import { Material, MaterialAmount, MaterialFormatting, Materials, MATERIAL_KEYS } from './common/Materials'; +import { Window } from '../layouts'; +import { Button, Input, Section, Stack, Tabs } from '../components'; + +const CATEGORY_ALL = "All"; + +const searchFor = searchText => createSearch( + searchText, + ([_, thing]) => thing.name + thing.description, +); + +const getCategory = (category: string[]) => { + return category[0] === "Circuitry" ? category[1] : category[0]; +}; + +type Design = { + name: string, + description: string, + materials: Record, + categories: string[], +} + +type ComponentPrinterData = { + designs: Record, + materials: Material[], +}; + +const canProduce = ( + designMaterials: Design["materials"], + storedMaterials: Material[], +) => { + for (const material of storedMaterials) { + const amountNeeded = designMaterials[material.name]; + + if (amountNeeded && amountNeeded > material.amount) { + return false; + } + } + + return true; +}; + +const MaterialCost = (props: { + materials: Design["materials"], +}) => { + return ( + + {Object.entries(props.materials) + .map(([material, amount]) => { + return ( + + + + ); + })} + + ); +}; + +export const ComponentPrinter = (props, context) => { + const { act, data } = useBackend(context); + + const [currentCategory, setCurrentCategory] = useLocalState(context, "category", CATEGORY_ALL); + const [searchText, setSearchText] = useLocalState(context, "searchText", ""); + + return ( + + + + +
+ { + act("remove_mat", { + ref: ref, + amount: amount, + }); + }} + /> +
+ + + +
+ + {Object.values(data.designs) + .reduce((categories, design) => { + const category = getCategory(design.categories); + if (categories.indexOf(category) === -1) { + return [category, ...categories]; + } else { + return categories; + } + }, [CATEGORY_ALL]).sort().map(category => { + return ( + setCurrentCategory(category)} + selected={category === currentCategory} + fluid + > + {category} + + ); + })} + +
+
+ + +
+ + + setSearchText(value)} /> + + + {Object.entries(data.designs) + .filter(([_, design]) => currentCategory === CATEGORY_ALL + || design.categories.indexOf(currentCategory) !== -1) + .filter(searchFor(searchText)) + .map(([designId, design]) => { + return ( + +
{ + act("print", { + designId, + }); + }} + disabled={ + !canProduce(design.materials, data.materials) + } + px={1.5} + > + Print + + )}> + {design.description} + + +
+
+ ); + })} +
+
+
+
+
+
+
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/ExosuitFabricator.js b/tgui/packages/tgui/interfaces/ExosuitFabricator.js index f149f9d4027..cc2a685b566 100644 --- a/tgui/packages/tgui/interfaces/ExosuitFabricator.js +++ b/tgui/packages/tgui/interfaces/ExosuitFabricator.js @@ -1,26 +1,12 @@ import { uniqBy } from 'common/collections'; -import { classes } from 'common/react'; import { createSearch } from 'common/string'; import { Fragment } from 'inferno'; import { useBackend, useSharedState } from '../backend'; -import { Box, Button, Flex, Icon, Input, NumberInput, ProgressBar, Section, Stack } from '../components'; -import { formatMoney, formatSiUnit } from '../format'; +import { Box, Button, Icon, Input, ProgressBar, Section, Stack } from '../components'; +import { Materials, MaterialAmount, MaterialFormatting } from './common/Materials'; +import { formatMoney } from '../format'; import { Window } from '../layouts'; -const MATERIAL_KEYS = { - "iron": "sheet-metal_3", - "glass": "sheet-glass_3", - "silver": "sheet-silver_3", - "gold": "sheet-gold_3", - "diamond": "sheet-diamond", - "plasma": "sheet-plasma_3", - "uranium": "sheet-uranium", - "bananium": "sheet-bananium", - "titanium": "sheet-titanium_3", - "bluespace crystal": "polycrystal", - "plastic": "sheet-plastic_3", -}; - const COLOR_NONE = 0; const COLOR_AVERAGE = 1; const COLOR_BAD = 2; @@ -144,7 +130,15 @@ export const ExosuitFabricator = (props, context) => {
- + { + act("remove_mat", { + ref: ref, + amount: amount, + }); + }} + />
@@ -191,94 +185,6 @@ export const ExosuitFabricator = (props, context) => { ); }; -const EjectMaterial = (props, context) => { - const { act } = useBackend(context); - const { material } = props; - const { - name, - removable, - sheets, - ref, - } = material; - const [removeMaterials, setRemoveMaterials] = useSharedState( - context, 'remove_mats_' + name, 1); - if (removeMaterials > 1 && sheets < removeMaterials) { - setRemoveMaterials(sheets || 1); - } - return ( - <> - { - const newVal = parseInt(val, 10); - if (Number.isInteger(newVal)) { - setRemoveMaterials(newVal); - } - }} /> - + ) || port.name} + + + + {port.type || "any"} + + + + + ); +}; diff --git a/tgui/packages/tgui/interfaces/common/Materials.tsx b/tgui/packages/tgui/interfaces/common/Materials.tsx new file mode 100644 index 00000000000..5501b18d662 --- /dev/null +++ b/tgui/packages/tgui/interfaces/common/Materials.tsx @@ -0,0 +1,153 @@ +import { BooleanLike } from 'common/react'; +import { Box, Button, NumberInput, Flex } from '../../components'; +import { classes } from 'common/react'; +import { formatMoney, formatSiUnit } from '../../format'; +import { useSharedState } from '../../backend'; +import { BoxProps } from '../../components/Box'; + +export const MATERIAL_KEYS = { + "iron": "sheet-metal_3", + "glass": "sheet-glass_3", + "silver": "sheet-silver_3", + "gold": "sheet-gold_3", + "diamond": "sheet-diamond", + "plasma": "sheet-plasma_3", + "uranium": "sheet-uranium", + "bananium": "sheet-bananium", + "titanium": "sheet-titanium_3", + "bluespace crystal": "polycrystal", + "plastic": "sheet-plastic_3", +} as const; + +export type Material = { + name: keyof typeof MATERIAL_KEYS; + ref: string; + amount: number; + sheets: number; + removable: BooleanLike; +}; + +interface MaterialIconProps extends BoxProps { + material: keyof typeof MATERIAL_KEYS; +} + +export const MaterialIcon = (props: MaterialIconProps) => { + const { material, ...rest } = props; + + return (); +}; + +const EjectMaterial = (props: { + material: Material, + onEject: (amount: number) => void, +}, context) => { + const { + name, + removable, + sheets, + } = props.material; + const [removeMaterials, setRemoveMaterials] = useSharedState( + context, 'remove_mats_' + name, 1); + if (removeMaterials > 1 && sheets < removeMaterials) { + setRemoveMaterials(sheets || 1); + } + return ( + <> + { + const newVal = parseInt(val, 10); + if (Number.isInteger(newVal)) { + setRemoveMaterials(newVal); + } + }} /> +