From a893559c6bf4edfaf5462957e5af036a151f9a2d Mon Sep 17 00:00:00 2001
From: arsserpentarium <32496644+arsserpentarium@users.noreply.github.com>
Date: Sun, 24 Dec 2017 06:55:37 +0300
Subject: [PATCH 1/2] [READY]Circuitry upgrades
---
code/modules/hydroponics/grown.dm | 4 +-
.../integrated_electronics/core/assemblies.dm | 30 +--
.../integrated_electronics/core/debugger.dm | 2 +-
.../integrated_electronics/core/helpers.dm | 4 +-
.../core/integrated_circuit.dm | 18 +-
.../integrated_electronics/core/pins.dm | 10 +-
.../core/special_pins/index_pin.dm | 6 +-
.../subtypes/arithmetic.dm | 60 ++---
.../subtypes/converters.dm | 8 +-
.../integrated_electronics/subtypes/input.dm | 137 +++++++++-
.../integrated_electronics/subtypes/logic.dm | 2 +-
.../subtypes/manipulation.dm | 16 +-
.../subtypes/reagents.dm | 239 +++++++++++++++---
.../integrated_electronics/subtypes/smart.dm | 2 +-
.../obj/assemblies/electronic_components.dmi | Bin 21775 -> 22954 bytes
15 files changed, 409 insertions(+), 129 deletions(-)
diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm
index 15456c1e34..dadf077c8a 100644
--- a/code/modules/hydroponics/grown.dm
+++ b/code/modules/hydroponics/grown.dm
@@ -146,7 +146,7 @@
/obj/item/reagent_containers/food/snacks/grown/on_grind()
var/nutriment = reagents.get_reagent_amount("nutriment")
- if(grind_results.len)
+ if(grind_results&&grind_results.len)
for(var/i in 1 to grind_results.len)
grind_results[grind_results[i]] = nutriment
reagents.del_reagent("nutriment")
@@ -154,7 +154,7 @@
/obj/item/reagent_containers/food/snacks/grown/on_juice()
var/nutriment = reagents.get_reagent_amount("nutriment")
- if(juice_results.len)
+ if(juice_results&&juice_results.len)
for(var/i in 1 to juice_results.len)
juice_results[juice_results[i]] = nutriment
reagents.del_reagent("nutriment")
diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm
index 805cf787f7..637c3bfcee 100644
--- a/code/modules/integrated_electronics/core/assemblies.dm
+++ b/code/modules/integrated_electronics/core/assemblies.dm
@@ -20,6 +20,8 @@
var/charge_tick = FALSE
var/charge_delay = 4
var/use_cyborg_cell = TRUE
+ max_integrity = 50
+ armor = list(melee = 50, bullet = 70, laser = 70, energy = 100, bomb = 10, bio = 100, rad = 100, fire = 0, acid = 0)
/obj/item/device/electronic_assembly/proc/check_interactivity(mob/user)
return user.canUseTopic(src,be_close = TRUE)
@@ -30,8 +32,6 @@
START_PROCESSING(SScircuit, src)
materials[MAT_METAL] = round((max_complexity + max_components) / 4) * SScircuit.cost_multiplier
-
-
/obj/item/device/electronic_assembly/Destroy()
STOP_PROCESSING(SScircuit, src)
return ..()
@@ -273,22 +273,9 @@
/obj/item/device/electronic_assembly/afterattack(atom/target, mob/user, proximity)
- for(var/obj/item/integrated_circuit/input/sensor/S in assembly_components)
- if(!proximity)
- if(istype(S,/obj/item/integrated_circuit/input/sensor/ranged)||(!user))
- if(user.client)
- if(!(target in view(user.client)))
- continue
- else
- if(!(target in view(user)))
- continue
- else
- continue
- S.set_pin_data(IC_OUTPUT, 1, WEAKREF(target))
- S.check_then_do_work()
- S.scan(target)
-
- visible_message(" [user] waves [src] around [target].")
+ 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/device/electronic_assembly/screwdriver_act(mob/living/user, obj/item/S)
@@ -326,8 +313,11 @@
interact(user)
return TRUE
else
+ for(var/obj/item/integrated_circuit/input/S in assembly_components)
+ S.attackby_react(I,user,user.a_intent)
return ..()
+
/obj/item/device/electronic_assembly/attack_self(mob/user)
if(!check_interactivity(user))
return
@@ -391,7 +381,6 @@
/obj/item/device/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()
@@ -406,6 +395,7 @@
/obj/item/device/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/device/electronic_assembly/calc
name = "type-b electronic assembly"
icon_state = "setup_small_calc"
@@ -507,4 +497,4 @@
/obj/item/device/electronic_assembly/drone/arms
name = "type-b electronic drone"
icon_state = "setup_drone_arms"
- desc = "It's a case, for building mobile electronics with. This one is armed and dangerous."
\ No newline at end of file
+ desc = "It's a case, for building mobile electronics with. This one is armed and dangerous."
diff --git a/code/modules/integrated_electronics/core/debugger.dm b/code/modules/integrated_electronics/core/debugger.dm
index ac6f5c1a1e..666fcf00d6 100644
--- a/code/modules/integrated_electronics/core/debugger.dm
+++ b/code/modules/integrated_electronics/core/debugger.dm
@@ -56,7 +56,7 @@
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].")
else if(io.io_type == PULSE_CHANNEL)
- io.holder.check_then_do_work(ignore_power = TRUE)
+ 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/code/modules/integrated_electronics/core/helpers.dm b/code/modules/integrated_electronics/core/helpers.dm
index e84823f201..773c4f0684 100644
--- a/code/modules/integrated_electronics/core/helpers.dm
+++ b/code/modules/integrated_electronics/core/helpers.dm
@@ -15,9 +15,9 @@
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))
+ 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))
+ 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)
diff --git a/code/modules/integrated_electronics/core/integrated_circuit.dm b/code/modules/integrated_electronics/core/integrated_circuit.dm
index 069ca4245c..0c1a2fdad5 100644
--- a/code/modules/integrated_electronics/core/integrated_circuit.dm
+++ b/code/modules/integrated_electronics/core/integrated_circuit.dm
@@ -58,6 +58,12 @@ a creative player the means to solve many problems. Circuits are held inside an
/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)
@@ -291,17 +297,18 @@ a creative player the means to solve many problems. Circuits are held inside an
return TRUE // Battery has enough.
return FALSE // Not enough power.
-/obj/item/integrated_circuit/proc/check_then_do_work(var/ignore_power = FALSE)
+/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
+ return FALSE
if(power_draw_per_use && !ignore_power)
if(!check_power())
power_fail()
- return
+ return FALSE
next_use = world.time + cooldown_per_use
- do_work()
+ do_work(ord)
+ return TRUE
-/obj/item/integrated_circuit/proc/do_work()
+/obj/item/integrated_circuit/proc/do_work(ord)
return
/obj/item/integrated_circuit/proc/disconnect_all()
@@ -369,4 +376,3 @@ a creative player the means to solve many problems. Circuits are held inside an
return TRUE
return FALSE
-
diff --git a/code/modules/integrated_electronics/core/pins.dm b/code/modules/integrated_electronics/core/pins.dm
index bff96b713c..528281c3b7 100644
--- a/code/modules/integrated_electronics/core/pins.dm
+++ b/code/modules/integrated_electronics/core/pins.dm
@@ -25,14 +25,16 @@ D [1]/ ||
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)
+/datum/integrated_io/New(loc, _name, _data, _pin_type,_ord)
name = _name
if(_data)
data = _data
if(_pin_type)
pin_type = _pin_type
+ if(_ord)
+ ord = _ord
holder = loc
@@ -148,7 +150,7 @@ D [1]/ ||
/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.holder.check_then_do_work(io.ord)
/datum/integrated_io/proc/pull_data()
for(var/k in 1 to linked.len)
@@ -207,7 +209,7 @@ D [1]/ ||
write_data_to_pin(new_data)
/datum/integrated_io/activate/ask_for_pin_data(mob/user) // This just pulses the pin.
- holder.check_then_do_work(ignore_power = TRUE)
+ holder.check_then_do_work(ord,ignore_power = TRUE)
to_chat(user, "You pulse \the [holder]'s [src] pin.")
/datum/integrated_io/activate
diff --git a/code/modules/integrated_electronics/core/special_pins/index_pin.dm b/code/modules/integrated_electronics/core/special_pins/index_pin.dm
index 51b12a0f3a..06267eec61 100644
--- a/code/modules/integrated_electronics/core/special_pins/index_pin.dm
+++ b/code/modules/integrated_electronics/core/special_pins/index_pin.dm
@@ -1,4 +1,4 @@
-// These pins can only contain integer numbers between 1 and IC_MAX_LIST_LENGTH. Null is not allowed.
+// 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
@@ -11,10 +11,10 @@
/datum/integrated_io/index/write_data_to_pin(new_data)
if(isnull(new_data))
- new_data = 1
+ new_data = 0
if(isnum(new_data))
- data = CLAMP(round(new_data), 1, IC_MAX_LIST_LENGTH)
+ data = CLAMP(round(new_data), 0, IC_MAX_LIST_LENGTH)
holder.on_data_written()
/datum/integrated_io/index/display_pin_type()
diff --git a/code/modules/integrated_electronics/subtypes/arithmetic.dm b/code/modules/integrated_electronics/subtypes/arithmetic.dm
index 7dec779f83..e491a34a69 100644
--- a/code/modules/integrated_electronics/subtypes/arithmetic.dm
+++ b/code/modules/integrated_electronics/subtypes/arithmetic.dm
@@ -30,10 +30,9 @@
/obj/item/integrated_circuit/arithmetic/addition/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(I.data))
- result = result + I.data
+ var/I = get_pin_data(IC_INPUT, k)
+ if(isnum(I))
+ result += I
set_pin_data(IC_OUTPUT, 1, result)
push_data()
@@ -56,13 +55,10 @@
return
var/result = A.data
- for(var/k in 1 to inputs.len)
- var/datum/integrated_io/I = inputs[k]
- if(I == A)
- continue
- I.pull_data()
- if(isnum(I.data))
- result = result - I.data
+ for(var/k in 2 to inputs.len)
+ var/I = get_pin_data(IC_INPUT, k)
+ if(isnum(I))
+ result -= I
set_pin_data(IC_OUTPUT, 1, result)
push_data()
@@ -85,13 +81,10 @@
if(!isnum(A.data))
return
var/result = A.data
- for(var/k in 1 to inputs.len)
- var/datum/integrated_io/I = inputs[k]
- if(I == A)
- continue
- I.pull_data()
- if(isnum(I.data))
- result = result * I.data
+ for(var/k in 2 to inputs.len)
+ var/I = get_pin_data(IC_INPUT, k)
+ if(isnum(I))
+ result *= I
set_pin_data(IC_OUTPUT, 1, result)
push_data()
@@ -114,13 +107,12 @@
return
var/result = A.data
- for(var/k in 1 to inputs.len)
- var/datum/integrated_io/I = inputs[k]
- if(I == A)
- continue
- I.pull_data()
- if(isnum(I.data) && I.data != 0) //No runtimes here.
- result = result / I.data
+
+ for(var/k in 2 to inputs.len)
+ var/I = get_pin_data(IC_INPUT, k)
+ if(isnum(I) && (I != 0))
+ result /= I
+
set_pin_data(IC_OUTPUT, 1, result)
push_data()
@@ -228,12 +220,11 @@
/obj/item/integrated_circuit/arithmetic/average/do_work()
var/result = 0
var/inputs_used = 0
- for(var/k in 1 to inputs.len)
- var/datum/integrated_io/I = inputs[k]
- I.pull_data()
- if(isnum(I.data))
+ for(var/k in 2 to inputs.len)
+ var/I = get_pin_data(IC_INPUT, k)
+ if(isnum(I))
inputs_used++
- result = result + I.data
+ result += I
if(inputs_used)
result = result / inputs_used
@@ -288,11 +279,10 @@
/obj/item/integrated_circuit/arithmetic/square_root/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(I.data))
- result = sqrt(I.data)
+ for(var/k in 2 to inputs.len)
+ var/I = get_pin_data(IC_INPUT, k)
+ if(isnum(I))
+ result += sqrt(I)
set_pin_data(IC_OUTPUT, 1, result)
push_data()
diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm
index d622ea8ca9..cd9306d0da 100644
--- a/code/modules/integrated_electronics/subtypes/converters.dm
+++ b/code/modules/integrated_electronics/subtypes/converters.dm
@@ -160,10 +160,10 @@
/obj/item/integrated_circuit/converter/concatenator/do_work()
var/result = null
- for(var/datum/integrated_io/I in inputs)
- I.pull_data()
- if(!isnull(I.data))
- result = result + I.data
+ for(var/k in 1 to inputs.len)
+ var/I = get_pin_data(IC_INPUT, k)
+ if(!isnull(I))
+ result = result + I
set_pin_data(IC_OUTPUT, 1, result)
push_data()
diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm
index c39cfeac44..91b4b437e3 100644
--- a/code/modules/integrated_electronics/subtypes/input.dm
+++ b/code/modules/integrated_electronics/subtypes/input.dm
@@ -128,7 +128,7 @@
var/mob/living/carbon/human/H = get_pin_data_as_type(IC_INPUT, 1, /mob/living/carbon/human)
if(!istype(H)) //Invalid input
return
- if(H in view(get_turf(H))) // Like medbot's analyzer it can be used in range..
+ 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
@@ -143,6 +143,49 @@
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."
+ icon_state = "medscan_adv"
+ complexity = 12
+ inputs = list("\[ target")
+ 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 params of plants in trays. \
@@ -180,7 +223,7 @@
return
for(var/i=1, i<=outputs.len, i++)
set_pin_data(IC_OUTPUT, i, null)
- if(H in view(get_turf(H))) // Like medbot's analyzer it can be used in range..
+ 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)
@@ -228,7 +271,7 @@
return
for(var/i=1, i<=outputs.len, i++)
set_pin_data(IC_OUTPUT, i, null)
- if(H in view(get_turf(H))) // Like medbot's analyzer it can be used in range..
+ 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())
@@ -671,12 +714,15 @@
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 120
-/obj/item/integrated_circuit/input/sensor/proc/scan(var/atom/A)
+/obj/item/integrated_circuit/input/sensor/sense(var/atom/A,mob/user,prox)
+ if(!prox)
+ 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()
activate_pin(1)
@@ -694,6 +740,52 @@
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 120
+/obj/item/integrated_circuit/input/sensor/ranged/sense(var/atom/A,mob/user)
+ if(!user)
+ 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()
+ activate_pin(1)
+ return TRUE
+
+/obj/item/integrated_circuit/input/objscaner
+ name = "scaner"
+ desc = "Scans and obtains a reference for any objects you use on assembly."
+ extended_desc = "If 'put down' pin is set to true, assembly will take scanned object from your hands to it's location.\
+ useful for interaction with grabber. Scaner works only with 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/objscaner/attackby_react(var/atom/A,var/mob/user,intent)
+ if(intent!=INTENT_HELP)
+ 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()
+ 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."
@@ -760,3 +852,38 @@
activate_pin(2)
push_data()
return
+
+/obj/item/integrated_circuit/input/ntnetsc
+ name = "NTnet scaner"
+ desc = "This can return NTnet id of component insi given object, if there is 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/list/processing_list = list(AM)
+ var/datum/component/ntnet_interface/net = null
+ set_pin_data(IC_OUTPUT, 1, null)
+ 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)
+ activate_pin(2)
+ else
+ activate_pin(3)
+ push_data()
+ return
diff --git a/code/modules/integrated_electronics/subtypes/logic.dm b/code/modules/integrated_electronics/subtypes/logic.dm
index 627301ef10..f8e858ef94 100644
--- a/code/modules/integrated_electronics/subtypes/logic.dm
+++ b/code/modules/integrated_electronics/subtypes/logic.dm
@@ -2,7 +2,7 @@
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 = 3
+ complexity = 1
outputs = list("result")
activators = list("compare" = IC_PINTYPE_PULSE_IN)
category_text = "Logic"
diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm
index f32f414fbb..5099547197 100644
--- a/code/modules/integrated_electronics/subtypes/manipulation.dm
+++ b/code/modules/integrated_electronics/subtypes/manipulation.dm
@@ -155,9 +155,11 @@
if(isnum(wanted_dir.data))
if(step(assembly, wanted_dir.data))
activate_pin(2)
+ return
else
activate_pin(3)
return FALSE
+ return FALSE
/obj/item/integrated_circuit/manipulation/grenade
name = "grenade primer"
@@ -247,9 +249,14 @@
/obj/item/integrated_circuit/manipulation/plant_module/do_work()
..()
var/turf/T = get_turf(src)
- var/obj/machinery/hydroponics/AM = get_pin_data_as_type(IC_INPUT, 1, /obj/machinery/hydroponics)
- if(!istype(AM)) //Invalid input
+ var/obj/OM = get_pin_data_as_type(IC_INPUT, 1, /obj)
+ if(istype(OM,/obj/structure/spacevine) && get_pin_data(IC_INPUT, 2) == 2)
+ qdel(OM)
+ activate_pin(2)
return
+ var/obj/machinery/hydroponics/AM = OM
+ if(!istype(AM)) //Invalid input
+ return FALSE
var/mob/living/M = get_turf(AM)
if(!M.Adjacent(T))
return //Can't reach
@@ -276,6 +283,7 @@
qdel(AM.myseed)
AM.myseed = null
AM.weedlevel = 0 //Has a side effect of cleaning up those nasty weeds
+ AM.dead = 0
AM.update_icon()
else
activate_pin(2)
@@ -284,7 +292,7 @@
/obj/item/integrated_circuit/manipulation/grabber
name = "grabber"
- desc = "A circuit with it's own inventory for small/medium items, used to grab and store things."
+ desc = "A circuit with it's own inventory for tiny/small items, used to grab and store things."
icon_state = "grabber"
extended_desc = "The circuit accepts a reference to thing to be grabbed. It can store up to 10 things. Modes: 1 for grab. 0 for eject the first thing. -1 for eject all."
w_class = WEIGHT_CLASS_SMALL
@@ -307,7 +315,7 @@
var/mode = get_pin_data(IC_INPUT, 2)
if(mode == 1)
- if(check_target(AM, exclude_contents = TRUE))
+ if(check_target(AM))
if((contents.len < max_items) && (!max_w_class || AM.w_class <= max_w_class))
AM.forceMove(src)
if(mode == 0)
diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm
index 33f92c3646..6f527c8149 100644
--- a/code/modules/integrated_electronics/subtypes/reagents.dm
+++ b/code/modules/integrated_electronics/subtypes/reagents.dm
@@ -9,6 +9,11 @@
. = ..()
if(volume)
create_reagents(volume)
+ 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/smoke
name = "smoke generator"
@@ -29,7 +34,8 @@
)
activators = list(
"create smoke" = IC_PINTYPE_PULSE_IN,
- "on smoked" = IC_PINTYPE_PULSE_OUT
+ "on smoked" = IC_PINTYPE_PULSE_OUT,
+ "push ref" = IC_PINTYPE_PULSE_IN
)
spawn_flags = IC_SPAWN_RESEARCH
power_draw_per_use = 20
@@ -40,24 +46,27 @@
//reset warning only if we have reagents now
if(changetype == ADD_REAGENT)
notified = FALSE
- set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
- push_data()
+ push_vol()
-/obj/item/integrated_circuit/reagent/smoke/do_work()
- 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)
+/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()
/obj/item/integrated_circuit/reagent/injector
name = "integrated hypo-injector"
@@ -85,7 +94,9 @@
activators = list(
"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
@@ -93,15 +104,8 @@
var/transfer_amount = 10
var/busy = FALSE
-/obj/item/integrated_circuit/reagent/injector/interact(mob/user)
- set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
- push_data()
- ..()
-
-
/obj/item/integrated_circuit/reagent/injector/on_reagent_change(changetype)
- set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
- push_data()
+ push_vol()
/obj/item/integrated_circuit/reagent/injector/on_data_written()
var/new_amount = get_pin_data(IC_INPUT, 2)
@@ -127,7 +131,15 @@
temp_reagents.clear_reagents()
qdel(temp_reagents)
-/obj/item/integrated_circuit/reagent/injector/do_work()
+/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()
@@ -281,17 +293,20 @@
"volume used" = IC_PINTYPE_NUMBER,
"self reference" = IC_PINTYPE_REF
)
- activators = list()
+ activators = list("push ref" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
+<<<<<<< HEAD
/obj/item/integrated_circuit/reagent/storage/interact(mob/user)
+=======
+
+/obj/item/integrated_circuit/reagent/storage/do_work()
+>>>>>>> 95b9e19... [READY]Circuitry upgrades (#33579)
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
push_data()
- ..()
/obj/item/integrated_circuit/reagent/storage/on_reagent_change(changetype)
- set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
- push_data()
+ push_vol()
/obj/item/integrated_circuit/reagent/storage/cryo
name = "cryo reagent storage"
@@ -306,6 +321,7 @@
. = ..()
reagents.set_reacting(FALSE)
+
/obj/item/integrated_circuit/reagent/storage/big
name = "big reagent storage"
desc = "Stores liquid inside, and away from electrical components. Can store up to 180u."
@@ -317,6 +333,99 @@
complexity = 16
spawn_flags = IC_SPAWN_RESEARCH
+/obj/item/integrated_circuit/reagent/storage/grinder
+ name = "reagent grinder"
+ desc = "This is reagent grinder.It accepts ref to something and refines it into reagents. 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_REF
+ )
+ 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 reagent juicer.It accepts ref to something and refines it into reagents. 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_REF
+ )
+ 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, and away from electrical components. Can store up to 60u. On pulse this beaker will send list of contained reagents."
@@ -330,17 +439,22 @@
"list of reagents" = IC_PINTYPE_LIST
)
activators = list(
- "scan" = IC_PINTYPE_PULSE_IN
+ "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()
- var/cont[0]
- for(var/datum/reagent/RE in reagents.reagent_list)
- cont += RE.id
- set_pin_data(IC_OUTPUT, 3, cont)
- push_data()
-
+/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.id
+ 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"
@@ -394,7 +508,8 @@
if(!source.reagents || !target.reagents)
return
- if(!source.is_drainable() || !target.is_refillable())
+ // 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)
@@ -410,3 +525,45 @@
activate_pin(2)
push_data()
+/obj/item/integrated_circuit/reagent/storage/heater
+ name = "chemical heater"
+ desc = "Stores liquid inside, and away from electrical components. Can store up to 60u. Will heat or freeze reagents \
+ to target temperature, when turned on."
+ icon_state = "heater"
+ container_type = OPENCONTAINER
+ 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_REF,"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)
+ var/target_temperature = get_pin_data(IC_INPUT, 1)
+ 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()
diff --git a/code/modules/integrated_electronics/subtypes/smart.dm b/code/modules/integrated_electronics/subtypes/smart.dm
index ec59c3cab1..37a38677b0 100644
--- a/code/modules/integrated_electronics/subtypes/smart.dm
+++ b/code/modules/integrated_electronics/subtypes/smart.dm
@@ -27,6 +27,6 @@
push_data()
return // Can't see the target.
- set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_turf(A)))
+ set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_step_towards2(get_turf(src),A)))
push_data()
activate_pin(2)
diff --git a/icons/obj/assemblies/electronic_components.dmi b/icons/obj/assemblies/electronic_components.dmi
index 1852079e7392745c0a3911bf1ea557f74b052e0d..a9dac06d6b8bcc864bce0ca0194ba949b0856b4d 100644
GIT binary patch
literal 22954
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]D2czKwr)kovZSq6#znszP+l0hT
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