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 1852079e73..a9dac06d6b 100644 Binary files a/icons/obj/assemblies/electronic_components.dmi and b/icons/obj/assemblies/electronic_components.dmi differ