[MIRROR] Circuity improvements and minor additions (#11243)

Co-authored-by: Aura Dusklight <46622484+NovaDusklight@users.noreply.github.com>
This commit is contained in:
CHOMPStation2StaffMirrorBot
2025-07-26 03:47:44 -07:00
committed by GitHub
parent e4203500e0
commit 95e325d2b8
10 changed files with 218 additions and 12 deletions

View File

@@ -84,7 +84,8 @@ SUBSYSTEM_DEF(circuit)
/obj/item/clothing/shoes/circuitry,
/obj/item/clothing/head/circuitry,
/obj/item/clothing/ears/circuitry,
/obj/item/clothing/suit/circuitry
/obj/item/clothing/suit/circuitry,
/obj/item/electronic_assembly/circuit_bug
)
circuit_fabricator_recipe_list["Tools"] = list(

View File

@@ -266,16 +266,19 @@
IC.assembly = src
/obj/item/electronic_assembly/afterattack(atom/target, mob/user, proximity)
if(proximity)
var/scanned = FALSE
if(proximity)
// Existing sensor support
for(var/obj/item/integrated_circuit/input/sensor/S in contents)
// S.set_pin_data(IC_OUTPUT, 1, WEAKREF(target))
// S.check_then_do_work()
if(S.scan(target))
scanned = TRUE
if(scanned)
visible_message(span_infoplain(span_bold("\The [user]") + " waves \the [src] around [target]."))
// Support for reference grabber + future ranged circuitry.
for(var/obj/item/integrated_circuit/input/reference_grabber/G in contents)
G.afterattack(target, user, proximity, null)
/obj/item/electronic_assembly/attackby(var/obj/item/I, var/mob/user)
if(can_anchor && I.has_tool_quality(TOOL_WRENCH))
anchored = !anchored

View File

@@ -0,0 +1,16 @@
/obj/item/electronic_assembly/circuit_bug // A nerfed, circuitry version of the spy bug.
name = "electronic bug"
desc = "A tiny circuit assembly that looks perfect for hiding."
icon = 'icons/obj/integrated_electronics/electronic_setups.dmi'
icon_state = "setup_device_cylinder"
layer = TURF_LAYER+0.2 // Appears under many things, but with alt+click, unlike spy bug.
w_class = ITEMSIZE_TINY
slot_flags = SLOT_EARS
max_components = IC_COMPONENTS_BASE
max_complexity = 20 // Incredibly low complexity to prevent shenanigans.
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1)
/obj/item/electronic_assembly/circuit_bug/examine(mob/user)
. = ..()
if(get_dist(user, src) == 0)
. += "It looks like it could be hidden easily..."

View File

@@ -100,6 +100,13 @@
setup_integrated_circuit(/obj/item/electronic_assembly/clothing)
return ..()
/obj/item/clothing/under/circuitry/equipped(mob/user, slot) // Set wearer var when equiped.
wearer = WEAKREF(user)
..()
/obj/item/clothing/under/circuitry/dropped(mob/user) // Remove wearer var.
wearer = null
..()
// Gloves.
/obj/item/clothing/gloves/circuitry
@@ -114,6 +121,13 @@
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small)
return ..()
/obj/item/clothing/gloves/circuitry/equipped(mob/user, slot)
wearer = WEAKREF(user)
..()
/obj/item/clothing/gloves/circuitry/dropped(mob/user)
wearer = null
..()
// Glasses.
/obj/item/clothing/glasses/circuitry
@@ -128,6 +142,14 @@
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small)
return ..()
/obj/item/clothing/glasses/circuitry/equipped(mob/user, slot)
wearer = WEAKREF(user)
..()
/obj/item/clothing/glasses/circuitry/dropped(mob/user)
wearer = null
..()
// Shoes
/obj/item/clothing/shoes/circuitry
name = "electronic boots"
@@ -141,6 +163,14 @@
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small)
return ..()
/obj/item/clothing/shoes/circuitry/equipped(mob/user, slot)
wearer = WEAKREF(user)
..()
/obj/item/clothing/shoes/circuitry/dropped(mob/user)
wearer = null
..()
// Head
/obj/item/clothing/head/circuitry
name = "electronic headwear"
@@ -154,6 +184,14 @@
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small)
return ..()
/obj/item/clothing/head/circuitry/equipped(mob/user, slot)
wearer = WEAKREF(user)
..()
/obj/item/clothing/head/circuitry/dropped(mob/user)
wearer = null
..()
// Ear
/obj/item/clothing/ears/circuitry
name = "electronic earwear"
@@ -165,8 +203,18 @@
/obj/item/clothing/ears/circuitry/Initialize(mapload)
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small)
var/obj/item/integrated_circuit/built_in/earpiece_speaker/built_in_speaker = new(IC)
IC.force_add_circuit(built_in_speaker)
return ..()
/obj/item/clothing/ears/circuitry/equipped(mob/user, slot)
wearer = WEAKREF(user)
..()
/obj/item/clothing/ears/circuitry/dropped(mob/user)
wearer = null
..()
// Exo-slot
/obj/item/clothing/suit/circuitry
name = "electronic chestpiece"
@@ -179,3 +227,11 @@
/obj/item/clothing/suit/circuitry/Initialize(mapload)
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/large)
return ..()
/obj/item/clothing/suit/circuitry/equipped(mob/user, slot)
wearer = WEAKREF(user)
..()
/obj/item/clothing/suit/circuitry/dropped(mob/user)
wearer = null
..()

View File

@@ -37,3 +37,24 @@
/obj/item/integrated_circuit/built_in/action_button/do_work()
activate_pin(1)
/obj/item/integrated_circuit/built_in/earpiece_speaker
name = "earpiece speaker"
desc = "This small speaker can be used to output sound to a person wearing an earpiece."
extended_desc = "This speaker can only be heard by the one wearing the earpiece."
inputs = list("displayed data" = IC_PINTYPE_STRING)
activators = list("load data" = IC_PINTYPE_PULSE_IN)
var/speaker_output = null
/obj/item/integrated_circuit/built_in/earpiece_speaker/disconnect_all()
..()
speaker_output = null
/obj/item/integrated_circuit/built_in/earpiece_speaker/do_work()
var/datum/integrated_io/I = inputs[1]
speaker_output = I.data
var/obj/item/clothing/ears/circuitry/ep = assembly.loc
var/mob/wearer = ep.wearer?.resolve()
if(wearer && ismob(wearer)) // Only allow the wearer to hear the earpiece exclusive speaker
to_chat(wearer, span_notice("[icon2html(ep, wearer.client)] [speaker_output]"))

View File

@@ -6,6 +6,39 @@
/obj/item/integrated_circuit/input/proc/ask_for_input(mob/user)
return
/obj/item/integrated_circuit/input/reference_grabber // Allows grabbing non-adjacet refs, and their coords. (relative)
name = "reference grabber"
desc = "A handheld mechanism that can be aimed to attain distant references."
extended_desc = "When used, it will capture the reference of the target, and output coordinates relative to the user."
icon_state = "video_camera"
complexity = 4
inputs = list()
outputs = list(
"clicked ref" = IC_PINTYPE_REF,
"X" = IC_PINTYPE_NUMBER,
"Y" = IC_PINTYPE_NUMBER
)
activators = list(
"on success" = IC_PINTYPE_PULSE_OUT,
"on failure" = IC_PINTYPE_PULSE_OUT
)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/input/reference_grabber/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
if(!assembly || user.get_active_hand() != assembly)
activate_pin(2) // Failure pin, not in assembly, or not held.
return
if(!target || get_dist(user, target) > 7 || !(target in view(user)))
activate_pin(2) // Failure pin, out of range or not visible.
return
set_pin_data(IC_OUTPUT, 1, WEAKREF(target))
set_pin_data(IC_OUTPUT, 2, target.x - user.x)
set_pin_data(IC_OUTPUT, 3, target.y - user.y)
push_data()
activate_pin(1) // Success pin
/obj/item/integrated_circuit/input/button
name = "button"
desc = "This tiny button must do something, right?"
@@ -17,8 +50,6 @@
activators = list("on pressed" = IC_PINTYPE_PULSE_OUT)
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, span_notice("You press the button labeled '[src.displayed_name]'."))
activate_pin(1)
@@ -72,7 +103,7 @@
power_draw_per_use = 4
/obj/item/integrated_circuit/input/textpad/ask_for_input(mob/user)
var/new_input = tgui_input_text(user, "Enter some words, please.","Number pad", get_pin_data(IC_OUTPUT, 1),MAX_NAME_LEN, encode=FALSE)
var/new_input = tgui_input_text(user, "Enter some words, please.","Number pad", get_pin_data(IC_OUTPUT, 1),MAX_KEYPAD_INPUT_LEN, encode=FALSE)
new_input = sanitize(new_input,MAX_KEYPAD_INPUT_LEN) // Slightly increase the size of the character limit.
if(istext(new_input) && CanInteract(user, GLOB.tgui_physical_state))
set_pin_data(IC_OUTPUT, 1, new_input)
@@ -500,6 +531,12 @@
var/message = get_pin_data(IC_INPUT, 2)
var/text = get_pin_data(IC_INPUT, 3)
var/is_communicator = FALSE // improved communicator support
for(var/obj/item/communicator/comm in all_communicators)
if(comm.exonet && comm.exonet.address == target_address)
is_communicator = TRUE
break
if(target_address && istext(target_address))
if(!get_connection_to_tcomms())
set_pin_data(IC_OUTPUT, 1, null)
@@ -509,6 +546,9 @@
push_data()
activate_pin(2)
else
if(is_communicator)
text = message // For communicators, we need to set the text to the message.
message = "text"
exonet.send_message(target_address, message, text)
/obj/item/integrated_circuit/input/receive_exonet_message(var/atom/origin_atom, var/origin_address, var/message, var/text)

View File

@@ -223,3 +223,30 @@
/obj/item/integrated_circuit/logic/unary/not/do_check(var/datum/integrated_io/A)
return !A.data
/obj/item/integrated_circuit/logic/toggler // Allows parts of circuits to be toggled on/off.
name = "circuit toggler"
desc = "Outputs its input data if enabled, otherwise does nothing. Used for enable/disabling parts of your circuit boards"
icon_state = "toggle_button"
inputs = list(
"input" = IC_PINTYPE_ANY,
"enabled" = IC_PINTYPE_BOOLEAN,
"toggle enable" = IC_PINTYPE_PULSE_IN,
)
inputs_default = list("2" = TRUE)
outputs = list("output" = IC_PINTYPE_ANY)
activators = list(
"pulse in" = IC_PINTYPE_PULSE_IN,
"pulse out" = IC_PINTYPE_PULSE_OUT
)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/logic/toggler/do_work()
pull_data()
var/enabled_input = get_pin_data(IC_INPUT, 2)
if(!enabled_input)
return
else
set_pin_data(IC_OUTPUT, 1, get_pin_data(IC_INPUT, 1))
push_data()
activate_pin(2)

View File

@@ -18,8 +18,12 @@
flags = OPENCONTAINER
complexity = 20
cooldown_per_use = 30 SECONDS
inputs = list()
outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF)
inputs = list(
"reagent storage" = IC_PINTYPE_REF)
outputs = list(
"volume held" = IC_PINTYPE_NUMBER,
"self reference" = IC_PINTYPE_REF
)
activators = list("create smoke" = IC_PINTYPE_PULSE_IN,"on smoked" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_RESEARCH
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 3)
@@ -37,6 +41,15 @@
..()
/obj/item/integrated_circuit/reagent/smoke/do_work()
// Attempt to fill self from input storage before acting
var/input_storage = get_pin_data(IC_INPUT, 1)
if(input_storage && istype(input_storage, /obj/item/integrated_circuit/reagent/storage))
var/obj/item/integrated_circuit/reagent/storage/storage = input_storage
if(storage.reagents && storage.reagents.total_volume > 0)
var/amount_to_transfer = min(storage.reagents.total_volume, reagents.get_free_space())
if(amount_to_transfer > 0)
storage.reagents.trans_to(src, amount_to_transfer)
playsound(src, 'sound/effects/smoke.ogg', 50, 1, -3)
var/datum/effect/effect/system/smoke_spread/chem/smoke_system = new()
smoke_system.set_up(reagents, 10, 0, get_turf(src))
@@ -55,10 +68,19 @@
flags = OPENCONTAINER
complexity = 20
cooldown_per_use = 6 SECONDS
inputs = list("target" = IC_PINTYPE_REF, "injection amount" = IC_PINTYPE_NUMBER)
inputs = list("target" = IC_PINTYPE_REF,
"injection amount" = IC_PINTYPE_NUMBER,
"reagent storage" = IC_PINTYPE_REF)
inputs_default = list("2" = 5)
outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF)
activators = list("inject" = IC_PINTYPE_PULSE_IN, "on injected" = IC_PINTYPE_PULSE_OUT, "on fail" = IC_PINTYPE_PULSE_OUT)
outputs = list(
"volume contained" = IC_PINTYPE_NUMBER,
"self reference" = IC_PINTYPE_REF,
)
activators = list(
"inject" = IC_PINTYPE_PULSE_IN,
"on injected" = IC_PINTYPE_PULSE_OUT,
"on fail" = IC_PINTYPE_PULSE_OUT
)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
volume = 30
power_draw_per_use = 15
@@ -89,6 +111,16 @@
/obj/item/integrated_circuit/reagent/injector/do_work()
set waitfor = 0 // Don't sleep in a proc that is called by a processor without this set, otherwise it'll delay the entire thing
// Attempt to fill self from input storage before acting
var/input_storage = get_pin_data(IC_INPUT, 3)
if(input_storage && istype(input_storage, /obj/item/integrated_circuit/reagent/storage))
var/obj/item/integrated_circuit/reagent/storage/storage = input_storage
if(storage.reagents && storage.reagents.total_volume > 0)
var/amount_to_transfer = min(storage.reagents.total_volume, transfer_amount)
if(amount_to_transfer > 0)
storage.reagents.trans_to(src, amount_to_transfer)
var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
if(!istype(AM)) //Invalid input
activate_pin(3)

View File

@@ -145,3 +145,12 @@
materials = list(MAT_STEEL = 2000)
build_path = /obj/item/implant/integrated_circuit
sort_string = "UDAAF"
/datum/design/item/integrated_circuitry/assembly/circuit_bug
name = "Circuitry Bug"
desc = "A tiny circuit assembly that can easily be hidden."
id = "circuit-bug"
req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 3, TECH_POWER = 2)
materials = list(MAT_STEEL = 2000)
build_path = /obj/item/electronic_assembly/circuit_bug
sort_string = "UDAAG"

View File

@@ -2983,6 +2983,7 @@
#include "code\modules\integrated_electronics\core\pins.dm"
#include "code\modules\integrated_electronics\core\printer.dm"
#include "code\modules\integrated_electronics\core\tools.dm"
#include "code\modules\integrated_electronics\core\assemblies\circuit_bug.dm"
#include "code\modules\integrated_electronics\core\assemblies\clothing.dm"
#include "code\modules\integrated_electronics\core\assemblies\device.dm"
#include "code\modules\integrated_electronics\core\assemblies\generic.dm"