diff --git a/code/modules/integrated_electronics/input_output.dm b/code/modules/integrated_electronics/input_output.dm index d94bfa32da..5196617a83 100644 --- a/code/modules/integrated_electronics/input_output.dm +++ b/code/modules/integrated_electronics/input_output.dm @@ -150,6 +150,38 @@ O.push_data() +/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 a meter away from the machine." + extended_desc = "The first pin requires a ref to a 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") + outputs = list("located ref") + activators = list("locate") + +/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/weakref/w = I.data + var/atom/A = w.resolve() + 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)) + O.push_data() + /obj/item/integrated_circuit/input/signaler name = "integrated signaler" desc = "Signals from a signaler can be received with this, allowing for remote control. Additionally, it can send signals as well." diff --git a/code/modules/integrated_electronics/manipulation.dm b/code/modules/integrated_electronics/manipulation.dm index c9b10f4647..1fac6ba19c 100644 --- a/code/modules/integrated_electronics/manipulation.dm +++ b/code/modules/integrated_electronics/manipulation.dm @@ -111,6 +111,140 @@ smoke_system.start() reagents.clear_reagents() +/obj/item/integrated_circuit/manipulation/injector + name = "integrated hypo-injector" + desc = "This scary looking thing is able to pump liquids into whatever it's pointed at." + icon_state = "injector" + extended_desc = "This autoinjector can push 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." + flags = OPENCONTAINER + complexity = 20 + cooldown_per_use = 6 SECONDS + inputs = list("target ref", "injection amount") + outputs = list() + activators = list("inject") + var/inject_amount = 5 + +/obj/item/integrated_circuit/manipulation/injector/New() + ..() + create_reagents(30) + var/datum/integrated_io/amount = inputs[2] + amount.data = inject_amount + +/obj/item/integrated_circuit/manipulation/injector/on_data_written() + var/datum/integrated_io/amount = inputs[2] + if(isnum(amount.data)) + amount.data = Clamp(amount.data, 0, 30) + inject_amount = amount.data + +/obj/item/integrated_circuit/manipulation/injector/do_work() + var/datum/integrated_io/target = inputs[1] + var/atom/movable/AM = target.data_as_type(/atom/movable) + if(!istype(AM)) //Invalid input + return + if(!reagents.total_volume) // Empty + return + if(AM.Adjacent(get_turf(src))) + if(!AM.reagents) + return + if(!AM.is_open_container() && !ismob(AM) ) + return + if(!AM.reagents.get_free_space()) + return + + if(isliving(AM)) + var/mob/living/L = AM + if(!L.can_inject(null, 0, BP_TORSO)) + return + loc.visible_message("[src] is trying to inject [AM]!") + sleep(3 SECONDS) + if(!AM.Adjacent(get_turf(src))) + return + var/contained = reagents.get_reagents() + var/trans = reagents.trans_to_mob(target, inject_amount, CHEM_BLOOD) + message_admins("[src] injected \the [AM] with [trans]u of [english_list(contained)].") + to_chat(AM, "You feel a tiny prick!") + visible_message("[src] injects [AM]!") + else + reagents.trans_to(AM, inject_amount) + +/obj/item/integrated_circuit/manipulation/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 next to the machine. Note that this cannot be used on entities." + flags = OPENCONTAINER + complexity = 8 + inputs = list("source ref", "target ref", "injection amount") + outputs = list() + activators = list("transfer reagents") + var/transfer_amount = 10 + +/obj/item/integrated_circuit/manipulation/reagent_pump/New() + ..() + var/datum/integrated_io/amount = inputs[3] + amount.data = transfer_amount + +/obj/item/integrated_circuit/manipulation/reagent_pump/on_data_written() + var/datum/integrated_io/amount = inputs[3] + if(isnum(amount.data)) + amount.data = Clamp(amount.data, 0, 50) + transfer_amount = amount.data + +/obj/item/integrated_circuit/manipulation/reagent_pump/do_work() + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/atom/movable/source = A.data_as_type(/atom/movable) + var/atom/movable/target = B.data_as_type(/atom/movable) + if(!istype(source) || !istype(target)) //Invalid input + return + var/turf/T = get_turf(src) + if(source.Adjacent(T) && target.Adjacent(T)) + if(!source.reagents || !target.reagents) + return + if(ismob(source) || ismob(target)) + return + if(!source.is_open_container() || !target.is_open_container()) + return + if(!source.reagents.get_free_space() || !target.reagents.get_free_space()) + return + + source.reagents.trans_to(target, transfer_amount) + +// May make a reagent subclass of circuits in future. +/obj/item/integrated_circuit/manipulation/reagent_storage + name = "reagent storage" + desc = "Stores liquid inside, and away from electrical components. Can store up to 60u." + icon_state = "reagent_storage" + extended_desc = "This is effectively an internal beaker." + flags = OPENCONTAINER + complexity = 4 + inputs = list() + outputs = list("volume used") + activators = list() + +/obj/item/integrated_circuit/manipulation/reagent_storage/New() + ..() + create_reagents(60) + +/obj/item/integrated_circuit/manipulation/reagent_storage/on_reagent_change() + var/datum/integrated_io/A = outputs[1] + A.data = reagents.total_volume + A.push_data() + +/obj/item/integrated_circuit/manipulation/reagent_storage/cryo + name = "cryo reagent storage" + desc = "Stores liquid inside, and away from electrical components. Can store up to 60u. This will also suppress reactions." + icon_state = "reagent_storage_cryo" + extended_desc = "This is effectively an internal cryo beaker." + flags = OPENCONTAINER | NOREACT + complexity = 8 + inputs = list() + outputs = list("volume used") + activators = list() + /obj/item/integrated_circuit/manipulation/locomotion name = "locomotion circuit" desc = "This allows a machine to move in a given direction." @@ -126,7 +260,7 @@ Southwest = 10
\
\ Pulsing the 'step towards dir' activator pin will cause the machine to move a meter in that direction, assuming it is not \ - being held, or anchored in some way." + being held, or anchored in some way. It should be noted that heavy machines will be unable to move." complexity = 20 inputs = list("dir num") outputs = list() @@ -137,7 +271,7 @@ var/turf/T = get_turf(src) if(istype(loc, /obj/item/device/electronic_assembly)) var/obj/item/device/electronic_assembly/machine = loc - if(machine.anchored || machine.w_class >= 4) + if(machine.anchored || machine.w_class >= ITEMSIZE_LARGE) return if(machine.loc && machine.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] diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index 6f08e674bc..bbb54d7f7e 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -1523,6 +1523,14 @@ CIRCUITS BELOW materials = list(DEFAULT_WALL_MATERIAL = 20000) build_path = /obj/item/device/electronic_assembly/medium +/datum/design/item/custom_circuit_assembly/drone + name = "Drone custom assembly" + desc = "An customizable assembly optimized for autonomous devices." + id = "assembly-drone" + req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 4, TECH_POWER = 4) + materials = list(DEFAULT_WALL_MATERIAL = 30000) + build_path = /obj/item/device/electronic_assembly/drone + /datum/design/item/custom_circuit_assembly/large name = "Large custom assembly" desc = "An customizable assembly for large machines." @@ -1717,6 +1725,11 @@ CIRCUITS BELOW build_path = /obj/item/integrated_circuit/input/local_locator sort_string = "WAAEG" +/datum/design/circuit/integrated_circuit/input_output/adjacent_locator + id = "cc-adjacentlocator" + build_path = /obj/item/integrated_circuit/input/adjacent_locator + sort_string = "WAAEH" + /datum/design/circuit/integrated_circuit/input_output/signaler id = "cc-signaler" build_path = /obj/item/integrated_circuit/input/signaler @@ -1821,7 +1834,33 @@ CIRCUITS BELOW sort_string = "WAAGB" req_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) +/datum/design/circuit/integrated_circuit/manipulation/injector + name = "injector" + id = "cc-injector" + build_path = /obj/item/integrated_circuit/manipulation/injector + sort_string = "WAAGC" + req_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 3) +/datum/design/circuit/integrated_circuit/manipulation/reagent_pump + name = "reagent pump" + id = "cc-reagent_pump" + build_path = /obj/item/integrated_circuit/manipulation/reagent_pump + sort_string = "WAAGD" + req_tech = list(TECH_ENGINEERING = 1, TECH_DATA = 1, TECH_BIO = 2) + +/datum/design/circuit/integrated_circuit/manipulation/reagent_storage + name = "reagent storage" + id = "cc-reagent_storage" + build_path = /obj/item/integrated_circuit/manipulation/reagent_storage + sort_string = "WAAGE" + req_tech = list(TECH_ENGINEERING = 1, TECH_DATA = 1, TECH_BIO = 1) + +/datum/design/circuit/integrated_circuit/manipulation/reagent_storage_cryo + name = "cryo reagent storage" + id = "cc-reagent_storage_cryo" + build_path = /obj/item/integrated_circuit/manipulation/reagent_storage/cryo + sort_string = "WAAGF" + req_tech = list(TECH_MATERIALS = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) /datum/design/circuit/integrated_circuit/memory/AssembleDesignName() ..() diff --git a/icons/obj/electronic_assemblies.dmi b/icons/obj/electronic_assemblies.dmi index 1e020c396a..ab83834d66 100644 Binary files a/icons/obj/electronic_assemblies.dmi and b/icons/obj/electronic_assemblies.dmi differ