diff --git a/citadel.dme b/citadel.dme
index 5d6ff700e65..08ea92e3cc8 100644
--- a/citadel.dme
+++ b/citadel.dme
@@ -2891,6 +2891,7 @@
#include "code\modules\integrated_electronics\subtypes\built_in.dm"
#include "code\modules\integrated_electronics\subtypes\converters.dm"
#include "code\modules\integrated_electronics\subtypes\data_transfer.dm"
+#include "code\modules\integrated_electronics\subtypes\filters.dm"
#include "code\modules\integrated_electronics\subtypes\input.dm"
#include "code\modules\integrated_electronics\subtypes\lists.dm"
#include "code\modules\integrated_electronics\subtypes\logic.dm"
diff --git a/code/__DEFINES/math.dm b/code/__DEFINES/math.dm
index c2f52b031aa..dda5022df07 100644
--- a/code/__DEFINES/math.dm
+++ b/code/__DEFINES/math.dm
@@ -52,6 +52,15 @@
// Cosecant
#define CSC(x) (1 / sin(x))
+// ArcTan2. Returns the degree between two points in an x and y system.
+/proc/arctantwo(x1,y1,x2,y2)
+ var/dx = x2-x1
+ var/dy = y2-y1
+ if(!dy) return (dx>=0) ? 90 : 270
+ . = arctan(dx/dy)
+ if(dy<0) return .+180
+ if(dx<0) return .+360
+
// Greatest Common Divisor - Euclid's algorithm
/proc/GCD(a, b)
return b ? GCD(b, (a) % (b)) : a
diff --git a/code/modules/integrated_electronics/core/printer.dm b/code/modules/integrated_electronics/core/printer.dm
index a424b67d7bb..d176d6d0c9c 100644
--- a/code/modules/integrated_electronics/core/printer.dm
+++ b/code/modules/integrated_electronics/core/printer.dm
@@ -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
diff --git a/code/modules/integrated_electronics/passive/power.dm b/code/modules/integrated_electronics/passive/power.dm
index 945e153c90f..f55a2651d80 100644
--- a/code/modules/integrated_electronics/passive/power.dm
+++ b/code/modules/integrated_electronics/passive/power.dm
@@ -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()
diff --git a/code/modules/integrated_electronics/subtypes/arithmetic.dm b/code/modules/integrated_electronics/subtypes/arithmetic.dm
index 63a4aea4420..f218d3bb952 100644
--- a/code/modules/integrated_electronics/subtypes/arithmetic.dm
+++ b/code/modules/integrated_electronics/subtypes/arithmetic.dm
@@ -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
diff --git a/code/modules/integrated_electronics/subtypes/filters.dm b/code/modules/integrated_electronics/subtypes/filters.dm
index 0bb02a476ff..7605502bc4a 100644
--- a/code/modules/integrated_electronics/subtypes/filters.dm
+++ b/code/modules/integrated_electronics/subtypes/filters.dm
@@ -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
diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm
index 4f2b32bc5eb..c204466a52d 100644
--- a/code/modules/integrated_electronics/subtypes/input.dm
+++ b/code/modules/integrated_electronics/subtypes/input.dm
@@ -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)
diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm
index d6351db041f..7c98e83f8d9 100644
--- a/code/modules/integrated_electronics/subtypes/reagents.dm
+++ b/code/modules/integrated_electronics/subtypes/reagents.dm
@@ -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("[acting_object] failed to pierce [L] thick clothing!", \
+ "[acting_object] failed to pierce your thick clothing!")
activate_pin(3)
return
@@ -138,8 +160,8 @@
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, 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("[acting_object] injects [L] with its needle!", \
"[acting_object] injects you with its needle!")
@@ -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("[acting_object] failed to pierce [L] thick clothing!", \
+ "[acting_object] failed to pierce your thick clothing!")
+ activate_pin(3)
+ return
+
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, 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("[acting_object] takes a blood sample from [L]!", \
"[acting_object] takes a blood sample from you!")
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
diff --git a/code/modules/integrated_electronics/subtypes/trig.dm b/code/modules/integrated_electronics/subtypes/trig.dm
index 7ed9070408d..f4c98aa0559 100644
--- a/code/modules/integrated_electronics/subtypes/trig.dm
+++ b/code/modules/integrated_electronics/subtypes/trig.dm
@@ -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