Another set of QoL and changes for IC (#6317)

<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may
not be viewable. -->
<!-- You can view Contributing.MD for a detailed description of the pull
request process. -->

## About The Pull Request

This PR aims to solve a few things random things I have collected in my
to do list of issues and QoL.

First of, trignometry! You can now use the inverse function of sin, cos
and tan including atan2 because it is cool.
Mini fixes of the debug printer having no metal, a few reagent
containers having no ref pushes and resolving a few invisible icons. Not
to mention the external battery scanner being to near useless with no
adjecant check.
Lasty the two major things is that the injector now finally works, you
can draw blood, inject it properly and you can't inject someone else
with it if they are wearing armor. Second is the medical scanner is now
able to output nutrition, reagent types and quantity.

Late edit: Also added Min and Max math circuitry. Fixed and reenabled
filters plus a view filter that ties into it
This commit is contained in:
Dimasw99
2024-03-05 11:30:53 -08:00
committed by GitHub
parent 119d900e29
commit ca00dc18df
9 changed files with 267 additions and 39 deletions
@@ -37,6 +37,7 @@
/obj/item/integrated_circuit_printer/debug
name = "fractal integrated circuit printer"
desc = "A portable(ish) machine that makes modular circuitry seemingly out of thin air."
cur_metal = 250
debug = TRUE
upgraded = TRUE
can_clone = TRUE
@@ -113,7 +113,7 @@
a source of organic fuel; blood from sapient creatures is more efficient."
atom_flags = OPENCONTAINER
complexity = 4
inputs = list()
inputs = list("push ref" = IC_PINTYPE_PULSE_IN)
outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF)
activators = list()
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
@@ -130,6 +130,10 @@
push_data()
..()
/obj/item/integrated_circuit/passive/power/chemical_cell/do_work()
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
push_data()
/obj/item/integrated_circuit/passive/power/chemical_cell/on_reagent_change()
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
push_data()
@@ -308,3 +308,32 @@
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 length(inputs))
var/I = get_pin_data(IC_INPUT, k)
if(!isnum(I))
continue
if(!isnum(result) || (!min_comparision && I > result) || (min_comparision && I < result))
result = I
if(!isnum(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
@@ -3,8 +3,6 @@
power_draw_per_use = 5
complexity = 2
activators = list("compare" = IC_PINTYPE_PULSE_IN, "if valid" = IC_PINTYPE_PULSE_OUT, "if not valid" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
icon = 'icons/obj/electronic_assemblies.dmi'
/obj/item/integrated_circuit/filter/proc/may_pass(var/input)
return FALSE
@@ -17,12 +15,12 @@
var/filter_type
complexity = 4
inputs = list( "input" = IC_PINTYPE_REF )
outputs = list("result" = IC_PINTYPE_BOOLEAN)
outputs = list("result" = IC_PINTYPE_BOOLEAN, "self ref" = IC_PINTYPE_SELFREF)
/obj/item/integrated_circuit/filter/ref/may_pass(var/weakref/data)
/obj/item/integrated_circuit/filter/ref/may_pass(var/datum/weakref/data)
if(!(filter_type && isweakref(data)))
return FALSE
var/weakref/wref = data
var/datum/weakref/wref = data
return istype(wref.resolve(), filter_type)
/obj/item/integrated_circuit/filter/ref/do_work()
@@ -41,48 +39,69 @@
desc = "Only allow refs belonging to more complex, currently or formerly, living but not necessarily biological entities through."
icon_state = "filter_mob"
filter_type = /mob/living
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/filter/ref/mob/simple_mob
name = "creature filter"
desc = "Only allow refs belonging to more simple minded, currently or formerly, living but not necessarily biological entities through."
icon_state = "filter_mob"
filter_type = /mob/living/simple_mob
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/filter/ref/mob/simple_animal
name = "animal filter"
desc = "Only allow refs belonging to more animalistic, currently or formerly, living but not necessarily biological entities through."
icon_state = "filter_mob"
filter_type = /mob/living/simple_animal
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/filter/ref/mob/humanoid
name = "humanoid filter"
desc = "Only allow refs belonging to humanoids (dead or alive) through."
icon_state = "filter_humanoid"
filter_type = /mob/living/carbon/human
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/filter/ref/obj
name = "object filter"
desc = "Allows most kinds of refs to pass, as long as they are not considered (once) living entities."
icon_state = "filter_obj"
filter_type = /obj
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/filter/ref/obj/item
name = "item filter"
desc = "Only allow refs belonging to minor items through, typically hand-held such."
icon_state = "filter_item"
filter_type = /obj/item
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/filter/ref/obj/machinery
name = "machinery filter"
desc = "Only allow refs belonging machinery or complex objects through, such as computers and consoles."
icon_state = "filter_machinery"
filter_type = /obj/machinery
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/filter/ref/object/structure
name = "structure filter"
desc = "Only allow refs belonging larger objects and structures through, such as closets and beds."
icon_state = "filter_structure"
filter_type = /obj/structure
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/filter/ref/custom
name = "custom filter"
desc = "Allows custom filtering. It will match type against a stored reference."
icon_state = "filter_custom"
inputs = list( "input" = IC_PINTYPE_REF, "expected type" = IC_PINTYPE_REF )
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/filter/ref/custom/may_pass(var/weakref/data, var/weakref/typedata)
/obj/item/integrated_circuit/filter/ref/custom/may_pass(var/datum/weakref/data, var/datum/weakref/typedata)
if(!isweakref(data) || !isweakref(typedata))
return FALSE
var/weakref/wref = data
var/weakref/wref2 = typedata
var/datum/weakref/wref = data
var/datum/weakref/wref2 = typedata
var/atom/A = wref.resolve()
var/atom/B = wref2.resolve()
return (A && B && (istype(A, B.type)))
@@ -110,6 +129,7 @@
"expected string" = IC_PINTYPE_STRING
)
outputs = list("result" = IC_PINTYPE_BOOLEAN)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/filter/string/may_pass(var/datum/integrated_io/A, var/datum/integrated_io/B)
return A.data == B.data
@@ -224,7 +224,10 @@
"clone damage" = IC_PINTYPE_NUMBER,
"blood loss" = IC_PINTYPE_NUMBER,
"pain level" = IC_PINTYPE_NUMBER,
"radiation" = IC_PINTYPE_NUMBER
"radiation" = IC_PINTYPE_NUMBER,
"nutrition" = IC_PINTYPE_NUMBER,
"list of reagents" = IC_PINTYPE_LIST,
"quantity of reagents" = IC_PINTYPE_LIST
)
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_RESEARCH
@@ -254,10 +257,44 @@
set_pin_data(IC_OUTPUT, 10, round((H.vessel.get_reagent_amount("blood") / H.species.blood_volume)*100))
set_pin_data(IC_OUTPUT, 11, H.traumatic_shock)
set_pin_data(IC_OUTPUT, 12, H.radiation)
set_pin_data(IC_OUTPUT, 13, H.nutrition)
var/cont[0]
var/amt[0]
for(var/datum/reagent/RE in H.reagents.reagent_list)
if(RE.scannable)
cont += RE.id
amt += round(H.reagents.get_reagent_amount(RE.id), 1)
set_pin_data(IC_OUTPUT, 14, cont)
set_pin_data(IC_OUTPUT, 15, amt)
push_data()
activate_pin(2)
/obj/item/integrated_circuit/input/view_filter
name = "view filter"
desc = "This circuit will filter every object in assembly view."
extended_desc = "The first pin is ref to filter, to see avaliable filters go to Filter category. The output will contents everything with filtering type"
inputs = list(
"filter" = IC_PINTYPE_REF
)
outputs = list(
"objects" = IC_PINTYPE_LIST
)
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_RESEARCH
power_draw_per_use = 30
/obj/item/integrated_circuit/input/view_filter/do_work(ord)
var/list/objects = list()
var/obj/item/integrated_circuit/filter/ref/filter = get_pin_data(IC_INPUT, 1)
if(istype(filter) && assembly && (filter in assembly.assembly_components))
for(var/atom/A in view(get_turf(assembly)))
if(istype(A, filter.filter_type))
objects.Add(WEAKREF(A))
set_pin_data(IC_OUTPUT, 1, objects)
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."
@@ -1242,7 +1279,8 @@ GLOBAL_DATUM_INIT(circuit_translation_context, /datum/translation_context/simple
if(cell)
var/turf/A = get_turf(src)
if(AM in view(A))
var/turf/B = get_turf(AM)
if(A.Adjacent(B) || (AM in view(A)))
push_data()
set_pin_data(IC_OUTPUT, 1, cell.charge)
set_pin_data(IC_OUTPUT, 2, cell.maxcharge)
@@ -24,8 +24,15 @@
complexity = 20
cooldown_per_use = 30 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)
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
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 3)
volume = 100
@@ -40,15 +47,20 @@
push_data()
..()
/obj/item/integrated_circuit/reagent/smoke/do_work()
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
var/datum/effect_system/smoke_spread/chem/smoke_system = new()
smoke_system.set_up(reagents, 10, 0, get_turf(src))
spawn(0)
for(var/i = 1 to 8)
smoke_system.start()
reagents.clear_reagents()
activate_pin(2)
/obj/item/integrated_circuit/reagent/smoke/do_work(ord)
switch(ord)
if(1)
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
var/datum/effect_system/smoke_spread/chem/smoke_system = new()
smoke_system.set_up(reagents, 10, 0, get_turf(src))
spawn(0)
for(var/i = 1 to 8)
smoke_system.start()
reagents.clear_reagents()
activate_pin(2)
if(4)
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
push_data()
/obj/item/integrated_circuit/reagent/injector
name = "integrated hypo-injector"
@@ -60,17 +72,22 @@
volume = 30
complexity = 20
cooldown_per_use = 6 SECONDS
inputs = list("target" = IC_PINTYPE_REF, "injection amount" = IC_PINTYPE_NUMBER)
inputs_default = list("2" = 5)
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(
"push ref" = IC_PINTYPE_PULSE_IN,
"inject" = IC_PINTYPE_PULSE_IN,
"on injected" = IC_PINTYPE_PULSE_OUT,
"on fail" = 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
@@ -127,8 +144,13 @@
activate_pin(3)
return
if(isliving(AM))
var/mob/living/L = AM
if(!L.can_inject(null, 0))
var/mob/living/carbon/human/L = AM
var/bypass
if(assembly == L.r_store || assembly == L.l_store)
bypass = TRUE //The injector has been put under the thick layer
if(!L.can_inject(null, 0, BP_TORSO, bypass))
L.visible_message("<span class='danger'>[acting_object] failed to pierce [L] thick clothing!</span>", \
"<span class='userdanger'>[acting_object] failed to pierce your thick clothing!</span>")
activate_pin(3)
return
@@ -138,8 +160,8 @@
L.visible_message("<span class='danger'>[acting_object] is trying to inject [L]!</span>", \
"<span class='userdanger'>[acting_object] is trying to inject you!</span>")
busy = TRUE
if(do_atom(src, L, extra_checks=CALLBACK(L, TYPE_PROC_REF(/mob/living, can_inject),null,0)))
reagents.trans_to(L, transfer_amount)
if(do_atom(src, L, extra_checks=CALLBACK(L, TYPE_PROC_REF(/mob/living, can_inject),null,0,BP_TORSO,bypass)))
reagents.trans_to_mob(L, transfer_amount)
log_attack(src, L, "attempted to inject [L] which had [contained]")
L.visible_message("<span class='danger'>[acting_object] injects [L] with its needle!</span>", \
"<span class='userdanger'>[acting_object] injects you with its needle!</span>")
@@ -159,13 +181,28 @@
var/tramount = abs(transfer_amount)
if(isliving(AM))
var/mob/living/L = AM
var/mob/living/carbon/human/L = AM
var/bypass
if(assembly == L.r_store || assembly == L.l_store)
bypass = TRUE //The injector has been put under the thick layer
if(!L.can_inject(null, 0, BP_TORSO, bypass))
L.visible_message("<span class='danger'>[acting_object] failed to pierce [L] thick clothing!</span>", \
"<span class='userdanger'>[acting_object] failed to pierce your thick clothing!</span>")
activate_pin(3)
return
L.visible_message("<span class='danger'>[acting_object] is trying to take a blood sample from [L]!</span>", \
"<span class='userdanger'>[acting_object] is trying to take a blood sample from you!</span>")
busy = TRUE
if(do_atom(src, L, extra_checks=CALLBACK(L, TYPE_PROC_REF(/mob/living, can_inject),null,0)))
if(do_atom(src, L, extra_checks=CALLBACK(L, TYPE_PROC_REF(/mob/living, can_inject),null,0,BP_TORSO,bypass)))
var/mob/living/carbon/LB = L
if(LB.take_blood(src, tramount))
var/datum/reagent/B
B = LB.take_blood(src, tramount)
if(B)
reagents.reagent_list += B
reagents.update_total()
AM.on_reagent_change()
reagents.handle_reactions()
L.visible_message("<span class='danger'>[acting_object] takes a blood sample from [L]!</span>", \
"<span class='userdanger'>[acting_object] takes a blood sample from you!</span>")
else
@@ -182,15 +219,17 @@
activate_pin(3)
return
if(!AM.can_be_injected_by())
if(!AM.is_open_container())
activate_pin(3)
return
tramount = min(tramount, AM.reagents.total_volume)
AM.reagents.trans_to(src, tramount)
push_vol()
activate_pin(2)
/obj/item/integrated_circuit/reagent/pump
name = "reagent pump"
desc = "Moves liquids safely inside a machine, or even nearby it."
@@ -353,11 +392,14 @@
complexity = 4
inputs = list()
outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF)
activators = list()
activators = list("push ref" = IC_PINTYPE_PULSE_IN)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
volume = 60
/obj/item/integrated_circuit/reagent/storage/do_work()
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
push_data()
/obj/item/integrated_circuit/reagent/storage/interact(mob/user)
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
@@ -382,7 +424,7 @@
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"
icon_state = "reagent_storage"
complexity = 8
inputs = list(
"target temperature" = IC_PINTYPE_NUMBER,
@@ -422,7 +464,7 @@
category_text = "Reagent"
name = "reagent funnel"
desc = "A funnel with a small pump that lets you refill an internal reagent storage."
icon_state = "reagent_funnel"
icon_state = "reagent_pump"
can_be_asked_input = TRUE
inputs = list(
"target" = IC_PINTYPE_REF
@@ -456,7 +498,7 @@
name = "tubing"
desc = "A length of flexible piping that can be used to connect one container to another."
extended_desc = "Use these to supply your fuel cell with never-ending phoron! Beware of leaks."
icon_state = "reagent_funnel"
icon_state = "reagent_pump"
atom_flags = OPENCONTAINER
inputs = list(
"toggle cap" = IC_PINTYPE_BOOLEAN,
@@ -492,7 +534,7 @@
/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"
icon_state = "reagent_storage"
extended_desc = ""
inputs = list(
"target" = IC_PINTYPE_REF
@@ -74,6 +74,90 @@
push_data()
activate_pin(2)
// ArcSine //
/obj/item/integrated_circuit/trig/arcsine
name = "arcsin circuit"
desc = "Reverse function of sine."
icon_state = "sine"
inputs = list("A" = IC_PINTYPE_NUMBER)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/trig/arcsine/do_work()
var/result = null
var/A = get_pin_data(IC_INPUT, 1)
if(!isnull(A))
result = arcsin(A)
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
// ArcCos //
/obj/item/integrated_circuit/trig/arccos
name = "arccos circuit"
desc = "Reverse function of cosine."
icon_state = "cosine"
inputs = list("A" = IC_PINTYPE_NUMBER)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/trig/arccos/do_work()
var/result = null
var/A = get_pin_data(IC_INPUT, 1)
if(!isnull(A))
result = arccos(A)
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
// ArcTan //
/obj/item/integrated_circuit/trig/arctan
name = "arctan circuit"
desc = "Reverse function of tangent."
icon_state = "tangent"
inputs = list("A" = IC_PINTYPE_NUMBER)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/trig/arctan/do_work()
var/result = null
var/A = get_pin_data(IC_INPUT, 1)
if(!isnull(A))
result = arctan(A)
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
// ArcTan2 //
/obj/item/integrated_circuit/trig/arctantwo
name = "arctantwo circuit"
desc = "Returns the degree between two points in an x and y system. The delta is gained by subtracting the target by the origin. Leave origin at 0 for relative x and y."
icon_state = "tangent"
inputs = list(
"X1 Origin" = IC_PINTYPE_NUMBER,
"Y1 Origin" = IC_PINTYPE_NUMBER,
"X2 Target" = IC_PINTYPE_NUMBER,
"Y2 Target" = IC_PINTYPE_NUMBER
)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/trig/arctantwo/do_work()
var/result = null
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(X2) && !isnull(Y1) && !isnull(Y2))
result = arctantwo(X1,Y1,X2,Y2)
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
// Cosecant //
/obj/item/integrated_circuit/trig/cosecant