From 197e1b00f6f0b2f80f366a66998b0122716b84b0 Mon Sep 17 00:00:00 2001 From: Stakks Date: Sun, 8 Apr 2018 10:19:51 -0500 Subject: [PATCH 1/9] Stage 1 --- code/__HELPERS/maths.dm | 4 + .../objects/items/weapons/storage/belt.dm | 1 + .../integrated_electronics/_defines.dm | 356 ++++++++++++++++++ .../integrated_electronics/arithmetic.dm | 157 ++++++++ .../integrated_electronics/assemblies.dm | 109 ++++++ .../integrated_electronics/converters.dm | 96 +++++ .../integrated_electronics/coordinate.dm | 74 ++++ .../integrated_electronics/data_transfer.dm | 79 ++++ .../integrated_electronics/input_output.dm | 91 +++++ code/modules/integrated_electronics/logic.dm | 172 +++++++++ .../integrated_electronics/manipulation.dm | 118 ++++++ code/modules/integrated_electronics/memory.dm | 83 ++++ code/modules/integrated_electronics/time.dm | 120 ++++++ code/modules/integrated_electronics/tools.dm | 201 ++++++++++ code/modules/projectiles/gun.dm | 68 ++++ icons/obj/electronic_assemblies.dmi | Bin 0 -> 1370 bytes tgstation.dme | 12 + 17 files changed, 1741 insertions(+) create mode 100644 code/modules/integrated_electronics/_defines.dm create mode 100644 code/modules/integrated_electronics/arithmetic.dm create mode 100644 code/modules/integrated_electronics/assemblies.dm create mode 100644 code/modules/integrated_electronics/converters.dm create mode 100644 code/modules/integrated_electronics/coordinate.dm create mode 100644 code/modules/integrated_electronics/data_transfer.dm create mode 100644 code/modules/integrated_electronics/input_output.dm create mode 100644 code/modules/integrated_electronics/logic.dm create mode 100644 code/modules/integrated_electronics/manipulation.dm create mode 100644 code/modules/integrated_electronics/memory.dm create mode 100644 code/modules/integrated_electronics/time.dm create mode 100644 code/modules/integrated_electronics/tools.dm create mode 100644 icons/obj/electronic_assemblies.dmi diff --git a/code/__HELPERS/maths.dm b/code/__HELPERS/maths.dm index 82128de15ffd9..7f6d114ebab70 100644 --- a/code/__HELPERS/maths.dm +++ b/code/__HELPERS/maths.dm @@ -20,6 +20,10 @@ var/list/sqrtTable = list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, /proc/Ceiling(x) return -round(-x) +/proc/Floor(x) + return -round(-x)-1 + + ///proc/Clamp(val, min, max) // return max(min, min(val, max)) diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index c3d4af1d51679..95dfb1e214da9 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -30,6 +30,7 @@ /obj/item/device/t_scanner, /obj/item/device/analyzer, /obj/item/weapon/extinguisher/mini + /obj/item/device/integrated_electronics/wirer, ) /obj/item/weapon/storage/belt/utility/full/New() diff --git a/code/modules/integrated_electronics/_defines.dm b/code/modules/integrated_electronics/_defines.dm new file mode 100644 index 0000000000000..737b1914614b3 --- /dev/null +++ b/code/modules/integrated_electronics/_defines.dm @@ -0,0 +1,356 @@ +#define DATA_CHANNEL "data channel" +#define PULSE_CHANNEL "pulse channel" + +/obj/item/integrated_circuit + name = "integrated circuit" + desc = "It's a tiny chip! This one doesn't seem to do much, however." + icon = 'icons/obj/electronic_assemblies.dmi' + icon_state = "template" + w_class = 1 + var/extended_desc = null + var/list/inputs = list() + var/list/outputs = list() + var/list/activators = list() + var/number_of_inputs = 0 //This is how many input pins are created + var/number_of_outputs = 0 //Likewise for output + var/number_of_activators = 0 //Guess + var/list/input_names = list() + var/list/output_names = list() + var/list/activator_names = list() + var/last_used = 0 //Uses world.time + var/complexity = 1 //This acts as a limitation on building machines, more resource-intensive components cost more 'space'. + var/power_required = 5 //w + +/obj/item/integrated_circuit/examine(mob/user) + ..() + user << "This board has [inputs.len] input [inputs.len != 1 ? "pins" : "pin"] and \ + [outputs.len] output [outputs.len != 1 ? "pins" : "pin"]." + for(var/datum/integrated_io/input/I in inputs) + if(I.linked.len) + user << "\The [I.name] is connected to [I.get_linked_to_desc()]." + for(var/datum/integrated_io/output/O in outputs) + if(O.linked.len) + user << "\The [O.name] is connected to [O.get_linked_to_desc()]." + for(var/datum/integrated_io/activate/A in activators) + if(A.linked.len) + user << "\The [A.name] is connected to [A.get_linked_to_desc()]." + + interact(user) + +/obj/item/integrated_circuit/New() + ..() + var/i = 0 + if(number_of_inputs) + for(i = number_of_inputs, i > 0, i--) + inputs.Add(new /datum/integrated_io/input(src)) + + if(number_of_outputs) + for(i = number_of_outputs, i > 0, i--) + outputs.Add(new /datum/integrated_io/output(src)) + + if(number_of_activators) + for(i = number_of_activators, i > 0, i--) + activators.Add(new /datum/integrated_io/activate(src)) + + apply_names_to_io() + +/obj/item/integrated_circuit/proc/apply_names_to_io() + var/i = 1 + if(input_names.len) + for(var/datum/integrated_io/input/I in inputs) + I.name = "[input_names[i]]" + i++ + i = 1 + if(output_names.len) + for(var/datum/integrated_io/output/O in outputs) + O.name = "[output_names[i]]" + i++ + + i = 1 + if(activator_names.len) + for(var/datum/integrated_io/activate/A in activators) + A.name = "[activator_names[i]]" + i++ + +/obj/item/integrated_circuit/Destroy() + for(var/datum/integrated_io/I in inputs) + qdel(I) + for(var/datum/integrated_io/O in outputs) + qdel(O) + for(var/datum/integrated_io/A in activators) + qdel(A) + ..() + +/obj/item/integrated_circuit/emp_act(severity) + for(var/datum/integrated_io/io in inputs + outputs + activators) + io.scramble() + +/obj/item/integrated_circuit/verb/rename_component() + set name = "Rename Circuit" + set category = "Object" + set desc = "Rename your circuit, useful to stay organized." + + var/mob/M = usr + + var/input = sanitize_text(input("What do you want to name the circuit?", ,"")) + + if(src && input) + M << "The circuit '[src.name]' is now labeled '[input]'." + name = input + +/obj/item/integrated_circuit/proc/get_pin_ref(var/pin_type, var/pin_number) + switch(pin_type) + if("input") + if(pin_number > inputs.len) + return null + return inputs[pin_number] + if("output") + if(pin_number > outputs.len) + return null + return outputs[pin_number] + if("activator") + if(pin_number > activators.len) + return null + return activators[pin_number] + return null + +/obj/item/integrated_circuit/interact(mob/user) + if(get_dist(get_turf(src), user) > 1) + user.unset_machine(src) + return + var/HTML = "[src.name]" + HTML += "
" + HTML += "" + + HTML += "
\[Refresh\] | " + HTML += "\[Rename\]
" + + HTML += "" + HTML += "" + HTML += "" + HTML += "" + HTML += "" + + var/column_width = 3 + var/row_height = max(inputs.len, outputs.len, 1) + var/i + var/j + for(i = 1, i < row_height+1, i++) + HTML += "" + for(j = 1, j < column_width+1, j++) + var/datum/integrated_io/io = null + var/words = null + var/height = 1 + switch(j) + if(1) + io = get_pin_ref("input",i) + if(io) + if(io.linked.len) + words = "[io.name] [io.display_data()]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + else // "Click here!" + words = "[io.name] [io.display_data()]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + if(outputs.len > inputs.len) + height = Floor(outputs.len / inputs.len) + //world << "I wrote [words] at ([i],[j])." + if(2) + if(i == 1) + words = "[src.name]

[src.desc]" + height = row_height + //world << "I wrote the center piece because i was equal to 1, at ([i],[j])." + else + continue + if(3) + io = get_pin_ref("output",i) + if(io) + if(io.linked.len) + words = "[io.name] [io.display_data()]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + else + words = "[io.name] [io.display_data()]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + if(inputs.len > outputs.len) + height = Floor(inputs.len / outputs.len) + //world << "I wrote [words] at ([i],[j])." + HTML += "" + //HTML += "" + //world << "Writing to ([i],[j])." + HTML += "" + + if(activators.len) + for(i = 1, i < activators.len+1, i++) + var/datum/integrated_io/io = null + var/words = null + io = get_pin_ref("activator",i) + if(io) + if(io.linked.len) + words = "[io.name]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + else // "Click here!" + words = "[io.name]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + HTML += "" + HTML += "" + HTML += "" + + HTML += "
[words][words]
[words]
" + HTML += "
" + + HTML += "
[extended_desc]" + + HTML += "" + user << browse(HTML, "window=circuit-\ref[src];size=600x350;border=1;can_resize=1;can_close=1;can_minimize=1") + + user.set_machine(src) + onclose(user, "circuit-\ref[src]") + +/obj/item/integrated_circuit/Topic(href, href_list[]) + var/mob/living/user = locate(href_list["user"]) in mob_list + var/pin = locate(href_list["pin"]) in inputs + outputs + activators + + if(!user || !user.Adjacent(get_turf(src)) ) + return 1 + + if(href_list["wire"]) + if(ishuman(user) && Adjacent(user)) + var/mob/living/carbon/human/H = user + var/obj/item/device/integrated_electronics/wirer/wirer = null + if(istype(H.r_hand, /obj/item/device/integrated_electronics/wirer)) + wirer = H.r_hand + else if(istype(H.l_hand, /obj/item/device/integrated_electronics/wirer)) + wirer = H.l_hand + + if(wirer && pin) + wirer.wire(pin, user) + else + user << "You can't do a whole lot without tools." + + if(href_list["examine"]) + examine(user) + + if(href_list["rename"]) + rename_component(user) + + interact(user) // To refresh the UI. + +/datum/integrated_io + var/name = "input/output" + var/obj/item/integrated_circuit/holder = null + var/data = null + var/list/linked = list() + var/io_type = DATA_CHANNEL + +/datum/integrated_io/New(var/newloc) + ..() + holder = newloc + if(!holder) + message_admins("ERROR: An integrated_io ([src.name]) spawned without a holder! This is a bug.") + +/datum/integrated_io/Destroy() + disconnect() + holder = null + ..() + +/datum/integrated_io/proc/display_data() + if(!data) + return "(null)" // Empty data means nothing to show. + if(istext(data)) + return "(\"[data]\")" // Wraps the 'string' in escaped quotes, so that people know it's a 'string'. + if(istype(data, /atom)) + var/atom/A = data + return "([A.name] \[Ref\])" // For refs, we want just the name displayed. + return "([data])" // Nothing special needed for numbers or other stuff. + +/datum/integrated_io/activate/display_data() + return "(\[pulse\])" + +/datum/integrated_io/proc/scramble() + if(isnull(data)) + return + if(isnum(data)) + data = rand(-10000, 10000) + if(istext(data)) + data = "ERROR" + push_data() + +/datum/integrated_io/activate/scramble() + push_data() + +/datum/integrated_io/proc/push_data() + if(linked.len) + for(var/datum/integrated_io/io in linked) + io.data = data + +/datum/integrated_io/activate/push_data() + if(linked.len) + for(var/datum/integrated_io/io in linked) + io.holder.work() + +/datum/integrated_io/proc/pull_data() + if(linked.len) + for(var/datum/integrated_io/io in linked) + data = io.data + +/datum/integrated_io/proc/get_linked_to_desc() + if(linked.len) + var/result = english_list(linked) + return "the [result]" + return "nothing" + +/datum/integrated_io/proc/disconnect() + if(linked.len) + //First we iterate over everything we are linked to. + for(var/datum/integrated_io/their_io in linked) + //While doing that, we iterate them as well, and disconnect ourselves from them. + for(var/datum/integrated_io/their_linked_io in their_io.linked) + if(their_linked_io == src) + their_io.linked.Remove(src) + else + continue + //Now that we're removed from them, we gotta remove them from us. + src.linked.Remove(their_io) + +/datum/integrated_io/input + name = "input pin" + +/datum/integrated_io/output + name = "output pin" + +/datum/integrated_io/activate + name = "activation pin" + io_type = PULSE_CHANNEL + +/obj/item/integrated_circuit/proc/push_data() + for(var/datum/integrated_io/output/O in outputs) + O.push_data() + +/obj/item/integrated_circuit/proc/pull_data() + for(var/datum/integrated_io/input/I in inputs) + I.push_data() + +/obj/item/integrated_circuit/proc/work() + if(last_used + 2 SECONDS > world.time) // All intergrated circuits have an internal cooldown of two seconds to protect from spam. + return 0 + last_used = world.time + return 1 + +/obj/item/integrated_circuit/proc/disconnect_all() + for(var/datum/integrated_io/input/I in inputs) + I.disconnect() + for(var/datum/integrated_io/output/O in outputs) + O.disconnect() + for(var/datum/integrated_io/activate/A in activators) + A.disconnect() \ No newline at end of file diff --git a/code/modules/integrated_electronics/arithmetic.dm b/code/modules/integrated_electronics/arithmetic.dm new file mode 100644 index 0000000000000..5f5a4f1d2e6ae --- /dev/null +++ b/code/modules/integrated_electronics/arithmetic.dm @@ -0,0 +1,157 @@ +//These circuits do simple math. +/obj/item/integrated_circuit/arithmetic + complexity = 1 + number_of_inputs = 8 + number_of_outputs = 1 + number_of_activators = 1 + input_names = list( + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H" + ) + output_names = list( + "result" + ) + activator_names = list( + "compute" + ) + +// +Adding+ // + +/obj/item/integrated_circuit/arithmetic/addition + name = "addition circuit" + desc = "This circuit can add numbers together." + icon_state = "addition" + +/obj/item/integrated_circuit/arithmetic/addition/work() + if(..()) + var/result = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data)) + result = result + I.data + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// -Subtracting- // + +/obj/item/integrated_circuit/arithmetic/subtraction + name = "subtraction circuit" + desc = "This circuit can subtract numbers." + icon_state = "subtraction" + +/obj/item/integrated_circuit/arithmetic/subtraction/work() + if(..()) + var/result = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data)) + result = result - I.data + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// *Multiply* // + +/obj/item/integrated_circuit/arithmetic/multiplication + name = "multiplication circuit" + desc = "This circuit can multiply numbers." + icon_state = "multiplication" + +/obj/item/integrated_circuit/arithmetic/subtraction/work() + if(..()) + var/result = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data)) + result = result * I.data + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// /Division/ // + +/obj/item/integrated_circuit/arithmetic/division + name = "division circuit" + desc = "This circuit can divide numbers, just don't think about trying to divide by zero!" + icon_state = "division" + +/obj/item/integrated_circuit/arithmetic/division/work() + if(..()) + var/result = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data) && I.data != 0) //No runtimes here. + result = result / I.data + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// Absolute // + +/obj/item/integrated_circuit/arithmetic/absolute + name = "absolute circuit" + desc = "This outputs a non-negative version of the number you put in. This may also be thought of as its distance from zero." + icon_state = "absolute" + number_of_inputs = 1 + number_of_outputs = 1 + +/obj/item/integrated_circuit/arithmetic/absolute/work() + if(..()) + var/result = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data) && I.data != 0) + result = abs(result) + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// Averaging // + +/obj/item/integrated_circuit/arithmetic/average + name = "average circuit" + desc = "This circuit is of average quality, however it will compute the average for numbers you give it." + icon_state = "average" + +/obj/item/integrated_circuit/arithmetic/average/work() + if(..()) + var/result = 0 + var/inputs_used = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data)) + inputs_used++ + result = result + I.data + + if(inputs_used) + result = result / inputs_used + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// Pi, because why the hell not? // +/obj/item/integrated_circuit/arithmetic/pi + name = "pi constant circuit" + desc = "Not recommended for cooking. Outputs '3.14159' when it receives a pulse." + icon_state = "pi" + number_of_inputs = 0 + number_of_outputs = 1 + +/obj/item/integrated_circuit/arithmetic/pi/work() + if(..()) + var/datum/integrated_io/output/O = outputs[1] + O.data = 3.14159 + O.push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/assemblies.dm b/code/modules/integrated_electronics/assemblies.dm new file mode 100644 index 0000000000000..97690b977f880 --- /dev/null +++ b/code/modules/integrated_electronics/assemblies.dm @@ -0,0 +1,109 @@ +/obj/item/device/electronic_assembly + name = "electronic assembly" + desc = "It's a case, for building electronics with." + w_class = 2 + icon = 'icons/obj/electronic_assemblies.dmi' + icon_state = "setup" + var/max_components = 10 + var/max_complexity = 30 + var/opened = 0 + +/obj/item/device/electronic_assembly/medium + name = "electronic mechanism" + w_class = 3 + max_components = 20 + max_complexity = 50 + +/obj/item/device/electronic_assembly/large + name = "electronic machine" + w_class = 4 + max_components = 30 + max_complexity = 60 + +/* + +/obj/item/device/electronic_assembly/New() + ..() + processing_objects |= src + +/obj/item/device/electronic_assembly/Destroy() + processing_objects.Remove(src) + ..() + +/obj/item/device/electronic_assembly/process() + for(var/obj/item/integrated_circuit/IC in contents) + IC.work() +*/ + +/obj/item/device/electronic_assembly/examine(mob/user) + ..() + if(!opened) + for(var/obj/item/integrated_circuit/output/screen/S in contents) + if(S.stuff_to_display) + user << "There's a little screen labeled '[S.name]', which displays '[S.stuff_to_display]'." + else + var/obj/item/integrated_circuit/IC = input(user, "Which circuit do you want to examine?", "Examination") as null|anything in contents + if(IC) + IC.examine(user) + +/obj/item/device/electronic_assembly/attackby(var/obj/item/I, var/mob/user) + if(istype(I, /obj/item/integrated_circuit)) + if(!opened) + user << "\The [src] isn't opened, so you can't put anything inside. Try using a crowbar." + return 0 + var/obj/item/integrated_circuit/IC = I + var/total_parts = 0 + var/total_complexity = 0 + for(var/obj/item/integrated_circuit/part in contents) + total_parts++ + total_complexity = total_complexity + part.complexity + + if( (total_parts + 1) >= max_components) + user << "You can't seem to add this [IC.name], since there's no more room." + return 0 + if( (total_complexity + IC.complexity) >= max_complexity) + user << "You can't seem to add this [IC.name], since this setup's too complicated for the case." + return 0 + + user << "You slide \the [IC] inside \the [src]." + user.drop_item() + IC.forceMove(src) + playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) + if(istype(I, /obj/item/weapon/screwdriver)) + if(!opened) + user << "\The [src] isn't opened, so you can't remove anything inside. Try using a crowbar." + return 0 + if(!contents.len) + user << "There's nothing inside this to remove!" + return 0 + var/obj/item/integrated_circuit/option = input("What do you want to remove?", "Component Removal") as null|anything in contents + if(option) + option.disconnect_all() + option.forceMove(get_turf(src)) + playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) + user << "You pop \the [option] out of the case, and slide it out." + if(istype(I, /obj/item/weapon/crowbar)) + playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) + opened = !opened + user << "You [opened ? "opened" : "closed"] \the [src]." + if(istype(I, /obj/item/device/integrated_electronics/wirer)) + if(opened) + var/obj/item/integrated_circuit/IC = input(user, "Which circuit do you want to examine?", "Examination") as null|anything in contents + if(IC) + IC.examine(user) + else + user << "\The [src] isn't opened, so you can't fiddle with the internal components. \ + Try using a crowbar." + +/obj/item/device/electronic_assembly/attack_self(mob/user) + var/list/available_inputs = list() + for(var/obj/item/integrated_circuit/input/input in contents) + available_inputs.Add(input) + var/obj/item/integrated_circuit/input/choice = input(user, "What do you want to interact with?", "Interaction") as null|anything in available_inputs + if(choice) + choice.ask_for_input(user) + +/obj/item/device/electronic_assembly/emp_act(severity) + ..() + for(var/atom/movable/AM in contents) + AM.emp_act(severity) diff --git a/code/modules/integrated_electronics/converters.dm b/code/modules/integrated_electronics/converters.dm new file mode 100644 index 0000000000000..0bd2166419528 --- /dev/null +++ b/code/modules/integrated_electronics/converters.dm @@ -0,0 +1,96 @@ +//These circuits convert one variable to another. +/obj/item/integrated_circuit/converter + complexity = 2 + number_of_inputs = 1 + number_of_outputs = 1 + number_of_activators = 1 + input_names = list( + "input", + ) + output_names = list( + "result" + ) + activator_names = list( + "convert" + ) + +/obj/item/integrated_circuit/converter/num2text + name = "number to string" + desc = "This circuit can convert a number variable into a string." + icon_state = "addition" + +/obj/item/integrated_circuit/converter/num2text/work() + if(..()) + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + if(incoming.data && isnum(incoming.data)) + result = num2text(incoming.data) + + outgoing.data = result + outgoing.push_data() + +/obj/item/integrated_circuit/converter/text2num + name = "string to number" + desc = "This circuit can convert a string variable into a number." + icon_state = "addition" + +/obj/item/integrated_circuit/converter/text2num/work() + if(..()) + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + if(incoming.data && istext(incoming.data)) + result = text2num(incoming.data) + + outgoing.data = result + outgoing.push_data() + +/obj/item/integrated_circuit/converter/ref2text + name = "reference to string" + desc = "This circuit can convert a reference to something else to a string, specifically the name of that reference." + icon_state = "addition" + +/obj/item/integrated_circuit/converter/ref2text/work() + if(..()) + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + if(incoming.data && istype(incoming.data, /atom/)) + var/atom/A = incoming.data + result = A.name + + outgoing.data = result + outgoing.push_data() + +/obj/item/integrated_circuit/converter/lowercase + name = "lowercase string converter" + desc = "this will cause a string to come out in all lowercase." + icon_state = "addition" + +/obj/item/integrated_circuit/converter/lowercase/work() + if(..()) + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + if(incoming.data && istext(incoming.data)) + result = lowertext(incoming.data) + + outgoing.data = result + outgoing.push_data() + +/obj/item/integrated_circuit/converter/uppercase + name = "uppercase string converter" + desc = "THIS WILL CAUSE A STRING TO COME OUT IN ALL UPPERCASE." + icon_state = "addition" + +/obj/item/integrated_circuit/converter/uppercase/work() + if(..()) + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + if(incoming.data && istext(incoming.data)) + result = uppertext(incoming.data) + + outgoing.data = result + outgoing.push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/coordinate.dm b/code/modules/integrated_electronics/coordinate.dm new file mode 100644 index 0000000000000..04409907ac85c --- /dev/null +++ b/code/modules/integrated_electronics/coordinate.dm @@ -0,0 +1,74 @@ +//This circuit gives information on where the machine is. +/obj/item/integrated_circuit/gps + name = "global positioning system" + desc = "This allows you to easily know the position of a machine containing this device." + complexity = 4 + number_of_inputs = 0 + number_of_outputs = 2 + number_of_activators = 1 + input_names = list( + ) + output_names = list( + "X (abs)", + "Y (abs)" + ) + activator_names = list( + "get coordinates" + ) + +/obj/item/integrated_circuit/gps/work() + if(..()) + var/turf/T = get_turf(src) + var/datum/integrated_io/result_x = outputs[1] + var/datum/integrated_io/result_y = outputs[2] + + result_x.data = null + result_y.data = null + if(!T) + return + + result_x.data = T.x + result_y.data = T.y + + for(var/datum/integrated_io/output/O in outputs) + O.push_data() + +/obj/item/integrated_circuit/abs_to_rel_coords + name = "abs to rel coordinate converter" + desc = "Easily convert absolute coordinates to relative coordinates with this." + complexity = 4 + number_of_inputs = 0 + number_of_outputs = 4 + number_of_activators = 1 + input_names = list( + "X1 (abs)", + "Y1 (abs)", + "X2 (abs)", + "Y2 (abs)" + ) + output_names = list( + "X (rel)", + "Y (rel)" + ) + activator_names = list( + "compute rel coordinates" + ) + +/obj/item/integrated_circuit/abs_to_rel_coords/work() + var/datum/integrated_io/x1 = inputs[1] + var/datum/integrated_io/y1 = inputs[2] + + var/datum/integrated_io/x2 = inputs[3] + var/datum/integrated_io/y2 = inputs[4] + + var/datum/integrated_io/result_x = outputs[1] + var/datum/integrated_io/result_y = outputs[2] + + if(x1.data && y1.data && x2.data && y2.data) + result_x.data = x1.data - x2.data + result_y.data = y1.data - y2.data + + + for(var/datum/integrated_io/output/O in outputs) + O.push_data() + ..() diff --git a/code/modules/integrated_electronics/data_transfer.dm b/code/modules/integrated_electronics/data_transfer.dm new file mode 100644 index 0000000000000..12380e9ccac53 --- /dev/null +++ b/code/modules/integrated_electronics/data_transfer.dm @@ -0,0 +1,79 @@ +/obj/item/integrated_circuit/transfer/splitter + name = "splitter" + desc = "Splits incoming data into all of the output pins." + icon_state = "splitter" + complexity = 3 + number_of_inputs = 1 + number_of_outputs = 2 + input_names = list( + "data to split" + ) + output_names = list( + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H" + ) + +/obj/item/integrated_circuit/transfer/splitter/medium + name = "four splitter" + icon_state = "splitter4" + complexity = 5 + number_of_inputs = 1 + number_of_outputs = 4 + +/obj/item/integrated_circuit/transfer/splitter/large + name = "eight splitter" + icon_state = "splitter8" + complexity = 9 + number_of_inputs = 1 + number_of_outputs = 8 + +/obj/item/integrated_circuit/transfer/splitter/work() + if(..()) + var/datum/integrated_io/I = inputs[1] + for(var/datum/integrated_io/output/O in outputs) + O.data = I.data + +/obj/item/integrated_circuit/transfer/activator_splitter + name = "activator splitter" + desc = "Splits incoming activation pulses into all of the output pins." + icon_state = "splitter" + complexity = 3 + number_of_activators = 3 + activator_names = list( + "incoming pulse", + "outgoing pulse A", + "outgoing pulse B", + "outgoing pulse C", + "outgoing pulse D", + "outgoing pulse E", + "outgoing pulse F", + "outgoing pulse G", + "outgoing pulse H" + ) + +/obj/item/integrated_circuit/transfer/activator_splitter/work() + if(..()) + for(var/datum/integrated_io/activate/A in outputs) + if(A == activators[1]) + continue + if(A.linked.len) + for(var/datum/integrated_io/activate/target in A.linked) + target.holder.work() + +/obj/item/integrated_circuit/transfer/activator_splitter/medium + name = "four activator splitter" + icon_state = "splitter4" + complexity = 5 + number_of_activators = 5 + +/obj/item/integrated_circuit/transfer/activator_splitter/large + name = "eight activator splitter" + icon_state = "splitter4" + complexity = 9 + number_of_activators = 9 diff --git a/code/modules/integrated_electronics/input_output.dm b/code/modules/integrated_electronics/input_output.dm new file mode 100644 index 0000000000000..8f9c2cac0409e --- /dev/null +++ b/code/modules/integrated_electronics/input_output.dm @@ -0,0 +1,91 @@ +/obj/item/integrated_circuit/input/proc/ask_for_input(mob/user) + return + +/obj/item/integrated_circuit/input/button + name = "button" + desc = "This tiny button must do something, right?" + icon_state = "button" + number_of_inputs = 0 + number_of_outputs = 0 + number_of_activators = 1 + complexity = 1 + activator_names = list( + "on pressed" + ) + +/obj/item/integrated_circuit/input/button/ask_for_input(mob/user) //Bit misleading name for this specific use. + var/datum/integrated_io/A = activators[1] + if(A.linked.len) + for(var/datum/integrated_io/activate/target in A.linked) + target.holder.work() + user << "You press the button labeled '[src.name]'." + +/obj/item/integrated_circuit/input/numberpad + name = "number pad" + desc = "This small number pad allows someone to input a number into the system." + icon_state = "numberpad" + number_of_inputs = 0 + number_of_outputs = 1 + number_of_activators = 1 + complexity = 2 + output_names = list( + "number entered" + ) + activator_names = list( + "on entered" + ) + +/obj/item/integrated_circuit/input/numberpad/ask_for_input(mob/user) + var/new_input = input(user, "Enter a number, please.","Number pad") as num + if(new_input && isnum(new_input)) + var/datum/integrated_io/O = outputs[1] + O.data = new_input + O.push_data() + var/datum/integrated_io/A = activators[1] + if(A.linked) + A.holder.work() + +/obj/item/integrated_circuit/input/textpad + name = "text pad" + desc = "This small text pad allows someone to input a string into the system." + icon_state = "numberpad" + number_of_inputs = 0 + number_of_outputs = 1 + number_of_activators = 1 + complexity = 2 + output_names = list( + "string entered" + ) + activator_names = list( + "on entered" + ) + +/obj/item/integrated_circuit/input/textpad/ask_for_input(mob/user) + var/new_input = input(user, "Enter some words, please.","Number pad") as text + if(new_input && istext(new_input)) + var/datum/integrated_io/O = outputs[1] + O.data = new_input + O.push_data() + var/datum/integrated_io/A = activators[1] + if(A.linked) + A.holder.work() + +/obj/item/integrated_circuit/output/screen + name = "screen" + desc = "This small screen can display a single piece of data, when the machine is examined closely." + icon_state = "screen" + complexity = 4 + number_of_inputs = 1 + number_of_outputs = 0 + number_of_activators = 1 + input_names = list( + "displayed data" + ) + activator_names = list( + "load data" + ) + var/stuff_to_display = null + +/obj/item/integrated_circuit/output/screen/work() + var/datum/integrated_io/I = inputs[1] + stuff_to_display = I.data \ No newline at end of file diff --git a/code/modules/integrated_electronics/logic.dm b/code/modules/integrated_electronics/logic.dm new file mode 100644 index 0000000000000..4d123c61d097b --- /dev/null +++ b/code/modules/integrated_electronics/logic.dm @@ -0,0 +1,172 @@ +/obj/item/integrated_circuit/logic + name = "logic gate" + desc = "This tiny chip will decide for you!" + complexity = 3 + number_of_inputs = 2 + number_of_outputs = 1 + number_of_activators = 2 + input_names = list( + "A", + "B" + ) + output_names = list( + "result" + ) + activator_names = list( + "compare", + "on true result" + ) + +/obj/item/integrated_circuit/logic/equals + name = "equal gate" + desc = "This gate compares two values, and outputs the number one if both are the same." + icon_state = "equal" + +/obj/item/integrated_circuit/logic/equals/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data == B.data) + O.data = 1 + O.push_data() + P.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/not + name = "not gate" + desc = "This gate inverts what's fed into it." + icon_state = "not" + number_of_inputs = 1 + number_of_outputs = 1 + number_of_activators = 1 + output_names = list( + "invert" + ) + + +/obj/item/integrated_circuit/logic/not/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/O = outputs[1] + if(A.data) + O.data = !A.data + O.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/and + name = "and gate" + desc = "This gate will output 'one' if both inputs evaluate to true." + icon_state = "and" + +/obj/item/integrated_circuit/logic/and/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data && B.data) + O.data = 1 + O.push_data() + A.push_data() + P.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/or + name = "or gate" + desc = "This gate will output 'one' if one of the inputs evaluate to true." + icon_state = "or" + +/obj/item/integrated_circuit/logic/or/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data || B.data) + O.data = 1 + O.push_data() + A.push_data() + P.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/less_than + name = "less than gate" + desc = "This will output 'one' if the first input is less than the second input." + icon_state = "less_than" + +/obj/item/integrated_circuit/logic/less_than/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data < B.data) + O.data = 1 + O.push_data() + A.push_data() + P.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/less_than_or_equal + name = "less than or equal gate" + desc = "This will output 'one' if the first input is less than, or equal to the second input." + icon_state = "less_than_or_equal" + +/obj/item/integrated_circuit/logic/less_than_or_equal/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data <= B.data) + O.data = 1 + O.push_data() + A.push_data() + P.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/greater_than + name = "greater than gate" + desc = "This will output 'one' if the first input is greater than the second input." + icon_state = "greater_than" + +/obj/item/integrated_circuit/logic/greater_than/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data > B.data) + O.data = 1 + O.push_data() + A.push_data() + P.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/greater_than_or_equal + name = "greater_than or equal gate" + desc = "This will output 'one' if the first input is greater than, or equal to the second input." + icon_state = "greater_than_or_equal" + +/obj/item/integrated_circuit/logic/greater_than_or_equal/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data >= B.data) + O.data = 1 + O.push_data() + A.push_data() + P.push_data() + else + O.data = 0 \ No newline at end of file diff --git a/code/modules/integrated_electronics/manipulation.dm b/code/modules/integrated_electronics/manipulation.dm new file mode 100644 index 0000000000000..2b4d4248b3aa0 --- /dev/null +++ b/code/modules/integrated_electronics/manipulation.dm @@ -0,0 +1,118 @@ +/obj/item/integrated_circuit/manipulation/weapon_firing + name = "weapon firing mechanism" + desc = "This somewhat complicated system allows one to slot in a gun, direct it towards a position, and remotely fire it." + extended_desc = "The firing mechanism can slot in most ranged weapons, ballistic and energy. \ + The first and second inputs need to be numbers. They are coordinates for the gun to fire at, relative to the machine itself. \ + The 'fire' activator will cause the mechanism to attempt to fire the weapon at the coordinates, if possible. Note that the \ + normal limitations to firearms, such as ammunition requirements and firing delays, still hold true if fired by the mechanism." + complexity = 20 + number_of_inputs = 2 + number_of_outputs = 0 + number_of_activators = 1 + input_names = list( + "target X rel", + "target Y rel" + ) + activator_names = list( + "fire" + ) + var/obj/item/weapon/gun/installed_gun = null + +/obj/item/integrated_circuit/manipulation/weapon_firing/Destroy() + qdel(installed_gun) + ..() + +/obj/item/integrated_circuit/manipulation/weapon_firing/attackby(var/obj/O, var/mob/user) + if(istype(O, /obj/item/weapon/gun)) + var/obj/item/weapon/gun/gun = O + if(installed_gun) + user << "There's already a weapon installed." + return + user.remove_from_mob(gun) + //user.drop_from_inventory(gun) + installed_gun = gun + gun.forceMove(src) + user << "You slide \the [gun] into the firing mechanism." + playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) + else + ..() + +/obj/item/integrated_circuit/manipulation/weapon_firing/attack_self(var/mob/user) + if(installed_gun) + installed_gun.forceMove(get_turf(src)) + user << "You slide \the [installed_gun] out of the firing mechanism." + playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) + installed_gun = null + else + user << "There's no weapon to remove from the mechanism." + +/obj/item/integrated_circuit/manipulation/weapon_firing/work() + if(!installed_gun) + return + + var/datum/integrated_io/target_x = inputs[1] + var/datum/integrated_io/target_y = inputs[2] + + if(target_x.data && target_y.data && isnum(target_x.data) && isnum(target_y.data)) + var/turf/T = get_turf(src) + + if(target_x.data == 0 && target_y.data == 0) // Don't shoot ourselves. + return + + // We need to do this in order to enable relative coordinates, as locate() only works for absolute coordinates. + var/i + if(target_x.data > 0) + i = abs(target_x.data) + while(i) + T = get_step(T, EAST) + i-- + else if(target_x.data < 0) + i = abs(target_x.data) + while(i) + T = get_step(T, WEST) + i-- + + if(target_y.data > 0) + i = abs(target_y.data) + while(i) + T = get_step(T, NORTH) + i-- + else if(target_y.data < 0) + i = abs(target_y.data) + while(i) + T = get_step(T, SOUTH) + i-- + + if(!T) + return + installed_gun.shoot_live_shot(null, 0, T, 1) + //installed_gun.Fire_userless(T) + +/obj/item/integrated_circuit/manipulation/smoke + name = "smoke generator" + desc = "Unlike most electronics, creating smoke is completely intentional." + extended_desc = "This smoke generator creates clouds of smoke on command. It can also hold liquids inside, which will go \ + into the smoke clouds when activated." + flags = OPENCONTAINER + complexity = 20 + number_of_inputs = 0 + number_of_outputs = 0 + number_of_activators = 1 + input_names = list() + activator_names = list( + "create smoke" + ) + +/obj/item/integrated_circuit/manipulation/smoke/New() + ..() + create_reagents(100) + +/obj/item/integrated_circuit/manipulation/smoke/work() + if(..()) + playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3) + var/datum/effect/effect/system/smoke_spread/chem/smoke_system = new() + smoke_system.set_up(reagents, 10, 0, get_turf(src)) + spawn(0) + for(var/i = 1 to 8) + smoke_system.start() + reagents.clear_reagents() diff --git a/code/modules/integrated_electronics/memory.dm b/code/modules/integrated_electronics/memory.dm new file mode 100644 index 0000000000000..3305cf0a93914 --- /dev/null +++ b/code/modules/integrated_electronics/memory.dm @@ -0,0 +1,83 @@ +/obj/item/integrated_circuit/memory + name = "memory chip" + desc = "This tiny chip can store one piece of data." + icon_state = "memory" + complexity = 1 + number_of_inputs = 1 + number_of_outputs = 1 + number_of_activators = 1 + activator_names = list( + "set" + ) + +/obj/item/integrated_circuit/memory/examine(mob/user) + ..() + var/i + for(i = 1, i <= outputs.len, i++) + var/datum/integrated_io/O = outputs[i] + user << "\The [src] has [O.data ? "'O.data'" : "nothing"] saved to address [i]." + +/obj/item/integrated_circuit/memory/work() + if(..()) + var/i + for(i = 1, i <= inputs.len, i++) + var/datum/integrated_io/I = inputs[i] + var/datum/integrated_io/O = outputs[i] + O.data = I.data + +/obj/item/integrated_circuit/memory/medium + name = "memory circuit" + desc = "This circuit can store four pieces of data." + icon_state = "memory4" + complexity = 4 + number_of_inputs = 4 + number_of_outputs = 4 + +/obj/item/integrated_circuit/memory/large + name = "large memory circuit" + desc = "This big circuit can hold eight pieces of data." + icon_state = "memory8" + complexity = 8 + number_of_inputs = 8 + number_of_outputs = 8 + +/obj/item/integrated_circuit/memory/huge + name = "large memory stick" + desc = "This stick of memory can hold up up to sixteen pieces of data." + icon_state = "memory16" + complexity = 16 + number_of_inputs = 16 + number_of_outputs = 16 + +/obj/item/integrated_circuit/memory/constant + name = "constant chip" + desc = "This tiny chip can store one piece of data, which cannot be overwritten without disassembly." + icon_state = "memory" + complexity = 1 + number_of_inputs = 0 + number_of_outputs = 1 + number_of_activators = 1 + activator_names = list( + "trigger output" + ) + +/obj/item/integrated_circuit/memory/constant/work() + if(..()) + var/datum/integrated_io/O = outputs[1] + O.push_data() + +/obj/item/integrated_circuit/memory/constant/attack_hand(mob/user) + var/datum/integrated_io/O = outputs[1] + var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number") + var/new_data = null + switch(type_to_use) + if("string") + new_data = input("Now type in a string.","[src] string writing") as null|text + if(istext(new_data)) + O.data = new_data + user << "You set \the [src]'s memory to '[new_data]'." + if("number") + new_data = input("Now type in a number.","[src] number writing") as null|num + if(isnum(new_data)) + O.data = new_data + user << "You set \the [src]'s memory to '[new_data]'." \ No newline at end of file diff --git a/code/modules/integrated_electronics/time.dm b/code/modules/integrated_electronics/time.dm new file mode 100644 index 0000000000000..dde8369c69415 --- /dev/null +++ b/code/modules/integrated_electronics/time.dm @@ -0,0 +1,120 @@ +/obj/item/integrated_circuit/time + name = "time circuit" + desc = "Now you can build your own clock!" + complexity = 2 + number_of_inputs = 0 + number_of_outputs = 0 + +/obj/item/integrated_circuit/time/delay + name = "two-sec delay circuit" + desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ + This circuit is set to send a pulse after a delay of two seconds." + number_of_activators = 2 + var/delay = 20 + activator_names = list( + "incoming pulse", + "outgoing pulse" + ) + +/obj/item/integrated_circuit/time/delay/work() + if(..()) + var/datum/integrated_io/out_pulse = activators[2] + sleep(delay) + out_pulse.push_data() + +/obj/item/integrated_circuit/time/delay/five_sec + name = "five-sec delay circuit" + desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ + This circuit is set to send a pulse after a delay of five seconds." + delay = 10 + +/obj/item/integrated_circuit/time/delay/one_sec + name = "one-sec delay circuit" + desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ + This circuit is set to send a pulse after a delay of one second." + delay = 10 + +/obj/item/integrated_circuit/time/delay/half_sec + name = "half-sec delay circuit" + desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ + This circuit is set to send a pulse after a delay of half a second." + delay = 5 + +/obj/item/integrated_circuit/time/delay/tenth_sec + name = "tenth-sec delay circuit" + desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ + This circuit is set to send a pulse after a delay of 1/10th of a second." + delay = 1 + +/obj/item/integrated_circuit/time/delay/custom + name = "custom delay circuit" + desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ + This circuit's delay can be customized, between 1/10th of a second to one hour. The delay is updated upon receiving a pulse." + number_of_inputs = 1 + input_names = list( + "delay time", + ) + +/obj/item/integrated_circuit/time/delay/custom/work() + var/datum/integrated_io/delay_input = inputs[1] + if(delay_input.data && isnum(delay_input.data) ) + var/new_delay = min(delay_input.data, 1) + new_delay = max(new_delay, 36000) //An hour. + delay = new_delay + + ..() + +/obj/item/integrated_circuit/time/ticker + name = "ticker circuit" + desc = "This circuit sends an automatic pulse every four seconds." + complexity = 8 + number_of_inputs = 1 + number_of_activators = 1 + var/ticks_to_pulse = 2 + var/ticks_completed = 0 + input_names = list( + "toggle ticking" + ) + activator_names = list( + "outgoing pulse" + ) + +/obj/item/integrated_circuit/time/ticker/New() + ..() + //processing_objects |= src + +/obj/item/integrated_circuit/time/ticker/Destroy() + //processing_objects -= src + +/obj/item/integrated_circuit/time/ticker/process() + ticks_completed++ + if( (ticks_completed % ticks_to_pulse) == 0) + var/datum/integrated_io/pulser = activators[1] + pulser.push_data() + +/obj/item/integrated_circuit/time/ticker/fast + name = "fast ticker" + desc = "This advanced circuit sends an automatic pulse every two seconds." + complexity = 12 + ticks_to_pulse = 1 + +/obj/item/integrated_circuit/time/ticker/slow + name = "slow ticker" + desc = "This simple circuit sends an automatic pulse every six seconds." + complexity = 4 + ticks_to_pulse = 3 + + +/obj/item/integrated_circuit/time/clock + name = "integrated clock" + desc = "Tells you what the local time is, specific to your station or planet." + number_of_inputs = 0 + number_of_outputs = 6 + number_of_activators = 1 + output_names = list( + "time (string)", + "minute (string)", + "hour (string)", + "minute (number)", + "hour (number)", + ) \ No newline at end of file diff --git a/code/modules/integrated_electronics/tools.dm b/code/modules/integrated_electronics/tools.dm new file mode 100644 index 0000000000000..4aa57e45248e0 --- /dev/null +++ b/code/modules/integrated_electronics/tools.dm @@ -0,0 +1,201 @@ +#define WIRE "wire" +#define WIRING "wiring" +#define UNWIRE "unwire" +#define UNWIRING "unwiring" + + +/obj/item/device/integrated_electronics/wirer + name = "circuit wirer" + desc = "It's a small wiring tool, with a wire roll, electric soldering iron, wire cutter, and more in one package. \ + The wires used are generally useful for small electronics, such as circuitboards and breadboards, as opposed to larger wires \ + used for power or data transmission." + icon = 'icons/obj/electronic_assemblies.dmi' + icon_state = "numberpad" + flags = CONDUCT + w_class = 2 + var/datum/integrated_io/selected_io = null + var/mode = WIRE + +/obj/item/device/integrated_electronics/wirer/New() + ..() + +/obj/item/device/integrated_electronics/wirer/proc/wire(var/datum/integrated_io/io, mob/user) + if(mode == WIRE) + selected_io = io + user << "You attach a data wire to \the [selected_io.holder]'s [selected_io.name] data channel." + mode = WIRING + else if(mode == WIRING) + if(io == selected_io) + user << "Wiring \the [selected_io.holder]'s [selected_io.name] into itself is rather pointless." + return + if(io.io_type != selected_io.io_type) + user << "Those two types of channels are incompatable. The first is a [selected_io.io_type], \ + while the second is a [io.io_type]." + return + selected_io.linked |= io + io.linked |= selected_io + + user << "You connect \the [selected_io.holder]'s [selected_io.name] to \the [io.holder]'s [io.name]." + mode = WIRE + //io.updateDialog() + //selected_io.updateDialog() + selected_io.holder.interact(user) // This is to update the UI. + selected_io = null + + else if(mode == UNWIRE) + selected_io = io + if(!io.linked.len) + user << "There is nothing connected to \the [selected_io] data channel." + selected_io = null + return + user << "You prepare to detach a data wire from \the [selected_io.holder]'s [selected_io.name] data channel." + mode = UNWIRING + return + + else if(mode == UNWIRING) + if(io == selected_io) + user << "You can't wire a pin into each other, so unwiring \the [selected_io.holder] from \ + the same pin is rather moot." + return + if(selected_io in io.linked) + io.linked.Remove(selected_io) + selected_io.linked.Remove(io) + user << "You disconnect \the [selected_io.holder]'s [selected_io.name] from \ + \the [io.holder]'s [io.name]." + //io.updateDialog() + //selected_io.updateDialog() + selected_io.holder.interact(user) // This is to update the UI. + selected_io = null + mode = UNWIRE + else + user << "\The [selected_io.holder]'s [selected_io.name] and \the [io.holder]'s \ + [io.name] are not connected." + return + return + +/obj/item/device/integrated_electronics/wirer/attack_self(mob/user) + switch(mode) + if(WIRE) + mode = UNWIRE + if(WIRING) + if(selected_io) + user << "You decide not to wire the data channel." + selected_io = null + mode = UNWIRE + if(UNWIRE) + mode = WIRE + if(UNWIRING) + if(selected_io) + user << "You decide not to disconnect the data channel." + selected_io = null + mode = UNWIRE + user << "You set \the [src] to [mode]." + +#undef WIRE +#undef WIRING +#undef UNWIRE +#undef UNWIRING + +/* +/obj/item/weapon/storage/bag/circuits + name = "circuit satchel" + desc = "This bag's essential for any circuitry projects." + icon = 'icons/obj/mining.dmi' + icon_state = "satchel" + slot_flags = SLOT_BELT | SLOT_POCKET + w_class = 2 + storage_slots = 200 + max_storage_space = 400 + max_w_class = 3 + display_contents_with_number = 1 + can_hold = list(/obj/item/integrated_circuit) + +/obj/item/weapon/storage/bag/circuits/pre_filled/New() + ..() + var/i = 10 + while(i) + new /obj/item/integrated_circuit/arithmetic/addition(src) + i-- + i = 10 + while(i) + new /obj/item/integrated_circuit/arithmetic/subtraction(src) + i-- + i = 10 + while(i) + new /obj/item/integrated_circuit/arithmetic/multiplication(src) + i-- + i = 10 + while(i) + new /obj/item/integrated_circuit/arithmetic/division(src) + i-- + i = 5 + while(i) + new /obj/item/integrated_circuit/arithmetic/absolute(src) + i-- + i = 5 + while(i) + new /obj/item/integrated_circuit/arithmetic/average(src) + i-- + i = 10 + while(i) + new /obj/item/integrated_circuit/logic/equals(src) + i-- + i = 10 + while(i) + new /obj/item/integrated_circuit/logic/less_than(src) + i-- + i = 10 + while(i) + new /obj/item/integrated_circuit/logic/less_than_or_equal(src) + i-- + i = 10 + while(i) + new /obj/item/integrated_circuit/logic/greater_than(src) + i-- + i = 10 + while(i) + new /obj/item/integrated_circuit/logic/greater_than_or_equal(src) + i-- + i = 10 + while(i) + new /obj/item/integrated_circuit/logic/not(src) + i-- + i = 10 + while(i) + new /obj/item/integrated_circuit/memory(src) + i-- + i = 5 + while(i) + new /obj/item/integrated_circuit/memory/medium(src) + i-- + i = 5 + while(i) + new /obj/item/integrated_circuit/memory/large(src) + i-- + i = 5 + while(i) + new /obj/item/integrated_circuit/memory/huge(src) + i-- + i = 5 + while(i) + new /obj/item/integrated_circuit/input/numberpad(src) + i-- + i = 5 + while(i) + new /obj/item/integrated_circuit/input/button(src) + i-- + i = 5 + while(i) + new /obj/item/integrated_circuit/output/screen(src) + i-- + i = 5 + while(i) + new /obj/item/integrated_circuit/transfer/splitter(src) + i-- + i = 5 + while(i) + new /obj/item/integrated_circuit/transfer/activator_splitter(src) + i-- + new /obj/item/device/electronic_assembly(src) + new /obj/item/device/integrated_electronics/wirer(src) + */ \ No newline at end of file diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index c3d4115924cf9..b44cf20f3e6e2 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -230,6 +230,74 @@ user.update_inv_r_hand(0) return fired +/*// Similar to the above proc, but does not require a user, which is ideal for things like turrets. +/obj/item/weapon/gun/proc/Fire_userless(atom/target) + if(!target) + return + + if(world.time < next_fire_time) + return + + var/shoot_time = (burst - 1)* burst_delay + next_fire_time = world.time + shoot_time + + var/turf/targloc = get_turf(target) //cache this in case target gets deleted during shooting, e.g. if it was a securitron that got destroyed. + for(var/i in 1 to burst) + var/obj/projectile = consume_next_projectile() + if(!projectile) + handle_click_empty() + break + + if(istype(projectile, /obj/item/projectile)) + var/obj/item/projectile/P = projectile + + var/acc = burst_accuracy[min(i, burst_accuracy.len)] + var/disp = dispersion[min(i, dispersion.len)] + + P.accuracy = accuracy + acc + P.dispersion = disp + + P.shot_from = src.name + P.silenced = silenced + + P.launch(target) + + if(silenced) + playsound(src, fire_sound, 10, 1) + else + playsound(src, fire_sound, 50, 1) + + if(muzzle_flash) + set_light(muzzle_flash) + update_icon() + + //process_accuracy(projectile, user, target, acc, disp) + + // if(pointblank) + // process_point_blank(projectile, user, target) + + // if(process_projectile(projectile, null, target, user.zone_sel.selecting, clickparams)) + // handle_post_fire(null, target, pointblank, reflex) + + // update_icon() + + if(i < burst) + sleep(burst_delay) + + if(!(target && target.loc)) + target = targloc + //pointblank = 0 + + log_and_message_admins("Fired [src].") + + //admin_attack_log(usr, attacker_message="Fired [src]", admin_message="fired a gun ([src]) (MODE: [src.mode_name]) [reflex ? "by reflex" : "manually"].") + + //update timing + next_fire_time = world.time + fire_delay + + if(muzzle_flash) + set_light(0) +*/ /obj/item/weapon/gun/attack(mob/M as mob, mob/user) if (M == user && user.zone_sel.selecting == "mouth" && !mouthshoot && ishuman(user)) //Handle gun suicide diff --git a/icons/obj/electronic_assemblies.dmi b/icons/obj/electronic_assemblies.dmi new file mode 100644 index 0000000000000000000000000000000000000000..e4fd3c230bbfe419d4b55a94489b5b07ec47bca3 GIT binary patch literal 1370 zcmV-g1*Q6lP)ki0RPMY07?J=W&nzcitg_2{{R5Mz`!ahDy^-pbpX@&00001bW%=J06^y0W&i*I z0D4qdbVOxyV{&P5bZKvH004NLjnuJj10f6m(E0cZlu#!yoeCb6@sV&meTVK@)=KrEg~Jhr|lEDdb_yXcBqDO(|@Jh_NB%FDT7?eP?Mb;)~U#`^ki zggGtWm>Xcecf)her-bvJ`G8~I8m5O5!vd=ADFuK=FHH0$@#qV|%+>3~GN zfsjQ3^F5scYfA7gvK>e&pwqESfJ}*Qk#kax9q9g40R;pWusYn%!79(IT5}};$KZ3| z+eP}g08b>P0L=Gv5!WoLdl%V@tUpkIAkA2RD+eUcTlwCH4ekSHI`+eNAMikdG~;*| zeNO1JD9`~FoN)RyZ53&D#`;;83K0wId z+A}W19Caup<`R|bV%=Z{ixJlq6l$Md$O2wSFK`9I4b=^1P23i+9Z07mI%4X`>QA>Q z=GP-wLAf|DM_gZ^ymSoP>kEQRiNqW^GR1Jjrr75|hiSe!=VkhyHFB#xqfykuSJ8FW z$gTDf5fKp)5#3<8=(PJYwitFQFk}n;X&3li_5;%%+LfU1wufex;QMG_zW4n=N%sX` zLzL*3V8|^s3DdmM0MfQ^YiZ{OaL96zpVs*R2O~;@%t<807*qoM6N<$f;s4ehyVZp literal 0 HcmV?d00001 diff --git a/tgstation.dme b/tgstation.dme index 6082730afeaf2..94bd305cb2324 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1130,6 +1130,18 @@ #include "code\modules\hydroponics\grown\tobacco.dm" #include "code\modules\hydroponics\grown\tomato.dm" #include "code\modules\hydroponics\grown\towercap.dm" +#include "code\modules\integrated_electronics\_defines.dm" +#include "code\modules\integrated_electronics\arithmetic.dm" +#include "code\modules\integrated_electronics\assemblies.dm" +#include "code\modules\integrated_electronics\converters.dm" +#include "code\modules\integrated_electronics\coordinate.dm" +#include "code\modules\integrated_electronics\data_transfer.dm" +#include "code\modules\integrated_electronics\input_output.dm" +#include "code\modules\integrated_electronics\logic.dm" +#include "code\modules\integrated_electronics\manipulation.dm" +#include "code\modules\integrated_electronics\memory.dm" +#include "code\modules\integrated_electronics\time.dm" +#include "code\modules\integrated_electronics\tools.dm" #include "code\modules\library\lib_items.dm" #include "code\modules\library\lib_machines.dm" #include "code\modules\library\lib_readme.dm" From 4c3528af75151b3778a6d4f18ccc61deacdd6884 Mon Sep 17 00:00:00 2001 From: Stakks Date: Sun, 8 Apr 2018 22:56:38 -0500 Subject: [PATCH 2/9] Stage 2 --- .../objects/items/weapons/storage/belt.dm | 4 +- .../integrated_electronics/_defines.dm | 75 +++- .../integrated_electronics/arithmetic.dm | 28 +- .../integrated_electronics/assemblies.dm | 31 +- .../integrated_electronics/converters.dm | 47 +- .../integrated_electronics/coordinate.dm | 1 + .../integrated_electronics/input_output.dm | 421 +++++++++++++++++- .../integrated_electronics/manipulation.dm | 107 +++-- code/modules/integrated_electronics/memory.dm | 34 +- code/modules/integrated_electronics/time.dm | 28 +- code/modules/integrated_electronics/tools.dm | 217 +++++---- code/modules/research/designs.dm | 390 +++++++++++++++- config/admins.txt | 3 +- icons/obj/electronic_assemblies.dmi | Bin 1370 -> 23986 bytes tgstation.dme | 1 + 15 files changed, 1192 insertions(+), 195 deletions(-) diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 95dfb1e214da9..fa39d528fdb0d 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -29,8 +29,8 @@ /obj/item/stack/cable_coil, /obj/item/device/t_scanner, /obj/item/device/analyzer, - /obj/item/weapon/extinguisher/mini - /obj/item/device/integrated_electronics/wirer, + /obj/item/weapon/extinguisher/mini, + /obj/item/device/integrated_electronics/wirer ) /obj/item/weapon/storage/belt/utility/full/New() diff --git a/code/modules/integrated_electronics/_defines.dm b/code/modules/integrated_electronics/_defines.dm index 737b1914614b3..ed4be623c7bf7 100644 --- a/code/modules/integrated_electronics/_defines.dm +++ b/code/modules/integrated_electronics/_defines.dm @@ -19,7 +19,7 @@ var/list/activator_names = list() var/last_used = 0 //Uses world.time var/complexity = 1 //This acts as a limitation on building machines, more resource-intensive components cost more 'space'. - var/power_required = 5 //w + var/cooldown_per_use = 1 SECONDS /obj/item/integrated_circuit/examine(mob/user) ..() @@ -72,6 +72,9 @@ A.name = "[activator_names[i]]" i++ +/obj/item/integrated_circuit/proc/on_data_written() //Override this for special behaviour when new data gets pushed to the circuit. + return + /obj/item/integrated_circuit/Destroy() for(var/datum/integrated_io/I in inputs) qdel(I) @@ -92,7 +95,10 @@ var/mob/M = usr - var/input = sanitize_text(input("What do you want to name the circuit?", ,"")) + if(!M.canmove || M.stat || M.restrained()) + return + + var/input = sanitize_text(input("What do you want to name the circuit?","Rename", src.name), MAX_NAME_LEN) if(src && input) M << "The circuit '[src.name]' is now labeled '[input]'." @@ -156,13 +162,14 @@ words += "\[[linked.name]\] \ @ [linked.holder]
" if(outputs.len > inputs.len) - height = Floor(outputs.len / inputs.len) - //world << "I wrote [words] at ([i],[j])." + // height = Floor(outputs.len / inputs.len) + height = 1 // Because of bugs, if there's more outputs than inputs, it causes the output side to be hidden. + //world << "I wrote [words] at ([i],[j]). Height = [height]." if(2) if(i == 1) words = "[src.name]

[src.desc]" height = row_height - //world << "I wrote the center piece because i was equal to 1, at ([i],[j])." + //world << "I wrote the center piece because i was equal to 1, at ([i],[j]). Height = [height]." else continue if(3) @@ -179,8 +186,9 @@ words += "\[[linked.name]\] \ @ [linked.holder]
" if(inputs.len > outputs.len) - height = Floor(inputs.len / outputs.len) - //world << "I wrote [words] at ([i],[j])." + // height = Floor(inputs.len / outputs.len) + height = 1 // See above. + //world << "I wrote [words] at ([i],[j]). Height = [height]." HTML += "[words]" //HTML += "[words]" //world << "Writing to ([i],[j])." @@ -209,11 +217,15 @@ HTML += "" HTML += "" + HTML += "
Complexity: [complexity]" HTML += "
[extended_desc]" HTML += "" user << browse(HTML, "window=circuit-\ref[src];size=600x350;border=1;can_resize=1;can_close=1;can_minimize=1") + //user << sanitize_text(HTML, "window=debug;size=400x400;border=1;can_resize=1;can_close=1;can_minimize=1") + //world << sanitize_text(HTML) + user.set_machine(src) onclose(user, "circuit-\ref[src]") @@ -224,17 +236,31 @@ if(!user || !user.Adjacent(get_turf(src)) ) return 1 + if(!user.canmove || user.stat || user.restrained()) + return + if(href_list["wire"]) if(ishuman(user) && Adjacent(user)) var/mob/living/carbon/human/H = user - var/obj/item/device/integrated_electronics/wirer/wirer = null - if(istype(H.r_hand, /obj/item/device/integrated_electronics/wirer)) - wirer = H.r_hand - else if(istype(H.l_hand, /obj/item/device/integrated_electronics/wirer)) - wirer = H.l_hand - - if(wirer && pin) - wirer.wire(pin, user) + var/obj/held_item = H.get_active_hand() + + if(istype(held_item, /obj/item/device/integrated_electronics/wirer)) + var/obj/item/device/integrated_electronics/wirer/wirer = held_item + if(pin) + wirer.wire(pin, user) + + else if(istype(held_item, /obj/item/device/integrated_electronics/debugger)) + var/obj/item/device/integrated_electronics/debugger/debugger = held_item + if(pin) + debugger.write_data(pin, user) + + // if(istype(H.r_hand, /obj/item/device/integrated_electronics/wirer)) + // wirer = H.r_hand + // else if(istype(H.l_hand, /obj/item/device/integrated_electronics/wirer)) + // wirer = H.l_hand + + // if(wirer && pin) + // wirer.wire(pin, user) else user << "You can't do a whole lot without tools." @@ -265,7 +291,7 @@ ..() /datum/integrated_io/proc/display_data() - if(!data) + if(isnull(data)) return "(null)" // Empty data means nothing to show. if(istext(data)) return "(\"[data]\")" // Wraps the 'string' in escaped quotes, so that people know it's a 'string'. @@ -281,18 +307,23 @@ if(isnull(data)) return if(isnum(data)) - data = rand(-10000, 10000) + write_data_to_pin(rand(-10000, 10000)) if(istext(data)) - data = "ERROR" + write_data_to_pin("ERROR") push_data() /datum/integrated_io/activate/scramble() push_data() +/datum/integrated_io/proc/write_data_to_pin(var/new_data) + if(isnull(new_data) || isnum(new_data) || istext(new_data) || istype(new_data, /atom/) ) // Anything else is a type we don't want. + data = new_data + holder.on_data_written() + /datum/integrated_io/proc/push_data() if(linked.len) for(var/datum/integrated_io/io in linked) - io.data = data + io.write_data_to_pin(data) /datum/integrated_io/activate/push_data() if(linked.len) @@ -302,7 +333,7 @@ /datum/integrated_io/proc/pull_data() if(linked.len) for(var/datum/integrated_io/io in linked) - data = io.data + write_data_to_pin(io.data) /datum/integrated_io/proc/get_linked_to_desc() if(linked.len) @@ -341,8 +372,8 @@ for(var/datum/integrated_io/input/I in inputs) I.push_data() -/obj/item/integrated_circuit/proc/work() - if(last_used + 2 SECONDS > world.time) // All intergrated circuits have an internal cooldown of two seconds to protect from spam. +/obj/item/integrated_circuit/proc/work(var/datum/integrated_io/io) + if(last_used + cooldown_per_use > world.time) // All intergrated circuits have an internal cooldown, to protect from spam. return 0 last_used = world.time return 1 diff --git a/code/modules/integrated_electronics/arithmetic.dm b/code/modules/integrated_electronics/arithmetic.dm index 5f5a4f1d2e6ae..3fc60c64f9cd3 100644 --- a/code/modules/integrated_electronics/arithmetic.dm +++ b/code/modules/integrated_electronics/arithmetic.dm @@ -154,4 +154,30 @@ if(..()) var/datum/integrated_io/output/O = outputs[1] O.data = 3.14159 - O.push_data() \ No newline at end of file + O.push_data() + +// Random // +/obj/item/integrated_circuit/arithmetic/random + name = "random number generator circuit" + desc = "This gives a random (integer) number between values A and B inclusive." + icon_state = "random" + number_of_inputs = 2 + number_of_outputs = 1 + number_of_activators = 1 + input_names = list( + "L", + "H" + ) + +/obj/item/integrated_circuit/arithmetic/random/work() + if(..()) + var/result = 0 + var/datum/integrated_io/L = inputs[1] + var/datum/integrated_io/H = inputs[2] + + if(isnum(L.data) && isnum(H.data)) + result = rand(L.data, H.data) + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/assemblies.dm b/code/modules/integrated_electronics/assemblies.dm index 97690b977f880..e727f4c3d8131 100644 --- a/code/modules/integrated_electronics/assemblies.dm +++ b/code/modules/integrated_electronics/assemblies.dm @@ -3,19 +3,21 @@ desc = "It's a case, for building electronics with." w_class = 2 icon = 'icons/obj/electronic_assemblies.dmi' - icon_state = "setup" + icon_state = "setup_small" var/max_components = 10 var/max_complexity = 30 var/opened = 0 /obj/item/device/electronic_assembly/medium name = "electronic mechanism" + icon_state = "setup_medium" w_class = 3 max_components = 20 max_complexity = 50 /obj/item/device/electronic_assembly/large name = "electronic machine" + icon_state = "setup" w_class = 4 max_components = 30 max_complexity = 60 @@ -35,16 +37,23 @@ IC.work() */ +/obj/item/device/electronic_assembly/update_icon() + if(opened) + icon_state = initial(icon_state) + "-open" + else + icon_state = initial(icon_state) + /obj/item/device/electronic_assembly/examine(mob/user) ..() - if(!opened) - for(var/obj/item/integrated_circuit/output/screen/S in contents) - if(S.stuff_to_display) - user << "There's a little screen labeled '[S.name]', which displays '[S.stuff_to_display]'." - else - var/obj/item/integrated_circuit/IC = input(user, "Which circuit do you want to examine?", "Examination") as null|anything in contents - if(IC) - IC.examine(user) + if(user.Adjacent(src)) + if(!opened) + for(var/obj/item/integrated_circuit/output/screen/S in contents) + if(S.stuff_to_display) + user << "There's a little screen labeled '[S.name]', which displays '[S.stuff_to_display]'." + else + var/obj/item/integrated_circuit/IC = input(user, "Which circuit do you want to examine?", "Examination") as null|anything in contents + if(IC) + IC.examine(user) /obj/item/device/electronic_assembly/attackby(var/obj/item/I, var/mob/user) if(istype(I, /obj/item/integrated_circuit)) @@ -86,6 +95,7 @@ playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) opened = !opened user << "You [opened ? "opened" : "closed"] \the [src]." + update_icon() if(istype(I, /obj/item/device/integrated_electronics/wirer)) if(opened) var/obj/item/integrated_circuit/IC = input(user, "Which circuit do you want to examine?", "Examination") as null|anything in contents @@ -98,7 +108,8 @@ /obj/item/device/electronic_assembly/attack_self(mob/user) var/list/available_inputs = list() for(var/obj/item/integrated_circuit/input/input in contents) - available_inputs.Add(input) + if(input.can_be_asked_input) + available_inputs.Add(input) var/obj/item/integrated_circuit/input/choice = input(user, "What do you want to interact with?", "Interaction") as null|anything in available_inputs if(choice) choice.ask_for_input(user) diff --git a/code/modules/integrated_electronics/converters.dm b/code/modules/integrated_electronics/converters.dm index 0bd2166419528..7a837abbfa3af 100644 --- a/code/modules/integrated_electronics/converters.dm +++ b/code/modules/integrated_electronics/converters.dm @@ -17,7 +17,7 @@ /obj/item/integrated_circuit/converter/num2text name = "number to string" desc = "This circuit can convert a number variable into a string." - icon_state = "addition" + icon_state = "num-string" /obj/item/integrated_circuit/converter/num2text/work() if(..()) @@ -33,7 +33,7 @@ /obj/item/integrated_circuit/converter/text2num name = "string to number" desc = "This circuit can convert a string variable into a number." - icon_state = "addition" + icon_state = "string-num" /obj/item/integrated_circuit/converter/text2num/work() if(..()) @@ -49,7 +49,7 @@ /obj/item/integrated_circuit/converter/ref2text name = "reference to string" desc = "This circuit can convert a reference to something else to a string, specifically the name of that reference." - icon_state = "addition" + icon_state = "ref-string" /obj/item/integrated_circuit/converter/ref2text/work() if(..()) @@ -66,7 +66,7 @@ /obj/item/integrated_circuit/converter/lowercase name = "lowercase string converter" desc = "this will cause a string to come out in all lowercase." - icon_state = "addition" + icon_state = "lowercase" /obj/item/integrated_circuit/converter/lowercase/work() if(..()) @@ -82,7 +82,7 @@ /obj/item/integrated_circuit/converter/uppercase name = "uppercase string converter" desc = "THIS WILL CAUSE A STRING TO COME OUT IN ALL UPPERCASE." - icon_state = "addition" + icon_state = "uppercase" /obj/item/integrated_circuit/converter/uppercase/work() if(..()) @@ -92,5 +92,42 @@ if(incoming.data && istext(incoming.data)) result = uppertext(incoming.data) + outgoing.data = result + outgoing.push_data() + +/obj/item/integrated_circuit/converter/concatenatior + name = "concatenatior" + desc = "This joins many strings together to get one big string." + complexity = 4 + number_of_inputs = 8 + number_of_outputs = 1 + number_of_activators = 1 + input_names = list( + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H" + ) + output_names = list( + "result" + ) + activator_names = list( + "concatenate" + ) + + +/obj/item/integrated_circuit/converter/concatenatior/work() + if(..()) + var/result = null + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(istext(I.data)) + result = result + I.data + + var/datum/integrated_io/outgoing = outputs[1] outgoing.data = result outgoing.push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/coordinate.dm b/code/modules/integrated_electronics/coordinate.dm index 04409907ac85c..f70df7425901b 100644 --- a/code/modules/integrated_electronics/coordinate.dm +++ b/code/modules/integrated_electronics/coordinate.dm @@ -2,6 +2,7 @@ /obj/item/integrated_circuit/gps name = "global positioning system" desc = "This allows you to easily know the position of a machine containing this device." + icon_state = "gps" complexity = 4 number_of_inputs = 0 number_of_outputs = 2 diff --git a/code/modules/integrated_electronics/input_output.dm b/code/modules/integrated_electronics/input_output.dm index 8f9c2cac0409e..42da3406547d1 100644 --- a/code/modules/integrated_electronics/input_output.dm +++ b/code/modules/integrated_electronics/input_output.dm @@ -1,3 +1,6 @@ +/obj/item/integrated_circuit/input + var/can_be_asked_input = 0 + /obj/item/integrated_circuit/input/proc/ask_for_input(mob/user) return @@ -9,6 +12,7 @@ number_of_outputs = 0 number_of_activators = 1 complexity = 1 + can_be_asked_input = 1 activator_names = list( "on pressed" ) @@ -28,6 +32,7 @@ number_of_outputs = 1 number_of_activators = 1 complexity = 2 + can_be_asked_input = 1 output_names = list( "number entered" ) @@ -36,23 +41,23 @@ ) /obj/item/integrated_circuit/input/numberpad/ask_for_input(mob/user) - var/new_input = input(user, "Enter a number, please.","Number pad") as num - if(new_input && isnum(new_input)) + var/new_input = input(user, "Enter a number, please.","Number pad") as null|num + if(isnum(new_input)) var/datum/integrated_io/O = outputs[1] O.data = new_input O.push_data() var/datum/integrated_io/A = activators[1] - if(A.linked) - A.holder.work() + A.push_data() /obj/item/integrated_circuit/input/textpad name = "text pad" desc = "This small text pad allows someone to input a string into the system." - icon_state = "numberpad" + icon_state = "textpad" number_of_inputs = 0 number_of_outputs = 1 number_of_activators = 1 complexity = 2 + can_be_asked_input = 1 output_names = list( "string entered" ) @@ -61,14 +66,284 @@ ) /obj/item/integrated_circuit/input/textpad/ask_for_input(mob/user) - var/new_input = input(user, "Enter some words, please.","Number pad") as text + var/new_input = input(user, "Enter some words, please.","Number pad") as null|text if(new_input && istext(new_input)) var/datum/integrated_io/O = outputs[1] O.data = new_input O.push_data() var/datum/integrated_io/A = activators[1] - if(A.linked) - A.holder.work() + A.push_data() + +/obj/item/integrated_circuit/input/med_scanner + name = "integrated medical analyser" + desc = "A very small version of the common medical analyser. This allows the machine to know how healthy someone is." + icon_state = "medscan" + number_of_inputs = 1 + number_of_outputs = 2 + number_of_activators = 1 + complexity = 4 + input_names = list( + "target ref" + ) + output_names = list( + "total health %", + "total missing health" + ) + activator_names = list( + "scan" + ) + +/obj/item/integrated_circuit/input/med_scanner/work() + if(..()) + var/datum/integrated_io/I = inputs[1] + if(!I.data || !ishuman(I.data)) //Invalid input + return + var/mob/living/carbon/human/H = I.data + if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range. + var/total_health = round(H.health/H.maxHealth, 0.1)*100 + var/missing_health = H.maxHealth - H.health + + var/datum/integrated_io/total = outputs[1] + var/datum/integrated_io/missing = outputs[2] + + total.data = total_health + missing.data = missing_health + + for(var/datum/integrated_io/output/O in outputs) + O.push_data() + +/obj/item/integrated_circuit/input/adv_med_scanner + name = "integrated advanced medical analyser" + desc = "A very small version of the common medical analyser. This allows the machine to know how healthy someone is. \ + This type is much more precise, allowing the machine to know much more about the target than a normal analyzer." + icon_state = "medscan_adv" + number_of_inputs = 1 + number_of_outputs = 7 + number_of_activators = 1 + complexity = 12 + input_names = list( + "target ref" + ) + output_names = list( + "total health %", + "total missing health", + "brute damage", + "burn damage", + "tox damage", + "oxy damage", + "clone damage" + ) + activator_names = list( + "scan" + ) + +/obj/item/integrated_circuit/input/adv_med_scanner/work() + if(..()) + var/datum/integrated_io/I = inputs[1] + if(!I.data || !ishuman(I.data)) //Invalid input + return + var/mob/living/carbon/human/H = I.data + if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range. + var/total_health = round(H.health/H.maxHealth, 0.1)*100 + var/missing_health = H.maxHealth - H.health + + var/datum/integrated_io/total = outputs[1] + var/datum/integrated_io/missing = outputs[2] + var/datum/integrated_io/brute = outputs[3] + var/datum/integrated_io/burn = outputs[4] + var/datum/integrated_io/tox = outputs[5] + var/datum/integrated_io/oxy = outputs[6] + var/datum/integrated_io/clone = outputs[7] + + total.data = total_health + missing.data = missing_health + brute.data = H.getBruteLoss() + burn.data = H.getFireLoss() + tox.data = H.getToxLoss() + oxy.data = H.getOxyLoss() + clone.data = H.getCloneLoss() + + for(var/datum/integrated_io/output/O in outputs) + O.push_data() + +/obj/item/integrated_circuit/input/local_locator + name = "local locator" + desc = "This is needed for certain devices that demand a reference for a target to act upon. This type only locates something \ + that is holding the machine containing it." + number_of_inputs = 0 + number_of_outputs = 1 + number_of_activators = 1 + complexity = 4 + output_names = list( + "located ref" + ) + activator_names = list( + "locate" + ) + +/obj/item/integrated_circuit/input/local_locator/work() + if(..()) + var/mob/living/L = null + var/datum/integrated_io/O = outputs[1] + O.data = null + if(istype(src.loc, /obj/item/device/electronic_assembly)) // Check to make sure we're actually in a machine. + var/obj/item/device/electronic_assembly/assembly = src.loc + if(istype(assembly.loc, /mob/living)) // Now check if someone's holding us. + L = assembly.loc + + if(L) + O.data = L + + O.push_data() + +/obj/item/integrated_circuit/input/signaler + name = "integrated signaler" + desc = "Signals from a signaler can be received with this, allowing for remote control. Additionally, it can send signals as well." + extended_desc = "When a signal is received from another signaler, the 'on signal received' activator pin will be pulsed. \ + The two input pins are to configure the integrated signaler's settings. Note that the frequency should not have a decimal in it. \ + Meaning the default frequency is expressed as 1457, not 145.7. To send a signal, pulse the 'send signal' activator pin." + icon_state = "signal" + number_of_inputs = 2 + number_of_outputs = 0 + number_of_activators = 2 + complexity = 4 + input_names = list( + "frequency", + "code" + ) + activator_names = list( + "send signal", + "on signal received" + ) + var/frequency = 1457 + var/code = 30 + var/datum/radio_frequency/radio_connection + +/obj/item/integrated_circuit/input/signaler/New() + ..() + spawn(4 SECONDS) + set_frequency(frequency) + var/datum/integrated_io/new_freq = inputs[1] + var/datum/integrated_io/new_code = inputs[2] + // Set the pins so when someone sees them, they won't show as null + new_freq.data = frequency + new_code.data = code + +/obj/item/integrated_circuit/input/signaler/Destroy() + if(radio_controller) + radio_controller.remove_object(src,frequency) + frequency = 0 + ..() + +/obj/item/integrated_circuit/input/signaler/on_data_written() + var/datum/integrated_io/new_freq = inputs[1] + var/datum/integrated_io/new_code = inputs[2] + if(isnum(new_freq.data)) + set_frequency(new_freq.data) + if(isnum(new_code.data)) + code = new_code.data + + +/obj/item/integrated_circuit/input/signaler/work() // Sends a signal. + if(..()) + if(!radio_connection) + return + + var/datum/signal/signal = new() + signal.source = src + signal.encryption = code + signal.data["message"] = "ACTIVATE" + radio_connection.post_signal(src, signal) + +/obj/item/integrated_circuit/input/signaler/proc/set_frequency(new_frequency) + if(!frequency) + return + if(!radio_controller) + sleep(20) + if(!radio_controller) + return + radio_controller.remove_object(src, frequency) + frequency = new_frequency + radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT) + +/obj/item/integrated_circuit/input/signaler/receive_signal(datum/signal/signal) + var/datum/integrated_io/new_code = inputs[2] + var/code = 0 + + if(isnum(new_code.data)) + code = new_code.data + if(!signal) + return 0 + if(signal.encryption != code) + return 0 + if(signal.source == src) // Don't trigger ourselves. + return 0 + + var/datum/integrated_io/A = activators[2] + A.push_data() + + for(var/mob/O in hearers(1, src.loc)) + O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2) + + +/obj/item/integrated_circuit/input/EPv2 + name = "\improper EPv2 circuit" + desc = "Enables the sending and receiving of messages on the Exonet with the EPv2 protocol." + extended_desc = "An EPv2 address is a string with the format of XXXX:XXXX:XXXX:XXXX. Data can be send or received using the \ + second pin on each side, with additonal data reserved for the third pin. When a message is received, the second activaiton pin \ + will pulse whatever's connected to it. Pulsing the first activation pin will send a message." + icon_state = "signal" + number_of_inputs = 3 + number_of_outputs = 3 + number_of_activators = 2 + complexity = 4 + input_names = list( + "target EPv2 address", + "data to send", + "secondary text" + ) + output_names = list( + "address received", + "data received", + "secondary text received" + ) + activator_names = list( + "send data", + "on data received" + ) + var/datum/exonet_protocol/exonet = null + +/obj/item/integrated_circuit/input/EPv2/New() + ..() + exonet = new(src) + exonet.make_address("EPv2_circuit-\ref[src]") + desc += "This circuit's EPv2 address is: [exonet.address]." + +/obj/item/integrated_circuit/input/EPv2/Destroy() + if(exonet) + exonet.remove_address() + qdel(exonet) + ..() + +/obj/item/integrated_circuit/input/EPv2/work() + if(..()) + var/datum/integrated_io/target_address = inputs[1] + var/datum/integrated_io/message = inputs[2] + var/datum/integrated_io/text = inputs[3] + if(istext(target_address.data)) + exonet.send_message(target_address.data, message.data, text.data) + +/obj/item/integrated_circuit/input/receive_exonet_message(var/atom/origin_atom, var/origin_address, var/message, var/text) + var/datum/integrated_io/message_received = outputs[1] + var/datum/integrated_io/data_received = outputs[2] + var/datum/integrated_io/text_received = outputs[3] + + var/datum/integrated_io/A = activators[2] + A.push_data() + + message_received.write_data_to_pin(origin_address) + data_received.write_data_to_pin(message) + text_received.write_data_to_pin(text) /obj/item/integrated_circuit/output/screen name = "screen" @@ -88,4 +363,132 @@ /obj/item/integrated_circuit/output/screen/work() var/datum/integrated_io/I = inputs[1] - stuff_to_display = I.data \ No newline at end of file + stuff_to_display = I.data + +/obj/item/integrated_circuit/output/light + name = "light" + desc = "This light can turn on and off on command." + icon_state = "light_adv" +// icon_state = "light" + complexity = 4 + number_of_inputs = 0 + number_of_outputs = 0 + number_of_activators = 1 + activator_names = list( + "toggle light" + ) + var/light_toggled = 0 + var/light_brightness = 3 + var/light_rgb = "#FFFFFF" + +/obj/item/integrated_circuit/output/light/work() + if(..()) + light_toggled = !light_toggled + update_lighting() + +/obj/item/integrated_circuit/output/light/proc/update_lighting() + if(light_toggled) + set_light(l_range = light_brightness, l_power = light_brightness, l_color = light_rgb) + else + set_light(0) + +/obj/item/integrated_circuit/output/light/advanced/update_lighting() + var/datum/integrated_io/R = inputs[1] + var/datum/integrated_io/G = inputs[2] + var/datum/integrated_io/B = inputs[3] + var/datum/integrated_io/brightness = inputs[4] + + if(isnum(R.data) && isnum(G.data) && isnum(B.data) && isnum(brightness.data)) + R.data = Clamp(R.data, 0, 255) + G.data = Clamp(G.data, 0, 255) + B.data = Clamp(B.data, 0, 255) + brightness.data = Clamp(brightness.data, 0, 6) + light_rgb = rgb(R.data, G.data, B.data) + light_brightness = brightness.data + + ..() + +/obj/item/integrated_circuit/output/light/advanced + name = "advanced light" + desc = "This light can turn on and off on command, in any color, and in various brightness levels." + icon_state = "light_adv" + complexity = 8 + number_of_inputs = 4 + number_of_outputs = 0 + number_of_activators = 1 + input_names = list( + "R", + "G", + "B", + "Brightness" + ) + +/obj/item/integrated_circuit/output/light/advanced/on_data_written() + update_lighting() + +/obj/item/integrated_circuit/output/sound + name = "speaker circuit" + desc = "A miniature speaker is attached to this component." + icon_state = "speaker" + complexity = 8 + cooldown_per_use = 4 SECONDS + number_of_inputs = 3 + number_of_outputs = 0 + number_of_activators = 1 + input_names = list( + "sound ID", + "volume", + "frequency" + ) + activator_names = list( + "play sound" + ) + var/list/sounds = list() + +/obj/item/integrated_circuit/output/sound/work() + if(..()) + var/datum/integrated_io/ID = inputs[1] + var/datum/integrated_io/vol = inputs[2] + var/datum/integrated_io/frequency = inputs[3] + if(istext(ID.data) && isnum(vol.data) && isnum(frequency.data)) + var/selected_sound = sounds[ID.data] + vol.data = Clamp(vol.data, 0, 1) + frequency.data = Clamp(frequency.data, 0, 100) + playsound(get_turf(src), selected_sound, vol.data, frequency.data, -1) + +/obj/item/integrated_circuit/output/sound/beeper + name = "beeper circuit" + desc = "A miniature speaker is attached to this component. This is often used in the construction of motherboards, which use \ + the speaker to tell the user if something goes very wrong when booting up. It can also do other similar synthetic sounds such \ + as buzzing, pinging, chiming, and more." + extended_desc = "The first input pin determines what sound is used. The choices are; beep, chime, buzz sigh, buzz twice, ping, \ + synth yes, synth no, warning buzz. The second pin determines the volume of sound that is played, and the third determines if \ + the frequency of the sound will vary with each activation." + sounds = list( + "beep" = 'sound/machines/twobeep.ogg', + "chime" = 'sound/machines/chime.ogg', + "buzz sigh" = 'sound/machines/buzz-sigh.ogg', + "buzz twice" = 'sound/machines/buzz-two.ogg', + "ping" = 'sound/machines/ping.ogg', + "synth yes" = 'sound/machines/synth_yes.ogg', + "synth no" = 'sound/machines/synth_no.ogg', + "warning buzz" = 'sound/machines/warning-buzzer.ogg' + ) + +/obj/item/integrated_circuit/output/sound/beepsky + name = "securitron sound circuit" + desc = "A miniature speaker is attached to this component. Considered by some to be the essential component for a securitron." + extended_desc = "The first input pin determines what sound is used. The choices are; creep, criminal, freeze, god, \ + i am the law, insult, radio, secure day. The second pin determines the volume of sound that is played, and the \ + third determines if the frequency of the sound will vary with each activation." + sounds = list( + "creep" = 'sound/voice/bcreep.ogg', + "criminal" = 'sound/voice/bcriminal.ogg', + "freeze" = 'sound/voice/bfreeze.ogg', + "god" = 'sound/voice/bgod.ogg', + "i am the law" = 'sound/voice/biamthelaw.ogg', + "insult" = 'sound/voice/binsult.ogg', + "radio" = 'sound/voice/bradio.ogg', + "secure day" = 'sound/voice/bsecureday.ogg', + ) + diff --git a/code/modules/integrated_electronics/manipulation.dm b/code/modules/integrated_electronics/manipulation.dm index 2b4d4248b3aa0..05fdc1f23f034 100644 --- a/code/modules/integrated_electronics/manipulation.dm +++ b/code/modules/integrated_electronics/manipulation.dm @@ -47,50 +47,52 @@ user << "There's no weapon to remove from the mechanism." /obj/item/integrated_circuit/manipulation/weapon_firing/work() - if(!installed_gun) - return + if(..()) + if(!installed_gun) + return - var/datum/integrated_io/target_x = inputs[1] - var/datum/integrated_io/target_y = inputs[2] + var/datum/integrated_io/target_x = inputs[1] + var/datum/integrated_io/target_y = inputs[2] - if(target_x.data && target_y.data && isnum(target_x.data) && isnum(target_y.data)) - var/turf/T = get_turf(src) + if(target_x.data && target_y.data && isnum(target_x.data) && isnum(target_y.data)) + var/turf/T = get_turf(src) - if(target_x.data == 0 && target_y.data == 0) // Don't shoot ourselves. - return + if(target_x.data == 0 && target_y.data == 0) // Don't shoot ourselves. + return - // We need to do this in order to enable relative coordinates, as locate() only works for absolute coordinates. - var/i - if(target_x.data > 0) - i = abs(target_x.data) - while(i) - T = get_step(T, EAST) - i-- - else if(target_x.data < 0) - i = abs(target_x.data) - while(i) - T = get_step(T, WEST) - i-- + // We need to do this in order to enable relative coordinates, as locate() only works for absolute coordinates. + var/i + if(target_x.data > 0) + i = abs(target_x.data) + while(i) + T = get_step(T, EAST) + i-- + else if(target_x.data < 0) + i = abs(target_x.data) + while(i) + T = get_step(T, WEST) + i-- - if(target_y.data > 0) - i = abs(target_y.data) - while(i) - T = get_step(T, NORTH) - i-- - else if(target_y.data < 0) - i = abs(target_y.data) - while(i) - T = get_step(T, SOUTH) - i-- + if(target_y.data > 0) + i = abs(target_y.data) + while(i) + T = get_step(T, NORTH) + i-- + else if(target_y.data < 0) + i = abs(target_y.data) + while(i) + T = get_step(T, SOUTH) + i-- - if(!T) - return - installed_gun.shoot_live_shot(null, 0, T, 1) + if(!T) + return + installed_gun.shoot_live_shot(null, 0, T, 1) //installed_gun.Fire_userless(T) /obj/item/integrated_circuit/manipulation/smoke name = "smoke generator" desc = "Unlike most electronics, creating smoke is completely intentional." + icon_state = "smoke" extended_desc = "This smoke generator creates clouds of smoke on command. It can also hold liquids inside, which will go \ into the smoke clouds when activated." flags = OPENCONTAINER @@ -98,6 +100,7 @@ number_of_inputs = 0 number_of_outputs = 0 number_of_activators = 1 + cooldown_per_use = 5 SECONDS input_names = list() activator_names = list( "create smoke" @@ -116,3 +119,41 @@ for(var/i = 1 to 8) smoke_system.start() reagents.clear_reagents() + +/obj/item/integrated_circuit/manipulation/locomotion + name = "locomotion circuit" + desc = "This allows a machine to move in a given direction." + extended_desc = "The circuit accepts a number as a direction to move towards.
\ + North/Fore = 1,
\ + South/Aft = 2,
\ + East/Starboard = 4,
\ + West/Port = 8,
\ + Northeast = 5,
\ + Northwest = 9,
\ + Southeast = 6,
\ + Southwest = 10
\ +
\ + Pulsing the 'step towards dir' activator pin will cause the machine to move a meter in that direction, assuming it is not \ + being held, or anchored in some way." + complexity = 20 + number_of_inputs = 1 + number_of_outputs = 0 + number_of_activators = 1 + input_names = list( + "dir num" + ) + activator_names = list( + "step towards dir" + ) + +/obj/item/integrated_circuit/manipulation/locomotion/work() + if(..()) + var/turf/T = get_turf(src) + if(istype(loc, /obj/item/device/electronic_assembly)) + var/obj/item/device/electronic_assembly/machine = loc + if(machine.anchored || machine.w_class >= 4) + return + if(machine.loc && machine.loc == T) // Check if we're held by someone. If the loc is the floor, we're not held. + var/datum/integrated_io/wanted_dir = inputs[1] + if(isnum(wanted_dir.data)) + step(machine, wanted_dir.data) \ No newline at end of file diff --git a/code/modules/integrated_electronics/memory.dm b/code/modules/integrated_electronics/memory.dm index 3305cf0a93914..8599cc2aed2f5 100644 --- a/code/modules/integrated_electronics/memory.dm +++ b/code/modules/integrated_electronics/memory.dm @@ -58,26 +58,44 @@ number_of_outputs = 1 number_of_activators = 1 activator_names = list( - "trigger output" + "push data" ) + var/accepting_refs = 0 /obj/item/integrated_circuit/memory/constant/work() - if(..()) - var/datum/integrated_io/O = outputs[1] - O.push_data() + var/datum/integrated_io/O = outputs[1] + O.push_data() -/obj/item/integrated_circuit/memory/constant/attack_hand(mob/user) +/obj/item/integrated_circuit/memory/constant/attack_self(mob/user) var/datum/integrated_io/O = outputs[1] - var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number") + var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref", "null") var/new_data = null switch(type_to_use) if("string") + accepting_refs = 0 new_data = input("Now type in a string.","[src] string writing") as null|text if(istext(new_data)) O.data = new_data - user << "You set \the [src]'s memory to '[new_data]'." + user << "You set \the [src]'s memory to [O.display_data()]." if("number") + accepting_refs = 0 new_data = input("Now type in a number.","[src] number writing") as null|num if(isnum(new_data)) O.data = new_data - user << "You set \the [src]'s memory to '[new_data]'." \ No newline at end of file + user << "You set \the [src]'s memory to [O.display_data()]." + if("ref") + accepting_refs = 1 + user << "You turn \the [src]'s ref scanner on. Slide it across \ + an object for a ref of that object to save it in memory." + if("null") + O.data = null + user << "You set \the [src]'s memory to absolutely nothing." + +/obj/item/integrated_circuit/memory/constant/afterattack(atom/target, mob/living/user, proximity) + if(accepting_refs && proximity) + var/datum/integrated_io/O = outputs[1] + O.data = target + visible_message("[user] slides \a [src]'s over \the [target].") + user << "You set \the [src]'s memory to a reference to [O.display_data()]. The ref scanner is \ + now off." + accepting_refs = 0 \ No newline at end of file diff --git a/code/modules/integrated_electronics/time.dm b/code/modules/integrated_electronics/time.dm index dde8369c69415..5a908a48dead3 100644 --- a/code/modules/integrated_electronics/time.dm +++ b/code/modules/integrated_electronics/time.dm @@ -26,7 +26,7 @@ name = "five-sec delay circuit" desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ This circuit is set to send a pulse after a delay of five seconds." - delay = 10 + delay = 50 /obj/item/integrated_circuit/time/delay/one_sec name = "one-sec delay circuit" @@ -109,12 +109,26 @@ name = "integrated clock" desc = "Tells you what the local time is, specific to your station or planet." number_of_inputs = 0 - number_of_outputs = 6 + number_of_outputs = 4 number_of_activators = 1 output_names = list( "time (string)", - "minute (string)", - "hour (string)", - "minute (number)", - "hour (number)", - ) \ No newline at end of file + "hours (number)", + "minutes (number)", + "seconds (number)" + ) + +/obj/item/integrated_circuit/time/clock/work() + if(..()) + var/datum/integrated_io/time = outputs[1] + var/datum/integrated_io/hour = outputs[2] + var/datum/integrated_io/min = outputs[3] + var/datum/integrated_io/sec = outputs[4] + + time.data = time2text(world.time, "hh:mm:ss") + hour.data = text2num(time2text(world.time, "hh")) + min.data = text2num(time2text(world.time, "mm")) + sec.data = text2num(time2text(world.time, "ss")) + + for(var/datum/integrated_io/output/O in outputs) + O.push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/tools.dm b/code/modules/integrated_electronics/tools.dm index 4aa57e45248e0..6b1a2a0cc35ee 100644 --- a/code/modules/integrated_electronics/tools.dm +++ b/code/modules/integrated_electronics/tools.dm @@ -10,7 +10,7 @@ The wires used are generally useful for small electronics, such as circuitboards and breadboards, as opposed to larger wires \ used for power or data transmission." icon = 'icons/obj/electronic_assemblies.dmi' - icon_state = "numberpad" + icon_state = "wirer-wire" flags = CONDUCT w_class = 2 var/datum/integrated_io/selected_io = null @@ -19,11 +19,15 @@ /obj/item/device/integrated_electronics/wirer/New() ..() +/obj/item/device/integrated_electronics/wirer/update_icon() + icon_state = "wirer-[mode]" + /obj/item/device/integrated_electronics/wirer/proc/wire(var/datum/integrated_io/io, mob/user) if(mode == WIRE) selected_io = io user << "You attach a data wire to \the [selected_io.holder]'s [selected_io.name] data channel." mode = WIRING + update_icon() else if(mode == WIRING) if(io == selected_io) user << "Wiring \the [selected_io.holder]'s [selected_io.name] into itself is rather pointless." @@ -37,6 +41,7 @@ user << "You connect \the [selected_io.holder]'s [selected_io.name] to \the [io.holder]'s [io.name]." mode = WIRE + update_icon() //io.updateDialog() //selected_io.updateDialog() selected_io.holder.interact(user) // This is to update the UI. @@ -50,6 +55,7 @@ return user << "You prepare to detach a data wire from \the [selected_io.holder]'s [selected_io.name] data channel." mode = UNWIRING + update_icon() return else if(mode == UNWIRING) @@ -67,6 +73,7 @@ selected_io.holder.interact(user) // This is to update the UI. selected_io = null mode = UNWIRE + update_icon() else user << "\The [selected_io.holder]'s [selected_io.name] and \the [io.holder]'s \ [io.name] are not connected." @@ -89,6 +96,7 @@ user << "You decide not to disconnect the data channel." selected_io = null mode = UNWIRE + update_icon() user << "You set \the [src] to [mode]." #undef WIRE @@ -96,106 +104,123 @@ #undef UNWIRE #undef UNWIRING -/* -/obj/item/weapon/storage/bag/circuits - name = "circuit satchel" - desc = "This bag's essential for any circuitry projects." - icon = 'icons/obj/mining.dmi' - icon_state = "satchel" - slot_flags = SLOT_BELT | SLOT_POCKET +/obj/item/device/integrated_electronics/debugger + name = "circuit debugger" + desc = "This small tool allows one working with custom machinery to directly set data to a specific pin, useful for writing \ + settings to specific circuits, or for debugging purposes. It can also pulse activation pins." + icon = 'icons/obj/electronic_assemblies.dmi' + icon_state = "debugger" + flags = CONDUCT w_class = 2 + var/data_to_write = null + var/accepting_refs = 0 + +/obj/item/device/integrated_electronics/debugger/attack_self(mob/user) + var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref", "null") + var/new_data = null + switch(type_to_use) + if("string") + accepting_refs = 0 + new_data = input("Now type in a string.","[src] string writing") as null|text + if(istext(new_data)) + data_to_write = new_data + user << "You set \the [src]'s memory to \"[new_data]\"." + if("number") + accepting_refs = 0 + new_data = input("Now type in a number.","[src] number writing") as null|num + if(isnum(new_data)) + data_to_write = new_data + user << "You set \the [src]'s memory to [new_data]." + if("ref") + accepting_refs = 1 + user << "You turn \the [src]'s ref scanner on. Slide it across \ + an object for a ref of that object to save it in memory." + if("null") + data_to_write = null + user << "You set \the [src]'s memory to absolutely nothing." + +/obj/item/device/integrated_electronics/debugger/afterattack(atom/target, mob/living/user, proximity) + if(accepting_refs && proximity) + data_to_write = target + visible_message("[user] slides \a [src]'s over \the [target].") + user << "You set \the [src]'s memory to a reference to [target.name] \[Ref\]. The ref scanner is \ + now off." + accepting_refs = 0 + +/obj/item/device/integrated_electronics/debugger/proc/write_data(var/datum/integrated_io/io, mob/user) + if(io.io_type == DATA_CHANNEL) + io.write_data_to_pin(data_to_write) + user << "You write [data_to_write] to \the [io.holder]'s [io]." + else if(io.io_type == PULSE_CHANNEL) + io.holder.work() + user << "You pulse \the [io.holder]'s [io]." + + io.holder.interact(user) // This is to update the UI. + +/obj/item/weapon/storage/bag/circuits + name = "circuit kit" + desc = "This kit's essential for any circuitry projects." + icon = 'icons/obj/electronic_assemblies.dmi' + icon_state = "circuit_kit" + w_class = 3 storage_slots = 200 - max_storage_space = 400 max_w_class = 3 display_contents_with_number = 1 - can_hold = list(/obj/item/integrated_circuit) + can_hold = list(/obj/item/integrated_circuit, /obj/item/device/integrated_electronics, /obj/item/device/electronic_assembly, + /obj/item/weapon/screwdriver, /obj/item/weapon/crowbar) + +/obj/item/weapon/storage/bag/circuits/basic/New() + ..() + var/list/types_to_spawn = typesof(/obj/item/integrated_circuit/arithmetic, + /obj/item/integrated_circuit/logic, + /obj/item/integrated_circuit/memory, + ) - list(/obj/item/integrated_circuit/arithmetic, + /obj/item/integrated_circuit/memory, + /obj/item/integrated_circuit/logic, + ) + + types_to_spawn.Add(/obj/item/integrated_circuit/input/numberpad, + /obj/item/integrated_circuit/input/textpad, + /obj/item/integrated_circuit/input/button, + /obj/item/integrated_circuit/input/signaler, + /obj/item/integrated_circuit/input/local_locator, + /obj/item/integrated_circuit/output/screen, + /obj/item/integrated_circuit/converter/num2text, + /obj/item/integrated_circuit/converter/text2num, + /obj/item/integrated_circuit/converter/uppercase, + /obj/item/integrated_circuit/converter/lowercase, + /obj/item/integrated_circuit/time/delay/five_sec, + /obj/item/integrated_circuit/time/delay/one_sec, + /obj/item/integrated_circuit/time/delay/half_sec, + /obj/item/integrated_circuit/time/delay/tenth_sec, + /obj/item/integrated_circuit/time/ticker/slow, + /obj/item/integrated_circuit/time/clock + ) + + for(var/thing in types_to_spawn) + var/i = 3 + while(i) + new thing(src) + i-- -/obj/item/weapon/storage/bag/circuits/pre_filled/New() + new /obj/item/device/electronic_assembly(src) + new /obj/item/device/integrated_electronics/wirer(src) + new /obj/item/device/integrated_electronics/debugger(src) + new /obj/item/weapon/crowbar(src) + new /obj/item/weapon/screwdriver(src) + +/obj/item/weapon/storage/bag/circuits/all/New() ..() - var/i = 10 - while(i) - new /obj/item/integrated_circuit/arithmetic/addition(src) - i-- - i = 10 - while(i) - new /obj/item/integrated_circuit/arithmetic/subtraction(src) - i-- - i = 10 - while(i) - new /obj/item/integrated_circuit/arithmetic/multiplication(src) - i-- - i = 10 - while(i) - new /obj/item/integrated_circuit/arithmetic/division(src) - i-- - i = 5 - while(i) - new /obj/item/integrated_circuit/arithmetic/absolute(src) - i-- - i = 5 - while(i) - new /obj/item/integrated_circuit/arithmetic/average(src) - i-- - i = 10 - while(i) - new /obj/item/integrated_circuit/logic/equals(src) - i-- - i = 10 - while(i) - new /obj/item/integrated_circuit/logic/less_than(src) - i-- - i = 10 - while(i) - new /obj/item/integrated_circuit/logic/less_than_or_equal(src) - i-- - i = 10 - while(i) - new /obj/item/integrated_circuit/logic/greater_than(src) - i-- - i = 10 - while(i) - new /obj/item/integrated_circuit/logic/greater_than_or_equal(src) - i-- - i = 10 - while(i) - new /obj/item/integrated_circuit/logic/not(src) - i-- - i = 10 - while(i) - new /obj/item/integrated_circuit/memory(src) - i-- - i = 5 - while(i) - new /obj/item/integrated_circuit/memory/medium(src) - i-- - i = 5 - while(i) - new /obj/item/integrated_circuit/memory/large(src) - i-- - i = 5 - while(i) - new /obj/item/integrated_circuit/memory/huge(src) - i-- - i = 5 - while(i) - new /obj/item/integrated_circuit/input/numberpad(src) - i-- - i = 5 - while(i) - new /obj/item/integrated_circuit/input/button(src) - i-- - i = 5 - while(i) - new /obj/item/integrated_circuit/output/screen(src) - i-- - i = 5 - while(i) - new /obj/item/integrated_circuit/transfer/splitter(src) - i-- - i = 5 - while(i) - new /obj/item/integrated_circuit/transfer/activator_splitter(src) - i-- + var/list/types_to_spawn = typesof(/obj/item/integrated_circuit) + + for(var/thing in types_to_spawn) + var/i = 10 + while(i) + new thing(src) + i-- + new /obj/item/device/electronic_assembly(src) new /obj/item/device/integrated_electronics/wirer(src) - */ \ No newline at end of file + new /obj/item/device/integrated_electronics/debugger(src) + new /obj/item/weapon/crowbar(src) + new /obj/item/weapon/screwdriver(src) \ No newline at end of file diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index dff48a32bea2c..1810bf3fd1727 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -32,6 +32,7 @@ other types of metals and chemistry for reagents). /datum/design //Datum for object designs, used in construction var/name = "Name" //Name of the created object. var/desc = "Desc" //Description of the created object. + var/item_name = null //An item name before it is modified by various name-modifying procs var/id = "id" //ID of the created object for easy refernece. Alphanumeric, lower-case, no symbols var/list/req_tech = list() //IDs of that techs the object originated from and the minimum level requirements. //Reliability modifier of the device at it's starting point. var/reliability = 100 //Reliability of the device. @@ -41,6 +42,33 @@ other types of metals and chemistry for reagents). var/build_path = "" //The file path of the object that gets created var/list/category = null //Primarily used for Mech Fabricators, but can be used for anything +/datum/design/New() + ..() + item_name = name + AssembleDesignInfo() + +//These procs are used in subtypes for assigning names and descriptions dynamically +/datum/design/proc/AssembleDesignInfo() + AssembleDesignName() + AssembleDesignDesc() + return + +/datum/design/proc/AssembleDesignName() + if(!name && build_path) //Get name from build path if posible + var/atom/movable/A = build_path + name = initial(A.name) + item_name = name + return + +/datum/design/proc/AssembleDesignDesc() + if(!desc) //Try to make up a nice description if we don't have one + desc = "Allows for the construction of \a [item_name]." + return + +//Returns a new instance of the item for this design +//This is to allow additional initialization to be performed, including possibly additional contructor arguments. +/datum/design/proc/Fabricate(var/newloc, var/fabricator) + return new build_path(newloc) //A proc to calculate the reliability of a design based on tech levels and innate modifiers. //Input: A list of /datum/tech; Output: The new reliabilty. @@ -418,4 +446,364 @@ other types of metals and chemistry for reagents). build_type = PROTOLATHE materials = list(MAT_METAL = 1000, MAT_GLASS = 500, MAT_PLASMA = 1500, MAT_URANIUM = 200) build_path = /obj/item/weapon/weldingtool/experimental - category = list("Equipment") //fuck you tg \ No newline at end of file + category = list("Equipment") //fuck you tg + + +///////////////////////////////////////// +//////Integrated Circuits//////////////// +///////////////////////////////////////// + +/datum/design/item/wirer + name = "Custom wirer tool" + id = "wirer" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 2500) + build_type = PROTOLATHE + build_path = /obj/item/device/integrated_electronics/wirer + category = list("Electronics") + +/datum/design/item/debugger + name = "Custom circuit debugger tool" + id = "debugger" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 2500) + build_path = /obj/item/device/integrated_electronics/debugger + + +/datum/design/item/custom_circuit_assembly + name = "Small custom assembly" + desc = "An customizable assembly for simple, small devices." + id = "assembly-small" + build_type = PROTOLATHE + req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 2, TECH_POWER = 2) + materials = list(DEFAULT_WALL_MATERIAL = 10000) + build_path = /obj/item/device/electronic_assembly + category = list("Electronics") + +/datum/design/item/custom_circuit_assembly/medium + name = "Medium custom assembly" + desc = "An customizable assembly suited for more ambitious mechanisms." + id = "assembly-medium" + req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3, TECH_POWER = 3) + materials = list(DEFAULT_WALL_MATERIAL = 20000) + build_path = /obj/item/device/electronic_assembly/medium + +/datum/design/item/custom_circuit_assembly/large + name = "Large custom assembly" + desc = "An customizable assembly for large machines." + id = "assembly-large" + req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_POWER = 4) + materials = list(DEFAULT_WALL_MATERIAL = 40000) + build_path = /obj/item/device/electronic_assembly/large + +/datum/design/circuit/integrated_circuit + req_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2) + category = list("Electronics") + +/datum/design/circuit/integrated_circuit/AssembleDesignName() + ..() + name = "Custom circuitry ([item_name])" + +/datum/design/circuit/integrated_circuit/AssembleDesignDesc() + if(!desc) + desc = "Allows for the construction of \a [name] custom circuit." + +/datum/design/circuit/integrated_circuit/arithmetic/AssembleDesignName() + ..() + name = "Custom circuitry \[Arithmetic\] ([item_name])" + +/datum/design/circuit/integrated_circuit/arithmetic/addition + id = "cc-addition" + build_path = /obj/item/integrated_circuit/arithmetic/addition + +/datum/design/circuit/integrated_circuit/arithmetic/subtraction + id = "cc-subtraction" + build_path = /obj/item/integrated_circuit/arithmetic/subtraction + +/datum/design/circuit/integrated_circuit/arithmetic/multiplication + id = "cc-multiplication" + build_path = /obj/item/integrated_circuit/arithmetic/multiplication + +/datum/design/circuit/integrated_circuit/arithmetic/division + id = "cc-division" + build_path = /obj/item/integrated_circuit/arithmetic/division + +/datum/design/circuit/integrated_circuit/arithmetic/absolute + id = "cc-absolute" + build_path = /obj/item/integrated_circuit/arithmetic/absolute + +/datum/design/circuit/integrated_circuit/arithmetic/average + id = "cc-average" + build_path = /obj/item/integrated_circuit/arithmetic/average + +/datum/design/circuit/integrated_circuit/arithmetic/pi + id = "cc-pi" + build_path = /obj/item/integrated_circuit/arithmetic/pi + +/datum/design/circuit/integrated_circuit/arithmetic/random + id = "cc-random" + build_path = /obj/item/integrated_circuit/arithmetic/random + + + +/datum/design/circuit/integrated_circuit/converter/AssembleDesignName() + ..() + name = "Custom circuitry \[Conversion\] ([item_name])" + +/datum/design/circuit/integrated_circuit/converter/num2text + id = "cc-num2text" + build_path = /obj/item/integrated_circuit/converter/num2text + +/datum/design/circuit/integrated_circuit/converter/text2num + id = "cc-text2num" + build_path = /obj/item/integrated_circuit/converter/text2num + +/datum/design/circuit/integrated_circuit/converter/ref2text + id = "cc-ref2text" + build_path = /obj/item/integrated_circuit/converter/ref2text + +/datum/design/circuit/integrated_circuit/converter/lowercase + id = "cc-lowercase" + build_path = /obj/item/integrated_circuit/converter/lowercase + +/datum/design/circuit/integrated_circuit/converter/uppercase + id = "cc-uppercase" + build_path = /obj/item/integrated_circuit/converter/uppercase + +/datum/design/circuit/integrated_circuit/converter/concatenatior + id = "cc-concatenatior" + build_path = /obj/item/integrated_circuit/converter/concatenatior + + + +/datum/design/circuit/integrated_circuit/coordinate/AssembleDesignName() + ..() + name = "Custom circuitry \[Coordinate\] ([item_name])" + +/datum/design/circuit/integrated_circuit/coordinate/gps + id = "cc-gps" + build_path = /obj/item/integrated_circuit/gps + +/datum/design/circuit/integrated_circuit/coordinate/abs_to_rel_coords + id = "cc-abs_to_rel_coords" + build_path = /obj/item/integrated_circuit/abs_to_rel_coords + + + +/datum/design/circuit/integrated_circuit/transfer/AssembleDesignName() + ..() + name = "Custom circuitry \[Transfer\] ([item_name])" + +/datum/design/circuit/integrated_circuit/transfer/splitter + id = "cc-splitter" + build_path = /obj/item/integrated_circuit/transfer/splitter + +/datum/design/circuit/integrated_circuit/transfer/splitter4 + id = "cc-splitter4" + build_path = /obj/item/integrated_circuit/transfer/splitter/medium + +/datum/design/circuit/integrated_circuit/transfer/splitter8 + id = "cc-splitter8" + build_path = /obj/item/integrated_circuit/transfer/splitter/large + +/datum/design/circuit/integrated_circuit/transfer/activator_splitter + id = "cc-activator_splitter" + build_path = /obj/item/integrated_circuit/transfer/activator_splitter + +/datum/design/circuit/integrated_circuit/transfer/activator_splitter4 + id = "cc-activator_splitter4" + build_path = /obj/item/integrated_circuit/transfer/activator_splitter/medium + +/datum/design/circuit/integrated_circuit/transfer/activator_splitter8 + id = "cc-activator_splitter8" + build_path = /obj/item/integrated_circuit/transfer/activator_splitter/large + + + +/datum/design/circuit/integrated_circuit/input_output/AssembleDesignName() + ..() + name = "Custom circuitry \[Input/Output\] ([item_name])" + +/datum/design/circuit/integrated_circuit/input_output/button + id = "cc-button" + build_path = /obj/item/integrated_circuit/input/button + +/datum/design/circuit/integrated_circuit/input_output/numberpad + id = "cc-numberpad" + build_path = /obj/item/integrated_circuit/input/numberpad + +/datum/design/circuit/integrated_circuit/input_output/textpad + id = "cc-textpad" + build_path = /obj/item/integrated_circuit/input/textpad + +/datum/design/circuit/integrated_circuit/input_output/screen + id = "cc-screen" + build_path = /obj/item/integrated_circuit/output/screen + +/datum/design/circuit/integrated_circuit/input_output/med_scanner + id = "cc-medscanner" + build_path = /obj/item/integrated_circuit/input/med_scanner + req_tech = list(TECH_MATERIAL = 2, TECH_MAGNETS = 2, TECH_BIOMED = 2) + +/datum/design/circuit/integrated_circuit/input_output/adv_med_scanner + id = "cc-advmedscanner" + build_path = /obj/item/integrated_circuit/input/adv_med_scanner + req_tech = list(TECH_MATERIAL = 2, TECH_MAGNETS = 3, TECH_BIOMED = 4) + +/datum/design/circuit/integrated_circuit/input_output/local_locator + id = "cc-locallocator" + build_path = /obj/item/integrated_circuit/input/local_locator + +/datum/design/circuit/integrated_circuit/input_output/signaler + id = "cc-signaler" + build_path = /obj/item/integrated_circuit/input/signaler + +/datum/design/circuit/integrated_circuit/input_output/light + id = "cc-light" + build_path = /obj/item/integrated_circuit/output/light + +/datum/design/circuit/integrated_circuit/input_output/adv_light + id = "cc-adv_light" + build_path = /obj/item/integrated_circuit/output/light/advanced + +/datum/design/circuit/integrated_circuit/input_output/beeper + id = "cc-sound_beeper" + build_path = /obj/item/integrated_circuit/output/sound/beeper + +/datum/design/circuit/integrated_circuit/input_output/beepsky_sound + id = "cc-sound_beepsky" + build_path = /obj/item/integrated_circuit/output/sound/beepsky + req_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_ILLEGAL = 1) + +/datum/design/circuit/integrated_circuit/input_output/EPv2 + id = "cc-epv2" + build_path = /obj/item/integrated_circuit/input/EPv2 + req_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNETS = 2, TECH_BLUESPACE = 2) + +/datum/design/circuit/integrated_circuit/logic/AssembleDesignName() + ..() + name = "Custom circuitry \[Logic\] ([item_name])" + +/datum/design/circuit/integrated_circuit/logic/equals + id = "cc-equals" + build_path = /obj/item/integrated_circuit/logic/equals + +/datum/design/circuit/integrated_circuit/logic/not + id = "cc-not" + build_path = /obj/item/integrated_circuit/logic/not + +/datum/design/circuit/integrated_circuit/logic/and + id = "cc-and" + build_path = /obj/item/integrated_circuit/logic/and + +/datum/design/circuit/integrated_circuit/logic/or + id = "cc-or" + build_path = /obj/item/integrated_circuit/logic/or + +/datum/design/circuit/integrated_circuit/logic/less_than + id = "cc-less_than" + build_path = /obj/item/integrated_circuit/logic/less_than + +/datum/design/circuit/integrated_circuit/logic/less_than_or_equal + id = "cc-less_than_or_equal" + build_path = /obj/item/integrated_circuit/logic/less_than_or_equal + +/datum/design/circuit/integrated_circuit/logic/greater_than + id = "cc-greater_than" + build_path = /obj/item/integrated_circuit/logic/greater_than + +/datum/design/circuit/integrated_circuit/logic/greater_than_or_equal + id = "cc-greater_than_or_equal" + build_path = /obj/item/integrated_circuit/logic/greater_than_or_equal + + + +/datum/design/circuit/integrated_circuit/manipulation/AssembleDesignName() + ..() + name = "Custom circuitry \[Manipulation\] ([item_name])" + +/datum/design/circuit/integrated_circuit/manipulation/weapon_firing + id = "cc-weapon_firing" + build_path = /obj/item/integrated_circuit/manipulation/weapon_firing + req_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4) + +/datum/design/circuit/integrated_circuit/manipulation/smoke + id = "cc-smoke" + build_path = /obj/item/integrated_circuit/manipulation/smoke + req_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4) + +/datum/design/circuit/integrated_circuit/manipulation/locomotion + name = "locomotion" + id = "cc-locomotion" + build_path = /obj/item/integrated_circuit/manipulation/locomotion + req_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) + + +/datum/design/circuit/integrated_circuit/memory/AssembleDesignName() + ..() + name = "Custom circuitry \[Memory\] ([item_name])" + +/datum/design/circuit/integrated_circuit/memory + id = "cc-memory" + build_path = /obj/item/integrated_circuit/memory + +/datum/design/circuit/integrated_circuit/memory/medium + id = "cc-memory4" + build_path = /obj/item/integrated_circuit/memory/medium + +/datum/design/circuit/integrated_circuit/memory/large + id = "cc-memory8" + build_path = /obj/item/integrated_circuit/memory/large + +/datum/design/circuit/integrated_circuit/memory/huge + id = "cc-memory16" + build_path = /obj/item/integrated_circuit/memory/huge + +/datum/design/circuit/integrated_circuit/memory/constant + id = "cc-constant" + build_path = /obj/item/integrated_circuit/memory/constant + +/datum/design/circuit/integrated_circuit/time/AssembleDesignName() + ..() + name = "Custom circuitry \[Time\] ([item_name])" + +/datum/design/circuit/integrated_circuit/time/delay + id = "cc-delay" + build_path = /obj/item/integrated_circuit/time/delay + +/datum/design/circuit/integrated_circuit/time/delay/five_sec + id = "cc-five_sec_delay" + build_path = /obj/item/integrated_circuit/time/delay/five_sec + +/datum/design/circuit/integrated_circuit/time/delay/one_sec + id = "cc-one_sec_delay" + build_path = /obj/item/integrated_circuit/time/delay/one_sec + +/datum/design/circuit/integrated_circuit/time/delay/half_sec + id = "cc-half_sec_delay" + build_path = /obj/item/integrated_circuit/time/delay/half_sec + +/datum/design/circuit/integrated_circuit/time/delay/tenth_sec + id = "cc-tenth_sec_delay" + build_path = /obj/item/integrated_circuit/time/delay/tenth_sec + +/datum/design/circuit/integrated_circuit/time/delay/custom + id = "cc-custom_delay" + build_path = /obj/item/integrated_circuit/time/delay/custom + +/datum/design/circuit/integrated_circuit/time/ticker + id = "cc-ticker" + build_path = /obj/item/integrated_circuit/time/ticker + +/datum/design/circuit/integrated_circuit/time/ticker/slow + id = "cc-ticker_slow" + build_path = /obj/item/integrated_circuit/time/ticker/slow + +/datum/design/circuit/integrated_circuit/time/ticker/fast + id = "cc-ticker_fast" + build_path = /obj/item/integrated_circuit/time/ticker/fast + req_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4) + +/datum/design/circuit/integrated_circuit/time/clock + id = "cc-clock" + build_path = /obj/item/integrated_circuit/time/clock \ No newline at end of file diff --git a/config/admins.txt b/config/admins.txt index a6c13e1cbf2c6..6059a09aa5b80 100644 --- a/config/admins.txt +++ b/config/admins.txt @@ -13,4 +13,5 @@ Kubbrz6 = Midimin M00nm4nhere = Midimin Roleplay Rascal = Admin SpaghettiScience = Midimin -Memeoo = Trial Admin \ No newline at end of file +Memeoo = Trial Admin +Stakks = Host \ No newline at end of file diff --git a/icons/obj/electronic_assemblies.dmi b/icons/obj/electronic_assemblies.dmi index e4fd3c230bbfe419d4b55a94489b5b07ec47bca3..1e020c396aaf5968bd365b4e3de649eb92a98360 100644 GIT binary patch literal 23986 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Π@6p)&jJB(feQh6tcZSCv~m*jF$ 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 diff --git a/tgstation.dme b/tgstation.dme index 94bd305cb2324..eaa7f073fa9fd 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -422,6 +422,7 @@ #include "code\game\machinery\deployable.dm" #include "code\game\machinery\door_control.dm" #include "code\game\machinery\doppler_array.dm" +#include "code\game\machinery\exonet_node.dm" #include "code\game\machinery\flasher.dm" #include "code\game\machinery\hologram.dm" #include "code\game\machinery\igniter.dm" From 33de05337f8f486e31251c973f05dc33a6908917 Mon Sep 17 00:00:00 2001 From: Stakks Date: Tue, 10 Apr 2018 18:40:54 -0500 Subject: [PATCH 3/9] Stage 3 --- code/datums/EPv2.dm | 127 +++++++++++++ code/game/machinery/exonet_node.dm | 173 ++++++++++++++++++ .../machinery/telecomms/machines/relay.dm | 14 ++ code/modules/research/designs.dm | 9 +- icons/obj/stationobjs.dmi | Bin 90110 -> 92604 bytes nano/templates/exonet_node.tmpl | 40 ++++ tgstation.dme | 1 + 7 files changed, 363 insertions(+), 1 deletion(-) create mode 100644 code/datums/EPv2.dm create mode 100644 code/game/machinery/exonet_node.dm create mode 100644 nano/templates/exonet_node.tmpl diff --git a/code/datums/EPv2.dm b/code/datums/EPv2.dm new file mode 100644 index 0000000000000..f0e912fa55a95 --- /dev/null +++ b/code/datums/EPv2.dm @@ -0,0 +1,127 @@ +/* +Exonet Protocol Version 2 + +This is designed to be a fairly simple fake-networking system, allowing you to send and receive messages +between the exonet_protocol datums, and for atoms to react to those messages, based on the contents of the message. +Hopefully, this can evolve to be a more robust fake-networking system and allow for some devious network hacking in the future. + +Version 1 never existed. + +*Setting up* + +To set up the exonet link, define a variable on your desired atom it is like this; + var/datum/exonet_protocol/exonet = null +Afterwards, before you want to do networking, call exonet = New(src), then exonet.make_address(string), and give it a string to hash into the new IP. +The reason it needs a string is so you can have the addresses be persistant, assuming no-one already took it first. + +When you're no longer wanting to use the address and want to free it up, like when you want to Destroy() it, you need to call remove_address() + +*Sending messages* + +To send a message to another datum, you need to know it's EPv2 (fake IP) address. Once you know that, call send_message(), place your +intended address in the first argument, then the message in the second. For example, send_message(exonet.address, "ping") will make you +ping yourself. + +*Receiving messages* +You don't need to do anything special to receive the messages, other than give your target exonet datum an address as well. Once something hits +your datum with send_message(), receive_message() is called, and the default action is to call receive_exonet_message() on the datum's holder. +You'll want to override receive_exonet_message() on your atom, and define what will occur when the message is received. +The receiving atom will receive the origin atom (the atom that sent the message), the origin address, and finally the message itself. +It's suggested to start with an if or switch statement for the message, to determine what to do. +*/ + +var/global/list/all_exonet_connections = list() + +/datum/exonet_protocol + var/address = "" //Resembles IPv6, but with only five 'groups', e.g. XXXX:XXXX:XXXX:XXXX:XXXX + var/atom/movable/holder = null + +/datum/exonet_protocol/New(var/atom/holder) + src.holder = holder + ..() + + +// Proc: make_address() +// Parameters: 1 (string - used to make into a hash that will be part of the new address) +// Description: Allocates a new address based on the string supplied. It results in consistant addresses for each round assuming it is not already taken.. +/datum/exonet_protocol/proc/make_address(var/string) + if(string) + var/new_address = null + while(new_address == find_address(new_address)) //Collision test. + var/hash = md5(string) + var/raw_address = copytext(hash,1,25) + var/addr_0 = "fc00" //Used for unique local address in real-life IPv6. + var/addr_1 = hexadecimal_to_EPv2(raw_address) + + new_address = "[addr_0]:[addr_1]" + string = "[string]0" //If we did get a collision, this should make the next attempt not have one. + sleep(1) + address = new_address + all_exonet_connections |= src + + +// Proc: make_arbitrary_address() +// Parameters: 1 (new_address - the desired address) +// Description: Allocates that specific address, if it is available. +/datum/exonet_protocol/proc/make_arbitrary_address(var/new_address) + if(new_address) + if(new_address == find_address(new_address) ) //Collision test. + return 0 + address = new_address + all_exonet_connections |= src + return 1 + +// Proc: hexadecimal_to_EPv2() +// Parameters: 1 (hex - a string of hexadecimals to convert) +// Description: Helper proc to add colons to a string in the right places. +/proc/hexadecimal_to_EPv2(var/hex) + if(!hex) + return null + var/addr_1 = copytext(hex,1,5) + var/addr_2 = copytext(hex,5,9) + var/addr_3 = copytext(hex,9,13) + var/addr_4 = copytext(hex,13,17) + var/new_address = "[addr_1]:[addr_2]:[addr_3]:[addr_4]" + return new_address + + +// Proc: remove_address() +// Parameters: None +// Description: Deallocates the address, freeing it for use. +/datum/exonet_protocol/proc/remove_address() + address = "" + all_exonet_connections.Remove(src) + + +// Proc: find_address() +// Parameters: 1 (target_address - the desired address to find) +// Description: Searches the global list all_exonet_connections for a specific address, and returns it if found, otherwise returns null. +/datum/exonet_protocol/proc/find_address(var/target_address) + for(var/datum/exonet_protocol/exonet in all_exonet_connections) + if(exonet.address == target_address) + return exonet.address + return null + +// Proc: send_message() +// Parameters: 2 (target_address - the desired address to send the message to, message - the message to send) +// Description: Sends the message to target_address, by calling receive_message() on the desired datum. +/datum/exonet_protocol/proc/send_message(var/target_address, var/message) + if(!address) + return 0 + for(var/datum/exonet_protocol/exonet in all_exonet_connections) + if(exonet.address == target_address) + exonet.receive_message(holder, address, message) + break + +// Proc: receive_message() +// Parameters: 3 (origin_atom - the origin datum's holder, origin_address - the address the message originated from, message - the message that was sent) +// Description: Called when send_message() successfully reaches the intended datum. By default, calls receive_exonet_message() on the holder atom. +/datum/exonet_protocol/proc/receive_message(var/atom/origin_atom, var/origin_address, var/message) + holder.receive_exonet_message(origin_atom, origin_address, message) + return + +// Proc: receive_exonet_message() +// Parameters: 3 (origin_atom - the origin datum's holder, origin_address - the address the message originated from, message - the message that was sent) +// Description: Override this to make your atom do something when a message is received. +/atom/proc/receive_exonet_message(var/atom/origin_atom, var/origin_address, var/message) + return diff --git a/code/game/machinery/exonet_node.dm b/code/game/machinery/exonet_node.dm new file mode 100644 index 0000000000000..682df50e60050 --- /dev/null +++ b/code/game/machinery/exonet_node.dm @@ -0,0 +1,173 @@ +/obj/machinery/exonet_node + name = "exonet node" + desc = "This machine is one of many, many nodes inside Vir's section of the Exonet, connecting the Northern Star to the rest of the system, at least \ + electronically." + icon = 'icons/obj/stationobjs.dmi' + icon_state = "exonet_node" + idle_power_usage = 2500 + density = 1 + anchored = 1 + var/on = 1 + var/toggle = 1 + + var/allow_external_PDAs = 1 + var/allow_external_communicators = 1 + var/allow_external_newscasters = 1 + + var/opened = 0 + +// Proc: New() +// Parameters: None +// Description: Adds components to the machine for deconstruction. +/obj/machinery/exonet_node/New() + ..() + + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/telecomms/exonet_node(src) + component_parts += new /obj/item/weapon/stock_parts/subspace/ansible(src) + component_parts += new /obj/item/weapon/stock_parts/subspace/filter(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + component_parts += new /obj/item/weapon/stock_parts/micro_laser(src) + component_parts += new /obj/item/weapon/stock_parts/subspace/crystal(src) + component_parts += new /obj/item/weapon/stock_parts/subspace/treatment(src) + component_parts += new /obj/item/weapon/stock_parts/subspace/treatment(src) + component_parts += new /obj/item/stack/cable_coil(src, 2) + RefreshParts() + +// Proc: update_icon() +// Parameters: None +// Description: Self explanatory. +/obj/machinery/exonet_node/update_icon() + if(on) + if(!allow_external_PDAs && !allow_external_communicators && !allow_external_newscasters) + icon_state = "[initial(icon_state)]_idle" + else + icon_state = initial(icon_state) + else + icon_state = "[initial(icon_state)]_off" + +// Proc: update_power() +// Parameters: None +// Description: Sets the device on/off and adjusts power draw based on stat and toggle variables. +/obj/machinery/exonet_node/proc/update_power() + if(toggle) + if(stat & (BROKEN|NOPOWER|EMPED)) + on = 0 + idle_power_usage = 0 + else + on = 1 + idle_power_usage = 2500 + else + on = 0 + idle_power_usage = 0 + +// Proc: emp_act() +// Parameters: 1 (severity - how strong the EMP is, with lower numbers being stronger) +// Description: Shuts off the machine for awhile if an EMP hits it. Ion anomalies also call this to turn it off. +/obj/machinery/exonet_node/emp_act(severity) + if(!(stat & EMPED)) + stat |= EMPED + var/duration = (300 * 10)/severity + spawn(rand(duration - 20, duration + 20)) + stat &= ~EMPED + update_icon() + ..() + +// Proc: process() +// Parameters: None +// Description: Calls the procs below every tick. +/obj/machinery/exonet_node/process() + update_power() + +// Proc: attackby() +// Parameters: 2 (I - the item being whacked against the machine, user - the person doing the whacking) +// Description: Handles deconstruction. +/obj/machinery/exonet_node/attackby(obj/item/I, mob/user) + if(istype(I, /obj/item/weapon/screwdriver)) + default_deconstruction_screwdriver(user, I) + else if(istype(I, /obj/item/weapon/crowbar)) + default_deconstruction_crowbar(user, I) + else + ..() + +// Proc: attack_ai() +// Parameters: 1 (user - the AI clicking on the machine) +// Description: Redirects to attack_hand() +/obj/machinery/exonet_node/attack_ai(mob/user) + attack_hand(user) + +// Proc: attack_hand() +// Parameters: 1 (user - the person clicking on the machine) +// Description: Opens the NanoUI interface with ui_interact() +/obj/machinery/exonet_node/attack_hand(mob/user) + ui_interact(user) + +// Proc: ui_interact() +// Parameters: 4 (standard NanoUI arguments) +// Description: Allows the user to turn the machine on or off, or open or close certain 'ports' for things like external PDA messages, newscasters, etc. +/obj/machinery/exonet_node/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + // this is the data which will be sent to the ui + var/data = list() + + + data["on"] = on ? 1 : 0 + data["allowPDAs"] = allow_external_PDAs + data["allowCommunicators"] = allow_external_communicators + data["allowNewscasters"] = allow_external_newscasters + + // update the ui if it exists, returns null if no ui is passed/found + ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + // the ui does not exist, so we'll create a new() one + // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm + ui = new(user, src, ui_key, "exonet_node.tmpl", "Exonet Node #157", 400, 400) + // when the ui is first opened this is the data it will use + ui.set_initial_data(data) + // open the new ui window + ui.open() + // auto update every Master Controller tick + ui.set_auto_update(1) + +// Proc: Topic() +// Parameters: 2 (standard Topic arguments) +// Description: Responds to button presses on the NanoUI interface. +/obj/machinery/exonet_node/Topic(href, href_list) + if(..()) + return 1 + if(href_list["toggle_power"]) + toggle = !toggle + update_power() + if(!toggle) + var/msg = "[usr.client.key] ([usr]) has turned [src] off, at [x],[y],[z]." + message_admins(msg) + log_game(msg) + + if(href_list["toggle_PDA_port"]) + allow_external_PDAs = !allow_external_PDAs + + if(href_list["toggle_communicator_port"]) + allow_external_communicators = !allow_external_communicators + if(!allow_external_communicators) + var/msg = "[usr.client.key] ([usr]) has turned [src]'s communicator port off, at [x],[y],[z]." + message_admins(msg) + log_game(msg) + + if(href_list["toggle_newscaster_port"]) + allow_external_newscasters = !allow_external_newscasters + if(!allow_external_newscasters) + var/msg = "[usr.client.key] ([usr]) has turned [src]'s newscaster port off, at [x],[y],[z]." + message_admins(msg) + log_game(msg) + + update_icon() + SSnano.update_uis(src) + add_fingerprint(usr) + +// Proc: get_exonet_node() +// Parameters: None +// Description: Helper proc to get a reference to an Exonet node. +/proc/get_exonet_node() + for(var/obj/machinery/exonet_node/E in machines) + if(E.on) + return E diff --git a/code/game/machinery/telecomms/machines/relay.dm b/code/game/machinery/telecomms/machines/relay.dm index 51d76d47255a4..1326e569d5f3e 100644 --- a/code/game/machinery/telecomms/machines/relay.dm +++ b/code/game/machinery/telecomms/machines/relay.dm @@ -84,3 +84,17 @@ hide = 1 toggled = 0 autolinkers = list("r_relay") + +//This isn't a real telecomms board but I don't want to make a whole file to hold only one circuitboard. +/obj/item/weapon/circuitboard/telecomms/exonet_node + name = "exonet node" + build_path = "/obj/machinery/exonet_node" + origin_tech = list(TECH_DATA = 5, TECH_ENGINEERING = 5, TECH_BLUESPACE = 4) + req_components = list( + "/obj/item/weapon/stock_parts/subspace/ansible" = 1, + "/obj/item/weapon/stock_parts/subspace/filter" = 1, + "/obj/item/weapon/stock_parts/manipulator" = 2, + "/obj/item/weapon/stock_parts/micro_laser" = 1, + "/obj/item/weapon/stock_parts/subspace/crystal" = 1, + "/obj/item/weapon/stock_parts/subspace/treatment" = 2, + "/obj/item/stack/cable_coil" = 2) diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index 1810bf3fd1727..12946977867e5 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -806,4 +806,11 @@ other types of metals and chemistry for reagents). /datum/design/circuit/integrated_circuit/time/clock id = "cc-clock" - build_path = /obj/item/integrated_circuit/time/clock \ No newline at end of file + build_path = /obj/item/integrated_circuit/time/clock + + +/datum/design/circuit/tcom/exonet_node + name = "exonet node" + id = "tcom-exonet_node" + req_tech = list(TECH_DATA = 5, TECH_ENGINEERING = 5, TECH_BLUESPACE = 4) + build_path = /obj/item/weapon/circuitboard/telecomms/exonet_node diff --git a/icons/obj/stationobjs.dmi b/icons/obj/stationobjs.dmi index f9a90f670fd564304fece1caf622ba0d0c93f890..c20a6d3113d4288a66a074e763009ed4e0568d12 100644 GIT binary patch delta 28117 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 EKR{~O@c;k- delta 25603 zcmZ^~c|26{_dh;%WlKV`Oi|hQEtIijDI%36Vq}*!dyKgxDPod+SE3^OzK-l`sO-zw zm3>T@VV2+3`~CiW|N1>1n&!@(dtT>tme)DwdCoNbq$8v0-f{!EjPwu)Bx$<88Umrc z9{j+<@1~=#y^pK6pR1QA1QL|lY+>LveeI0;G+N6AWgz|4JUvD_=9~`emcRi6<2l6| z#`_;M?mflr9NJnX+r>IR0B?nd?_{K`_707};OJ)ZE1MQ{38wX#$FvK#Bj7b&lu)9@ zzx6@kVd<0MC_pt6z+a@f+4ws_y-GDK23BmI6ret(gAJ|@te}E!eei28Z0$L8;qDaV z!t#5m4e?U({s}cvA<=KY9MpHe&h{O4UO}-hLhOyH-jB~U=JX%MJ?;x;4@D$A^Y*C} z<0eSRUrFOI)-_b^5GwnCUNZYA*c>nJmUa63@RJgKRde8M{41Wtg6C%1I=X`Fy}^!O zw?0@W4!!!Lf1gdj(yRPy3&W4^JJqM=PdiS}e|=mZ=FOg0#+Uw%UHjSc9XGX*3*(pi zCu4Pf2sl^8@I0x1XA4Mu>@Yy%0z@DGtnDfkN?x9<(iL#%UH!=aS^cfgy?7%g)v)j& zdlo0H>z*oUuK*pvv+R^?^cPO6nP~RC#WJeH*5Ai<#eA85R_`lRllLI>O+JtUTPuKQAr(q z&f$N5OfFq(VSFEQ?u*(?DcvV~hP5{{LBSO%W(`kfBHt2$dPscnAAwZwa8d5mr{OB6 zzP3V>{%G62Dg3Svt(xMU99eMxs`gjI`5RC7gh#R3->|>GpIZ40>suCsFTu=W46z?$ z@3UU$ttx&i_FLIj)i5Kd>yp|Izf|7S6yFFIhjR;%eBPgs{17r^Kg+M@(z{}qfNUP3 zMoQlS{buJifQs6Ecs@DEAYbKfwI9RZ-x(6`eXn=C?N**`E$}LJNY;bfaLj$v-!V8& zkSY^@_tf#x+c);UVSC%ysIBPLesz z{`d!tUD&E$6us%r6|?9ihO{lS8QdA^A5XdaB>|z}A-#fC+kuzmIZ*um1%)&^DR5sA5@4-{Qi~{cttF`l(UCiT) zCA3P%KIlFh0xaTpCzMooZaX{Xe`JfNq5J7I?7Ga;? zu6IRf@1CQDV#R3rIacZR8v8ef47x2sp9xZ$Tb;Tsm7A7dLmWDJz6^F&_H=S%C9<#H zOn$Cg+mKiyQ}&5>l5_L#`+|`qnjId=i(%m`d!zB@uw+9A8_N5&fsA_ePWZbOrI1+( zffe%F?+sMS@0H_?BcO`)?WZ7o^M z$`zi?w=7PNa(20@!2kSRp~vN^axE3)rOX~B+FME)Jy~mP^Q_yCW}ZQ9H5LwUFgS;O z18mg~=XeGXYs%=5wIz$ua{3gTu~+#!7N=LXxEE^Cgutdd4+X8&87ZWqM(@AQL-X*Q z8?Ry8)-i5YQ{E#wr^$a&(qneT3WpF```^*5~o8N>*$yVlJT&I;Gj#9Qp)8#dx>Qn_?Jb4Oy z+WPw2qgB)#^~dn+5vI4W#dol!cd*3)21r-;R=#g3CtAFgP7hE(mCSJIse59acZ(;k zwhT+jk=3N6_!{P(Vy80+VL~}xl-ql=Rg{6evV4{UWn_0fj)>QIYxKdQ3SP(ihd#aO{cOH8;YkcuZ8C zIzHT_x+@2Z6Ac@%*qV75{2EuB%-M3-$-N=$##ZDQxf6Boo=6OI+ZC_7l1=N>>`q&`1|*x7~@%jEb$mE{$r(h z*+HFZ{?8{MT3DVEO)On|dX%(=C2>^ZF|di4Ap{vfW|Bt@t{nl{?QOhkWs66LkGDHA z{RkI{BReFa?OSuNU#I0P{H5NF*dfs%ab8RoM{$lpq+g}O6^p9Oz+>@k(#)Fois`t1 z%3(W3t>He8fWVmEj`Vf9xBRWCm+Ds2i?9h_au&6%p&iBr$mmfh@yu1#FjMghcW|&@ z`4+VNLwn+wL zUj92JcyWPXRt$VkxsH8h$s#&EWUFc82pYQj%={P=&1-&Pqx!5H5m3 z9-v-jyeT=0>24+T5Zpl&ffD%9;(Iu7OgWcltR6*XLmM-Mv9fJJ_YXcDjR%t2qr>D* zl$(%{@Oyh(S1P6Zx|kFMauIUtrsjk8a{KP#*;$Xl+6%s8y@t@c zoPaZiq%Y)sQ_6l}Vc_BZ z!-J{7dr~R#0wq_}9mEAt_C7vmJv=7 zD~H>>spFp1QQydt=8%usadV}IobU`?Ke}k6vVWljsNeHx+8ZiesBpue(9KwBY+Ac^ z&`OR0t`xjObXfmXfT=iqk2OAp@FXjm+r;Huzwj2wg$~`YB+gPniJ)nPGDH*ggcd80 zj^{DKSOy#;;RJ6up9ww~QuQ-PlWe=r=`FD6a^Vafxp;7MGbCI;Md3`ofgyqD){(5X`_;S;@u(c9)W>@lWW~xDlgQKWd-hi zFjn)-J(b)6+H#kR*w;Ig5Ss0Q5|K|cD4D#R4>PIg;5C}ogRN;!F1q>smSm@;11`0m z8{}EaDL#k*nnG#krvWbBAmDs}Xm$J|jP|vIjGoPueC?QPjd0T_04kgkQ zkUcGOu!vq_aQk@Q>D|`?!vY3j35hc~_?7ltQ!P21_}p{K5=-ENBzYaO)lH^#pgja}p2t(4XqC!73N0LdAm93kFRF?d;; zc3z$XtEYVi2frUJjw@p-saBz0h(Gx$4e8x(hiX9pceSqf#rlkkW@no3#}m6)T*nCxjF7-QKB@6T3yQ>11_j z&mmPko%hYK*F`LX?1L0J(0ok@<&95B!C*C2ZTl)``3 zP-JU4S^u>$ktqs5+nD;7cdM5^QnDJ$!xZ^UeqHehTpX8%k0?kEN8j2n0weH^=m=@> z>)<++w)xUhEy#DNwM5Y0Q4Z%A&%VAX7_Wa>ng7EpW8&>sf~}YT^U24CAJa1u3fHcE z#{GN}gYPJHCi6o{so#xn{rdu4LJ{Nc{CqC3o%pILlcENQLwUmKmF2(AEMy)z%*|3tWaPqM#;V+Q1RZfxvjultw}k5X4U zUSdt=CSq}1o)U*b8luZRu4E&ybp4LVfX!>3?pCjJ_|*hd;lIMah~@*w0iip)Wfkff zidnxeME;5FSsTZ+ZgC)hdir+0){yw!N#g7y6)6Yu_7_n{QjNz^xX1K4q&lqGmVhQn zLUI=(xj*726+V9uNKeA=f2%bNw-pA|ur%kOY5`w2l}<#teK;nAeGMN%I3c$>2Bbrz z3p8g=q?x22Yf)NwM0Mx>MB=Ete&|0%LPb(@?qn!M0wxc>OeA!6b#+PP4BRFj%^R@D zG-hQ~zCx5g(kEkmuwA+dRE$s5LFERoRQkO%mlQ-xaHpnWgxLf-ICp|;dm-k1M7i>B z{SQ5>W;NFS8P<;Os2uE*QC8bXo?bumdF)1vR~q%m*cko9&DIG?OmDfY9~e&Ns1Mv| zffK^3n2DORWv?NXiBTtHqsEIX4Z}YtvO5VkKGDf~1sWcFg7_pIy2t@7J5OiVT)56u zWKM&_t+-9ra|F#(DSRJ_@Mlfu^d4J~fkHu0dK5VZKY!$K>7B63Knb_-8|Crf*8RR^sZNJsd`h3w61LS%HpAD&C2 z@D;GH>UEXzUdp>C?0n*B)$O$x-gj-u3ZKTc>s@>e&q3_ae@c(u z>71g6Ko@Nx9OMb$rpJQ@t4oXTjbM1H@$=l=?>!;y7aqur3@a*#u<`c~_4S;31qxMx zUtC;7B)L)DvWkkFN4HYJg8*4Y+?a#UQx?}M>$XY7*A(7AzJrQ(G>}$Gj_I@uda~}? zZI3D}Ji4R29|=6{kn0sh4TQ0yk%X~44aAlk-Opa;;qO_IgwDfy7=gp^G`mb1fsQ8&s?sPPl6B1@nEh4|R8kMf}e4i`zc zgb7D7mKi?&1p9k^gC@Cqq>y>a8Jit(Kz_ds0pB=B} zkpTb*mrjR6>b|%YZ_Nsun(nu>^rb^{9guP4b#q9VsX6=(VsZKn4Y8FbKLI9hD{&Uz zN&~UYBsRuyg2o;!mC*@$#P_*UbJI|7@4JWBjh@6)wYqEVv@`}I%rK2RN_tvFz0R8? z;F#&^W(cMTd5rTfbs~lDdCY$x_tz9I?B>l-tY4*J*h;OOcj2K}x_`d3NeVU{-NFCv z{wvdUip#jA3C|j_xy%F!G0s*nYCAE0ZfUpz+6?qTD%-yur`l;5R*sW;iPvr8%`7C5 z2j7lX^=8N!0OjxwW-^Y(Jrmf~q3L+-53wAKEL&SWox=uGd^xJT|M<_3wwxd1Ng_jz zx^?LY2GhtPuP70`ol0RR28|g2qvW&g^JbV|T$ymDV|0WCL!IJ{LfIWcJ%`25ymU{4 zE<4$wXRRBN<>#jxe^od(JQ!8rG;Zl}Dp$_XL8J7~ogDsC3%Ks{z|{ckV8I7M=a>8E zZ}^|4VU3@^EiQ&LzfWXX4Ie7VThY7hgdEDg;g$|hrWq(Xm(``Q5`wO+N=;cYCWaA= zRa8`5L##lnD|J?nNxT+IHGm@T&Lwje>~tWmlRqwB6=oA*@%=S36P+OJEE)Aeo>YLw z1PvLrG#xcIJX*U9yzIl2(@a!cQAL_`2$Ss=;nvo+`~4-5bO(QCnfMIgDJc(wt1y!iMpNy_R?YRGQ8Vb^?y zU~5D~M6iJY@9Jt?eQ*UQ=giv!)ZXb9;^Ue>qwWKqqeZ# z>q(4|N&VhJ;Dx+RhqtPLJD7R0V%%a_!FaBeCgjjA6hQw%P`A!~5jBthe3zgRj<#nw z;JV{IO3?5lTDnl|R6diq^^P$C(;ioG{g-1PxTA&NBAx>0L2{7up+~O$`n#!v*qWhB z=NAC8c5~p=H2UcD?n*($PGJ{tDBfzojz#<2soF=SN++;WISB&=^(q_G)m2qI!a-`U zg#jD8%WwWkTpn#WG?Z0F+zPQWOI6LZxTSz@`YQO1L?Q)iYim#TDueORz|>Y86w6uD{l?A730pq`6MllvuluCXU9ZM1CDJ0s zRYV?L@6H9asr`PCy0<6($=gM%9Xy}gzb$cb@0#1Z4(Akqv&0qyLGi0yRa7;@HTS&I zP`}28sPFv^={z|d>Bwqp;VB=MFq!)2N8nv>>O{}u?}Pll{zXe=F^)>W#G5}#upIf& zt0#&W`XKz?EWQO1Vrgg|*l7-o3YNL_U^O)7~ zbv(@r`yh$VG}t1b*9wSQs(T^R-kf6$5I-DD_MQhb{`mAT0)a0*eK9pde&{4uOB=e! z^ZhiT3EAm+!d24!x`TA_e!&5WwX)F#CGoorqYXtA#_bum?IZz|RqC1T<>`s@-MtB` z{$~N~E>B8Qd-9N>?E~WH4X7eU`}oAl)e2M~`G9>t3Lx4O=XOZhe;O?$oZcAO%YDlv zB=G~OVvfk0OYJC4127%T@Cn=6lW8g}EiE0OElWTrb;a=~!0=QuuvcxK$h%1W)A?jW zyO4=$ou_jjieYzc^sd$(cM2AxS3I<#mbISNX{Vfop(co^j4s`cJ)VAUVbqb+ttU(YQYn>#_F}wyxA~BLt|v^JoS^;jX_5OWhUg4bfC^j0%34Btp^5&EN{vplAI1P#Ps(T6e zjTwD2HfB~;QCoNYtG$qyxmZz>m5tRa4V}x zad%mq5C?W60Zl8S-kD#_lF`r@S`4IGo9^95s)tDPDiyv#`wF)f7%n2rzAqln^yr6A zkG;fy&+6giX~CO}=M<%2=L-3waX$5#CObNC;HjGLzCv}ZDXHCsA~sGL<%UD1%kjsgX7DQAc`=b0?d%`r@@SY)!J)Vf8Kx(OH(0JUl7<8$wbfVE=1 z^(n#LzGua!Kr~~h2q-Qdd=>T@xVy-Ko+H5c_&Y&`Eq(d&DL;omAg+PwsDhE1d*3R~ z65Iwm6*7Uvf*EITc-+`93`h8!+ql~M4$FqHHoktBx;_*XkPj|=BUEh|v`{AAJS5om-L!0uhLf0r6rv_c1@rLMW?3{AQ78f++RXndg_l11w8Au2M8^(fj_mZlE%g4Yr!uoW3gT1Hoo~I z@3%lLJO$acUpJGWo|&GuI^d6CmQ_^F@JdorxON`FO`oWfYayIkY&ZN)K(<`!7psZqc@Jh?ewE=KEnq*7hAu6 zw}mgg;Gz2Ibo_q1GytW0{`2}_MK4+@ZfB^|i~JRBu` z!*sMI+v7+UXym}r>t(~hG|Lf4-?b^5(gME%o3!>&{K%=?RQF_ zgGi1)pI`~Wdex*!g~F|!VR{>a+>%>h_!gMi%>n{|*n3Mkcn2!m%Pp)^^LX-9){1U$ zJ*i(oMQJs7?O*JZX1(B*M6;;_`rPkyY1VYugp9)JRZ_N4}E3-M~95>3Q0Ky4O zuofevv>UwN$=#>xw_9iqN4ziCIDtE0s>sA{DCDlGDI2Z#+k_KG+lytCfpO&;8e!CW z|Ma0wtdjeuP_jzD}eZ*3MlJrF1J}_(Xwi7%@s8 zgaVdeaf#@oLjYYufTw21y(!IBQ|5Fejry(?s0VGP9$s?Q`n3k^CFs{ulxw|EiIl8` z1$_dT2FJWJrcb?jT2r1I4w4&Jn`0NHKvSfE*hI>fV?PLWV1F10tpJ-9{et#IYv1o! z6W|m#2L$BRyOSmM`{Uz#CZ?{W`01DeU8q8`p)_K{Dt<2~J6Z{Xl(CHqYK~@>d3{df z93j8QE0OqF2raSqtW%p!rwg@raLirs$$#sef!HCRIYW7m+k-9Rcz85X%87gyD3TVt zAwg%0!J+W`gK&w$$ex`eMgpbIPn3NB1<^~|ihidZ8}&)rCRj9pCTO30EVST-FG9C@ z4P|AVR?<%fNInj&yKgpM1}tTL>|?KzEG?%_KogL1%nL8S=P^^n|6?@R%8Hj2tT91m{7=3O)U9s7yJu#~ zD_~HFUtnO=)Wfi~%A&c?1Q7Z8FRqB?W&zPamcqhyWzIa|q;~_vGOKxzRiw_hOEK2Z zDqvH~6RBA1K=>Dy$sE-9^0LGHwB|n`=${W=gHz=m?wgJgAy;s|f6dXRE;jQT(NlexPGWolyZ(m_}tN_F}|Pkql^Ji#~ri6CjoDvpM)h8f2l|KvHP z_4@9lUls9H$H0!A87K>YqS-J&z7gV1d4a>J{BOgrp|a?8kXr3G9P zxcem{qG43reGJr)l+Cjig3|&W#J&_ASDqv;dvLS?=5yfR@9m9tkmARUjGUqOUwV%Y zn6ccK(0IZBa3n1S2E*<+{z^n-{z4HNc(DZ!)j6^r#qY$ur6jq1CZAEs7n7}bj=hD;MM&60C_cD@w>&CzLhm46jtqg|l|KXp! zxB!;ENlIM*DJ!+eUkptb(C1`feMe|DOLd44MftPpy<2`C-{CWWMkF`SWo?m%^%I=G zsfwe;c^g%6R>pX-Z|ECrBGcaV#1h(K@ z=hX%*hz8#*=ADc+#9y1hkj$1KW{nwYFzn)nTxb_vnzwx%wgm#UK~;jsKes>(-^ES- z-S3R_#R++3XJXAxMZb)S*@aYIK!mxK1ycWr6;z2fXb%GDl{1!o(w48$7KGW^*5%9C zjU@O#xTLdNna5V#{!%{;%UMo`cs&!)16r)ET!4$UFm>ap^I_1t>bXjd!47gOXE}{q zB@TOTyUzv^ZCS$hgdm^=K zs|unSX2q6Q6g5xC^A=lG_w6-CL6H{dotES4dPxtBf7(AEaW;RuSz`dID8p-Y;M9I+ z4Vca*o9AjQyjBF0z|_Plek`|WPO+QMS(OY%TCDV4WIW5SKV;A$qC>ld>N6!go*e7lhu1xxL}%n&U6TDTmA1owR9+4B-7P()(6uTHw%Xga#RBRA{JJoFEi8^?w6V%XRBc5^hcC&R*bnMRimWM+ zEqMGEu=AdzT?{3R3AkMD3RJ0{rb3+^ZW6>85o4r2rW?!3FW2 z^JOPd0!^AmFLb=-NG{E_i}3PF&rvoG+@`f{p`HcpyD12J|)%B@%^`}!+QF1z7Q^wLs9rN*^r}j||Bpqb+ zG~DH|=MepQ3RXyht&>nwn2zG!C1}4USCFY1**pQhb<{XX(VB0(Kqn|62?T)MuFk>Q zpC8}ScyNY`8nj8S9rUIAYr+91QNldC)Fquh*Y>$q-tA=v`s2j-^-A#ALyW(rY>|NZFZX>C(}`q+~zC({O+ zLc{6=iD#4lnI!-;AN&$kTt5O&1F%j)+R|JHJ7zm`&1!!mT=Oq!Xm<@%%;py4L^lp8ak%z#)u* zfnooVl3RLTGA>>48*A$0-xd8*?GvfBJ=`a?4>9>iuiDbu6P=;oAV; zRg>tKLAT7y-qlH|arB7~gqGoUr)8RtFdiwd8^|5PEu6q0HumU!(lLUkoasH;&~r-j zQNh^8&h&|P)+Hr9u4N8hzyV;c1c4Z&BqzsoFSYEwu!{^t*UNeu;9Z&DaH{27dg3pobt!&JiT_ zEXKX#xG*B?M-HkfbkCt1vVBqhnd0JOT=4{=9`E>kuLw&ybo?hTu*+l^7kg=Lf)N73 zDR!RQ=clHo-mENQwFImK18b!@HvRf76sSV#ILKESXf#0+e}S20F*MR`1Geke-W=|P zV2-cj0=9yHo0#Tf2tC92#&j)<{q%vJ-+<9G8{@&x)l7DwUk$yl&p|wtn5wJUV;4SB z(h~=%rrf!(b-qt@&Mx?yHEI4#lu@mWjf;Cebczcm&##V{2!clo4ne%3CQkc1vkj(D zC=Yg)wb`n6eb$;E*@e z+82=*_kBY)@elan3%Z5M74dI}XG4pfNRAkW74r@J+9ag1M;Ze55g)&6Y@V7OcLw_e zinY;?>5`35o!ES)B9Hjn%)kezByk9h43KO z%Y?NMNFr#d7$Ul|Gij-H!+h)cN}Bd=XI_8yBS35ngCfw`o>wmr(lh$d+)Skrl=bby zuXrKh@|N<4+pN3tzDAHxV>k zJ;YeAKoa!9`54I}4E~PQnei21^u=Dmtk-gSsrFsuTcV?|x>ubJZV-UJ%oJQOyE=O- znchO7@N2~M%#18VL(1*Dqm{lXZwl?TaDx=Z@!e~8aL9HwuiEM|JoNudf-Uu zUlhBQ*UOEw!r|&()XlG?OH+=Zmi5Nvi)v|VX@qm*+#kti2w@zr-?0^T)<$9idqXFT zK(yK2Q2|rZ?lIb-A)pcUT%wO}_%nfhHTNDVuNWBSv%PmquYxY6|C5%C{EW+j{UkzY z|9xFtQHmPW>7goBzd2L?i`|VS73Ad@>KI&CHi>ih>vLI1kvY2Z+PDfsYAK+a#ac~v z54{d%KHpHG>&(yhnp3?-atRAUdD?eG8VX!bLnj?JstnZ50R63{Lu@(4Lw8hfx*$G2 zO7k8kE*?1`riJ8Vj`l_@laI>$L}kF*rmJETJVM5uU7xS5`MNxbZueO8>(h)?Vn|wt zdawp7g4k4bt#W(+E4u2Eg9E3FY8!Qrv}wY8BM+^++GV(y@Av=hvRZpO%W1G1V?MOR z@1+dY}{`@A*h-u9Wu z*mbg65RbC(jvL<4*U9-;XcurB)iE8>{Yhzl(!`s9EBx`sUR#P;>vItQO2b;07OL`Y zz5gN_MweM7<2K9^BQAup7V_76u0tRH+cK5y`)a1?mpdK1HCq!c z9_OD>WVYSmO)9OzOT~`+uI}DBKd|6#7pDx8ZSe_fyC@hEYLk|scWK0p3LR8k^(YUB zpDGJ;vrOOpgg)e}p=@0VBFsE9UOB-gZ%FQ#ZEbDkvwhWzW+-Qr_6l~yF%x>I=4!oi z)_m%dGW2^KMd!Ir0br3F%Qp8s^ti=+kPC0N@7=$K4zxsr!#Uu*$X5ZM zOKJ<p-RDKS-22}KgJJg0cF6EjDF;uM*IKOM=AB}sGA_{IO3>ZBQ zvSQupu?w0$(D6W0<*F#hEO<=E9)0zC)XLt?{FNT!JTf|CyS#&Ze7rM11sF{5M?Mcn zhH5GoFfm=ZPas?$zBH6v1wBNynOYbDJx?`*6ztelj)Y zi_?Mq%0qDL>gY#*#>W8EFA@3H%`cuH+>w{Z3#FpBz3G!>gy&WAX!}ng8vE)(#+t5~ z%3F8j1C`VoqS!L%r*3s*_PzEVDo;HwP}MF&4?i(wzN!77qU>gvm5dXw-Ke#SD@BdJ zh6C4rvP0&(#HHH$*S_=OsOAB1m)8oeTm1R+DaVOnfB4?T z?BMk;%2c^fi}k9nhGzEUzE#wXWAUZt6h2!lSJPjmdgJ7|}CHi;cI!^`S@8 z!vt+N^@r&TSLrlsn1!D%(^<)HI?ZzR)AIMWal_(Yx>zc^_xh7FRzCJIQ zK_~wWoZbXLz+wXJ%r-pc8-$nP$QCAH@pE%cC_2G?G4T znv;qBR@WCQXW-&I8{69fj?YCI6p#2GsCmwg!k+W}eXxG-0e?x^YYSNC~s?gB&pow5wh^wMU3a_obSV!WXTn|B) zHWj**k}v)$9^T4F;xxtwu-iJlX#_`{{+yG#+#kNYrV}5r-Xk3imM}^%eb(KQW`;z` zjq#1t(K43S&0p-U13o~&I^!?$V+D!jN7CIDzKvr=HIBnoLM|4z-I-sXkv4CsEgt!H z`nc$w{&K46kGsf#bN?Xqgnuqkwnwg7nM>dmwo8REYkspc@OjAe^bqgH)3Y(3pL9Bp zN9|vvMuviA&zmJZM8~+;(MBNOJXp&RrP8@jfACrlm|{Mq6xp!`SNn!lvP2>#x26MmaF)FNLL+pY z@i%;E2a_>CO7c>*efKuC+W{B}!&c2k_01<9);K-v&Gerrv+es$aYSdwmZrqlsGBc4YwdtW*>D?z(P~P{{mVfcW5wYIup%b5 zBK@kmOlwkpv;5SHPfgfb`^jsqFR!mc8aZ_>gQ)=_$+ z#rk_u!dE0XJDbmJ^asLy8dLbwDiu*~W42MXaprf&L+V_anY7qHE2ak`_Lmsy8cW$g z4`c$(li*mJQIr|6o(_Eng5#ycVF7^8O9GG&`!;?mGjr5?x#!mAcPH7Pk7wvsVKk8n zul5HQWMUDRI$Yh-l_VdL&1_odPrBRK-h3nP13MwbGQEJ8JdySr%PPnYUK?>-<5cG> zHo4w)Orw91y1LwABmczC>@WE820uR}EEfT}>va3Zur)3wPbn6&4ZwbrJRe)1Rt8R| zxgoKt!9;fmxk50<0PQ!l15qvQPW$6bS}bqE1^=}xD!GiPf^{Eq?4MLc0!o-WM>^H` zfEC6FFMlG=SJvT>Qpz}pE-~R;#5aG^O2n~f+p&J!taPDn1JO&kF)>J+uekHG ztGWKw#6OqA=p}NSn|UJiCV;$TlLH=+^W8EXZ+>sa(^V-c3(n1ZbZV-7OZ$0sGgbzg zrcV{5Yr4;?CG&0Qb78iY>w`fVp-?-4-Dq(1=b3x(V#g`-jd!C^stuUB+=seibdT}S zfbD0O=Mf?|;cZCauvUdA(zTGWo54_L;7Uw{sjr-`&Q#o5Z z5z@MX?W<}@S8lg#hVy9RM^(v5{v(cTXxppFH@>Hat_rn=tggP{mPUSLs8KH z^+)gT?^99!8n6CwR=3YKyL&ax6daMO71OK6?^^;zq>|G_a4cYt%7**gl9q z^nXc+>~TI{`ZA$%q6P@%7MKi>c5-%()#JeB)Ouhd_Xk+py%1x>r?_Ll2+_OKjHRhTFCTWWp>`5K zuqVP}DQHJpi#NmyQ3y`P<((1CjC~#)njK%Qb?39FRmr{7>%(X9iEsEeRg%ahURIA-| zHTSO1g#nYB)FtRAJQYk#LDSPrq8FK%T8C^%#ctc2DNT`GFX#A1- z|ATGSuJwOtGU^`XUJ5ak%O9)4gT( zHM-`K+WNOk8Cf^NLTWvfyVhpG6gxeD_KE!U*q8S;i+QqEpslRYVm-(W81UWmH3d;iercZ>YvMpFR(8)NI92#{OB)_Xa*j&a<&B+>B^UXS&~lG+TFbYkQvp?-pu25QCKE1I!U?a zK^FsuAixQnli^+xHed9Nox-)xP3f5aYxexfAQrdO;H(IGxffB5fx#ct_h(Z3@PTKy z5+u;`%RoYJ;TLN)fstAkjO#ChE$FYntvSi!@e{^`03aYrO1@k(v0rjNas@4GSe=BA z@J(d^CXcd~oqo%e+R@Bfg+l*_B*I6U;(k1O9Lc%IwK9ePe}l5$hxRSAWu2@#yYfn_ z+NSijhp*b?7Tf3?!+$&BN6X`xR9F8Yqagk%_61Cx{tq=}dgu@a{I4_apMOOobS(^| z`G4&{bPK+~$_Z6!s73C%=I^$nJo~&l z9*ds;Mr=5*m&inZ!GJWT!CFN*5GyWTzs2JE#2LO zX3Q_$E{fJa81U40K7d-(MF7t+)e~g=3Nd>wFK~5Zs;91Ef{?~K?+!r%1vIH?SOa0? zFXHDz*#A0R;+-iM<}Y7fReo(+V(_-j#Ob-$utKMsG%Oqze$GbcY#{@=Xn;1Vb)0|c za0Ov6Bw>au$lFzCgwf>Y(dY*$JO;-(N?p?{+=~i@bA=T1E~ZHssXf}fO%MNOH%s}i z?6{Rc!2n;!`Eq<8%b`VyiWxaMaf6+zI7uZ%JfGL|*uKw&-w!vJ9KSiQ9-jUvGawD# zceKkQyr2Wryq?qS8pP&kq3{_*KX<{gH0cb~<*WGEyP_?QJX+xBE$Y@q%ImhnilgMD z_dUj!{au8XqPy0YB8CQ1OiB5U`gVdKTO;g%0PKXlk=dk6f-NR59RxH95ZhEtoYt}M zdu=@*EzQ0bJ_JcNPUZk0*O={8?5x)~ejcVsC*8gJQcn9kETqxS>g8!N1^2W3RPHXU zYKDtboqR3%Jv9Q0Z}0PVS!vnxFrjM6zOD83lcU;$u$*+!e6781suun+KFsIJCBXPf zEjR&VIFWoQO)np>`i^7C*~>iJ#MIjCi2%X_FoP8x^ATeyQwY@H|o#m zd#h!P4SbKCO&z+8^S>rW+X8eh>~swD03n2v^|gqrVI zA6U<44EO^H{wdeM3-0ZQaloX5fbhyWEKivh;;O znch3qS-~&%km8`LY*QikRi(uQK389FhcFugwcJ+7{8FsL_(~$U>)1I*%;;9%Tgpx5 z$6i3!ZKuBiMRE@c$xQ?YUDOs1!IRon0-L6s=%|l5t?y!u_7(hB63G9s?0qx(G1h!t z9}M{=)hf_!dLQh{$f28pep)$2KjRpP%Lw(mr*mWzcxGL^%9;CXA3=jjI=J39DHikteyu-VM3qrwalIL^7Ur*wfD_bx9^bQnPc=^f7raTgN>P`kP2CE=$H!hxX@N@k*E=DbJCq`eyx9jLy zn%3+X@kQ$TThJ+!13h0pPxPmq7#O0RH&B*R8}3y?K2+7vN@I)}DxEH2z8cxX?bxvO zK(mFvyPRLE1TC?08OEO>vJE7xI5K`AcfF=-1^3rC^;|mTPrzNeDU2vf+uzX016cN@ zIeG`jIM6De?@9j5e3VF~@q3?JB~Db7im=$pqPCDS8&IuE|Kbr~1|N513@;T@`9}67 zV!KSiV*p40cJ?4CDI9%;j|*M{w*ueY;J=zf(fukuErm$4sBZ)2X;ztdTRb`gAh(Y- zEV`i)BeFCDeu-K3_yCKRm0%Hh9-OTBMfmlWi7mF%_ihC1*)0ylIa8e*;=Z&?U{agJ zMkR%Zvem)JDfceQ1^?-MjoPa?RDI`L;b`c3=7Yr8&fjKXsp*pDmKbRB7SpRpE69~)^F zt_}R<_-?Wgw(l(6!k2x{`?xan`}&6%iiD!wr7DWnD^-SyzlS* zW3FqigE{w^@4bHR&wZmI#74-|n$-FRzdeJ!^O<5QNk=FmTo4fDc=a2EB7wT zsL9#Viy@lnkDd=@5UqOw1s~frO)6qG1RsO0{LDf^h>P~tm!stIzN6%s}e^}~?Us<`~iFq(rO@qnHVp24Y4yW~prxjzz` z1qZZ>cb=nTkKpxm#OHtDcYh&5BI%yK%pAu8d=+GIuH=jwY2W6(4odFGx(@nF^k!;T zyfXhv?ZH{{Ldzd2L0J1faPqxDZ}?H$7sR-NU}en(q_ zXEEY0@ret7b=_Cg%0^8g5uwHPs>Pt2ndXvH9Ot9e_dOIM>GIEjl-`i_w$zfu5V1Gh zPQU>L)YJ4{0R@=Lr)__)aF>ZDu_7^j(6B$FE7(ZYGoGbO8Y|JCk|$u-S|#?n$_G6t z#d!S4hWRT4Y=B{gSX;t-T zVi~T3Ukz2R0jHaN*P8Zg)HaUuV@x9+*m0>Bm>Uy4j!3}HzMXL{?9(YC*3Wn#w-bP4 zQ1t;FGSICBmA{)Q=s24Z@-46ju^uvgcgufHX-xR!Eg+TwTQL`;-DeS)90V(*F9%f6 z5a_W3QVg1&Oc0~8iw0L%r{`Feyj+4^(zTTAc!ccUZSwrQ4CBasnG!zlx{02>@g<(% ziQjTc9k5Bic`QeDzd0x}v+solki@)D?u~{Clk)8qAFlhdWTG_-J@j+Mvcx}oAkfe` z8q!|HWNp`Vz@JQ{X1y}VSZ*+gCYsIk=Wv(rqeqU45F3eKwuy}`ZED|18`=m6mVm6^ z4T%kFs(aoBW&3`h#l#`lzyutbO|i&D$oBGlV%Klz3f`*AaOVi*WCA3UiGEKrI;4lLuez5#~BQ0dMQvxy_3Nfw~A-vV|5 zDfQnMq!|cRCY3Qp|5pQ}Nv1nY{r8I4bHr~mz$Y+0%|Xmx^SQKox#K3Bdx4IZYhm-7 zk8JvebWCTw24JSK6^iF(_UR$0BetqgT_1rV~;hYg;%1DgAg#OzqV0X%|p z!s7d}LJx9?FC=%+(!e(24qFCM+(tVjYQYZ-9LvC0$kCZ3#vYhQ{A5kZko5mXxFwWK z<>)i|oF*pN2cSCm62^fruYH zTueahS_M`tKLGmTzi%QCChIuvj?n`v*>$JG@8UrCJnn;NsNd>b;LWM$K$Mj(DjSGk z%O+P2PxtClKpJK@f`=!8I9PcdaS;5CuQ3 zFm3RRcQ!j4)AM{!HA#?l?yVJ{Kg9mqusL*+=izd{BEc21Y(gwQp^0@6)T(lop1x0} zZWnlVG#w?H68wQfU~I2I6lDCH%@t2I zHVL?xJM`+@;?9I;=zIw$Q?k}o&xXg7FyhQgtG zwEMSktHc<7w*Z@CYA6;-%U*hbPJOxoMP9gC8N^VHAlykc+*?RGW&E_ zyE^?EeWJnmxmn$Fc*N%gvj-mby;irO?_2M_Jw4794WG?F{u9Xj=At$VSL2*nXCVZ4 zF&jJ+vsA@~Gmqn{fZr!)61v|Bz|JH36aE&MwQq$At!h6Z%cdb&1z^%aB**mMp31CV zXTFhtacJ<%f=1CxoT%>8m4Bq{%$zw42P0FWbwTJcD6c!q1bq!rNix@aNKF?7Z6;`s zg0ByB8Z$~p{#<_}J9!{~$&fa-Ty;Y0Tm(m0WvZAx^Ecq#ev(A7it_0r{XgRtqMP~H zlv>EZOUh{77T99$2~ArSbYx%sc-I+{YI@%kJ95rIZGGX)bsjM(rLqM<`=RkZ8P*T< zr>Y^ad5xtLiV?Z6nvcr8oq09VS(>^ZF7q$@Hg-{bt)Fsst)kjk3CC=AmUem;iVM$U z#JCSCh`WIGB!+k;`)^eqsH}$BS;V&DtnB%E`piZ^*lnys0!%pZy#Z(;OXgNe)n}(R z?Ad*dlwZ(&q8g?%?x{2}>dxzI>l;W64SQLg&{9r#9t0pJMmD^y>e-ly^*S*JG(*q5 zw@(tl6tKgzm9x{WOoA(ivE2wer>1CIrMGlU63E05{<&b>9bOk>o4k32B6sV@>Wdob z;bM&|zk9Io@gL8G$;9ofdbWGWZH>xGYC+XL{&6qoDivcV^s9Qm;KwS4xYF~44CltG zb-1YO1LM~67G$E7fNJ+bS}9^LiEdHA@WC3*zV%hp^K@BDVOwi&hd{LTUHJR{i9DGI z5bIXaFH_iMFFYaTXLc>5e_1{9tmnhu$+8w54E<*#gIE!>$jPCTf+hUZJ9UGIBbS5B zE-|py`swkD+t}qc(E?u*=)eWcy^7NB@;}$e@P1eG5Fyr5r6x4#>gM~@w%5sj9hD2E zd0k7>p`Uj>L-Gt}Tr)zaqY;I-i{6d{tYDU=sN0fJ^(`#^8VLHsxWfkDpYwhj^EDui zkA~Ry+4373e<$_$1A}6%ClHItG;&*kggLQd?NqhKk0w7dMnC(Bx@bKXjN*TPdAyqov_ z@+H#)A*J)&gPI>(7qjM$a?;7&B=}SYvB&z<-}m%SXzay+nTSBNT1YbPgf=PlmKOZv zns-{3K~wjz`bs+0N(5?YM*$>`7>wFl)3;@psV}p@zP=-po z2(e|F3~sH768N3F;_z{%=2qK<4Q{3rN!^4;qGAkAGlo8;L1z-r$ITH)f0)!))eZek>=>`YnDPG=6Jq!osLlqcT?!@8$2 zCH~rz8iLRL&D8kKhfmN&U`RcUPSae{IQ=qtARmN4YTOsM7e;B*aneq+V?MFQlX%Nl ziEd|Dz?>aSd|o;2jn#^go**2lRE>J|fyh3@b}cJ_x)q2uo_DPqjr7DYmMvfT^4t+h z1(t2QzGgX$FwV}qM^B2MYhM=ov|JaKSEl^4j|zYFX(D7p;p}62#QE!5U3TnXn)Ea)HO;<+SzO_hR!PD@Ghy^XgN_$Me|)rnIIrMn*FUA9uVuIwt*fkz7ad^+mrfVK4jLkYMvj~^izv3 zikQ)JQN$Qj14^Dae&vHs^7vN(v1HL5<2GLOtg4Ow86*| zPhFh>Dy8;{K1VA2Z{h(_=5|zIiTw{3|JZf6G%a#iXLylD7j=v7@B>e|Oq$sZHr? zZ%0;!^MlmP_wN{bi`Fkss%1E$n+-}B7l%yn! z11_O%*I6H!wliWwe*ujyp}zR|?j6-bxdsuom5wz$58OXHIJ!NGW97ZS%MEVtfd9RR z%ev+;tT&whWvETK2Gd_uzE_!>i}7gbFi++$jPhoQpP=+3$qQM` z(U?5j!t!TjtD`X|vK!iKGFE}netcq$KR-)v9oNZqC=w07knzFPT0X=!XRF!)e33yk zZy!YVKpFqW*gCXDjz)%;tlhqOsp;rt`ZLqyxQ!@ErR+J3g%YLyu%K;CmD>xJl{(GS zrvbygj=%G>h^stY&YJ076}6=up&FGKbnW4)X;)1QwqQivdmZ?`4ibhpBkr*J(FHT8 zC)aTgDX5L9;)D0C3<`>rAk|8W7!5g3mq#G}fuXp_mt>-{d^zGjAZve!fxb%|p!@njoQ0|*fDLVnjzbp9M& zAHG=;sSfz*1}krrgNU4AFV~E}b_BY6?5Ho5 z`q`h)HG+M^p9qC`;ZH#!Lkl{CIEmGm9X)OVOOyw=5$LSl+6+fUMTKl}4na{9WmN(# z3ID5j2ZEeHw~h#u8azB3`|^rDh&|?hv=r8;4VO#N%6y}FmH|A8 zh(Nq=u8O>cBKfXCJy<@Yo_i@c-M}1PTHi@P+5C)IgVmZxoBM4l=*ya{niEuE=rSjN zY+}+8CN=)&HvIZjSI>;?bizM53jX~Iw_c8#cH_Ncfr zOpZkka7i5N`a7X(8wO1gB8xA_-J6KqPsovnJYzL{%{!- zFHU#|n4s&g(TMlGV#!M+1p&*7C^2Qe5 zLQ>fjGf`o>WHgav{M49Yw3ot$UmLS*bMHlt|jPJJXOtFK?g(-DRs%gqHYqGWyvr5f>riH|Ii+VMU9QK5u7W5g&x7) z1+*(*H)N=8kY4&JIW`alH1{=HBxt@Nsgh3pJXC@S9n^kf9o+yfQj5CSmTmml z7UN@nn}Q%c*Wr&1X4dj8D75XGGo-ZV)QCIYh^+gMYnaW<8p5+Trs>t$5@>Q)4*MO!7AN+_}Zcp z>Ne&BuJtZ#W2i0>0M*3I?9McZu6jhJtC>+ja5v>uZRJ+WBus(vVnLkN9{YVY)j(*8 z5V^h@E?0i`;2L^8yy+ljZ(C@B>kTS&0V@3+9WuR8M^w|vRnD@R$6Ma^V%gJPxjTR5 zn((mtn)O>6hh0wIopxx3Sc7Y0zOPRsofdW2<_Z2B4Cw4XCLZPKk5tJ>Cg$jHV1I;b zXk$f=y6Lq18pxL%Jzr)q+kQ$RR{qXy5do4l&u#T(21tWgzt(8A<=5qfhd?lNipDhE zX#E)8h(|M;2)KXc>vYIb@9gBANQ+)kO%@>NesMFJ&$(tiohsN6IS$RV^w&l8*!cB5 zX%&_MJOa6V3qg~9c+oT&j}M1EM*n4C;N~O(!zH6ZRJz0zkk)YT8Fxq-myspJSjWm zF@NzaZkfgGt093wQ+3`cA`KRuFh(@0yHPku<@xJ|~?H-Ck% z7E>{H^+6Yvr8|E`gk?Rnna=+qzabzHSb96!9&G6aw=+?$+PY;-4R|~)1%Q9dt(0Nt zY8lLu=mJ5*`hn(qMk`_SNGZ?lX#^#N1EHbJ7bMmu8|regX=;vI-i?y(y2e%+-s0?s zKy+;zj*hiBh~yj_2;jpG>yoL+QDnl$MqN**b=t<`kB!fSNK4Jd^JAZG5*$bA7Rkm} z=$sghGQ+c_%J)!X;gn;5N7){h&KJAC>uk>~id5cE9bAxYFFJL(JWHH@J>G=Fx!O+J zgsDH6rU+Gnp(TAdD4=mAf*rU}zg>3w=7&Qd#w7B?x4Th$@&V1hm0f%N(U+550d=le z2ab5~&>TIq4|{_2jlo0Y)ob1{Z%1`)zr?Wb@j1|eSpg!n92f4m9A-fr9I9DE>;)xly;OuBqvvP)!JBcO_@Km0MhzK)VdU3cUc&zJ(2|2pYt#_qgw ztK#em5DYdy1$#@#o|MrAO^#QQateZ(genQR*_|T=`S|`5=?0~RK7MF1E1}-~tMZwz zWpG!_?r@ZHB429>EE{`;<(Ni*pv=TgOAo^r3R8|j?-Ib?p>8`^RW8afHs{T9Wc`Mq zr(T&*q5|gh=g{#Lq{3gp$(^bZM<}}2a$SL@DaVcN7viyh^%$KByZ<(r!Fjdbv$jem z&NClgL$4i>T5nqySvuQ}V7}+FcXC7Oms$!0zY$B@0T;L(=79yj2YLiG3|zPBeqNSS zb)JRf=$--HqyUKGhnydOjJEhbss^?xw5@v;KBHCC^2Iv9{sGeJZn@IJ3GZ`oAhT~_ zARZW;u!1JY}74{$UV0@!`vP zx+dmpdr|YaxoA#5)$2vAyteiY4VvW~n^%+;35GY&n z?w&(BTmEovO+78E@1p#{BjN%;3DXH47u|ir7rcS&W?Lfy>zu8Jv1TnUlKLms_9SAY zdI4*O&QNiI^3jLaRJD4be!zT3YM#mZMZxN#S3zjdhbEXlghDP`3f}oUqerTJ(L-j# z*-Aq?`ScBNcnVa%E*rmB9t5yn>@g@RkO1=LHic=vysaLW03EOm=!MX>KFqhYc8_7` zT#Pog?gwHwMrEIIQ}VyS+-ZB;WaIUVqSP79JsmoStaOry(u$*GJl~RLE5s?U;>1etucbvnU&;ZbW_YB@ys)wJ z6S#Tqn`q6n{YZNJf&sG6pSP=aCR=O^iFhudaei zK%U5XqRs`5Q40>ctM^$b`FK4%d1x>-l4bG=AoYl#`W=ls!w6Uov&(fv?6HG?qEi_7 zLNZ}FB02@r<|fu}xPa+Wh<3@ZA+JieY;vr(SggH~yR!dE!613dbU_iLm)dTdVrjCwFTF;2U3v zzFE&z0D_vyTD3U225rBW8Oo0{;oyy)Bqaz=#L307Pet97q!qYZ)}}|;Y2r?u)uxAh z(EiwA6X-Fo10kjKfPnB?8BuvvCrDpIC#pAVmg&oPQp(M&5XH*V@Ha()!=ee<)c5!u z@7TY?84Fj}F6_hzg{VKT8-QW~A6jWH20#-u0&V-w+SU5UzwH&inOByHwrS)iC^D2x zD*aJEWTYTZ=XWlcPwPWIU+M{Y-%;Tjjf2nPSiurRT|9oZoB6I5nuJ9BP{`d2(84|V zNqY3$5?)HPntKIe>s^uaEyqIcRS~S;_q+tPzPn~_AEWaT*iT`w0+2N-gRZ|qO=~=E zKN@mG5N%TNG#M=R`!yeZ{cI0XWghy3mW_${>x0ElLE4q(M98ox<9a7^`I=<7^Qvd1 zh%3wGcQA^0Ca<8SCP&-MjkbFfaejt4qiyz7U~&2OW(>ps z+{c~q9S2A|kQN)pcleh6j~OczqGm+M=Drrd|Jp(YT-yfLn>wamZco!%pU#M#HAUXc z1S<2?Od@}oAVG@Iu;&J}lR4V1j~-{cvHyhH6^U|Gum|_)kr2{7>XjZXEL6@e%U9F`*f!H(vBAsDe{B{zl9;{K4Pif6|HJtiAEHXEQrnL6-Ca~8a29zz0(R?JF&t^fUywBh2p`x6>UqaiBD3^WOA56tS1#1~g z82S&f4Pf^^ZqijF6|26&xIR6wBER^~h_^vn{W`iQX^L^e^MK~Flyf*UuD@P9O#zv} zmFLySR^TI7-<3;*19X?4jLRkW)5F@kRuKz&!>3sP07pNVr64?#o8t>Zw(fW26X7_z z%gCSKD~du`i2i3|t)0#5isRwOkC}&8F{ES}^&&m7KH1>E`hZ+EwKAzT@_6_^scpj^ diff --git a/nano/templates/exonet_node.tmpl b/nano/templates/exonet_node.tmpl new file mode 100644 index 0000000000000..f9d81d4e92f98 --- /dev/null +++ b/nano/templates/exonet_node.tmpl @@ -0,0 +1,40 @@ + + +

Status

+
+
+ Power: +
+
+ {{:helper.link('On', 'power', {'toggle_power' : 1}, data.on ? 'selected' : null)}}{{:helper.link('Off', 'close', {'toggle_power' : 1}, data.on ? null : 'selected', data.on ? 'redButton' : null)}} +
+
+ +

Ports

+
+
+ Incoming PDA Messages: +
+
+ {{:helper.link('Open', 'check', {'toggle_PDA_port' : 1}, data.allowPDAs ? 'selected' : null)}}{{:helper.link('Close', 'close', {'toggle_PDA_port' : 1}, data.allowPDAs ? null : 'selected')}} +
+
+
+
+ Incoming Communicators: +
+
+ {{:helper.link('Open', 'check', {'toggle_communicator_port' : 1}, data.allowCommunicators ? 'selected' : null)}}{{:helper.link('Close', 'close', {'toggle_communicator_port' : 1}, data.allowCommunicators ? null : 'selected')}} +
+
+
+
+ Incoming Newscaster Content: +
+
+ {{:helper.link('Open', 'check', {'toggle_newscaster_port' : 1}, data.allowNewscasters ? 'selected' : null)}}{{:helper.link('Close', 'close', {'toggle_newscaster_port' : 1}, data.allowNewscasters ? null : 'selected')}} +
+
diff --git a/tgstation.dme b/tgstation.dme index eaa7f073fa9fd..d73ccd96065a1 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -166,6 +166,7 @@ #include "code\datums\computerfiles.dm" #include "code\datums\datacore.dm" #include "code\datums\datumvars.dm" +#include "code\datums\EPv2.dm" #include "code\datums\gas_mixture.dm" #include "code\datums\hud.dm" #include "code\datums\martial.dm" From d4dd2d8363d25b466ff7341a390ad5c4f79605f3 Mon Sep 17 00:00:00 2001 From: Stakks Date: Thu, 12 Apr 2018 15:23:58 -0500 Subject: [PATCH 4/9] Stage 4 --- code/_macros.dm | 53 +++ code/datums/weakref.dm | 31 ++ .../objects/items/weapons/storage/storage.dm | 10 + code/modules/error_handler/~defines.dm | 6 + .../integrated_electronics/_defines.dm | 333 ++++++++-------- .../integrated_electronics/arithmetic.dm | 172 ++++----- .../integrated_electronics/assemblies.dm | 118 +++--- .../integrated_electronics/converters.dm | 148 +++---- .../integrated_electronics/coordinate.dm | 65 +--- .../integrated_electronics/data_transfer.dm | 78 ++-- .../integrated_electronics/input_output.dm | 364 +++++++----------- code/modules/integrated_electronics/logic.dm | 214 ++++------ .../integrated_electronics/manipulation.dm | 77 ++-- code/modules/integrated_electronics/memory.dm | 108 ++++-- code/modules/integrated_electronics/time.dm | 132 ++++--- code/modules/integrated_electronics/tools.dm | 35 +- .../integrated_electronics/~defines.dm | 6 + code/modules/projectiles/gun.dm | 46 ++- code/modules/research/designs.dm | 32 +- tgstation.dme | 3 + 20 files changed, 982 insertions(+), 1049 deletions(-) create mode 100644 code/_macros.dm create mode 100644 code/datums/weakref.dm create mode 100644 code/modules/error_handler/~defines.dm create mode 100644 code/modules/integrated_electronics/~defines.dm diff --git a/code/_macros.dm b/code/_macros.dm new file mode 100644 index 0000000000000..67267ab7cc26a --- /dev/null +++ b/code/_macros.dm @@ -0,0 +1,53 @@ +#define Clamp(x, y, z) (x <= y ? y : (x >= z ? z : x)) + +#define CLAMP01(x) (Clamp(x, 0, 1)) + +//Already defined + +//#define get_turf(A) get_step(A,0) + +//#define isAI(A) istype(A, /mob/living/silicon/ai) + +//#define isalien(A) istype(A, /mob/living/carbon/alien) + +//#define isanimal(A) istype(A, /mob/living/simple_animal) + +//#define isairlock(A) istype(A, /obj/machinery/door/airlock) + +//#define isbrain(A) istype(A, /mob/living/carbon/brain) + +//#define iscarbon(A) istype(A, /mob/living/carbon) + +//#define iscorgi(A) istype(A, /mob/living/simple_animal/corgi) + +//#define isEye(A) istype(A, /mob/observer/eye) + +//#define ishuman(A) istype(A, /mob/living/carbon/human) + +//#define isliving(A) istype(A, /mob/living) + +//#define ismouse(A) istype(A, /mob/living/simple_animal/mouse) + +//#define isnewplayer(A) istype(A, /mob/new_player) + +//#define isobserver(A) istype(A, /mob/observer/dead) + +//#define isorgan(A) istype(A, /obj/item/organ/external) + +//#define ispAI(A) istype(A, /mob/living/silicon/pai) + +//#define isrobot(A) istype(A, /mob/living/silicon/robot) + +//#define issilicon(A) istype(A, /mob/living/silicon) + +//#define isslime(A) istype(A, /mob/living/carbon/slime) + +//#define isxeno(A) istype(A, /mob/living/simple_animal/xeno) + +#define isweakref(A) istype(A, /weakref) + +#define RANDOM_BLOOD_TYPE pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+") + +#define to_chat(target, message) target << message + +//#define CanInteract(user,src) user.canUseTopic(src,0,0) //I'll figure this out later \ No newline at end of file diff --git a/code/datums/weakref.dm b/code/datums/weakref.dm new file mode 100644 index 0000000000000..1b9f0b8d56c65 --- /dev/null +++ b/code/datums/weakref.dm @@ -0,0 +1,31 @@ +/datum + var/weakref/weakref + +/datum/Destroy() + weakref = null // Clear this reference to ensure it's kept for as brief duration as possible. + . = ..() + +//obtain a weak reference to a datum +/proc/weakref(datum/D) + if(D.gc_destroyed) + return + if(!D.weakref) + D.weakref = new/weakref(D) + return D.weakref + +/weakref + var/ref + +/weakref/New(datum/D) + ref = "\ref[D]" + +/weakref/Destroy() + // A weakref datum should not be manually destroyed as it is a shared resource, + // rather it should be automatically collected by the BYOND GC when all references are gone. + return 0 + +/weakref/proc/resolve() + var/datum/D = locate(ref) + if(D && D.weakref == src) + return D + return null \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index 1a4e1f3224f52..42ddd910ca6a7 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -502,3 +502,13 @@ if(verbs.Find(/obj/item/weapon/storage/verb/quick_empty)) quick_empty() +/obj/item/weapon/storage/proc/make_exact_fit() + storage_slots = contents.len + + can_hold.Cut() + max_w_class = 0 + max_combined_w_class = 0 + for(var/obj/item/I in src) + can_hold[I.type]++ + max_w_class = max(I.w_class, max_w_class) + max_combined_w_class += I.w_class diff --git a/code/modules/error_handler/~defines.dm b/code/modules/error_handler/~defines.dm new file mode 100644 index 0000000000000..98712eaa091bd --- /dev/null +++ b/code/modules/error_handler/~defines.dm @@ -0,0 +1,6 @@ +// Settings for the error handler and error viewer +#undef ERROR_COOLDOWN +#undef ERROR_LIMIT +#undef ERROR_MAX_COOLDOWN +#undef ERROR_SILENCE_TIME +#undef ERROR_MSG_DELAY diff --git a/code/modules/integrated_electronics/_defines.dm b/code/modules/integrated_electronics/_defines.dm index ed4be623c7bf7..b5a4c4b786f69 100644 --- a/code/modules/integrated_electronics/_defines.dm +++ b/code/modules/integrated_electronics/_defines.dm @@ -1,3 +1,7 @@ +#define IC_INPUT "input" +#define IC_OUTPUT "output" +#define IC_ACTIVATOR "activator" + #define DATA_CHANNEL "data channel" #define PULSE_CHANNEL "pulse channel" @@ -11,20 +15,14 @@ var/list/inputs = list() var/list/outputs = list() var/list/activators = list() - var/number_of_inputs = 0 //This is how many input pins are created - var/number_of_outputs = 0 //Likewise for output - var/number_of_activators = 0 //Guess - var/list/input_names = list() - var/list/output_names = list() - var/list/activator_names = list() - var/last_used = 0 //Uses world.time + var/next_use = 0 //Uses world.time var/complexity = 1 //This acts as a limitation on building machines, more resource-intensive components cost more 'space'. var/cooldown_per_use = 1 SECONDS + var/category = /obj/item/integrated_circuit // Used by the toolsets to filter out category types /obj/item/integrated_circuit/examine(mob/user) ..() - user << "This board has [inputs.len] input [inputs.len != 1 ? "pins" : "pin"] and \ - [outputs.len] output [outputs.len != 1 ? "pins" : "pin"]." + user << "This board has [inputs.len] input pin\s and [outputs.len] output pin\s." for(var/datum/integrated_io/input/I in inputs) if(I.linked.len) user << "\The [I.name] is connected to [I.get_linked_to_desc()]." @@ -38,39 +36,16 @@ interact(user) /obj/item/integrated_circuit/New() + setup_io(inputs, /datum/integrated_io/input) + setup_io(outputs, /datum/integrated_io/output) + setup_io(activators, /datum/integrated_io/activate) ..() - var/i = 0 - if(number_of_inputs) - for(i = number_of_inputs, i > 0, i--) - inputs.Add(new /datum/integrated_io/input(src)) - - if(number_of_outputs) - for(i = number_of_outputs, i > 0, i--) - outputs.Add(new /datum/integrated_io/output(src)) - - if(number_of_activators) - for(i = number_of_activators, i > 0, i--) - activators.Add(new /datum/integrated_io/activate(src)) - - apply_names_to_io() - -/obj/item/integrated_circuit/proc/apply_names_to_io() - var/i = 1 - if(input_names.len) - for(var/datum/integrated_io/input/I in inputs) - I.name = "[input_names[i]]" - i++ - i = 1 - if(output_names.len) - for(var/datum/integrated_io/output/O in outputs) - O.name = "[output_names[i]]" - i++ - - i = 1 - if(activator_names.len) - for(var/datum/integrated_io/activate/A in activators) - A.name = "[activator_names[i]]" - i++ + +/obj/item/integrated_circuit/proc/setup_io(var/list/io_list, var/io_type) + var/list/names = io_list.Copy() + io_list.Cut() + for(var/name in names) + io_list.Add(new io_type(src, name)) /obj/item/integrated_circuit/proc/on_data_written() //Override this for special behaviour when new data gets pushed to the circuit. return @@ -82,7 +57,12 @@ qdel(O) for(var/datum/integrated_io/A in activators) qdel(A) - ..() + . = ..() + +/obj/item/integrated_circuit/proc/nano_host() + if(istype(src.loc, /obj/item/device/electronic_assembly)) + return loc + return ..() /obj/item/integrated_circuit/emp_act(severity) for(var/datum/integrated_io/io in inputs + outputs + activators) @@ -94,42 +74,42 @@ set desc = "Rename your circuit, useful to stay organized." var/mob/M = usr + //if(!CanInteract(M,src)) + // return - if(!M.canmove || M.stat || M.restrained()) - return - - var/input = sanitize_text(input("What do you want to name the circuit?","Rename", src.name), MAX_NAME_LEN) - + var/input = sanitize_text(input("What do you want to name the circuit?", "Rename", src.name) as null|text, MAX_NAME_LEN) if(src && input) M << "The circuit '[src.name]' is now labeled '[input]'." name = input /obj/item/integrated_circuit/proc/get_pin_ref(var/pin_type, var/pin_number) switch(pin_type) - if("input") + if(IC_INPUT) if(pin_number > inputs.len) return null return inputs[pin_number] - if("output") + if(IC_OUTPUT) if(pin_number > outputs.len) return null return outputs[pin_number] - if("activator") + if(IC_ACTIVATOR) if(pin_number > activators.len) return null return activators[pin_number] return null /obj/item/integrated_circuit/interact(mob/user) - if(get_dist(get_turf(src), user) > 1) - user.unset_machine(src) - return - var/HTML = "[src.name]" + //if(!CanInteract(user,src)) + // return + + var/HTML = list() + HTML += "[src.name]" HTML += "
" HTML += "" - HTML += "
\[Refresh\] | " - HTML += "\[Rename\]
" + HTML += "
\[Refresh\] | " + HTML += "\[Rename\] | " + HTML += "\[Remove\]
" HTML += "" HTML += "" @@ -139,80 +119,69 @@ var/column_width = 3 var/row_height = max(inputs.len, outputs.len, 1) - var/i - var/j - for(i = 1, i < row_height+1, i++) + + for(var/i = 1 to row_height) HTML += "" - for(j = 1, j < column_width+1, j++) + for(var/j = 1 to column_width) var/datum/integrated_io/io = null - var/words = null + var/words = list() var/height = 1 switch(j) if(1) - io = get_pin_ref("input",i) + io = get_pin_ref(IC_INPUT, i) if(io) if(io.linked.len) - words = "[io.name] [io.display_data()]
" + words += "[io.name] [io.display_data()]
" for(var/datum/integrated_io/linked in io.linked) - words += "\[[linked.name]\] \ - @ [linked.holder]
" - else // "Click here!" - words = "[io.name] [io.display_data()]
" + words += "\[[linked.name]\] \ + @ [linked.holder]
" + else + words += "[io.name] [io.display_data()]
" for(var/datum/integrated_io/linked in io.linked) - words += "\[[linked.name]\] \ - @ [linked.holder]
" + words += "\[[linked.name]\] \ + @ [linked.holder]
" if(outputs.len > inputs.len) - // height = Floor(outputs.len / inputs.len) - height = 1 // Because of bugs, if there's more outputs than inputs, it causes the output side to be hidden. - //world << "I wrote [words] at ([i],[j]). Height = [height]." + height = 1 if(2) if(i == 1) - words = "[src.name]

[src.desc]" + words += "[src.name]

[src.desc]" height = row_height - //world << "I wrote the center piece because i was equal to 1, at ([i],[j]). Height = [height]." else continue if(3) - io = get_pin_ref("output",i) + io = get_pin_ref(IC_OUTPUT, i) if(io) if(io.linked.len) - words = "[io.name] [io.display_data()]
" + words += "[io.name] [io.display_data()]
" for(var/datum/integrated_io/linked in io.linked) - words += "\[[linked.name]\] \ + words += "\[[linked.name]\] \ @ [linked.holder]
" else - words = "[io.name] [io.display_data()]
" + words += "[io.name] [io.display_data()]
" for(var/datum/integrated_io/linked in io.linked) - words += "\[[linked.name]\] \ - @ [linked.holder]
" + words += "\[[linked.name]\] \ + @ [linked.holder]
" if(inputs.len > outputs.len) - // height = Floor(inputs.len / outputs.len) - height = 1 // See above. - //world << "I wrote [words] at ([i],[j]). Height = [height]." - HTML += "" - //HTML += "" - //world << "Writing to ([i],[j])." + height = 1 + HTML += "" HTML += "" - if(activators.len) - for(i = 1, i < activators.len+1, i++) - var/datum/integrated_io/io = null - var/words = null - io = get_pin_ref("activator",i) - if(io) - if(io.linked.len) - words = "[io.name]
" - for(var/datum/integrated_io/linked in io.linked) - words += "\[[linked.name]\] \ - @ [linked.holder]
" - else // "Click here!" - words = "[io.name]
" - for(var/datum/integrated_io/linked in io.linked) - words += "\[[linked.name]\] \ - @ [linked.holder]
" - HTML += "" - HTML += "" - HTML += "" + for(var/activator in activators) + var/datum/integrated_io/io = activator + var/words = list() + if(io.linked.len) + words += "[io.name]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + else + words += "[io.name]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + HTML += "" + HTML += "" + HTML += "" HTML += "
[words][words][jointext(words, null)]
[words]
[jointext(words, null)]
" HTML += "
" @@ -221,56 +190,50 @@ HTML += "
[extended_desc]" HTML += "" - user << browse(HTML, "window=circuit-\ref[src];size=600x350;border=1;can_resize=1;can_close=1;can_minimize=1") + user << browse(jointext(HTML, null), "window=circuit-\ref[src];size=600x350;border=1;can_resize=1;can_close=1;can_minimize=1") - //user << sanitize_text(HTML, "window=debug;size=400x400;border=1;can_resize=1;can_close=1;can_minimize=1") - //world << sanitize_text(HTML) - - user.set_machine(src) onclose(user, "circuit-\ref[src]") -/obj/item/integrated_circuit/Topic(href, href_list[]) - var/mob/living/user = locate(href_list["user"]) in mob_list - var/pin = locate(href_list["pin"]) in inputs + outputs + activators - - if(!user || !user.Adjacent(get_turf(src)) ) +/obj/item/integrated_circuit/Topic(href, href_list) + if(..()) return 1 + var/pin = locate(href_list["pin"]) in inputs + outputs + activators - if(!user.canmove || user.stat || user.restrained()) - return - + var/obj/held_item = usr.get_active_hand() if(href_list["wire"]) - if(ishuman(user) && Adjacent(user)) - var/mob/living/carbon/human/H = user - var/obj/held_item = H.get_active_hand() - - if(istype(held_item, /obj/item/device/integrated_electronics/wirer)) - var/obj/item/device/integrated_electronics/wirer/wirer = held_item - if(pin) - wirer.wire(pin, user) - - else if(istype(held_item, /obj/item/device/integrated_electronics/debugger)) - var/obj/item/device/integrated_electronics/debugger/debugger = held_item - if(pin) - debugger.write_data(pin, user) - - // if(istype(H.r_hand, /obj/item/device/integrated_electronics/wirer)) - // wirer = H.r_hand - // else if(istype(H.l_hand, /obj/item/device/integrated_electronics/wirer)) - // wirer = H.l_hand - - // if(wirer && pin) - // wirer.wire(pin, user) - else - user << "You can't do a whole lot without tools." + if(istype(held_item, /obj/item/device/integrated_electronics/wirer)) + var/obj/item/device/integrated_electronics/wirer/wirer = held_item + if(pin) + wirer.wire(pin, usr) + + else if(istype(held_item, /obj/item/device/integrated_electronics/debugger)) + var/obj/item/device/integrated_electronics/debugger/debugger = held_item + if(pin) + debugger.write_data(pin, usr) + else + usr << "You can't do a whole lot without the proper tools." if(href_list["examine"]) - examine(user) + examine(usr) if(href_list["rename"]) - rename_component(user) + rename_component(usr) + + if(href_list["remove"]) + if(istype(held_item, /obj/item/weapon/screwdriver)) + disconnect_all() + var/turf/T = get_turf(src) + forceMove(T) + playsound(T, 'sound/items/Crowbar.ogg', 50, 1) + usr << "You pop \the [src] out of the case, and slide it out." + else + usr << "You need a screwdriver to remove components." + var/obj/item/device/electronic_assembly/ea = loc + if(istype(ea)) + ea.interact(usr) + return - interact(user) // To refresh the UI. + interact(usr) // To refresh the UI. /datum/integrated_io var/name = "input/output" @@ -279,25 +242,39 @@ var/list/linked = list() var/io_type = DATA_CHANNEL -/datum/integrated_io/New(var/newloc) +/datum/integrated_io/New(var/newloc, var/name) ..() + src.name = name holder = newloc - if(!holder) - message_admins("ERROR: An integrated_io ([src.name]) spawned without a holder! This is a bug.") + if(!istype(holder)) + message_admins("ERROR: An integrated_io ([src.name]) spawned without a valid holder! This is a bug.") /datum/integrated_io/Destroy() disconnect() + data = null holder = null - ..() + . = ..() + +/datum/integrated_io/proc/nano_host() + return holder + + +/datum/integrated_io/proc/data_as_type(var/as_type) + if(!isweakref(data)) + return + var/weakref/w = data + var/output = w.resolve() + return istype(output, as_type) ? output : null /datum/integrated_io/proc/display_data() if(isnull(data)) return "(null)" // Empty data means nothing to show. if(istext(data)) return "(\"[data]\")" // Wraps the 'string' in escaped quotes, so that people know it's a 'string'. - if(istype(data, /atom)) - var/atom/A = data - return "([A.name] \[Ref\])" // For refs, we want just the name displayed. + if(isweakref(data)) + var/weakref/w = data + var/atom/A = w.resolve() + return A ? "([A.name] \[Ref\])" : "(null)" // For refs, we want just the name displayed. return "([data])" // Nothing special needed for numbers or other stuff. /datum/integrated_io/activate/display_data() @@ -316,43 +293,38 @@ push_data() /datum/integrated_io/proc/write_data_to_pin(var/new_data) - if(isnull(new_data) || isnum(new_data) || istext(new_data) || istype(new_data, /atom/) ) // Anything else is a type we don't want. + if(isnull(new_data) || isnum(new_data) || istext(new_data) || isweakref(new_data)) // Anything else is a type we don't want. data = new_data holder.on_data_written() /datum/integrated_io/proc/push_data() - if(linked.len) - for(var/datum/integrated_io/io in linked) - io.write_data_to_pin(data) + for(var/datum/integrated_io/io in linked) + io.write_data_to_pin(data) /datum/integrated_io/activate/push_data() - if(linked.len) - for(var/datum/integrated_io/io in linked) - io.holder.work() + for(var/datum/integrated_io/io in linked) + io.holder.check_then_do_work() /datum/integrated_io/proc/pull_data() - if(linked.len) - for(var/datum/integrated_io/io in linked) - write_data_to_pin(io.data) + for(var/datum/integrated_io/io in linked) + write_data_to_pin(io.data) /datum/integrated_io/proc/get_linked_to_desc() if(linked.len) - var/result = english_list(linked) - return "the [result]" + return "the [english_list(linked)]" return "nothing" /datum/integrated_io/proc/disconnect() - if(linked.len) - //First we iterate over everything we are linked to. - for(var/datum/integrated_io/their_io in linked) - //While doing that, we iterate them as well, and disconnect ourselves from them. - for(var/datum/integrated_io/their_linked_io in their_io.linked) - if(their_linked_io == src) - their_io.linked.Remove(src) - else - continue - //Now that we're removed from them, we gotta remove them from us. - src.linked.Remove(their_io) + //First we iterate over everything we are linked to. + for(var/datum/integrated_io/their_io in linked) + //While doing that, we iterate them as well, and disconnect ourselves from them. + for(var/datum/integrated_io/their_linked_io in their_io.linked) + if(their_linked_io == src) + their_io.linked.Remove(src) + else + continue + //Now that we're removed from them, we gotta remove them from us. + src.linked.Remove(their_io) /datum/integrated_io/input name = "input pin" @@ -372,11 +344,14 @@ for(var/datum/integrated_io/input/I in inputs) I.push_data() -/obj/item/integrated_circuit/proc/work(var/datum/integrated_io/io) - if(last_used + cooldown_per_use > world.time) // All intergrated circuits have an internal cooldown, to protect from spam. - return 0 - last_used = world.time - return 1 +/obj/item/integrated_circuit/proc/check_then_do_work() + if(world.time < next_use) // All intergrated circuits have an internal cooldown, to protect from spam. + return + next_use = world.time + cooldown_per_use + do_work() + +/obj/item/integrated_circuit/proc/do_work() + return /obj/item/integrated_circuit/proc/disconnect_all() for(var/datum/integrated_io/input/I in inputs) diff --git a/code/modules/integrated_electronics/arithmetic.dm b/code/modules/integrated_electronics/arithmetic.dm index 3fc60c64f9cd3..31265e297ec4c 100644 --- a/code/modules/integrated_electronics/arithmetic.dm +++ b/code/modules/integrated_electronics/arithmetic.dm @@ -1,25 +1,10 @@ //These circuits do simple math. /obj/item/integrated_circuit/arithmetic complexity = 1 - number_of_inputs = 8 - number_of_outputs = 1 - number_of_activators = 1 - input_names = list( - "A", - "B", - "C", - "D", - "E", - "F", - "G", - "H" - ) - output_names = list( - "result" - ) - activator_names = list( - "compute" - ) + inputs = list("A","B","C","D","E","F","G","H") + outputs = list("result") + activators = list("compute") + category = /obj/item/integrated_circuit/arithmetic // +Adding+ // @@ -28,17 +13,16 @@ desc = "This circuit can add numbers together." icon_state = "addition" -/obj/item/integrated_circuit/arithmetic/addition/work() - if(..()) - var/result = 0 - for(var/datum/integrated_io/input/I in inputs) - I.pull_data() - if(isnum(I.data)) - result = result + I.data +/obj/item/integrated_circuit/arithmetic/addition/do_work() + var/result = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data)) + result = result + I.data - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() // -Subtracting- // @@ -47,7 +31,7 @@ desc = "This circuit can subtract numbers." icon_state = "subtraction" -/obj/item/integrated_circuit/arithmetic/subtraction/work() +/obj/item/integrated_circuit/arithmetic/subtraction/do_work() if(..()) var/result = 0 for(var/datum/integrated_io/input/I in inputs) @@ -66,17 +50,16 @@ desc = "This circuit can multiply numbers." icon_state = "multiplication" -/obj/item/integrated_circuit/arithmetic/subtraction/work() - if(..()) - var/result = 0 - for(var/datum/integrated_io/input/I in inputs) - I.pull_data() - if(isnum(I.data)) - result = result * I.data +/obj/item/integrated_circuit/arithmetic/subtraction/do_work() + var/result = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data)) + result = result * I.data - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() // /Division/ // @@ -85,17 +68,16 @@ desc = "This circuit can divide numbers, just don't think about trying to divide by zero!" icon_state = "division" -/obj/item/integrated_circuit/arithmetic/division/work() - if(..()) - var/result = 0 - for(var/datum/integrated_io/input/I in inputs) - I.pull_data() - if(isnum(I.data) && I.data != 0) //No runtimes here. - result = result / I.data +/obj/item/integrated_circuit/arithmetic/division/do_work() + var/result = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data) && I.data != 0) //No runtimes here. + result = result / I.data - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() // Absolute // @@ -103,20 +85,18 @@ name = "absolute circuit" desc = "This outputs a non-negative version of the number you put in. This may also be thought of as its distance from zero." icon_state = "absolute" - number_of_inputs = 1 - number_of_outputs = 1 + inputs = list("A") -/obj/item/integrated_circuit/arithmetic/absolute/work() - if(..()) - var/result = 0 - for(var/datum/integrated_io/input/I in inputs) - I.pull_data() - if(isnum(I.data) && I.data != 0) - result = abs(result) +/obj/item/integrated_circuit/arithmetic/absolute/do_work() + var/result = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data) && I.data != 0) + result = abs(result) - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() // Averaging // @@ -125,59 +105,49 @@ desc = "This circuit is of average quality, however it will compute the average for numbers you give it." icon_state = "average" -/obj/item/integrated_circuit/arithmetic/average/work() - if(..()) - var/result = 0 - var/inputs_used = 0 - for(var/datum/integrated_io/input/I in inputs) - I.pull_data() - if(isnum(I.data)) - inputs_used++ - result = result + I.data +/obj/item/integrated_circuit/arithmetic/average/do_work() + var/result = 0 + var/inputs_used = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data)) + inputs_used++ + result = result + I.data - if(inputs_used) - result = result / inputs_used + if(inputs_used) + result = result / inputs_used - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() // Pi, because why the hell not? // /obj/item/integrated_circuit/arithmetic/pi name = "pi constant circuit" desc = "Not recommended for cooking. Outputs '3.14159' when it receives a pulse." icon_state = "pi" - number_of_inputs = 0 - number_of_outputs = 1 + inputs = list() -/obj/item/integrated_circuit/arithmetic/pi/work() - if(..()) - var/datum/integrated_io/output/O = outputs[1] - O.data = 3.14159 - O.push_data() +/obj/item/integrated_circuit/arithmetic/pi/do_work() + var/datum/integrated_io/output/O = outputs[1] + O.data = 3.14159 + O.push_data() // Random // /obj/item/integrated_circuit/arithmetic/random name = "random number generator circuit" desc = "This gives a random (integer) number between values A and B inclusive." icon_state = "random" - number_of_inputs = 2 - number_of_outputs = 1 - number_of_activators = 1 - input_names = list( - "L", - "H" - ) - -/obj/item/integrated_circuit/arithmetic/random/work() - if(..()) - var/result = 0 - var/datum/integrated_io/L = inputs[1] - var/datum/integrated_io/H = inputs[2] + inputs = list("L","H") - if(isnum(L.data) && isnum(H.data)) - result = rand(L.data, H.data) +/obj/item/integrated_circuit/arithmetic/random/do_work() + var/result = 0 + var/datum/integrated_io/L = inputs[1] + var/datum/integrated_io/H = inputs[2] - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() \ No newline at end of file + if(isnum(L.data) && isnum(H.data)) + result = rand(L.data, H.data) + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/assemblies.dm b/code/modules/integrated_electronics/assemblies.dm index e727f4c3d8131..7cd7ce36cd8d0 100644 --- a/code/modules/integrated_electronics/assemblies.dm +++ b/code/modules/integrated_electronics/assemblies.dm @@ -22,20 +22,62 @@ max_components = 30 max_complexity = 60 -/* +/obj/item/device/electronic_assembly/drone + name = "electronic drone" + icon_state = "setup_drone" + w_class = 3 + max_components = 25 + max_complexity = 100 -/obj/item/device/electronic_assembly/New() - ..() - processing_objects |= src +/obj/item/device/electronic_assembly/interact(mob/user) + //if(!CanInteract(user,src)) + // return -/obj/item/device/electronic_assembly/Destroy() - processing_objects.Remove(src) - ..() + var/total_parts = 0 + var/total_complexity = 0 + for(var/obj/item/integrated_circuit/part in contents) + total_parts++ + total_complexity = total_complexity + part.complexity + var/HTML = list() + + HTML += "[src.name]" + HTML += "
\[Refresh\] | " + HTML += "\[Rename\]
" + HTML += "[total_parts]/[max_components] ([round((total_parts / max_components) * 100, 0.1)]%) space taken up in the assembly.
" + HTML += "[total_complexity]/[max_complexity] ([round((total_complexity / max_complexity) * 100, 0.1)]%) maximum complexity." + HTML += "

" + HTML += "Components;
" + for(var/obj/item/integrated_circuit/circuit in contents) + HTML += "[circuit.name] | " + HTML += "\[Rename\] | " + HTML += "\[Remove\]" + HTML += "
" + + HTML += "" + user << browse(jointext(HTML,null), "window=assembly-\ref[src];size=600x350;border=1;can_resize=1;can_close=1;can_minimize=1") + +/obj/item/device/electronic_assembly/Topic(href, href_list[]) + if(..()) + return 1 + + if(href_list["rename"]) + rename(usr) + + interact(usr) // To refresh the UI. + +/obj/item/device/electronic_assembly/verb/rename() + set name = "Rename Circuit" + set category = "Object" + set desc = "Rename your circuit, useful to stay organized." + + var/mob/M = usr + //if(!CanInteract(M,src)) + // return -/obj/item/device/electronic_assembly/process() - for(var/obj/item/integrated_circuit/IC in contents) - IC.work() -*/ + var/input = sanitize_text(input("What do you want to name this?", "Rename", src.name) as null|text, MAX_NAME_LEN) + if(src && input) + M << "The machine now has a label reading '[input]'." + name = input /obj/item/device/electronic_assembly/update_icon() if(opened) @@ -44,16 +86,13 @@ icon_state = initial(icon_state) /obj/item/device/electronic_assembly/examine(mob/user) - ..() - if(user.Adjacent(src)) - if(!opened) - for(var/obj/item/integrated_circuit/output/screen/S in contents) - if(S.stuff_to_display) - user << "There's a little screen labeled '[S.name]', which displays '[S.stuff_to_display]'." - else - var/obj/item/integrated_circuit/IC = input(user, "Which circuit do you want to examine?", "Examination") as null|anything in contents - if(IC) - IC.examine(user) + . = ..(user, 1) + if(.) + for(var/obj/item/integrated_circuit/output/screen/S in contents) + if(S.stuff_to_display) + user << "There's a little screen labeled '[S.name]', which displays '[S.stuff_to_display]'." + if(opened) + interact(user) /obj/item/device/electronic_assembly/attackby(var/obj/item/I, var/mob/user) if(istype(I, /obj/item/integrated_circuit)) @@ -67,45 +106,36 @@ total_parts++ total_complexity = total_complexity + part.complexity - if( (total_parts + 1) >= max_components) + if( (total_parts + 1) > max_components) user << "You can't seem to add this [IC.name], since there's no more room." return 0 - if( (total_complexity + IC.complexity) >= max_complexity) + if( (total_complexity + IC.complexity) > max_complexity) user << "You can't seem to add this [IC.name], since this setup's too complicated for the case." return 0 user << "You slide \the [IC] inside \the [src]." user.drop_item() IC.forceMove(src) - playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) - if(istype(I, /obj/item/weapon/screwdriver)) - if(!opened) - user << "\The [src] isn't opened, so you can't remove anything inside. Try using a crowbar." - return 0 - if(!contents.len) - user << "There's nothing inside this to remove!" - return 0 - var/obj/item/integrated_circuit/option = input("What do you want to remove?", "Component Removal") as null|anything in contents - if(option) - option.disconnect_all() - option.forceMove(get_turf(src)) - playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) - user << "You pop \the [option] out of the case, and slide it out." - if(istype(I, /obj/item/weapon/crowbar)) - playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) + playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) + interact(user) + else if(istype(I, /obj/item/weapon/crowbar)) + playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1) opened = !opened user << "You [opened ? "opened" : "closed"] \the [src]." update_icon() - if(istype(I, /obj/item/device/integrated_electronics/wirer)) + else if(istype(I, /obj/item/device/integrated_electronics/wirer) || istype(I, /obj/item/device/integrated_electronics/debugger) || istype(I, /obj/item/weapon/screwdriver)) if(opened) - var/obj/item/integrated_circuit/IC = input(user, "Which circuit do you want to examine?", "Examination") as null|anything in contents - if(IC) - IC.examine(user) + interact(user) else user << "\The [src] isn't opened, so you can't fiddle with the internal components. \ Try using a crowbar." + else + return ..() /obj/item/device/electronic_assembly/attack_self(mob/user) + if(opened) + interact(user) + var/list/available_inputs = list() for(var/obj/item/integrated_circuit/input/input in contents) if(input.can_be_asked_input) @@ -117,4 +147,4 @@ /obj/item/device/electronic_assembly/emp_act(severity) ..() for(var/atom/movable/AM in contents) - AM.emp_act(severity) + AM.emp_act(severity) \ No newline at end of file diff --git a/code/modules/integrated_electronics/converters.dm b/code/modules/integrated_electronics/converters.dm index 7a837abbfa3af..ad5f282356a78 100644 --- a/code/modules/integrated_electronics/converters.dm +++ b/code/modules/integrated_electronics/converters.dm @@ -1,133 +1,101 @@ //These circuits convert one variable to another. /obj/item/integrated_circuit/converter complexity = 2 - number_of_inputs = 1 - number_of_outputs = 1 - number_of_activators = 1 - input_names = list( - "input", - ) - output_names = list( - "result" - ) - activator_names = list( - "convert" - ) + inputs = list("input") + outputs = list("output") + activators = list("convert") + category = /obj/item/integrated_circuit/converter /obj/item/integrated_circuit/converter/num2text name = "number to string" desc = "This circuit can convert a number variable into a string." icon_state = "num-string" -/obj/item/integrated_circuit/converter/num2text/work() - if(..()) - var/result = null - var/datum/integrated_io/incoming = inputs[1] - var/datum/integrated_io/outgoing = outputs[1] - if(incoming.data && isnum(incoming.data)) - result = num2text(incoming.data) +/obj/item/integrated_circuit/converter/num2text/do_work() + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + if(incoming.data && isnum(incoming.data)) + result = num2text(incoming.data) - outgoing.data = result - outgoing.push_data() + outgoing.data = result + outgoing.push_data() /obj/item/integrated_circuit/converter/text2num name = "string to number" desc = "This circuit can convert a string variable into a number." icon_state = "string-num" -/obj/item/integrated_circuit/converter/text2num/work() - if(..()) - var/result = null - var/datum/integrated_io/incoming = inputs[1] - var/datum/integrated_io/outgoing = outputs[1] - if(incoming.data && istext(incoming.data)) - result = text2num(incoming.data) +/obj/item/integrated_circuit/converter/text2num/do_work() + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + if(incoming.data && istext(incoming.data)) + result = text2num(incoming.data) - outgoing.data = result - outgoing.push_data() + outgoing.data = result + outgoing.push_data() /obj/item/integrated_circuit/converter/ref2text name = "reference to string" desc = "This circuit can convert a reference to something else to a string, specifically the name of that reference." icon_state = "ref-string" -/obj/item/integrated_circuit/converter/ref2text/work() - if(..()) - var/result = null - var/datum/integrated_io/incoming = inputs[1] - var/datum/integrated_io/outgoing = outputs[1] - if(incoming.data && istype(incoming.data, /atom/)) - var/atom/A = incoming.data - result = A.name +/obj/item/integrated_circuit/converter/ref2text/do_work() + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + var/atom/A = incoming.data_as_type(/atom) + result = A && A.name - outgoing.data = result - outgoing.push_data() + outgoing.data = result + outgoing.push_data() /obj/item/integrated_circuit/converter/lowercase name = "lowercase string converter" desc = "this will cause a string to come out in all lowercase." icon_state = "lowercase" -/obj/item/integrated_circuit/converter/lowercase/work() - if(..()) - var/result = null - var/datum/integrated_io/incoming = inputs[1] - var/datum/integrated_io/outgoing = outputs[1] - if(incoming.data && istext(incoming.data)) - result = lowertext(incoming.data) +/obj/item/integrated_circuit/converter/lowercase/do_work() + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + if(incoming.data && istext(incoming.data)) + result = lowertext(incoming.data) - outgoing.data = result - outgoing.push_data() + outgoing.data = result + outgoing.push_data() /obj/item/integrated_circuit/converter/uppercase name = "uppercase string converter" desc = "THIS WILL CAUSE A STRING TO COME OUT IN ALL UPPERCASE." icon_state = "uppercase" -/obj/item/integrated_circuit/converter/uppercase/work() - if(..()) - var/result = null - var/datum/integrated_io/incoming = inputs[1] - var/datum/integrated_io/outgoing = outputs[1] - if(incoming.data && istext(incoming.data)) - result = uppertext(incoming.data) +/obj/item/integrated_circuit/converter/uppercase/do_work() + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + if(incoming.data && istext(incoming.data)) + result = uppertext(incoming.data) - outgoing.data = result - outgoing.push_data() + outgoing.data = result + outgoing.push_data() /obj/item/integrated_circuit/converter/concatenatior name = "concatenatior" desc = "This joins many strings together to get one big string." complexity = 4 - number_of_inputs = 8 - number_of_outputs = 1 - number_of_activators = 1 - input_names = list( - "A", - "B", - "C", - "D", - "E", - "F", - "G", - "H" - ) - output_names = list( - "result" - ) - activator_names = list( - "concatenate" - ) - - -/obj/item/integrated_circuit/converter/concatenatior/work() - if(..()) - var/result = null - for(var/datum/integrated_io/input/I in inputs) - I.pull_data() - if(istext(I.data)) - result = result + I.data - - var/datum/integrated_io/outgoing = outputs[1] - outgoing.data = result - outgoing.push_data() \ No newline at end of file + inputs = list("A","B","C","D","E","F","G","H") + outputs = list("result") + activators = list("concatenate") + +/obj/item/integrated_circuit/converter/concatenatior/do_work() + var/result = null + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(istext(I.data)) + result = result + I.data + + var/datum/integrated_io/outgoing = outputs[1] + outgoing.data = result + outgoing.push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/coordinate.dm b/code/modules/integrated_electronics/coordinate.dm index f70df7425901b..b97a1c1546938 100644 --- a/code/modules/integrated_electronics/coordinate.dm +++ b/code/modules/integrated_electronics/coordinate.dm @@ -4,58 +4,35 @@ desc = "This allows you to easily know the position of a machine containing this device." icon_state = "gps" complexity = 4 - number_of_inputs = 0 - number_of_outputs = 2 - number_of_activators = 1 - input_names = list( - ) - output_names = list( - "X (abs)", - "Y (abs)" - ) - activator_names = list( - "get coordinates" - ) + inputs = list() + outputs = list("X (abs)", "Y (abs)") + activators = list("get coordinates") -/obj/item/integrated_circuit/gps/work() - if(..()) - var/turf/T = get_turf(src) - var/datum/integrated_io/result_x = outputs[1] - var/datum/integrated_io/result_y = outputs[2] +/obj/item/integrated_circuit/gps/do_work() + var/turf/T = get_turf(src) + var/datum/integrated_io/result_x = outputs[1] + var/datum/integrated_io/result_y = outputs[2] - result_x.data = null - result_y.data = null - if(!T) - return + result_x.data = null + result_y.data = null + if(!T) + return - result_x.data = T.x - result_y.data = T.y + result_x.data = T.x + result_y.data = T.y - for(var/datum/integrated_io/output/O in outputs) - O.push_data() + for(var/datum/integrated_io/output/O in outputs) + O.push_data() /obj/item/integrated_circuit/abs_to_rel_coords name = "abs to rel coordinate converter" desc = "Easily convert absolute coordinates to relative coordinates with this." complexity = 4 - number_of_inputs = 0 - number_of_outputs = 4 - number_of_activators = 1 - input_names = list( - "X1 (abs)", - "Y1 (abs)", - "X2 (abs)", - "Y2 (abs)" - ) - output_names = list( - "X (rel)", - "Y (rel)" - ) - activator_names = list( - "compute rel coordinates" - ) + inputs = list("X1 (abs)", "Y1 (abs)", "X2 (abs)", "Y2 (abs)") + outputs = list("X (rel)", "Y (rel)") + activators = list("compute rel coordinates") -/obj/item/integrated_circuit/abs_to_rel_coords/work() +/obj/item/integrated_circuit/abs_to_rel_coords/do_work() var/datum/integrated_io/x1 = inputs[1] var/datum/integrated_io/y1 = inputs[2] @@ -69,7 +46,5 @@ result_x.data = x1.data - x2.data result_y.data = y1.data - y2.data - for(var/datum/integrated_io/output/O in outputs) - O.push_data() - ..() + O.push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/data_transfer.dm b/code/modules/integrated_electronics/data_transfer.dm index 12380e9ccac53..23ce3e5aeab30 100644 --- a/code/modules/integrated_electronics/data_transfer.dm +++ b/code/modules/integrated_electronics/data_transfer.dm @@ -3,77 +3,69 @@ desc = "Splits incoming data into all of the output pins." icon_state = "splitter" complexity = 3 - number_of_inputs = 1 - number_of_outputs = 2 - input_names = list( - "data to split" - ) - output_names = list( - "A", - "B", - "C", - "D", - "E", - "F", - "G", - "H" - ) + inputs = list("data to split") + outputs = list("A","B") /obj/item/integrated_circuit/transfer/splitter/medium name = "four splitter" icon_state = "splitter4" complexity = 5 - number_of_inputs = 1 - number_of_outputs = 4 + outputs = list("A","B","C","D") /obj/item/integrated_circuit/transfer/splitter/large name = "eight splitter" icon_state = "splitter8" complexity = 9 - number_of_inputs = 1 - number_of_outputs = 8 + outputs = list("A","B","C","D","E","F","G","H") -/obj/item/integrated_circuit/transfer/splitter/work() - if(..()) - var/datum/integrated_io/I = inputs[1] - for(var/datum/integrated_io/output/O in outputs) - O.data = I.data +/obj/item/integrated_circuit/transfer/splitter/do_work() + var/datum/integrated_io/I = inputs[1] + for(var/datum/integrated_io/output/O in outputs) + O.data = I.data /obj/item/integrated_circuit/transfer/activator_splitter name = "activator splitter" desc = "Splits incoming activation pulses into all of the output pins." icon_state = "splitter" complexity = 3 - number_of_activators = 3 - activator_names = list( + activators = list( "incoming pulse", "outgoing pulse A", - "outgoing pulse B", - "outgoing pulse C", - "outgoing pulse D", - "outgoing pulse E", - "outgoing pulse F", - "outgoing pulse G", - "outgoing pulse H" + "outgoing pulse B" ) -/obj/item/integrated_circuit/transfer/activator_splitter/work() - if(..()) - for(var/datum/integrated_io/activate/A in outputs) - if(A == activators[1]) - continue - if(A.linked.len) - for(var/datum/integrated_io/activate/target in A.linked) - target.holder.work() +/obj/item/integrated_circuit/transfer/activator_splitter/do_work() + for(var/datum/integrated_io/activate/A in outputs) + if(A == activators[1]) + continue + if(A.linked.len) + for(var/datum/integrated_io/activate/target in A.linked) + target.holder.check_then_do_work() /obj/item/integrated_circuit/transfer/activator_splitter/medium name = "four activator splitter" icon_state = "splitter4" complexity = 5 - number_of_activators = 5 + activators = list( + "incoming pulse", + "outgoing pulse A", + "outgoing pulse B", + "outgoing pulse C", + "outgoing pulse D" + ) /obj/item/integrated_circuit/transfer/activator_splitter/large name = "eight activator splitter" icon_state = "splitter4" complexity = 9 - number_of_activators = 9 + activators = list( + "incoming pulse", + "outgoing pulse A", + "outgoing pulse B", + "outgoing pulse C", + "outgoing pulse D", + "outgoing pulse E", + "outgoing pulse F", + "outgoing pulse G", + "outgoing pulse H" + ) \ No newline at end of file diff --git a/code/modules/integrated_electronics/input_output.dm b/code/modules/integrated_electronics/input_output.dm index 42da3406547d1..3e8cff40f5508 100644 --- a/code/modules/integrated_electronics/input_output.dm +++ b/code/modules/integrated_electronics/input_output.dm @@ -8,37 +8,28 @@ name = "button" desc = "This tiny button must do something, right?" icon_state = "button" - number_of_inputs = 0 - number_of_outputs = 0 - number_of_activators = 1 complexity = 1 can_be_asked_input = 1 - activator_names = list( - "on pressed" - ) + inputs = list() + outputs = list() + activators = list("on pressed") /obj/item/integrated_circuit/input/button/ask_for_input(mob/user) //Bit misleading name for this specific use. var/datum/integrated_io/A = activators[1] if(A.linked.len) for(var/datum/integrated_io/activate/target in A.linked) - target.holder.work() + target.holder.check_then_do_work() user << "You press the button labeled '[src.name]'." /obj/item/integrated_circuit/input/numberpad name = "number pad" desc = "This small number pad allows someone to input a number into the system." icon_state = "numberpad" - number_of_inputs = 0 - number_of_outputs = 1 - number_of_activators = 1 complexity = 2 can_be_asked_input = 1 - output_names = list( - "number entered" - ) - activator_names = list( - "on entered" - ) + inputs = list() + outputs = list("number entered") + activators = list("on entered") /obj/item/integrated_circuit/input/numberpad/ask_for_input(mob/user) var/new_input = input(user, "Enter a number, please.","Number pad") as null|num @@ -53,21 +44,15 @@ name = "text pad" desc = "This small text pad allows someone to input a string into the system." icon_state = "textpad" - number_of_inputs = 0 - number_of_outputs = 1 - number_of_activators = 1 complexity = 2 can_be_asked_input = 1 - output_names = list( - "string entered" - ) - activator_names = list( - "on entered" - ) + inputs = list() + outputs = list("string entered") + activators = list("on entered") /obj/item/integrated_circuit/input/textpad/ask_for_input(mob/user) var/new_input = input(user, "Enter some words, please.","Number pad") as null|text - if(new_input && istext(new_input)) + if(istext(new_input)) var/datum/integrated_io/O = outputs[1] O.data = new_input O.push_data() @@ -78,53 +63,37 @@ name = "integrated medical analyser" desc = "A very small version of the common medical analyser. This allows the machine to know how healthy someone is." icon_state = "medscan" - number_of_inputs = 1 - number_of_outputs = 2 - number_of_activators = 1 complexity = 4 - input_names = list( - "target ref" - ) - output_names = list( - "total health %", - "total missing health" - ) - activator_names = list( - "scan" - ) + inputs = list("target ref") + outputs = list("total health %", "total missing health") + activators = list("scan") -/obj/item/integrated_circuit/input/med_scanner/work() - if(..()) - var/datum/integrated_io/I = inputs[1] - if(!I.data || !ishuman(I.data)) //Invalid input - return - var/mob/living/carbon/human/H = I.data - if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range. - var/total_health = round(H.health/H.maxHealth, 0.1)*100 - var/missing_health = H.maxHealth - H.health +/obj/item/integrated_circuit/input/med_scanner/do_work() + var/datum/integrated_io/I = inputs[1] + var/mob/living/carbon/human/H = I.data_as_type(/mob/living/carbon/human) + if(!istype(H)) //Invalid input + return + if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range. + var/total_health = round(H.health/H.maxHealth, 0.1)*100 + var/missing_health = H.maxHealth - H.health - var/datum/integrated_io/total = outputs[1] - var/datum/integrated_io/missing = outputs[2] + var/datum/integrated_io/total = outputs[1] + var/datum/integrated_io/missing = outputs[2] - total.data = total_health - missing.data = missing_health + total.data = total_health + missing.data = missing_health - for(var/datum/integrated_io/output/O in outputs) - O.push_data() + for(var/datum/integrated_io/output/O in outputs) + O.push_data() /obj/item/integrated_circuit/input/adv_med_scanner name = "integrated advanced medical analyser" desc = "A very small version of the common medical analyser. This allows the machine to know how healthy someone is. \ This type is much more precise, allowing the machine to know much more about the target than a normal analyzer." icon_state = "medscan_adv" - number_of_inputs = 1 - number_of_outputs = 7 - number_of_activators = 1 complexity = 12 - input_names = list( - "target ref" - ) - output_names = list( + inputs = list("target ref") + outputs = list( "total health %", "total missing health", "brute damage", @@ -133,68 +102,53 @@ "oxy damage", "clone damage" ) - activator_names = list( - "scan" - ) + activators = list("scan") -/obj/item/integrated_circuit/input/adv_med_scanner/work() - if(..()) - var/datum/integrated_io/I = inputs[1] - if(!I.data || !ishuman(I.data)) //Invalid input - return - var/mob/living/carbon/human/H = I.data - if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range. - var/total_health = round(H.health/H.maxHealth, 0.1)*100 - var/missing_health = H.maxHealth - H.health - - var/datum/integrated_io/total = outputs[1] - var/datum/integrated_io/missing = outputs[2] - var/datum/integrated_io/brute = outputs[3] - var/datum/integrated_io/burn = outputs[4] - var/datum/integrated_io/tox = outputs[5] - var/datum/integrated_io/oxy = outputs[6] - var/datum/integrated_io/clone = outputs[7] - - total.data = total_health - missing.data = missing_health - brute.data = H.getBruteLoss() - burn.data = H.getFireLoss() - tox.data = H.getToxLoss() - oxy.data = H.getOxyLoss() - clone.data = H.getCloneLoss() - - for(var/datum/integrated_io/output/O in outputs) - O.push_data() +/obj/item/integrated_circuit/input/adv_med_scanner/do_work() + var/datum/integrated_io/I = inputs[1] + var/mob/living/carbon/human/H = I.data_as_type(/mob/living/carbon/human) + if(!istype(H)) //Invalid input + return + if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range. + var/total_health = round(H.health/H.maxHealth, 0.1)*100 + var/missing_health = H.maxHealth - H.health + + var/datum/integrated_io/total = outputs[1] + var/datum/integrated_io/missing = outputs[2] + var/datum/integrated_io/brute = outputs[3] + var/datum/integrated_io/burn = outputs[4] + var/datum/integrated_io/tox = outputs[5] + var/datum/integrated_io/oxy = outputs[6] + var/datum/integrated_io/clone = outputs[7] + + total.data = total_health + missing.data = missing_health + brute.data = H.getBruteLoss() + burn.data = H.getFireLoss() + tox.data = H.getToxLoss() + oxy.data = H.getOxyLoss() + clone.data = H.getCloneLoss() + + for(var/datum/integrated_io/output/O in outputs) + O.push_data() /obj/item/integrated_circuit/input/local_locator name = "local locator" desc = "This is needed for certain devices that demand a reference for a target to act upon. This type only locates something \ that is holding the machine containing it." - number_of_inputs = 0 - number_of_outputs = 1 - number_of_activators = 1 - complexity = 4 - output_names = list( - "located ref" - ) - activator_names = list( - "locate" - ) - -/obj/item/integrated_circuit/input/local_locator/work() - if(..()) - var/mob/living/L = null - var/datum/integrated_io/O = outputs[1] - O.data = null - if(istype(src.loc, /obj/item/device/electronic_assembly)) // Check to make sure we're actually in a machine. - var/obj/item/device/electronic_assembly/assembly = src.loc - if(istype(assembly.loc, /mob/living)) // Now check if someone's holding us. - L = assembly.loc + inputs = list() + outputs = list("located ref") + activators = list("locate") - if(L) - O.data = L +/obj/item/integrated_circuit/input/local_locator/do_work() + var/datum/integrated_io/O = outputs[1] + O.data = null + if(istype(src.loc, /obj/item/device/electronic_assembly)) // Check to make sure we're actually in a machine. + var/obj/item/device/electronic_assembly/assembly = src.loc + if(istype(assembly.loc, /mob/living)) // Now check if someone's holding us. + O.data = weakref(assembly.loc) - O.push_data() + O.push_data() /obj/item/integrated_circuit/input/signaler name = "integrated signaler" @@ -203,37 +157,29 @@ The two input pins are to configure the integrated signaler's settings. Note that the frequency should not have a decimal in it. \ Meaning the default frequency is expressed as 1457, not 145.7. To send a signal, pulse the 'send signal' activator pin." icon_state = "signal" - number_of_inputs = 2 - number_of_outputs = 0 - number_of_activators = 2 complexity = 4 - input_names = list( - "frequency", - "code" - ) - activator_names = list( - "send signal", - "on signal received" - ) + inputs = list("frequency","code") + outputs = list() + activators = list("send signal","on signal received") + var/frequency = 1457 var/code = 30 var/datum/radio_frequency/radio_connection -/obj/item/integrated_circuit/input/signaler/New() +/obj/item/integrated_circuit/input/signaler/initialize() ..() - spawn(4 SECONDS) - set_frequency(frequency) - var/datum/integrated_io/new_freq = inputs[1] - var/datum/integrated_io/new_code = inputs[2] - // Set the pins so when someone sees them, they won't show as null - new_freq.data = frequency - new_code.data = code + set_frequency(frequency) + var/datum/integrated_io/new_freq = inputs[1] + var/datum/integrated_io/new_code = inputs[2] + // Set the pins so when someone sees them, they won't show as null + new_freq.data = frequency + new_code.data = code /obj/item/integrated_circuit/input/signaler/Destroy() if(radio_controller) radio_controller.remove_object(src,frequency) frequency = 0 - ..() + . = ..() /obj/item/integrated_circuit/input/signaler/on_data_written() var/datum/integrated_io/new_freq = inputs[1] @@ -244,16 +190,15 @@ code = new_code.data -/obj/item/integrated_circuit/input/signaler/work() // Sends a signal. - if(..()) - if(!radio_connection) - return +/obj/item/integrated_circuit/input/signaler/do_work() // Sends a signal. + if(!radio_connection) + return - var/datum/signal/signal = new() - signal.source = src - signal.encryption = code - signal.data["message"] = "ACTIVATE" - radio_connection.post_signal(src, signal) + var/datum/signal/signal = new() + signal.source = src + signal.encryption = code + signal.data["message"] = "ACTIVATE" + radio_connection.post_signal(src, signal) /obj/item/integrated_circuit/input/signaler/proc/set_frequency(new_frequency) if(!frequency) @@ -282,10 +227,9 @@ var/datum/integrated_io/A = activators[2] A.push_data() - for(var/mob/O in hearers(1, src.loc)) + for(var/mob/O in hearers(1, get_turf(src))) O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2) - /obj/item/integrated_circuit/input/EPv2 name = "\improper EPv2 circuit" desc = "Enables the sending and receiving of messages on the Exonet with the EPv2 protocol." @@ -293,31 +237,17 @@ second pin on each side, with additonal data reserved for the third pin. When a message is received, the second activaiton pin \ will pulse whatever's connected to it. Pulsing the first activation pin will send a message." icon_state = "signal" - number_of_inputs = 3 - number_of_outputs = 3 - number_of_activators = 2 complexity = 4 - input_names = list( - "target EPv2 address", - "data to send", - "secondary text" - ) - output_names = list( - "address received", - "data received", - "secondary text received" - ) - activator_names = list( - "send data", - "on data received" - ) + inputs = list("target EPv2 address", "data to send", "secondary text") + outputs = list("address received", "data received", "secondary text received") + activators = list("send data", "on data received") var/datum/exonet_protocol/exonet = null /obj/item/integrated_circuit/input/EPv2/New() ..() exonet = new(src) exonet.make_address("EPv2_circuit-\ref[src]") - desc += "This circuit's EPv2 address is: [exonet.address]." + desc += "
This circuit's EPv2 address is: [exonet.address]." /obj/item/integrated_circuit/input/EPv2/Destroy() if(exonet) @@ -325,13 +255,12 @@ qdel(exonet) ..() -/obj/item/integrated_circuit/input/EPv2/work() - if(..()) - var/datum/integrated_io/target_address = inputs[1] - var/datum/integrated_io/message = inputs[2] - var/datum/integrated_io/text = inputs[3] - if(istext(target_address.data)) - exonet.send_message(target_address.data, message.data, text.data) +/obj/item/integrated_circuit/input/EPv2/do_work() + var/datum/integrated_io/target_address = inputs[1] + var/datum/integrated_io/message = inputs[2] + var/datum/integrated_io/text = inputs[3] + if(istext(target_address.data)) + exonet.send_message(target_address.data, message.data, text.data) /obj/item/integrated_circuit/input/receive_exonet_message(var/atom/origin_atom, var/origin_address, var/message, var/text) var/datum/integrated_io/message_received = outputs[1] @@ -349,42 +278,35 @@ name = "screen" desc = "This small screen can display a single piece of data, when the machine is examined closely." icon_state = "screen" - complexity = 4 - number_of_inputs = 1 - number_of_outputs = 0 - number_of_activators = 1 - input_names = list( - "displayed data" - ) - activator_names = list( - "load data" - ) + inputs = list("displayed data") + outputs = list() + activators = list("load data") var/stuff_to_display = null -/obj/item/integrated_circuit/output/screen/work() +/obj/item/integrated_circuit/output/screen/do_work() var/datum/integrated_io/I = inputs[1] - stuff_to_display = I.data + if(isweakref(I.data)) + var/datum/d = I.data_as_type(/datum) + if(d) + stuff_to_display = "[d]" + else + stuff_to_display = I.data /obj/item/integrated_circuit/output/light name = "light" desc = "This light can turn on and off on command." icon_state = "light_adv" -// icon_state = "light" complexity = 4 - number_of_inputs = 0 - number_of_outputs = 0 - number_of_activators = 1 - activator_names = list( - "toggle light" - ) + inputs = list() + outputs = list() + activators = list("toggle light") var/light_toggled = 0 var/light_brightness = 3 var/light_rgb = "#FFFFFF" -/obj/item/integrated_circuit/output/light/work() - if(..()) - light_toggled = !light_toggled - update_lighting() +/obj/item/integrated_circuit/output/light/do_work() + light_toggled = !light_toggled + update_lighting() /obj/item/integrated_circuit/output/light/proc/update_lighting() if(light_toggled) @@ -413,15 +335,13 @@ desc = "This light can turn on and off on command, in any color, and in various brightness levels." icon_state = "light_adv" complexity = 8 - number_of_inputs = 4 - number_of_outputs = 0 - number_of_activators = 1 - input_names = list( + inputs = list( "R", "G", "B", "Brightness" ) + outputs = list() /obj/item/integrated_circuit/output/light/advanced/on_data_written() update_lighting() @@ -432,38 +352,43 @@ icon_state = "speaker" complexity = 8 cooldown_per_use = 4 SECONDS - number_of_inputs = 3 - number_of_outputs = 0 - number_of_activators = 1 - input_names = list( + inputs = list( "sound ID", "volume", "frequency" ) - activator_names = list( - "play sound" - ) + outputs = list() + activators = list("play sound") var/list/sounds = list() + category = /obj/item/integrated_circuit/output/sound -/obj/item/integrated_circuit/output/sound/work() - if(..()) - var/datum/integrated_io/ID = inputs[1] - var/datum/integrated_io/vol = inputs[2] - var/datum/integrated_io/frequency = inputs[3] - if(istext(ID.data) && isnum(vol.data) && isnum(frequency.data)) - var/selected_sound = sounds[ID.data] - vol.data = Clamp(vol.data, 0, 1) - frequency.data = Clamp(frequency.data, 0, 100) - playsound(get_turf(src), selected_sound, vol.data, frequency.data, -1) +/obj/item/integrated_circuit/output/sound/New() + ..() + extended_desc = list() + extended_desc += "The first input pin determines which sound is used. The choices are; " + extended_desc += jointext(sounds, ", ") + extended_desc += ". The second pin determines the volume of sound that is played" + extended_desc += ", and the third determines if the frequency of the sound will vary with each activation." + extended_desc = jointext(extended_desc, null) + +/obj/item/integrated_circuit/output/sound/do_work() + var/datum/integrated_io/ID = inputs[1] + var/datum/integrated_io/vol = inputs[2] + var/datum/integrated_io/frequency = inputs[3] + if(istext(ID.data) && isnum(vol.data) && isnum(frequency.data)) + var/selected_sound = sounds[ID.data] + if(!selected_sound) + world << "No sound" + return + vol.data = Clamp(vol.data, 0, 100) + frequency.data = round(Clamp(frequency.data, 0, 1)) + playsound(get_turf(src), selected_sound, vol.data, frequency.data, -1) /obj/item/integrated_circuit/output/sound/beeper name = "beeper circuit" desc = "A miniature speaker is attached to this component. This is often used in the construction of motherboards, which use \ the speaker to tell the user if something goes very wrong when booting up. It can also do other similar synthetic sounds such \ as buzzing, pinging, chiming, and more." - extended_desc = "The first input pin determines what sound is used. The choices are; beep, chime, buzz sigh, buzz twice, ping, \ - synth yes, synth no, warning buzz. The second pin determines the volume of sound that is played, and the third determines if \ - the frequency of the sound will vary with each activation." sounds = list( "beep" = 'sound/machines/twobeep.ogg', "chime" = 'sound/machines/chime.ogg', @@ -478,9 +403,6 @@ /obj/item/integrated_circuit/output/sound/beepsky name = "securitron sound circuit" desc = "A miniature speaker is attached to this component. Considered by some to be the essential component for a securitron." - extended_desc = "The first input pin determines what sound is used. The choices are; creep, criminal, freeze, god, \ - i am the law, insult, radio, secure day. The second pin determines the volume of sound that is played, and the \ - third determines if the frequency of the sound will vary with each activation." sounds = list( "creep" = 'sound/voice/bcreep.ogg', "criminal" = 'sound/voice/bcriminal.ogg', diff --git a/code/modules/integrated_electronics/logic.dm b/code/modules/integrated_electronics/logic.dm index 4d123c61d097b..cb4fc55f3587f 100644 --- a/code/modules/integrated_electronics/logic.dm +++ b/code/modules/integrated_electronics/logic.dm @@ -1,172 +1,106 @@ /obj/item/integrated_circuit/logic 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 - number_of_inputs = 2 - number_of_outputs = 1 - number_of_activators = 2 - input_names = list( - "A", - "B" - ) - output_names = list( - "result" - ) - activator_names = list( - "compare", - "on true result" - ) - -/obj/item/integrated_circuit/logic/equals + outputs = list("result") + activators = list("compare", "on true result") + category = /obj/item/integrated_circuit/logic + +/obj/item/integrated_circuit/logic/do_work() + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + O.push_data() + if(O.data) + P.push_data() + +/obj/item/integrated_circuit/logic/binary + inputs = list("A","B") + category = /obj/item/integrated_circuit/logic/binary + +/obj/item/integrated_circuit/logic/binary/do_work() + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + O.data = do_compare(A, B) ? TRUE : FALSE + ..() + +/obj/item/integrated_circuit/logic/binary/proc/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) + return FALSE + +/obj/item/integrated_circuit/logic/unary + inputs = list("A") + category = /obj/item/integrated_circuit/logic/unary + +/obj/item/integrated_circuit/logic/unary/do_work() + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/O = outputs[1] + O.data = do_check(A) ? TRUE : FALSE + ..() + +/obj/item/integrated_circuit/logic/unary/proc/do_check(var/datum/integrated_io/A) + return FALSE + +/obj/item/integrated_circuit/logic/binary/equals name = "equal gate" desc = "This gate compares two values, and outputs the number one if both are the same." icon_state = "equal" -/obj/item/integrated_circuit/logic/equals/work() - if(..()) - var/datum/integrated_io/A = inputs[1] - var/datum/integrated_io/B = inputs[2] - var/datum/integrated_io/O = outputs[1] - var/datum/integrated_io/P = activators[2] - if(A.data == B.data) - O.data = 1 - O.push_data() - P.push_data() - else - O.data = 0 - -/obj/item/integrated_circuit/logic/not - name = "not gate" - desc = "This gate inverts what's fed into it." - icon_state = "not" - number_of_inputs = 1 - number_of_outputs = 1 - number_of_activators = 1 - output_names = list( - "invert" - ) - - -/obj/item/integrated_circuit/logic/not/work() - if(..()) - var/datum/integrated_io/A = inputs[1] - var/datum/integrated_io/O = outputs[1] - if(A.data) - O.data = !A.data - O.push_data() - else - O.data = 0 - -/obj/item/integrated_circuit/logic/and +/obj/item/integrated_circuit/logic/binary/equals/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) + return A.data == B.data + +/obj/item/integrated_circuit/logic/binary/and name = "and gate" desc = "This gate will output 'one' if both inputs evaluate to true." icon_state = "and" -/obj/item/integrated_circuit/logic/and/work() - if(..()) - var/datum/integrated_io/A = inputs[1] - var/datum/integrated_io/B = inputs[2] - var/datum/integrated_io/O = outputs[1] - var/datum/integrated_io/P = activators[2] - if(A.data && B.data) - O.data = 1 - O.push_data() - A.push_data() - P.push_data() - else - O.data = 0 - -/obj/item/integrated_circuit/logic/or +/obj/item/integrated_circuit/logic/binary/and/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) + return A.data && B.data + +/obj/item/integrated_circuit/logic/binary/or name = "or gate" desc = "This gate will output 'one' if one of the inputs evaluate to true." icon_state = "or" -/obj/item/integrated_circuit/logic/or/work() - if(..()) - var/datum/integrated_io/A = inputs[1] - var/datum/integrated_io/B = inputs[2] - var/datum/integrated_io/O = outputs[1] - var/datum/integrated_io/P = activators[2] - if(A.data || B.data) - O.data = 1 - O.push_data() - A.push_data() - P.push_data() - else - O.data = 0 - -/obj/item/integrated_circuit/logic/less_than +/obj/item/integrated_circuit/logic/binary/or/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) + return A.data || B.data + +/obj/item/integrated_circuit/logic/binary/less_than name = "less than gate" desc = "This will output 'one' if the first input is less than the second input." icon_state = "less_than" -/obj/item/integrated_circuit/logic/less_than/work() - if(..()) - var/datum/integrated_io/A = inputs[1] - var/datum/integrated_io/B = inputs[2] - var/datum/integrated_io/O = outputs[1] - var/datum/integrated_io/P = activators[2] - if(A.data < B.data) - O.data = 1 - O.push_data() - A.push_data() - P.push_data() - else - O.data = 0 - -/obj/item/integrated_circuit/logic/less_than_or_equal +/obj/item/integrated_circuit/logic/binary/less_than/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) + return A.data < B.data + +/obj/item/integrated_circuit/logic/binary/less_than_or_equal name = "less than or equal gate" desc = "This will output 'one' if the first input is less than, or equal to the second input." icon_state = "less_than_or_equal" -/obj/item/integrated_circuit/logic/less_than_or_equal/work() - if(..()) - var/datum/integrated_io/A = inputs[1] - var/datum/integrated_io/B = inputs[2] - var/datum/integrated_io/O = outputs[1] - var/datum/integrated_io/P = activators[2] - if(A.data <= B.data) - O.data = 1 - O.push_data() - A.push_data() - P.push_data() - else - O.data = 0 - -/obj/item/integrated_circuit/logic/greater_than +/obj/item/integrated_circuit/logic/binary/less_than_or_equal/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) + return A.data <= B.data + +/obj/item/integrated_circuit/logic/binary/greater_than name = "greater than gate" desc = "This will output 'one' if the first input is greater than the second input." icon_state = "greater_than" -/obj/item/integrated_circuit/logic/greater_than/work() - if(..()) - var/datum/integrated_io/A = inputs[1] - var/datum/integrated_io/B = inputs[2] - var/datum/integrated_io/O = outputs[1] - var/datum/integrated_io/P = activators[2] - if(A.data > B.data) - O.data = 1 - O.push_data() - A.push_data() - P.push_data() - else - O.data = 0 - -/obj/item/integrated_circuit/logic/greater_than_or_equal +/obj/item/integrated_circuit/logic/binary/greater_than/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) + return A.data > B.data + +/obj/item/integrated_circuit/logic/binary/greater_than_or_equal name = "greater_than or equal gate" desc = "This will output 'one' if the first input is greater than, or equal to the second input." icon_state = "greater_than_or_equal" -/obj/item/integrated_circuit/logic/greater_than_or_equal/work() - if(..()) - var/datum/integrated_io/A = inputs[1] - var/datum/integrated_io/B = inputs[2] - var/datum/integrated_io/O = outputs[1] - var/datum/integrated_io/P = activators[2] - if(A.data >= B.data) - O.data = 1 - O.push_data() - A.push_data() - P.push_data() - else - O.data = 0 \ No newline at end of file +/obj/item/integrated_circuit/logic/binary/greater_than_or_equal/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) + return A.data >= B.data + +/obj/item/integrated_circuit/logic/unary/not + name = "not gate" + desc = "This gate inverts what's fed into it." + icon_state = "not" + +/obj/item/integrated_circuit/logic/unary/not/do_check(var/datum/integrated_io/A) + return !A.data \ No newline at end of file diff --git a/code/modules/integrated_electronics/manipulation.dm b/code/modules/integrated_electronics/manipulation.dm index 05fdc1f23f034..35d9b445eb854 100644 --- a/code/modules/integrated_electronics/manipulation.dm +++ b/code/modules/integrated_electronics/manipulation.dm @@ -6,14 +6,12 @@ The 'fire' activator will cause the mechanism to attempt to fire the weapon at the coordinates, if possible. Note that the \ normal limitations to firearms, such as ammunition requirements and firing delays, still hold true if fired by the mechanism." complexity = 20 - number_of_inputs = 2 - number_of_outputs = 0 - number_of_activators = 1 - input_names = list( + inputs = list( "target X rel", "target Y rel" ) - activator_names = list( + outputs = list() + activators = list( "fire" ) var/obj/item/weapon/gun/installed_gun = null @@ -46,7 +44,7 @@ else user << "There's no weapon to remove from the mechanism." -/obj/item/integrated_circuit/manipulation/weapon_firing/work() +/obj/item/integrated_circuit/manipulation/weapon_firing/do_work() if(..()) if(!installed_gun) return @@ -86,8 +84,7 @@ if(!T) return - installed_gun.shoot_live_shot(null, 0, T, 1) - //installed_gun.Fire_userless(T) + installed_gun.Fire_userless(T) /obj/item/integrated_circuit/manipulation/smoke name = "smoke generator" @@ -97,32 +94,28 @@ into the smoke clouds when activated." flags = OPENCONTAINER complexity = 20 - number_of_inputs = 0 - number_of_outputs = 0 - number_of_activators = 1 - cooldown_per_use = 5 SECONDS - input_names = list() - activator_names = list( - "create smoke" - ) + cooldown_per_use = 30 SECONDS + inputs = list() + outputs = list() + activators = list("create smoke") /obj/item/integrated_circuit/manipulation/smoke/New() ..() create_reagents(100) -/obj/item/integrated_circuit/manipulation/smoke/work() - if(..()) - playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3) - var/datum/effect/effect/system/smoke_spread/chem/smoke_system = new() - smoke_system.set_up(reagents, 10, 0, get_turf(src)) - spawn(0) - for(var/i = 1 to 8) - smoke_system.start() - reagents.clear_reagents() +/obj/item/integrated_circuit/manipulation/smoke/do_work() + playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3) + var/datum/effect/effect/system/smoke_spread/chem/smoke_system = new() + smoke_system.set_up(reagents, 10, 0, get_turf(src)) + spawn(0) + for(var/i = 1 to 8) + smoke_system.start() + reagents.clear_reagents() /obj/item/integrated_circuit/manipulation/locomotion name = "locomotion circuit" desc = "This allows a machine to move in a given direction." + icon_state = "locomotion" extended_desc = "The circuit accepts a number as a direction to move towards.
\ North/Fore = 1,
\ South/Aft = 2,
\ @@ -136,24 +129,18 @@ Pulsing the 'step towards dir' activator pin will cause the machine to move a meter in that direction, assuming it is not \ being held, or anchored in some way." complexity = 20 - number_of_inputs = 1 - number_of_outputs = 0 - number_of_activators = 1 - input_names = list( - "dir num" - ) - activator_names = list( - "step towards dir" - ) + inputs = list("dir num") + outputs = list() + activators = list("step towards dir") -/obj/item/integrated_circuit/manipulation/locomotion/work() - if(..()) - var/turf/T = get_turf(src) - if(istype(loc, /obj/item/device/electronic_assembly)) - var/obj/item/device/electronic_assembly/machine = loc - if(machine.anchored || machine.w_class >= 4) - return - if(machine.loc && machine.loc == T) // Check if we're held by someone. If the loc is the floor, we're not held. - var/datum/integrated_io/wanted_dir = inputs[1] - if(isnum(wanted_dir.data)) - step(machine, wanted_dir.data) \ No newline at end of file +/obj/item/integrated_circuit/manipulation/locomotion/do_work() + ..() + var/turf/T = get_turf(src) + if(istype(loc, /obj/item/device/electronic_assembly)) + var/obj/item/device/electronic_assembly/machine = loc + if(machine.anchored || machine.w_class >= 4) + return + if(machine.loc && machine.loc == T) // Check if we're held by someone. If the loc is the floor, we're not held. + var/datum/integrated_io/wanted_dir = inputs[1] + if(isnum(wanted_dir.data)) + step(machine, wanted_dir.data) \ No newline at end of file diff --git a/code/modules/integrated_electronics/memory.dm b/code/modules/integrated_electronics/memory.dm index 8599cc2aed2f5..ce9a15e6652f2 100644 --- a/code/modules/integrated_electronics/memory.dm +++ b/code/modules/integrated_electronics/memory.dm @@ -3,72 +3,124 @@ desc = "This tiny chip can store one piece of data." icon_state = "memory" complexity = 1 - number_of_inputs = 1 - number_of_outputs = 1 - number_of_activators = 1 - activator_names = list( - "set" - ) + inputs = list("input pin 1") + outputs = list("output pin 1") + activators = list("set") + category = /obj/item/integrated_circuit/memory /obj/item/integrated_circuit/memory/examine(mob/user) ..() var/i for(i = 1, i <= outputs.len, i++) var/datum/integrated_io/O = outputs[i] - user << "\The [src] has [O.data ? "'O.data'" : "nothing"] saved to address [i]." + var/data = "nothing" + if(isweakref(O.data)) + var/datum/d = O.data_as_type(/datum) + if(d) + data = "[d]" + else if(!isnull(O.data)) + data = O.data + user << "\The [src] has [data] saved to address [i]." -/obj/item/integrated_circuit/memory/work() - if(..()) - var/i - for(i = 1, i <= inputs.len, i++) - var/datum/integrated_io/I = inputs[i] - var/datum/integrated_io/O = outputs[i] - O.data = I.data +/obj/item/integrated_circuit/memory/do_work() + for(var/i = 1 to inputs.len) + var/datum/integrated_io/I = inputs[i] + var/datum/integrated_io/O = outputs[i] + O.data = I.data /obj/item/integrated_circuit/memory/medium name = "memory circuit" desc = "This circuit can store four pieces of data." icon_state = "memory4" complexity = 4 - number_of_inputs = 4 - number_of_outputs = 4 + inputs = list("input pin 1","input pin 2","input pin 3","input pin 4") + outputs = list("output pin 1","output pin 2","output pin 3","output pin 4") /obj/item/integrated_circuit/memory/large name = "large memory circuit" desc = "This big circuit can hold eight pieces of data." icon_state = "memory8" complexity = 8 - number_of_inputs = 8 - number_of_outputs = 8 + inputs = list( + "input pin 1", + "input pin 2", + "input pin 3", + "input pin 4", + "input pin 5", + "input pin 6", + "input pin 7", + "input pin 8") + outputs = list( + "output pin 1", + "output pin 2", + "output pin 3", + "output pin 4", + "output pin 5", + "output pin 6", + "output pin 7", + "output pin 8") /obj/item/integrated_circuit/memory/huge name = "large memory stick" desc = "This stick of memory can hold up up to sixteen pieces of data." icon_state = "memory16" complexity = 16 - number_of_inputs = 16 - number_of_outputs = 16 + inputs = list( + "input pin 1", + "input pin 2", + "input pin 3", + "input pin 4", + "input pin 5", + "input pin 6", + "input pin 7", + "input pin 8", + "input pin 9", + "input pin 10", + "input pin 11", + "input pin 12", + "input pin 13", + "input pin 14", + "input pin 15", + "input pin 16" + ) + outputs = list( + "output pin 1", + "output pin 2", + "output pin 3", + "output pin 4", + "output pin 5", + "output pin 6", + "output pin 7", + "output pin 8", + "output pin 9", + "output pin 10", + "output pin 11", + "output pin 12", + "output pin 13", + "output pin 14", + "output pin 15", + "output pin 16") /obj/item/integrated_circuit/memory/constant name = "constant chip" desc = "This tiny chip can store one piece of data, which cannot be overwritten without disassembly." icon_state = "memory" complexity = 1 - number_of_inputs = 0 - number_of_outputs = 1 - number_of_activators = 1 - activator_names = list( - "push data" - ) + inputs = list() + outputs = list("output pin") + activators = list("push data") var/accepting_refs = 0 -/obj/item/integrated_circuit/memory/constant/work() +/obj/item/integrated_circuit/memory/constant/do_work() var/datum/integrated_io/O = outputs[1] O.push_data() /obj/item/integrated_circuit/memory/constant/attack_self(mob/user) var/datum/integrated_io/O = outputs[1] var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref", "null") + //if(!CanInteract(user,src)) + // return + var/new_data = null switch(type_to_use) if("string") @@ -94,7 +146,7 @@ /obj/item/integrated_circuit/memory/constant/afterattack(atom/target, mob/living/user, proximity) if(accepting_refs && proximity) var/datum/integrated_io/O = outputs[1] - O.data = target + O.data = weakref(target) visible_message("[user] slides \a [src]'s over \the [target].") user << "You set \the [src]'s memory to a reference to [O.display_data()]. The ref scanner is \ now off." diff --git a/code/modules/integrated_electronics/time.dm b/code/modules/integrated_electronics/time.dm index 5a908a48dead3..6b1cb255a9ddd 100644 --- a/code/modules/integrated_electronics/time.dm +++ b/code/modules/integrated_electronics/time.dm @@ -2,60 +2,61 @@ name = "time circuit" desc = "Now you can build your own clock!" complexity = 2 - number_of_inputs = 0 - number_of_outputs = 0 + inputs = list() + outputs = list() + category = /obj/item/integrated_circuit/time /obj/item/integrated_circuit/time/delay name = "two-sec delay circuit" desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ This circuit is set to send a pulse after a delay of two seconds." - number_of_activators = 2 - var/delay = 20 - activator_names = list( - "incoming pulse", - "outgoing pulse" - ) - -/obj/item/integrated_circuit/time/delay/work() - if(..()) - var/datum/integrated_io/out_pulse = activators[2] - sleep(delay) - out_pulse.push_data() + icon_state = "delay-20" + var/delay = 2 SECONDS + activators = list("incoming pulse","outgoing pulse") + +/obj/item/integrated_circuit/time/delay/do_work() + set waitfor = 0 // Don't sleep in a proc that is called by a processor. It'll delay the entire thing + + var/datum/integrated_io/out_pulse = activators[2] + sleep(delay) + out_pulse.push_data() /obj/item/integrated_circuit/time/delay/five_sec name = "five-sec delay circuit" desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ This circuit is set to send a pulse after a delay of five seconds." - delay = 50 + icon_state = "delay-50" + delay = 5 SECONDS /obj/item/integrated_circuit/time/delay/one_sec name = "one-sec delay circuit" desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ This circuit is set to send a pulse after a delay of one second." - delay = 10 + icon_state = "delay-10" + delay = 1 SECONDS /obj/item/integrated_circuit/time/delay/half_sec name = "half-sec delay circuit" desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ This circuit is set to send a pulse after a delay of half a second." + icon_state = "delay-5" delay = 5 /obj/item/integrated_circuit/time/delay/tenth_sec name = "tenth-sec delay circuit" desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ This circuit is set to send a pulse after a delay of 1/10th of a second." + icon_state = "delay-1" delay = 1 /obj/item/integrated_circuit/time/delay/custom name = "custom delay circuit" desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ This circuit's delay can be customized, between 1/10th of a second to one hour. The delay is updated upon receiving a pulse." - number_of_inputs = 1 - input_names = list( - "delay time", - ) + icon_state = "delay" + inputs = list("delay time") -/obj/item/integrated_circuit/time/delay/custom/work() +/obj/item/integrated_circuit/time/delay/custom/do_work() var/datum/integrated_io/delay_input = inputs[1] if(delay_input.data && isnum(delay_input.data) ) var/new_delay = min(delay_input.data, 1) @@ -67,68 +68,71 @@ /obj/item/integrated_circuit/time/ticker name = "ticker circuit" desc = "This circuit sends an automatic pulse every four seconds." + icon_state = "tick-m" complexity = 8 - number_of_inputs = 1 - number_of_activators = 1 - var/ticks_to_pulse = 2 + var/ticks_to_pulse = 4 var/ticks_completed = 0 - input_names = list( - "toggle ticking" - ) - activator_names = list( - "outgoing pulse" - ) - -/obj/item/integrated_circuit/time/ticker/New() - ..() - //processing_objects |= src + var/is_running = FALSE + inputs = list("enable ticking") + activators = list("outgoing pulse") /obj/item/integrated_circuit/time/ticker/Destroy() - //processing_objects -= src + if(is_running) + SSmachine.processing -= src + . = ..() + +/obj/item/integrated_circuit/time/ticker/on_data_written() + var/datum/integrated_io/do_tick = inputs[1] + if(do_tick.data && !is_running) + is_running = TRUE + SSmachine.processing |= src + else if(is_running) + is_running = FALSE + SSmachine.processing -= src + ticks_completed = 0 /obj/item/integrated_circuit/time/ticker/process() - ticks_completed++ - if( (ticks_completed % ticks_to_pulse) == 0) + var/process_ticks = SSmachine.priority //process_schedule_interval("obj") + ticks_completed += process_ticks + if(ticks_completed >= ticks_to_pulse) + if(ticks_to_pulse >= process_ticks) + ticks_completed -= ticks_to_pulse + else + ticks_completed = 0 var/datum/integrated_io/pulser = activators[1] pulser.push_data() /obj/item/integrated_circuit/time/ticker/fast name = "fast ticker" desc = "This advanced circuit sends an automatic pulse every two seconds." + icon_state = "tick-f" complexity = 12 - ticks_to_pulse = 1 + ticks_to_pulse = 2 /obj/item/integrated_circuit/time/ticker/slow name = "slow ticker" desc = "This simple circuit sends an automatic pulse every six seconds." + icon_state = "tick-s" complexity = 4 - ticks_to_pulse = 3 - + ticks_to_pulse = 6 /obj/item/integrated_circuit/time/clock name = "integrated clock" desc = "Tells you what the local time is, specific to your station or planet." - number_of_inputs = 0 - number_of_outputs = 4 - number_of_activators = 1 - output_names = list( - "time (string)", - "hours (number)", - "minutes (number)", - "seconds (number)" - ) - -/obj/item/integrated_circuit/time/clock/work() - if(..()) - var/datum/integrated_io/time = outputs[1] - var/datum/integrated_io/hour = outputs[2] - var/datum/integrated_io/min = outputs[3] - var/datum/integrated_io/sec = outputs[4] - - time.data = time2text(world.time, "hh:mm:ss") - hour.data = text2num(time2text(world.time, "hh")) - min.data = text2num(time2text(world.time, "mm")) - sec.data = text2num(time2text(world.time, "ss")) - - for(var/datum/integrated_io/output/O in outputs) - O.push_data() \ No newline at end of file + icon_state = "clock" + inputs = list() + outputs = list("time (string)", "hours (number)", "minutes (number)", "seconds (number)") + +/obj/item/integrated_circuit/time/clock/do_work() + var/datum/integrated_io/time = outputs[1] + var/datum/integrated_io/hour = outputs[2] + var/datum/integrated_io/min = outputs[3] + var/datum/integrated_io/sec = outputs[4] + + time.data = time2text(world.time, "hh:mm:ss") + hour.data = text2num(time2text(world.time, "hh")) + min.data = text2num(time2text(world.time, "mm")) + sec.data = text2num(time2text(world.time, "ss")) + + for(var/datum/integrated_io/output/O in outputs) + O.push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/tools.dm b/code/modules/integrated_electronics/tools.dm index 6b1a2a0cc35ee..34947a1dbb680 100644 --- a/code/modules/integrated_electronics/tools.dm +++ b/code/modules/integrated_electronics/tools.dm @@ -117,6 +117,9 @@ /obj/item/device/integrated_electronics/debugger/attack_self(mob/user) var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref", "null") + //if(!CanInteract(user,src)) + // return + var/new_data = null switch(type_to_use) if("string") @@ -150,9 +153,14 @@ /obj/item/device/integrated_electronics/debugger/proc/write_data(var/datum/integrated_io/io, mob/user) if(io.io_type == DATA_CHANNEL) io.write_data_to_pin(data_to_write) - user << "You write [data_to_write] to \the [io.holder]'s [io]." + var/data_to_show = data_to_write + if(isweakref(data_to_write)) + var/weakref/w = data_to_write + var/atom/A = w.resolve() + data_to_show = A.name + 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.work() + io.holder.check_then_do_work() user << "You pulse \the [io.holder]'s [io]." io.holder.interact(user) // This is to update the UI. @@ -198,29 +206,32 @@ ) for(var/thing in types_to_spawn) - var/i = 3 - while(i) + var/obj/item/integrated_circuit/ic = thing + if(initial(ic.category) == thing) + continue + + for(var/i = 1 to 4) new thing(src) - i-- new /obj/item/device/electronic_assembly(src) new /obj/item/device/integrated_electronics/wirer(src) new /obj/item/device/integrated_electronics/debugger(src) new /obj/item/weapon/crowbar(src) new /obj/item/weapon/screwdriver(src) + make_exact_fit() /obj/item/weapon/storage/bag/circuits/all/New() ..() - var/list/types_to_spawn = typesof(/obj/item/integrated_circuit) - - for(var/thing in types_to_spawn) - var/i = 10 - while(i) + for(var/thing in subtypesof(/obj/item/integrated_circuit)) + var/obj/item/integrated_circuit/ic = thing + if(initial(ic.category) == thing) + continue + for(var/i = 1 to 10) new thing(src) - i-- new /obj/item/device/electronic_assembly(src) new /obj/item/device/integrated_electronics/wirer(src) new /obj/item/device/integrated_electronics/debugger(src) new /obj/item/weapon/crowbar(src) - new /obj/item/weapon/screwdriver(src) \ No newline at end of file + new /obj/item/weapon/screwdriver(src) + make_exact_fit() \ No newline at end of file diff --git a/code/modules/integrated_electronics/~defines.dm b/code/modules/integrated_electronics/~defines.dm new file mode 100644 index 0000000000000..7aea6dabbb938 --- /dev/null +++ b/code/modules/integrated_electronics/~defines.dm @@ -0,0 +1,6 @@ +#undef IC_INPUT +#undef IC_OUTPUT +#undef IC_ACTIVATOR + +#undef DATA_CHANNEL +#undef PULSE_CHANNEL \ No newline at end of file diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index b44cf20f3e6e2..f5e71cee29ca5 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -230,45 +230,49 @@ user.update_inv_r_hand(0) return fired -/*// Similar to the above proc, but does not require a user, which is ideal for things like turrets. +// Similar to the above proc, but does not require a user, which is ideal for things like turrets. /obj/item/weapon/gun/proc/Fire_userless(atom/target) if(!target) return - if(world.time < next_fire_time) + if(world.time < semicd) return - var/shoot_time = (burst - 1)* burst_delay - next_fire_time = world.time + shoot_time + var/shoot_time = (burst_size - 1)* fire_delay + semicd = world.time + shoot_time var/turf/targloc = get_turf(target) //cache this in case target gets deleted during shooting, e.g. if it was a securitron that got destroyed. - for(var/i in 1 to burst) - var/obj/projectile = consume_next_projectile() + for(var/i in 1 to burst_size) + var/obj/projectile = process_chamber() if(!projectile) - handle_click_empty() + src.visible_message("*click*") + //handle_click_empty() break if(istype(projectile, /obj/item/projectile)) var/obj/item/projectile/P = projectile + //Not supported, maybe later + /* var/acc = burst_accuracy[min(i, burst_accuracy.len)] var/disp = dispersion[min(i, dispersion.len)] P.accuracy = accuracy + acc P.dispersion = disp + */ + P.firer = src.name + P.suppressed = suppressed - P.shot_from = src.name - P.silenced = silenced + P.original = target + P.fire() - P.launch(target) - - if(silenced) + if(suppressed) playsound(src, fire_sound, 10, 1) else playsound(src, fire_sound, 50, 1) - if(muzzle_flash) - set_light(muzzle_flash) + //if(muzzle_flash) //Not supported, maybe later + //set_light(muzzle_flash) update_icon() //process_accuracy(projectile, user, target, acc, disp) @@ -281,23 +285,23 @@ // update_icon() - if(i < burst) - sleep(burst_delay) + if(i < burst_size) + sleep(fire_delay) if(!(target && target.loc)) target = targloc //pointblank = 0 - log_and_message_admins("Fired [src].") + //log_and_message_admins("Fired [src].") //admin_attack_log(usr, attacker_message="Fired [src]", admin_message="fired a gun ([src]) (MODE: [src.mode_name]) [reflex ? "by reflex" : "manually"].") //update timing - next_fire_time = world.time + fire_delay + semicd = world.time + fire_delay + + //if(muzzle_flash) + //set_light(0) - if(muzzle_flash) - set_light(0) -*/ /obj/item/weapon/gun/attack(mob/M as mob, mob/user) if (M == user && user.zone_sel.selecting == "mouth" && !mouthshoot && ishuman(user)) //Handle gun suicide diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index 12946977867e5..ae5778c808e78 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -684,37 +684,37 @@ other types of metals and chemistry for reagents). ..() name = "Custom circuitry \[Logic\] ([item_name])" -/datum/design/circuit/integrated_circuit/logic/equals +/datum/design/circuit/integrated_circuit/logic/binary/equals id = "cc-equals" - build_path = /obj/item/integrated_circuit/logic/equals + build_path = /obj/item/integrated_circuit/logic/binary/equals -/datum/design/circuit/integrated_circuit/logic/not +/datum/design/circuit/integrated_circuit/logic/unary/not id = "cc-not" - build_path = /obj/item/integrated_circuit/logic/not + build_path = /obj/item/integrated_circuit/logic/unary/not -/datum/design/circuit/integrated_circuit/logic/and +/datum/design/circuit/integrated_circuit/logic/binary/and id = "cc-and" - build_path = /obj/item/integrated_circuit/logic/and + build_path = /obj/item/integrated_circuit/logic/binary/and -/datum/design/circuit/integrated_circuit/logic/or +/datum/design/circuit/integrated_circuit/logic/binary/or id = "cc-or" - build_path = /obj/item/integrated_circuit/logic/or + build_path = /obj/item/integrated_circuit/logic/binary/or -/datum/design/circuit/integrated_circuit/logic/less_than +/datum/design/circuit/integrated_circuit/logic/binary/less_than id = "cc-less_than" - build_path = /obj/item/integrated_circuit/logic/less_than + build_path = /obj/item/integrated_circuit/logic/binary/less_than -/datum/design/circuit/integrated_circuit/logic/less_than_or_equal +/datum/design/circuit/integrated_circuit/logic/binary/less_than_or_equal id = "cc-less_than_or_equal" - build_path = /obj/item/integrated_circuit/logic/less_than_or_equal + build_path = /obj/item/integrated_circuit/logic/binary/less_than_or_equal -/datum/design/circuit/integrated_circuit/logic/greater_than +/datum/design/circuit/integrated_circuit/logic/binary/greater_than id = "cc-greater_than" - build_path = /obj/item/integrated_circuit/logic/greater_than + build_path = /obj/item/integrated_circuit/logic/binary/greater_than -/datum/design/circuit/integrated_circuit/logic/greater_than_or_equal +/datum/design/circuit/integrated_circuit/logic/binary/greater_than_or_equal id = "cc-greater_than_or_equal" - build_path = /obj/item/integrated_circuit/logic/greater_than_or_equal + build_path = /obj/item/integrated_circuit/logic/binary/greater_than_or_equal diff --git a/tgstation.dme b/tgstation.dme index d73ccd96065a1..1c1ca76e67031 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -15,6 +15,7 @@ // BEGIN_INCLUDE #include "_maps\metastation.dm" #include "code\_compile_options.dm" +#include "code\_macros.dm" #include "code\hub.dm" #include "code\world.dm" #include "code\__DATASTRUCTURES\heap.dm" @@ -179,6 +180,7 @@ #include "code\datums\spell.dm" #include "code\datums\supplypacks.dm" #include "code\datums\uplink_item.dm" +#include "code\datums\weakref.dm" #include "code\datums\diseases\_disease.dm" #include "code\datums\diseases\_MobProcs.dm" #include "code\datums\diseases\anxiety.dm" @@ -1144,6 +1146,7 @@ #include "code\modules\integrated_electronics\memory.dm" #include "code\modules\integrated_electronics\time.dm" #include "code\modules\integrated_electronics\tools.dm" +#include "code\modules\integrated_electronics\~defines.dm" #include "code\modules\library\lib_items.dm" #include "code\modules\library\lib_machines.dm" #include "code\modules\library\lib_readme.dm" From 95e3c42e14f6efc9b7e7d954437e458e2e223373 Mon Sep 17 00:00:00 2001 From: Stakks Date: Wed, 18 Apr 2018 16:37:50 -0500 Subject: [PATCH 5/9] Stage 5 --- code/_macros.dm | 2 +- code/datums/weakref.dm | 2 + .../objects/items/weapons/implants/implant.dm | 11 + .../items/weapons/implants/implantcircuits.dm | 44 +++ .../integrated_electronics/_defines.dm | 66 +++- .../integrated_electronics/arithmetic.dm | 177 +++++++++- .../integrated_electronics/assemblies.dm | 60 +++- .../integrated_electronics/converters.dm | 72 +++- .../integrated_electronics/data_transfer.dm | 8 + .../integrated_electronics/input_output.dm | 155 ++++++++- code/modules/integrated_electronics/logic.dm | 8 +- .../integrated_electronics/manipulation.dm | 28 +- code/modules/integrated_electronics/memory.dm | 3 +- .../integrated_electronics/reagents.dm | 149 ++++++++ code/modules/integrated_electronics/time.dm | 1 - code/modules/integrated_electronics/tools.dm | 246 +++++++++---- code/modules/integrated_electronics/trig.dm | 135 ++++++++ .../reagents/Chemistry-Reagents-Helpers.dm | 17 + code/modules/research/designs.dm | 327 ------------------ icons/obj/electronic_assemblies.dmi | Bin 23986 -> 30877 bytes icons/obj/library.dmi | Bin 31000 -> 31251 bytes tgstation.dme | 30 +- 22 files changed, 1051 insertions(+), 490 deletions(-) create mode 100644 code/game/objects/items/weapons/implants/implantcircuits.dm create mode 100644 code/modules/integrated_electronics/reagents.dm create mode 100644 code/modules/integrated_electronics/trig.dm create mode 100644 code/modules/reagents/Chemistry-Reagents-Helpers.dm diff --git a/code/_macros.dm b/code/_macros.dm index 67267ab7cc26a..b3359678236e7 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -50,4 +50,4 @@ #define to_chat(target, message) target << message -//#define CanInteract(user,src) user.canUseTopic(src,0,0) //I'll figure this out later \ No newline at end of file +#define CanInteract(user,src) user.Adjacent(src) //changed so you need to be next to it is all \ No newline at end of file diff --git a/code/datums/weakref.dm b/code/datums/weakref.dm index 1b9f0b8d56c65..d225de991fb68 100644 --- a/code/datums/weakref.dm +++ b/code/datums/weakref.dm @@ -1,3 +1,5 @@ +#define QDELETED(X) (!X || X.gc_destroyed) + /datum var/weakref/weakref diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index e1c44eac0cd66..0bfa2a47bdee2 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -70,6 +70,17 @@ removed(imp_in) ..() +/obj/item/weapon/implant/attackby(obj/item/I, mob/user) + if(istype(I, /obj/item/weapon/implanter)) + var/obj/item/weapon/implanter/implanter = I + if(implanter.imp) + return // It's full. + user.remove_from_mob(src) + forceMove(implanter) + implanter.imp = src + implanter.update_icon() + else + ..() /obj/item/weapon/implant/proc/get_data() return "No information available" diff --git a/code/game/objects/items/weapons/implants/implantcircuits.dm b/code/game/objects/items/weapons/implants/implantcircuits.dm new file mode 100644 index 0000000000000..2843c4f28c534 --- /dev/null +++ b/code/game/objects/items/weapons/implants/implantcircuits.dm @@ -0,0 +1,44 @@ +/obj/item/weapon/implant/integrated_circuit + name = "electronic implant" + icon = 'icons/obj/electronic_assemblies.dmi' + icon_state = "setup_implant" + var/obj/item/device/electronic_assembly/implant/IC = null + +/obj/item/weapon/implant/integrated_circuit/proc/islegal() + return TRUE + +/obj/item/weapon/implant/integrated_circuit/New() + ..() + IC = new(src) + IC.implant = src + +/obj/item/weapon/implant/integrated_circuit/Destroy() + IC.implant = null + qdel(IC) + ..() + +/obj/item/weapon/implant/integrated_circuit/get_data() + var/dat = {" + Implant Specifications:
+ Name: Modular Implant
+ Life: 3 years.
+ Important Notes: EMP can cause malfunctions in the internal electronics of this implant.
+
+ Implant Details:
+ Function: Contains no innate functions until other components are added.
+ Special Features: + Modular Circuitry- Can be loaded with specific modular circuitry in order to fulfill a wide possibility of functions.
+ Integrity: Implant is not shielded from electromagnetic interferance, otherwise it is independant of subject's status."} + return dat + +/obj/item/weapon/implant/integrated_circuit/emp_act(severity) + IC.emp_act(severity) + +/obj/item/weapon/implant/integrated_circuit/examine(mob/user) + IC.examine(user) + +/obj/item/weapon/implant/integrated_circuit/attackby(var/obj/item/O, var/mob/user) + if(istype(O, /obj/item/weapon/crowbar) || istype(O, /obj/item/device/integrated_electronics) || istype(O, /obj/item/integrated_circuit) || istype(O, /obj/item/weapon/screwdriver) ) + IC.attackby(O, user) + else + ..() \ No newline at end of file diff --git a/code/modules/integrated_electronics/_defines.dm b/code/modules/integrated_electronics/_defines.dm index b5a4c4b786f69..e2cb92ea00dc4 100644 --- a/code/modules/integrated_electronics/_defines.dm +++ b/code/modules/integrated_electronics/_defines.dm @@ -5,6 +5,15 @@ #define DATA_CHANNEL "data channel" #define PULSE_CHANNEL "pulse channel" +#define IC_SPAWN_DEFAULT 1 // If the circuit comes in the default circuit box. +#define IC_SPAWN_RESEARCH 2 // If the circuit design will be autogenerated for RnD. + +var/list/all_integrated_circuits = list() + +/proc/initialize_integrated_circuits_list() + for(var/thing in typesof(/obj/item/integrated_circuit)) + all_integrated_circuits += new thing() + /obj/item/integrated_circuit name = "integrated circuit" desc = "It's a tiny chip! This one doesn't seem to do much, however." @@ -18,7 +27,9 @@ var/next_use = 0 //Uses world.time var/complexity = 1 //This acts as a limitation on building machines, more resource-intensive components cost more 'space'. var/cooldown_per_use = 1 SECONDS - var/category = /obj/item/integrated_circuit // Used by the toolsets to filter out category types + var/spawn_flags = null // Used for world initializing, see the #defines above. + var/category_text = "NO CATEGORY" // To show up on circuit printer, and perhaps other places. + var/autopulse = -1 // When input is received, the circuit will pulse itself if set to 1. 0 means it won't. -1 means it is permanently off. /obj/item/integrated_circuit/examine(mob/user) ..() @@ -42,10 +53,10 @@ ..() /obj/item/integrated_circuit/proc/setup_io(var/list/io_list, var/io_type) - var/list/names = io_list.Copy() + var/list/io_list_copy = io_list.Copy() io_list.Cut() - for(var/name in names) - io_list.Add(new io_type(src, name)) + for(var/io_entry in io_list_copy) + io_list.Add(new io_type(src, io_entry, io_list_copy[io_entry])) /obj/item/integrated_circuit/proc/on_data_written() //Override this for special behaviour when new data gets pushed to the circuit. return @@ -61,7 +72,8 @@ /obj/item/integrated_circuit/proc/nano_host() if(istype(src.loc, /obj/item/device/electronic_assembly)) - return loc + var/obj/item/device/electronic_assembly/assembly = loc + return assembly.resolve_nano_host() return ..() /obj/item/integrated_circuit/emp_act(severity) @@ -78,7 +90,7 @@ // return var/input = sanitize_text(input("What do you want to name the circuit?", "Rename", src.name) as null|text, MAX_NAME_LEN) - if(src && input) + if(src && input && CanInteract(M, src)) M << "The circuit '[src.name]' is now labeled '[input]'." name = input @@ -102,6 +114,14 @@ //if(!CanInteract(user,src)) // return + var/window_height = 350 + var/window_width = 600 + + //var/table_edge_width = "[(window_width - window_width * 0.1) / 4]px" + //var/table_middle_width = "[(window_width - window_width * 0.1) - (table_edge_width * 2)]px" + var/table_edge_width = "30%" + var/table_middle_width = "40%" + var/HTML = list() HTML += "[src.name]" HTML += "
" @@ -112,9 +132,12 @@ HTML += "\[Remove\]
" HTML += "" - HTML += "" - HTML += "" - HTML += "" + //HTML += "" + //HTML += "" + //HTML += "" + HTML += "" + HTML += "" + HTML += "" HTML += "" var/column_width = 3 @@ -186,11 +209,16 @@ HTML += "" HTML += "
" - HTML += "
Complexity: [complexity]" - HTML += "
[extended_desc]" + if(autopulse != -1) + HTML += "
Meta Variables;" + HTML += "
\[Autopulse\] = [autopulse ? "ON" : "OFF"]" + HTML += "
" + + HTML += "
Complexity: [complexity]" + HTML += "
[extended_desc]" HTML += "" - user << browse(jointext(HTML, null), "window=circuit-\ref[src];size=600x350;border=1;can_resize=1;can_close=1;can_minimize=1") + user << browse(jointext(HTML, null), "window=circuit-\ref[src];size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1") onclose(user, "circuit-\ref[src]") @@ -219,6 +247,10 @@ if(href_list["rename"]) rename_component(usr) + if(href_list["autopulse"]) + if(autopulse != -1) + autopulse = !autopulse + if(href_list["remove"]) if(istype(held_item, /obj/item/weapon/screwdriver)) disconnect_all() @@ -238,13 +270,14 @@ /datum/integrated_io var/name = "input/output" var/obj/item/integrated_circuit/holder = null - var/data = null + var/weakref/data = null // This is a weakref, to reduce typecasts. Note that oftentimes numbers and text may also occupy this. var/list/linked = list() var/io_type = DATA_CHANNEL -/datum/integrated_io/New(var/newloc, var/name) +/datum/integrated_io/New(var/newloc, var/name, var/data) ..() src.name = name + src.data = data holder = newloc if(!istype(holder)) message_admins("ERROR: An integrated_io ([src.name]) spawned without a valid holder! This is a bug.") @@ -256,7 +289,7 @@ . = ..() /datum/integrated_io/proc/nano_host() - return holder + return holder.nano_host() /datum/integrated_io/proc/data_as_type(var/as_type) @@ -274,7 +307,8 @@ if(isweakref(data)) var/weakref/w = data var/atom/A = w.resolve() - return A ? "([A.name] \[Ref\])" : "(null)" // For refs, we want just the name displayed. + //return A ? "([A.name] \[Ref\])" : "(null)" // For refs, we want just the name displayed. + return A ? "(\ref[A] \[Ref\])" : "(null)" return "([data])" // Nothing special needed for numbers or other stuff. /datum/integrated_io/activate/display_data() diff --git a/code/modules/integrated_electronics/arithmetic.dm b/code/modules/integrated_electronics/arithmetic.dm index 31265e297ec4c..9200fa1c00005 100644 --- a/code/modules/integrated_electronics/arithmetic.dm +++ b/code/modules/integrated_electronics/arithmetic.dm @@ -4,13 +4,21 @@ inputs = list("A","B","C","D","E","F","G","H") outputs = list("result") activators = list("compute") - category = /obj/item/integrated_circuit/arithmetic + category_text = "Arithmetic" + autopulse = 1 + +/obj/item/integrated_circuit/arithmetic/on_data_written() + if(autopulse == 1) + check_then_do_work() // +Adding+ // /obj/item/integrated_circuit/arithmetic/addition name = "addition circuit" desc = "This circuit can add numbers together." + extended_desc = "The order that the calculation goes is;
\ + result = ((((A + B) + C) + D) ... ) and so on, until all pins have been added. \ + Null pins are ignored." icon_state = "addition" /obj/item/integrated_circuit/arithmetic/addition/do_work() @@ -29,30 +37,47 @@ /obj/item/integrated_circuit/arithmetic/subtraction name = "subtraction circuit" desc = "This circuit can subtract numbers." + extended_desc = "The order that the calculation goes is;
\ + result = ((((A - B) - C) - D) ... ) and so on, until all pins have been subtracted. \ + Null pins are ignored. Pin A must be a number or the circuit will not function." icon_state = "subtraction" /obj/item/integrated_circuit/arithmetic/subtraction/do_work() - if(..()) - var/result = 0 - for(var/datum/integrated_io/input/I in inputs) - I.pull_data() - if(isnum(I.data)) - result = result - I.data + var/datum/integrated_io/A = inputs[1] + if(!isnum(A.data)) + return + var/result = A.data + + for(var/datum/integrated_io/input/I in inputs) + if(I == A) + continue + I.pull_data() + if(isnum(I.data)) + result = result - I.data - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() // *Multiply* // /obj/item/integrated_circuit/arithmetic/multiplication name = "multiplication circuit" desc = "This circuit can multiply numbers." + extended_desc = "The order that the calculation goes is;
\ + result = ((((A * B) * C) * D) ... ) and so on, until all pins have been multiplied. \ + Null pins are ignored. Pin A must be a number or the circuit will not function." icon_state = "multiplication" -/obj/item/integrated_circuit/arithmetic/subtraction/do_work() - var/result = 0 + +/obj/item/integrated_circuit/arithmetic/multiplication/do_work() + var/datum/integrated_io/A = inputs[1] + if(!isnum(A.data)) + return + var/result = A.data for(var/datum/integrated_io/input/I in inputs) + if(I == A) + continue I.pull_data() if(isnum(I.data)) result = result * I.data @@ -66,11 +91,20 @@ /obj/item/integrated_circuit/arithmetic/division name = "division circuit" desc = "This circuit can divide numbers, just don't think about trying to divide by zero!" + extended_desc = "The order that the calculation goes is;
\ + result = ((((A / B) / C) / D) ... ) and so on, until all pins have been divided. \ + Null pins, and pins containing 0, are ignored. Pin A must be a number or the circuit will not function." icon_state = "division" /obj/item/integrated_circuit/arithmetic/division/do_work() - var/result = 0 + var/datum/integrated_io/A = inputs[1] + if(!isnum(A.data)) + return + var/result = A.data + for(var/datum/integrated_io/input/I in inputs) + if(I == A) + continue I.pull_data() if(isnum(I.data) && I.data != 0) //No runtimes here. result = result / I.data @@ -79,6 +113,73 @@ O.data = result O.push_data() +//^ Exponent ^// + +/obj/item/integrated_circuit/arithmetic/exponent + name = "exponent circuit" + desc = "Outputs A to the power of B." + icon_state = "exponent" + inputs = list("A", "B") + +/obj/item/integrated_circuit/arithmetic/exponent/do_work() + var/result = 0 + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + if(isnum(A.data) && isnum(B.data)) + result = A.data ** B.data + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// +-Sign-+ // + +/obj/item/integrated_circuit/arithmetic/sign + name = "sign circuit" + desc = "This will say if a number is positive, negative, or zero." + extended_desc = "Will output 1, -1, or 0, depending on if A is a postive number, a negative number, or zero, respectively." + icon_state = "sign" + inputs = list("A") + +/obj/item/integrated_circuit/arithmetic/sign/do_work() + var/result = 0 + var/datum/integrated_io/A = inputs[1] + if(isnum(A.data)) + if(A.data > 0) + result = 1 + else if (A.data < 0) + result = -1 + else + result = 0 + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// Round // + +/obj/item/integrated_circuit/arithmetic/round + name = "round circuit" + desc = "Rounds A to the nearest B multiple of A." + extended_desc = "If B is not given a number, it will output the floor of A instead." + icon_state = "round" + inputs = list("A", "B") + +/obj/item/integrated_circuit/arithmetic/round/do_work() + var/result = 0 + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + if(isnum(A.data)) + if(isnum(B.data) && B.data != 0) + result = round(A.data, B.data) + else + result = round(A.data) + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + + // Absolute // /obj/item/integrated_circuit/arithmetic/absolute @@ -91,8 +192,8 @@ var/result = 0 for(var/datum/integrated_io/input/I in inputs) I.pull_data() - if(isnum(I.data) && I.data != 0) - result = abs(result) + if(isnum(I.data)) + result = abs(I.data) for(var/datum/integrated_io/output/O in outputs) O.data = result @@ -103,6 +204,7 @@ /obj/item/integrated_circuit/arithmetic/average name = "average circuit" desc = "This circuit is of average quality, however it will compute the average for numbers you give it." + extended_desc = "Note that null pins are ignored, where as a pin containing 0 is included in the averaging calculation." icon_state = "average" /obj/item/integrated_circuit/arithmetic/average/do_work() @@ -137,6 +239,8 @@ /obj/item/integrated_circuit/arithmetic/random name = "random number generator circuit" desc = "This gives a random (integer) number between values A and B inclusive." + extended_desc = "'Inclusive' means that the upper bound is included in the range of numbers, e.g. L = 1 and H = 3 will allow \ + for outputs of 1, 2, or 3. L being the higher number is not strictly required." icon_state = "random" inputs = list("L","H") @@ -150,4 +254,45 @@ for(var/datum/integrated_io/output/O in outputs) O.data = result - O.push_data() \ No newline at end of file + O.push_data() + +// Square Root // + +/obj/item/integrated_circuit/arithmetic/square_root + name = "square root circuit" + desc = "This outputs the square root of a number you put in." + icon_state = "square_root" + inputs = list("A") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/arithmetic/square_root/do_work() + var/result = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data)) + result = sqrt(I.data) + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// % Modulo % // + +/obj/item/integrated_circuit/arithmetic/modulo + name = "modulo circuit" + desc = "Gets the remainder of A / B." + icon_state = "modulo" + inputs = list("A", "B") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/arithmetic/modulo/do_work() + var/result = 0 + var/datum/integrated_io/input/A = inputs[1] + var/datum/integrated_io/input/B = inputs[2] + if(isnum(A.data) && isnum(B.data) && B.data != 0) + result = A.data % B.data + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + diff --git a/code/modules/integrated_electronics/assemblies.dm b/code/modules/integrated_electronics/assemblies.dm index 7cd7ce36cd8d0..023c0b19abca3 100644 --- a/code/modules/integrated_electronics/assemblies.dm +++ b/code/modules/integrated_electronics/assemblies.dm @@ -1,37 +1,63 @@ +#define IC_COMPONENTS_BASE 20 +#define IC_COMPLEXITY_BASE 80 + /obj/item/device/electronic_assembly name = "electronic assembly" desc = "It's a case, for building electronics with." w_class = 2 icon = 'icons/obj/electronic_assemblies.dmi' icon_state = "setup_small" - var/max_components = 10 - var/max_complexity = 30 + var/show_messages = TRUE + var/max_components = IC_COMPONENTS_BASE + var/max_complexity = IC_COMPLEXITY_BASE var/opened = 0 /obj/item/device/electronic_assembly/medium name = "electronic mechanism" icon_state = "setup_medium" w_class = 3 - max_components = 20 - max_complexity = 50 + max_components = IC_COMPONENTS_BASE * 2 + max_complexity = IC_COMPLEXITY_BASE * 2 /obj/item/device/electronic_assembly/large name = "electronic machine" - icon_state = "setup" + icon_state = "setup_large" w_class = 4 - max_components = 30 - max_complexity = 60 + max_components = IC_COMPONENTS_BASE * 3 + max_complexity = IC_COMPLEXITY_BASE * 3 /obj/item/device/electronic_assembly/drone name = "electronic drone" icon_state = "setup_drone" w_class = 3 - max_components = 25 - max_complexity = 100 + max_components = IC_COMPONENTS_BASE * 1.5 + max_complexity = IC_COMPLEXITY_BASE * 1.5 + +/obj/item/device/electronic_assembly/implant + name = "electronic implant" + icon_state = "setup_implant" + w_class = 1 + max_components = IC_COMPONENTS_BASE / 2 + max_complexity = IC_COMPLEXITY_BASE / 2 + var/obj/item/weapon/implant/integrated_circuit/implant = null + +/obj/item/device/electronic_assembly/implant/update_icon() + ..() + implant.icon_state = icon_state + + +/obj/item/device/electronic_assembly/implant/proc/nano_host() + return implant + +/obj/item/device/electronic_assembly/proc/resolve_nano_host() + return src + +/obj/item/device/electronic_assembly/implant/resolve_nano_host() + return implant /obj/item/device/electronic_assembly/interact(mob/user) - //if(!CanInteract(user,src)) - // return + if(!CanInteract(user, src)) + return var/total_parts = 0 var/total_complexity = 0 @@ -71,14 +97,20 @@ set desc = "Rename your circuit, useful to stay organized." var/mob/M = usr - //if(!CanInteract(M,src)) - // return + if(!CanInteract(M, src)) + return var/input = sanitize_text(input("What do you want to name this?", "Rename", src.name) as null|text, MAX_NAME_LEN) if(src && input) M << "The machine now has a label reading '[input]'." name = input +/obj/item/device/electronic_assembly/proc/can_move() + return FALSE + +/obj/item/device/electronic_assembly/drone/can_move() + return TRUE + /obj/item/device/electronic_assembly/update_icon() if(opened) icon_state = initial(icon_state) + "-open" @@ -141,7 +173,7 @@ if(input.can_be_asked_input) available_inputs.Add(input) var/obj/item/integrated_circuit/input/choice = input(user, "What do you want to interact with?", "Interaction") as null|anything in available_inputs - if(choice) + if(choice && CanInteract(user, src)) choice.ask_for_input(user) /obj/item/device/electronic_assembly/emp_act(severity) diff --git a/code/modules/integrated_electronics/converters.dm b/code/modules/integrated_electronics/converters.dm index ad5f282356a78..12c7221cfc9a7 100644 --- a/code/modules/integrated_electronics/converters.dm +++ b/code/modules/integrated_electronics/converters.dm @@ -4,7 +4,12 @@ inputs = list("input") outputs = list("output") activators = list("convert") - category = /obj/item/integrated_circuit/converter + category_text = "Converter" + autopulse = 1 + +/obj/item/integrated_circuit/converter/on_data_written() + if(autopulse == 1) + check_then_do_work() /obj/item/integrated_circuit/converter/num2text name = "number to string" @@ -98,4 +103,67 @@ var/datum/integrated_io/outgoing = outputs[1] outgoing.data = result - outgoing.push_data() \ No newline at end of file + outgoing.push_data() + +/obj/item/integrated_circuit/converter/radians2degrees + name = "radians to degrees converter" + desc = "Converts radians to degrees." + inputs = list("radian") + outputs = list("degrees") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/converter/radians2degrees/do_work() + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + incoming.pull_data() + if(incoming.data && isnum(incoming.data)) + result = ToDegrees(incoming.data) + + outgoing.data = result + outgoing.push_data() + +/obj/item/integrated_circuit/converter/degrees2radians + name = "degrees to radians converter" + desc = "Converts degrees to radians." + inputs = list("degrees") + outputs = list("radians") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/converter/degrees2radians/do_work() + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + incoming.pull_data() + if(incoming.data && isnum(incoming.data)) + result = ToRadians(incoming.data) + + outgoing.data = result + outgoing.push_data() + + +/obj/item/integrated_circuit/converter/abs_to_rel_coords + name = "abs to rel coordinate converter" + desc = "Easily convert absolute coordinates to relative coordinates with this." + complexity = 4 + inputs = list("X1 (abs)", "Y1 (abs)", "X2 (abs)", "Y2 (abs)") + outputs = list("X (rel)", "Y (rel)") + activators = list("compute rel coordinates") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/converter/abs_to_rel_coords/do_work() + var/datum/integrated_io/x1 = inputs[1] + var/datum/integrated_io/y1 = inputs[2] + + var/datum/integrated_io/x2 = inputs[3] + var/datum/integrated_io/y2 = inputs[4] + + var/datum/integrated_io/result_x = outputs[1] + var/datum/integrated_io/result_y = outputs[2] + + if(x1.data && y1.data && x2.data && y2.data) + result_x.data = x1.data - x2.data + result_y.data = y1.data - y2.data + + for(var/datum/integrated_io/output/O in outputs) + O.push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/data_transfer.dm b/code/modules/integrated_electronics/data_transfer.dm index 23ce3e5aeab30..db9d046c396a5 100644 --- a/code/modules/integrated_electronics/data_transfer.dm +++ b/code/modules/integrated_electronics/data_transfer.dm @@ -1,3 +1,11 @@ +/obj/item/integrated_circuit/transfer + category_text = "Data Transfer" + autopulse = 1 + +/obj/item/integrated_circuit/transfer/on_data_written() + if(autopulse == 1) + check_then_do_work() + /obj/item/integrated_circuit/transfer/splitter name = "splitter" desc = "Splits incoming data into all of the output pins." diff --git a/code/modules/integrated_electronics/input_output.dm b/code/modules/integrated_electronics/input_output.dm index 3e8cff40f5508..bcd8793902a17 100644 --- a/code/modules/integrated_electronics/input_output.dm +++ b/code/modules/integrated_electronics/input_output.dm @@ -33,7 +33,7 @@ /obj/item/integrated_circuit/input/numberpad/ask_for_input(mob/user) var/new_input = input(user, "Enter a number, please.","Number pad") as null|num - if(isnum(new_input)) + if(isnum(new_input) && CanInteract(user, src)) var/datum/integrated_io/O = outputs[1] O.data = new_input O.push_data() @@ -52,7 +52,7 @@ /obj/item/integrated_circuit/input/textpad/ask_for_input(mob/user) var/new_input = input(user, "Enter some words, please.","Number pad") as null|text - if(istext(new_input)) + if(istext(new_input) && CanInteract(user, src)) var/datum/integrated_io/O = outputs[1] O.data = new_input O.push_data() @@ -67,6 +67,7 @@ inputs = list("target ref") outputs = list("total health %", "total missing health") activators = list("scan") + origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) /obj/item/integrated_circuit/input/med_scanner/do_work() var/datum/integrated_io/I = inputs[1] @@ -103,6 +104,7 @@ "clone damage" ) activators = list("scan") + origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4) /obj/item/integrated_circuit/input/adv_med_scanner/do_work() var/datum/integrated_io/I = inputs[1] @@ -150,6 +152,39 @@ O.push_data() +/obj/item/integrated_circuit/input/adjacent_locator + name = "adjacent locator" + desc = "This is needed for certain devices that demand a reference for a target to act upon. This type only locates something \ + that is standing a meter away from the machine." + extended_desc = "The first pin requires a ref to a kind of object that you want the locator to acquire. This means that it will \ + give refs to nearby objects that are similar. If more than one valid object is found nearby, it will choose one of them at \ + random." + inputs = list("desired type ref") + outputs = list("located ref") + activators = list("locate") + +/obj/item/integrated_circuit/input/adjacent_locator/do_work() + var/datum/integrated_io/I = inputs[1] + var/datum/integrated_io/O = outputs[1] + O.data = null + + if(!isweakref(I.data)) + return + var/atom/A = I.data + if(!A) + return + var/desired_type = A.type + + var/list/nearby_things = range(1, get_turf(src)) + var/list/valid_things = list() + for(var/atom/thing in nearby_things) + if(thing.type != desired_type) + continue + valid_things.Add(thing) + if(valid_things.len) + O.data = weakref(pick(valid_things)) + O.push_data() + /obj/item/integrated_circuit/input/signaler name = "integrated signaler" desc = "Signals from a signaler can be received with this, allowing for remote control. Additionally, it can send signals as well." @@ -161,6 +196,7 @@ inputs = list("frequency","code") outputs = list() activators = list("send signal","on signal received") + origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNETS = 2) var/frequency = 1457 var/code = 30 @@ -184,7 +220,7 @@ /obj/item/integrated_circuit/input/signaler/on_data_written() var/datum/integrated_io/new_freq = inputs[1] var/datum/integrated_io/new_code = inputs[2] - if(isnum(new_freq.data)) + if(isnum(new_freq.data) && new_freq.data > 0) set_frequency(new_freq.data) if(isnum(new_code.data)) code = new_code.data @@ -241,6 +277,7 @@ inputs = list("target EPv2 address", "data to send", "secondary text") outputs = list("address received", "data received", "secondary text received") activators = list("send data", "on data received") + origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNETS = 2, TECH_BLUESPACE = 2) var/datum/exonet_protocol/exonet = null /obj/item/integrated_circuit/input/EPv2/New() @@ -274,8 +311,74 @@ data_received.write_data_to_pin(message) text_received.write_data_to_pin(text) +//This circuit gives information on where the machine is. +/obj/item/integrated_circuit/input/gps + name = "global positioning system" + desc = "This allows you to easily know the position of a machine containing this device." + icon_state = "gps" + complexity = 4 + inputs = list() + outputs = list("X (abs)", "Y (abs)") + activators = list("get coordinates") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/input/gps/do_work() + var/turf/T = get_turf(src) + var/datum/integrated_io/result_x = outputs[1] + var/datum/integrated_io/result_y = outputs[2] + + result_x.data = null + result_y.data = null + if(!T) + return + + result_x.data = T.x + result_y.data = T.y + + for(var/datum/integrated_io/output/O in outputs) + O.push_data() + + +/obj/item/integrated_circuit/input/microphone + name = "microphone" + desc = "Useful for spying on people or for voice activated machines." + icon_state = "recorder" + flags = HEAR + complexity = 8 + inputs = list() + outputs = list("speaker \", "message \") + activators = list("on message received") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/* +/obj/item/integrated_circuit/input/microphone/New() + ..() + listening_objects |= src + +/obj/item/integrated_circuit/input/microphone/Destroy() + listening_objects -= src + ..() +*/ + +/obj/item/integrated_circuit/input/microphone/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans) + var/datum/integrated_io/V = outputs[1] + var/datum/integrated_io/O = outputs[2] + var/datum/integrated_io/A = activators[1] + if(speaker = src) + return + //msg = lang_treat(msg, M, message_langs, raw_message, spans) + V.data = speaker.GetVoice() + O.data = raw_message + A.push_data() + + + + +/obj/item/integrated_circuit/output + category_text = "Output" + /obj/item/integrated_circuit/output/screen - name = "screen" + name = "small screen" desc = "This small screen can display a single piece of data, when the machine is examined closely." icon_state = "screen" inputs = list("displayed data") @@ -292,6 +395,28 @@ else stuff_to_display = I.data +/obj/item/integrated_circuit/output/screen/medium + name = "screen" + desc = "This screen allows for people holding the device to see a piece of data." + icon_state = "screen_medium" + +/obj/item/integrated_circuit/output/screen/medium/do_work() + ..() + var/list/nearby_things = range(0, get_turf(src)) + for(var/mob/M in nearby_things) + var/obj/O = istype(loc, /obj/item/device/electronic_assembly) ? loc : src + visible_message("\icon[O] [stuff_to_display]") + +/obj/item/integrated_circuit/output/screen/large + name = "large screen" + desc = "This screen allows for people able to see the device to see a piece of data." + icon_state = "screen_large" + +/obj/item/integrated_circuit/output/screen/large/do_work() + ..() + var/obj/O = istype(loc, /obj/item/device/electronic_assembly) ? loc : src + O.visible_message("\icon[O] [stuff_to_display]") + /obj/item/integrated_circuit/output/light name = "light" desc = "This light can turn on and off on command." @@ -360,7 +485,23 @@ outputs = list() activators = list("play sound") var/list/sounds = list() - category = /obj/item/integrated_circuit/output/sound + +/obj/item/integrated_circuit/output/text_to_speech + name = "text-to-speech circuit" + desc = "A miniature speaker is attached to this component." + extended_desc = "This unit is more advanced than the plain speaker circuit, able to transpose any valid text to speech." + icon_state = "speaker" + complexity = 12 + cooldown_per_use = 4 SECONDS + inputs = list("text") + outputs = list() + activators = list("to speech") + +/obj/item/integrated_circuit/output/text_to_speech/do_work() + var/datum/integrated_io/text = inputs[1] + if(istext(text.data)) + var/obj/O = istype(loc, /obj/item/device/electronic_assembly) ? loc : src + audible_message("\icon[O] \The [O.name] states, \"[text.data]\"") /obj/item/integrated_circuit/output/sound/New() ..() @@ -378,7 +519,6 @@ if(istext(ID.data) && isnum(vol.data) && isnum(frequency.data)) var/selected_sound = sounds[ID.data] if(!selected_sound) - world << "No sound" return vol.data = Clamp(vol.data, 0, 100) frequency.data = round(Clamp(frequency.data, 0, 1)) @@ -412,5 +552,4 @@ "insult" = 'sound/voice/binsult.ogg', "radio" = 'sound/voice/bradio.ogg', "secure day" = 'sound/voice/bsecureday.ogg', - ) - + ) \ No newline at end of file diff --git a/code/modules/integrated_electronics/logic.dm b/code/modules/integrated_electronics/logic.dm index cb4fc55f3587f..838cf4f4e94bb 100644 --- a/code/modules/integrated_electronics/logic.dm +++ b/code/modules/integrated_electronics/logic.dm @@ -5,7 +5,11 @@ complexity = 3 outputs = list("result") activators = list("compare", "on true result") - category = /obj/item/integrated_circuit/logic + autopulse = 1 + +/obj/item/integrated_circuit/logic/on_data_written() + if(autopulse == 1) + check_then_do_work() /obj/item/integrated_circuit/logic/do_work() var/datum/integrated_io/O = outputs[1] @@ -16,7 +20,6 @@ /obj/item/integrated_circuit/logic/binary inputs = list("A","B") - category = /obj/item/integrated_circuit/logic/binary /obj/item/integrated_circuit/logic/binary/do_work() var/datum/integrated_io/A = inputs[1] @@ -30,7 +33,6 @@ /obj/item/integrated_circuit/logic/unary inputs = list("A") - category = /obj/item/integrated_circuit/logic/unary /obj/item/integrated_circuit/logic/unary/do_work() var/datum/integrated_io/A = inputs[1] diff --git a/code/modules/integrated_electronics/manipulation.dm b/code/modules/integrated_electronics/manipulation.dm index 35d9b445eb854..d202f5c299001 100644 --- a/code/modules/integrated_electronics/manipulation.dm +++ b/code/modules/integrated_electronics/manipulation.dm @@ -86,32 +86,6 @@ return installed_gun.Fire_userless(T) -/obj/item/integrated_circuit/manipulation/smoke - name = "smoke generator" - desc = "Unlike most electronics, creating smoke is completely intentional." - icon_state = "smoke" - extended_desc = "This smoke generator creates clouds of smoke on command. It can also hold liquids inside, which will go \ - into the smoke clouds when activated." - flags = OPENCONTAINER - complexity = 20 - cooldown_per_use = 30 SECONDS - inputs = list() - outputs = list() - activators = list("create smoke") - -/obj/item/integrated_circuit/manipulation/smoke/New() - ..() - create_reagents(100) - -/obj/item/integrated_circuit/manipulation/smoke/do_work() - playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3) - var/datum/effect/effect/system/smoke_spread/chem/smoke_system = new() - smoke_system.set_up(reagents, 10, 0, get_turf(src)) - spawn(0) - for(var/i = 1 to 8) - smoke_system.start() - reagents.clear_reagents() - /obj/item/integrated_circuit/manipulation/locomotion name = "locomotion circuit" desc = "This allows a machine to move in a given direction." @@ -140,7 +114,7 @@ var/obj/item/device/electronic_assembly/machine = loc if(machine.anchored || machine.w_class >= 4) return - if(machine.loc && machine.loc == T) // Check if we're held by someone. If the loc is the floor, we're not held. + if(machine.loc == T) // Check if we're held by someone. If the loc is the floor, we're not held. var/datum/integrated_io/wanted_dir = inputs[1] if(isnum(wanted_dir.data)) step(machine, wanted_dir.data) \ No newline at end of file diff --git a/code/modules/integrated_electronics/memory.dm b/code/modules/integrated_electronics/memory.dm index ce9a15e6652f2..0c3d038229703 100644 --- a/code/modules/integrated_electronics/memory.dm +++ b/code/modules/integrated_electronics/memory.dm @@ -6,7 +6,6 @@ inputs = list("input pin 1") outputs = list("output pin 1") activators = list("set") - category = /obj/item/integrated_circuit/memory /obj/item/integrated_circuit/memory/examine(mob/user) ..() @@ -59,6 +58,7 @@ "output pin 6", "output pin 7", "output pin 8") + origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) /obj/item/integrated_circuit/memory/huge name = "large memory stick" @@ -100,6 +100,7 @@ "output pin 14", "output pin 15", "output pin 16") + origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4) /obj/item/integrated_circuit/memory/constant name = "constant chip" diff --git a/code/modules/integrated_electronics/reagents.dm b/code/modules/integrated_electronics/reagents.dm new file mode 100644 index 0000000000000..67794a7f3f8b9 --- /dev/null +++ b/code/modules/integrated_electronics/reagents.dm @@ -0,0 +1,149 @@ +/obj/item/integrated_circuit/reagent + category_text = "Reagent" + var/volume = 0 + origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) + +/obj/item/integrated_circuit/reagent/New() + ..() + if(volume) + create_reagents(volume) + +/obj/item/integrated_circuit/reagent/smoke + name = "smoke generator" + desc = "Unlike most electronics, creating smoke is completely intentional." + icon_state = "smoke" + extended_desc = "This smoke generator creates clouds of smoke on command. It can also hold liquids inside, which will go \ + into the smoke clouds when activated." + flags = OPENCONTAINER + complexity = 20 + cooldown_per_use = 30 SECONDS + inputs = list() + outputs = list() + activators = list("create smoke") + spawn_flags = IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 3) + volume = 100 + +/obj/item/integrated_circuit/reagent/smoke/do_work() + playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3) + var/datum/effect/effect/system/smoke_spread/chem/smoke_system = new() + smoke_system.set_up(reagents, 10, 0, get_turf(src)) + spawn(0) + for(var/i = 1 to 8) + smoke_system.start() + reagents.clear_reagents() + +/obj/item/integrated_circuit/reagent/injector + name = "integrated hypo-injector" + desc = "This scary looking thing is able to pump liquids into whatever it's pointed at." + icon_state = "injector" + extended_desc = "This autoinjector can push reagents into another container or someone else outside of the machine. The target \ + must be adjacent to the machine, and if it is a person, they cannot be wearing thick clothing." + flags = OPENCONTAINER + complexity = 20 + cooldown_per_use = 6 SECONDS + inputs = list("target ref", "injection amount" = 5) + outputs = list() + activators = list("inject") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + volume = 30 + +/obj/item/integrated_circuit/reagent/injector/proc/inject_amount() + var/datum/integrated_io/amount = inputs[2] + if(isnum(amount.data)) + return Clamp(amount.data, 0, 30) + +/obj/item/integrated_circuit/reagent/injector/do_work() + set waitfor = 0 // Don't sleep in a proc that is called by a processor without this set, otherwise it'll delay the entire thing + + var/datum/integrated_io/target = inputs[1] + var/atom/movable/AM = target.data_as_type(/atom/movable) + if(!istype(AM)) //Invalid input + return + if(!reagents.total_volume) // Empty + return + if(AM.can_be_injected_by(src)) + if(isliving(AM)) + var/turf/T = get_turf(AM) + T.visible_message("[src] is trying to inject [AM]!") + sleep(3 SECONDS) + if(!AM.can_be_injected_by(src)) + return + var/contained = reagents.get_reagents() + var/trans = reagents.trans_to(target, inject_amount()) + message_admins("[src] injected \the [AM] with [trans]u of [contained].") + to_chat(AM, "You feel a tiny prick!") + visible_message("[src] injects [AM]!") + else + reagents.trans_to(AM, inject_amount()) + +/obj/item/integrated_circuit/reagent/pump + name = "reagent pump" + desc = "Moves liquids safely inside a machine, or even nearby it." + icon_state = "reagent_pump" + extended_desc = "This is a pump, which will move liquids from the source ref to the target ref. The third pin determines \ + how much liquid is moved per pulse, between 0 and 50. The pump can move reagents to any open container inside the machine, or \ + outside the machine if it is next to the machine. Note that this cannot be used on entities." + flags = OPENCONTAINER + complexity = 8 + inputs = list("source ref", "target ref", "injection amount" = 10) + outputs = list() + activators = list("transfer reagents") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) + var/transfer_amount = 10 + +/obj/item/integrated_circuit/reagent/pump/on_data_written() + var/datum/integrated_io/amount = inputs[3] + if(isnum(amount.data)) + amount.data = Clamp(amount.data, 0, 50) + transfer_amount = amount.data + +/obj/item/integrated_circuit/reagent/pump/do_work() + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/atom/movable/source = A.data_as_type(/atom/movable) + var/atom/movable/target = B.data_as_type(/atom/movable) + if(!istype(source) || !istype(target)) //Invalid input + return + var/turf/T = get_turf(src) + if(source.Adjacent(T) && target.Adjacent(T)) + if(!source.reagents || !target.reagents) + return + if(ismob(source) || ismob(target)) + return + if(!source.is_open_container() || !target.is_open_container()) + return + if(!source.reagents.get_free_space() || !target.reagents.get_free_space()) + return + + source.reagents.trans_to(target, transfer_amount) + +/obj/item/integrated_circuit/reagent/storage + name = "reagent storage" + desc = "Stores liquid inside, and away from electrical components. Can store up to 60u." + icon_state = "reagent_storage" + extended_desc = "This is effectively an internal beaker." + flags = OPENCONTAINER + complexity = 4 + inputs = list() + outputs = list("volume used") + activators = list() + 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/on_reagent_change() + var/datum/integrated_io/A = outputs[1] + A.data = reagents.total_volume + A.push_data() + +/obj/item/integrated_circuit/reagent/storage/cryo + name = "cryo reagent storage" + desc = "Stores liquid inside, and away from electrical components. Can store up to 60u. This will also suppress reactions." + icon_state = "reagent_storage_cryo" + extended_desc = "This is effectively an internal cryo beaker." + flags = OPENCONTAINER | NOREACT + complexity = 8 + spawn_flags = IC_SPAWN_RESEARCH + origin_tech = list(TECH_MATERIALS = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) \ No newline at end of file diff --git a/code/modules/integrated_electronics/time.dm b/code/modules/integrated_electronics/time.dm index 6b1cb255a9ddd..db8fde4b10d40 100644 --- a/code/modules/integrated_electronics/time.dm +++ b/code/modules/integrated_electronics/time.dm @@ -4,7 +4,6 @@ complexity = 2 inputs = list() outputs = list() - category = /obj/item/integrated_circuit/time /obj/item/integrated_circuit/time/delay name = "two-sec delay circuit" diff --git a/code/modules/integrated_electronics/tools.dm b/code/modules/integrated_electronics/tools.dm index 34947a1dbb680..b0ddf29e38884 100644 --- a/code/modules/integrated_electronics/tools.dm +++ b/code/modules/integrated_electronics/tools.dm @@ -16,9 +16,6 @@ var/datum/integrated_io/selected_io = null var/mode = WIRE -/obj/item/device/integrated_electronics/wirer/New() - ..() - /obj/item/device/integrated_electronics/wirer/update_icon() icon_state = "wirer-[mode]" @@ -42,8 +39,6 @@ user << "You connect \the [selected_io.holder]'s [selected_io.name] to \the [io.holder]'s [io.name]." mode = WIRE update_icon() - //io.updateDialog() - //selected_io.updateDialog() selected_io.holder.interact(user) // This is to update the UI. selected_io = null @@ -68,8 +63,6 @@ selected_io.linked.Remove(io) user << "You disconnect \the [selected_io.holder]'s [selected_io.name] from \ \the [io.holder]'s [io.name]." - //io.updateDialog() - //selected_io.updateDialog() selected_io.holder.interact(user) // This is to update the UI. selected_io = null mode = UNWIRE @@ -88,7 +81,7 @@ if(selected_io) user << "You decide not to wire the data channel." selected_io = null - mode = UNWIRE + mode = WIRE if(UNWIRE) mode = WIRE if(UNWIRING) @@ -171,67 +164,198 @@ icon = 'icons/obj/electronic_assemblies.dmi' icon_state = "circuit_kit" w_class = 3 - storage_slots = 200 - max_w_class = 3 - display_contents_with_number = 1 - can_hold = list(/obj/item/integrated_circuit, /obj/item/device/integrated_electronics, /obj/item/device/electronic_assembly, - /obj/item/weapon/screwdriver, /obj/item/weapon/crowbar) + display_contents_with_number = 0 + can_hold = list( + /obj/item/integrated_circuit, + /obj/item/weapon/storage/bag/circuits/mini, + /obj/item/device/electronic_assembly, + /obj/item/device/integrated_electronics, + /obj/item/weapon/crowbar, + /obj/item/weapon/screwdriver + ) /obj/item/weapon/storage/bag/circuits/basic/New() ..() - var/list/types_to_spawn = typesof(/obj/item/integrated_circuit/arithmetic, - /obj/item/integrated_circuit/logic, - /obj/item/integrated_circuit/memory, - ) - list(/obj/item/integrated_circuit/arithmetic, - /obj/item/integrated_circuit/memory, - /obj/item/integrated_circuit/logic, - ) + spawn(2 SECONDS) // So the list has time to initialize. +// for(var/obj/item/integrated_circuit/IC in all_integrated_circuits) +// if(IC.spawn_flags & IC_SPAWN_DEFAULT) +// for(var/i = 1 to 3) +// new IC.type(src) + new /obj/item/weapon/storage/bag/circuits/mini/arithmetic(src) + new /obj/item/weapon/storage/bag/circuits/mini/trig(src) + new /obj/item/weapon/storage/bag/circuits/mini/input(src) + new /obj/item/weapon/storage/bag/circuits/mini/output(src) + new /obj/item/weapon/storage/bag/circuits/mini/memory(src) + new /obj/item/weapon/storage/bag/circuits/mini/logic(src) + new /obj/item/weapon/storage/bag/circuits/mini/time(src) + new /obj/item/weapon/storage/bag/circuits/mini/reagents(src) + new /obj/item/weapon/storage/bag/circuits/mini/transfer(src) + new /obj/item/weapon/storage/bag/circuits/mini/converter(src) - types_to_spawn.Add(/obj/item/integrated_circuit/input/numberpad, - /obj/item/integrated_circuit/input/textpad, - /obj/item/integrated_circuit/input/button, - /obj/item/integrated_circuit/input/signaler, - /obj/item/integrated_circuit/input/local_locator, - /obj/item/integrated_circuit/output/screen, - /obj/item/integrated_circuit/converter/num2text, - /obj/item/integrated_circuit/converter/text2num, - /obj/item/integrated_circuit/converter/uppercase, - /obj/item/integrated_circuit/converter/lowercase, - /obj/item/integrated_circuit/time/delay/five_sec, - /obj/item/integrated_circuit/time/delay/one_sec, - /obj/item/integrated_circuit/time/delay/half_sec, - /obj/item/integrated_circuit/time/delay/tenth_sec, - /obj/item/integrated_circuit/time/ticker/slow, - /obj/item/integrated_circuit/time/clock - ) + new /obj/item/device/electronic_assembly(src) + new /obj/item/device/integrated_electronics/wirer(src) + new /obj/item/device/integrated_electronics/debugger(src) + new /obj/item/weapon/crowbar(src) + new /obj/item/weapon/screwdriver(src) + make_exact_fit() + +/obj/item/weapon/storage/bag/circuits/all/New() + ..() + spawn(2 SECONDS) // So the list has time to initialize. + for(var/obj/item/integrated_circuit/IC in all_integrated_circuits) + for(var/i = 1 to 10) + new IC.type(src) + + new /obj/item/device/electronic_assembly(src) + new /obj/item/device/integrated_electronics/wirer(src) + new /obj/item/device/integrated_electronics/debugger(src) + new /obj/item/weapon/crowbar(src) + new /obj/item/weapon/screwdriver(src) + make_exact_fit() + +/obj/item/weapon/storage/bag/circuits/mini/ + name = "circuit box" + desc = "Used to partition categories of circuits, for a neater workspace." + w_class = 2 + display_contents_with_number = 1 + can_hold = list(/obj/item/integrated_circuit) - for(var/thing in types_to_spawn) - var/obj/item/integrated_circuit/ic = thing - if(initial(ic.category) == thing) - continue +/obj/item/weapon/storage/bag/circuits/mini/arithmetic + name = "arithmetic circuit box" + desc = "Warning: Contains math." + icon_state = "box_arithmetic" - for(var/i = 1 to 4) - new thing(src) +/obj/item/weapon/storage/bag/circuits/mini/arithmetic/New() + ..() + for(var/obj/item/integrated_circuit/arithmetic/IC in all_integrated_circuits) + if(IC.spawn_flags & IC_SPAWN_DEFAULT) + for(var/i = 1 to 3) + new IC.type(src) + make_exact_fit() + + +/obj/item/weapon/storage/bag/circuits/mini/trig + name = "trig circuit box" + desc = "Danger: Contains more math." + icon_state = "box_trig" - new /obj/item/device/electronic_assembly(src) - new /obj/item/device/integrated_electronics/wirer(src) - new /obj/item/device/integrated_electronics/debugger(src) - new /obj/item/weapon/crowbar(src) - new /obj/item/weapon/screwdriver(src) +/obj/item/weapon/storage/bag/circuits/mini/trig/New() + ..() + for(var/obj/item/integrated_circuit/trig/IC in all_integrated_circuits) + if(IC.spawn_flags & IC_SPAWN_DEFAULT) + for(var/i = 1 to 3) + new IC.type(src) make_exact_fit() -/obj/item/weapon/storage/bag/circuits/all/New() + +/obj/item/weapon/storage/bag/circuits/mini/input + name = "input circuit box" + desc = "Tell these circuits everything you know." + icon_state = "box_input" + +/obj/item/weapon/storage/bag/circuits/mini/input/New() + ..() + for(var/obj/item/integrated_circuit/input/IC in all_integrated_circuits) + if(IC.spawn_flags & IC_SPAWN_DEFAULT) + for(var/i = 1 to 3) + new IC.type(src) + make_exact_fit() + + +/obj/item/weapon/storage/bag/circuits/mini/output + name = "output circuit box" + desc = "Circuits to interface with the world beyond itself." + icon_state = "box_output" + +/obj/item/weapon/storage/bag/circuits/mini/output/New() + ..() + for(var/obj/item/integrated_circuit/output/IC in all_integrated_circuits) + if(IC.spawn_flags & IC_SPAWN_DEFAULT) + for(var/i = 1 to 3) + new IC.type(src) + make_exact_fit() + + +/obj/item/weapon/storage/bag/circuits/mini/memory + name = "memory circuit box" + desc = "Machines can be quite forgetful without these." + icon_state = "box_memory" + +/obj/item/weapon/storage/bag/circuits/mini/memory/New() + ..() + for(var/obj/item/integrated_circuit/memory/IC in all_integrated_circuits) + if(IC.spawn_flags & IC_SPAWN_DEFAULT) + for(var/i = 1 to 3) + new IC.type(src) + make_exact_fit() + + + +/obj/item/weapon/storage/bag/circuits/mini/logic + name = "logic circuit box" + desc = "May or may not be Turing complete." + icon_state = "box_logic" + +/obj/item/weapon/storage/bag/circuits/mini/logic/New() + ..() + for(var/obj/item/integrated_circuit/logic/IC in all_integrated_circuits) + if(IC.spawn_flags & IC_SPAWN_DEFAULT) + for(var/i = 1 to 3) + new IC.type(src) + make_exact_fit() + + +/obj/item/weapon/storage/bag/circuits/mini/time + name = "time circuit box" + desc = "No time machine parts, sadly." + icon_state = "box_time" + +/obj/item/weapon/storage/bag/circuits/mini/time/New() + ..() + for(var/obj/item/integrated_circuit/time/IC in all_integrated_circuits) + if(IC.spawn_flags & IC_SPAWN_DEFAULT) + for(var/i = 1 to 3) + new IC.type(src) + make_exact_fit() + + +/obj/item/weapon/storage/bag/circuits/mini/reagents + name = "reagent circuit box" + desc = "Unlike most electronics, these circuits are supposed to come in contact with liquids." + icon_state = "box_reagents" + +/obj/item/weapon/storage/bag/circuits/mini/reagents/New() + ..() + for(var/obj/item/integrated_circuit/reagent/IC in all_integrated_circuits) + if(IC.spawn_flags & IC_SPAWN_DEFAULT) + for(var/i = 1 to 3) + new IC.type(src) + make_exact_fit() + + +/obj/item/weapon/storage/bag/circuits/mini/transfer + name = "transfer circuit box" + desc = "Useful for moving data representing something arbitrary to another arbitrary virtual place." + icon_state = "box_transfer" + +/obj/item/weapon/storage/bag/circuits/mini/transfer/New() + ..() + for(var/obj/item/integrated_circuit/transfer/IC in all_integrated_circuits) + if(IC.spawn_flags & IC_SPAWN_DEFAULT) + for(var/i = 1 to 3) + new IC.type(src) + make_exact_fit() + + +/obj/item/weapon/storage/bag/circuits/mini/converter + name = "converter circuit box" + desc = "Transform one piece of data to another type of data with these." + icon_state = "box_converter" + +/obj/item/weapon/storage/bag/circuits/mini/converter/New() ..() - for(var/thing in subtypesof(/obj/item/integrated_circuit)) - var/obj/item/integrated_circuit/ic = thing - if(initial(ic.category) == thing) - continue - for(var/i = 1 to 10) - new thing(src) - - new /obj/item/device/electronic_assembly(src) - new /obj/item/device/integrated_electronics/wirer(src) - new /obj/item/device/integrated_electronics/debugger(src) - new /obj/item/weapon/crowbar(src) - new /obj/item/weapon/screwdriver(src) + for(var/obj/item/integrated_circuit/converter/IC in all_integrated_circuits) + if(IC.spawn_flags & IC_SPAWN_DEFAULT) + for(var/i = 1 to 3) + new IC.type(src) make_exact_fit() \ No newline at end of file diff --git a/code/modules/integrated_electronics/trig.dm b/code/modules/integrated_electronics/trig.dm new file mode 100644 index 0000000000000..e8e2e09ca9eee --- /dev/null +++ b/code/modules/integrated_electronics/trig.dm @@ -0,0 +1,135 @@ +//These circuits do not-so-simple math. +/obj/item/integrated_circuit/trig + complexity = 1 + inputs = list("A","B","C","D","E","F","G","H") + outputs = list("result") + activators = list("compute") + category_text = "Trig" + extended_desc = "Input and output are in degrees." + autopulse = 1 + +/obj/item/integrated_circuit/trig/on_data_written() + if(autopulse == 1) + check_then_do_work() + +// Sine // + +/obj/item/integrated_circuit/trig/sine + name = "sin circuit" + desc = "Has nothing to do with evil, unless you consider trigonometry to be evil. Outputs the sine of A." + icon_state = "sine" + inputs = list("A") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/trig/sine/do_work() + var/result = null + var/datum/integrated_io/input/A = inputs[1] + A.pull_data() + if(isnum(A.data)) + result = sin(A.data) + + var/datum/integrated_io/output/O = outputs[1] + O.data = result + O.push_data() + +// Cosine // + +/obj/item/integrated_circuit/trig/cosine + name = "cos circuit" + desc = "Outputs the cosine of A." + icon_state = "cosine" + inputs = list("A") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/trig/cosine/do_work() + var/result = null + var/datum/integrated_io/input/A = inputs[1] + A.pull_data() + if(isnum(A.data)) + result = cos(A.data) + + var/datum/integrated_io/output/O = outputs[1] + O.data = result + O.push_data() + +// Tangent // + +/obj/item/integrated_circuit/trig/tangent + name = "tan circuit" + desc = "Outputs the tangent of A. Guaranteed to not go on a tangent about its existance." + icon_state = "tangent" + inputs = list("A") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/trig/tangent/do_work() + var/result = null + var/datum/integrated_io/input/A = inputs[1] + A.pull_data() + if(isnum(A.data)) + result = Tan(A.data) + + var/datum/integrated_io/output/O = outputs[1] + O.data = result + O.push_data() + +// Cosecant // + +/obj/item/integrated_circuit/trig/cosecant + name = "csc circuit" + desc = "Outputs the cosecant of A." + icon_state = "cosecant" + inputs = list("A") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/trig/cosecant/do_work() + var/result = null + var/datum/integrated_io/input/A = inputs[1] + A.pull_data() + if(isnum(A.data)) + result = Csc(A.data) + + var/datum/integrated_io/output/O = outputs[1] + O.data = result + O.push_data() + + +// Secant // + +/obj/item/integrated_circuit/trig/secant + name = "sec circuit" + desc = "Outputs the secant of A. Has nothing to do with the security department." + icon_state = "secant" + inputs = list("A") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/trig/secant/do_work() + var/result = null + var/datum/integrated_io/input/A = inputs[1] + A.pull_data() + if(isnum(A.data)) + result = Sec(A.data) + + var/datum/integrated_io/output/O = outputs[1] + O.data = result + O.push_data() + + +// Cotangent // + +/obj/item/integrated_circuit/trig/cotangent + name = "cot circuit" + desc = "Outputs the cotangent of A. Has nothing to do with the security department." + icon_state = "cotangent" + inputs = list("A") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/trig/cotangent/do_work() + var/result = null + var/datum/integrated_io/input/A = inputs[1] + A.pull_data() + if(isnum(A.data)) + result = Cot(A.data) + + var/datum/integrated_io/output/O = outputs[1] + O.data = result + O.push_data() \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Reagents-Helpers.dm b/code/modules/reagents/Chemistry-Reagents-Helpers.dm new file mode 100644 index 0000000000000..917d9f4649cc8 --- /dev/null +++ b/code/modules/reagents/Chemistry-Reagents-Helpers.dm @@ -0,0 +1,17 @@ +/atom/movable/proc/can_be_injected_by(var/atom/injector) + if(!Adjacent(get_turf(injector))) + return FALSE + if(!reagents) + return FALSE + if(!reagents.get_free_space()) + return FALSE + return TRUE + +/obj/can_be_injected_by(var/atom/injector) + return is_open_container() && ..() + +/mob/living/can_be_injected_by(var/atom/injector) + return ..() && (can_inject(null, 0, "torso") || can_inject(null, 0, "groin")) + +/datum/reagents/proc/get_free_space() // Returns free space. + return maximum_volume - total_volume \ No newline at end of file diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index ae5778c808e78..124ed773d9a6a 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -469,37 +469,6 @@ other types of metals and chemistry for reagents). materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 2500) build_path = /obj/item/device/integrated_electronics/debugger - -/datum/design/item/custom_circuit_assembly - name = "Small custom assembly" - desc = "An customizable assembly for simple, small devices." - id = "assembly-small" - build_type = PROTOLATHE - req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 2, TECH_POWER = 2) - materials = list(DEFAULT_WALL_MATERIAL = 10000) - build_path = /obj/item/device/electronic_assembly - category = list("Electronics") - -/datum/design/item/custom_circuit_assembly/medium - name = "Medium custom assembly" - desc = "An customizable assembly suited for more ambitious mechanisms." - id = "assembly-medium" - req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3, TECH_POWER = 3) - materials = list(DEFAULT_WALL_MATERIAL = 20000) - build_path = /obj/item/device/electronic_assembly/medium - -/datum/design/item/custom_circuit_assembly/large - name = "Large custom assembly" - desc = "An customizable assembly for large machines." - id = "assembly-large" - req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_POWER = 4) - materials = list(DEFAULT_WALL_MATERIAL = 40000) - build_path = /obj/item/device/electronic_assembly/large - -/datum/design/circuit/integrated_circuit - req_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2) - category = list("Electronics") - /datum/design/circuit/integrated_circuit/AssembleDesignName() ..() name = "Custom circuitry ([item_name])" @@ -512,302 +481,6 @@ other types of metals and chemistry for reagents). ..() name = "Custom circuitry \[Arithmetic\] ([item_name])" -/datum/design/circuit/integrated_circuit/arithmetic/addition - id = "cc-addition" - build_path = /obj/item/integrated_circuit/arithmetic/addition - -/datum/design/circuit/integrated_circuit/arithmetic/subtraction - id = "cc-subtraction" - build_path = /obj/item/integrated_circuit/arithmetic/subtraction - -/datum/design/circuit/integrated_circuit/arithmetic/multiplication - id = "cc-multiplication" - build_path = /obj/item/integrated_circuit/arithmetic/multiplication - -/datum/design/circuit/integrated_circuit/arithmetic/division - id = "cc-division" - build_path = /obj/item/integrated_circuit/arithmetic/division - -/datum/design/circuit/integrated_circuit/arithmetic/absolute - id = "cc-absolute" - build_path = /obj/item/integrated_circuit/arithmetic/absolute - -/datum/design/circuit/integrated_circuit/arithmetic/average - id = "cc-average" - build_path = /obj/item/integrated_circuit/arithmetic/average - -/datum/design/circuit/integrated_circuit/arithmetic/pi - id = "cc-pi" - build_path = /obj/item/integrated_circuit/arithmetic/pi - -/datum/design/circuit/integrated_circuit/arithmetic/random - id = "cc-random" - build_path = /obj/item/integrated_circuit/arithmetic/random - - - -/datum/design/circuit/integrated_circuit/converter/AssembleDesignName() - ..() - name = "Custom circuitry \[Conversion\] ([item_name])" - -/datum/design/circuit/integrated_circuit/converter/num2text - id = "cc-num2text" - build_path = /obj/item/integrated_circuit/converter/num2text - -/datum/design/circuit/integrated_circuit/converter/text2num - id = "cc-text2num" - build_path = /obj/item/integrated_circuit/converter/text2num - -/datum/design/circuit/integrated_circuit/converter/ref2text - id = "cc-ref2text" - build_path = /obj/item/integrated_circuit/converter/ref2text - -/datum/design/circuit/integrated_circuit/converter/lowercase - id = "cc-lowercase" - build_path = /obj/item/integrated_circuit/converter/lowercase - -/datum/design/circuit/integrated_circuit/converter/uppercase - id = "cc-uppercase" - build_path = /obj/item/integrated_circuit/converter/uppercase - -/datum/design/circuit/integrated_circuit/converter/concatenatior - id = "cc-concatenatior" - build_path = /obj/item/integrated_circuit/converter/concatenatior - - - -/datum/design/circuit/integrated_circuit/coordinate/AssembleDesignName() - ..() - name = "Custom circuitry \[Coordinate\] ([item_name])" - -/datum/design/circuit/integrated_circuit/coordinate/gps - id = "cc-gps" - build_path = /obj/item/integrated_circuit/gps - -/datum/design/circuit/integrated_circuit/coordinate/abs_to_rel_coords - id = "cc-abs_to_rel_coords" - build_path = /obj/item/integrated_circuit/abs_to_rel_coords - - - -/datum/design/circuit/integrated_circuit/transfer/AssembleDesignName() - ..() - name = "Custom circuitry \[Transfer\] ([item_name])" - -/datum/design/circuit/integrated_circuit/transfer/splitter - id = "cc-splitter" - build_path = /obj/item/integrated_circuit/transfer/splitter - -/datum/design/circuit/integrated_circuit/transfer/splitter4 - id = "cc-splitter4" - build_path = /obj/item/integrated_circuit/transfer/splitter/medium - -/datum/design/circuit/integrated_circuit/transfer/splitter8 - id = "cc-splitter8" - build_path = /obj/item/integrated_circuit/transfer/splitter/large - -/datum/design/circuit/integrated_circuit/transfer/activator_splitter - id = "cc-activator_splitter" - build_path = /obj/item/integrated_circuit/transfer/activator_splitter - -/datum/design/circuit/integrated_circuit/transfer/activator_splitter4 - id = "cc-activator_splitter4" - build_path = /obj/item/integrated_circuit/transfer/activator_splitter/medium - -/datum/design/circuit/integrated_circuit/transfer/activator_splitter8 - id = "cc-activator_splitter8" - build_path = /obj/item/integrated_circuit/transfer/activator_splitter/large - - - -/datum/design/circuit/integrated_circuit/input_output/AssembleDesignName() - ..() - name = "Custom circuitry \[Input/Output\] ([item_name])" - -/datum/design/circuit/integrated_circuit/input_output/button - id = "cc-button" - build_path = /obj/item/integrated_circuit/input/button - -/datum/design/circuit/integrated_circuit/input_output/numberpad - id = "cc-numberpad" - build_path = /obj/item/integrated_circuit/input/numberpad - -/datum/design/circuit/integrated_circuit/input_output/textpad - id = "cc-textpad" - build_path = /obj/item/integrated_circuit/input/textpad - -/datum/design/circuit/integrated_circuit/input_output/screen - id = "cc-screen" - build_path = /obj/item/integrated_circuit/output/screen - -/datum/design/circuit/integrated_circuit/input_output/med_scanner - id = "cc-medscanner" - build_path = /obj/item/integrated_circuit/input/med_scanner - req_tech = list(TECH_MATERIAL = 2, TECH_MAGNETS = 2, TECH_BIOMED = 2) - -/datum/design/circuit/integrated_circuit/input_output/adv_med_scanner - id = "cc-advmedscanner" - build_path = /obj/item/integrated_circuit/input/adv_med_scanner - req_tech = list(TECH_MATERIAL = 2, TECH_MAGNETS = 3, TECH_BIOMED = 4) - -/datum/design/circuit/integrated_circuit/input_output/local_locator - id = "cc-locallocator" - build_path = /obj/item/integrated_circuit/input/local_locator - -/datum/design/circuit/integrated_circuit/input_output/signaler - id = "cc-signaler" - build_path = /obj/item/integrated_circuit/input/signaler - -/datum/design/circuit/integrated_circuit/input_output/light - id = "cc-light" - build_path = /obj/item/integrated_circuit/output/light - -/datum/design/circuit/integrated_circuit/input_output/adv_light - id = "cc-adv_light" - build_path = /obj/item/integrated_circuit/output/light/advanced - -/datum/design/circuit/integrated_circuit/input_output/beeper - id = "cc-sound_beeper" - build_path = /obj/item/integrated_circuit/output/sound/beeper - -/datum/design/circuit/integrated_circuit/input_output/beepsky_sound - id = "cc-sound_beepsky" - build_path = /obj/item/integrated_circuit/output/sound/beepsky - req_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_ILLEGAL = 1) - -/datum/design/circuit/integrated_circuit/input_output/EPv2 - id = "cc-epv2" - build_path = /obj/item/integrated_circuit/input/EPv2 - req_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNETS = 2, TECH_BLUESPACE = 2) - -/datum/design/circuit/integrated_circuit/logic/AssembleDesignName() - ..() - name = "Custom circuitry \[Logic\] ([item_name])" - -/datum/design/circuit/integrated_circuit/logic/binary/equals - id = "cc-equals" - build_path = /obj/item/integrated_circuit/logic/binary/equals - -/datum/design/circuit/integrated_circuit/logic/unary/not - id = "cc-not" - build_path = /obj/item/integrated_circuit/logic/unary/not - -/datum/design/circuit/integrated_circuit/logic/binary/and - id = "cc-and" - build_path = /obj/item/integrated_circuit/logic/binary/and - -/datum/design/circuit/integrated_circuit/logic/binary/or - id = "cc-or" - build_path = /obj/item/integrated_circuit/logic/binary/or - -/datum/design/circuit/integrated_circuit/logic/binary/less_than - id = "cc-less_than" - build_path = /obj/item/integrated_circuit/logic/binary/less_than - -/datum/design/circuit/integrated_circuit/logic/binary/less_than_or_equal - id = "cc-less_than_or_equal" - build_path = /obj/item/integrated_circuit/logic/binary/less_than_or_equal - -/datum/design/circuit/integrated_circuit/logic/binary/greater_than - id = "cc-greater_than" - build_path = /obj/item/integrated_circuit/logic/binary/greater_than - -/datum/design/circuit/integrated_circuit/logic/binary/greater_than_or_equal - id = "cc-greater_than_or_equal" - build_path = /obj/item/integrated_circuit/logic/binary/greater_than_or_equal - - - -/datum/design/circuit/integrated_circuit/manipulation/AssembleDesignName() - ..() - name = "Custom circuitry \[Manipulation\] ([item_name])" - -/datum/design/circuit/integrated_circuit/manipulation/weapon_firing - id = "cc-weapon_firing" - build_path = /obj/item/integrated_circuit/manipulation/weapon_firing - req_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4) - -/datum/design/circuit/integrated_circuit/manipulation/smoke - id = "cc-smoke" - build_path = /obj/item/integrated_circuit/manipulation/smoke - req_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4) - -/datum/design/circuit/integrated_circuit/manipulation/locomotion - name = "locomotion" - id = "cc-locomotion" - build_path = /obj/item/integrated_circuit/manipulation/locomotion - req_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) - - -/datum/design/circuit/integrated_circuit/memory/AssembleDesignName() - ..() - name = "Custom circuitry \[Memory\] ([item_name])" - -/datum/design/circuit/integrated_circuit/memory - id = "cc-memory" - build_path = /obj/item/integrated_circuit/memory - -/datum/design/circuit/integrated_circuit/memory/medium - id = "cc-memory4" - build_path = /obj/item/integrated_circuit/memory/medium - -/datum/design/circuit/integrated_circuit/memory/large - id = "cc-memory8" - build_path = /obj/item/integrated_circuit/memory/large - -/datum/design/circuit/integrated_circuit/memory/huge - id = "cc-memory16" - build_path = /obj/item/integrated_circuit/memory/huge - -/datum/design/circuit/integrated_circuit/memory/constant - id = "cc-constant" - build_path = /obj/item/integrated_circuit/memory/constant - -/datum/design/circuit/integrated_circuit/time/AssembleDesignName() - ..() - name = "Custom circuitry \[Time\] ([item_name])" - -/datum/design/circuit/integrated_circuit/time/delay - id = "cc-delay" - build_path = /obj/item/integrated_circuit/time/delay - -/datum/design/circuit/integrated_circuit/time/delay/five_sec - id = "cc-five_sec_delay" - build_path = /obj/item/integrated_circuit/time/delay/five_sec - -/datum/design/circuit/integrated_circuit/time/delay/one_sec - id = "cc-one_sec_delay" - build_path = /obj/item/integrated_circuit/time/delay/one_sec - -/datum/design/circuit/integrated_circuit/time/delay/half_sec - id = "cc-half_sec_delay" - build_path = /obj/item/integrated_circuit/time/delay/half_sec - -/datum/design/circuit/integrated_circuit/time/delay/tenth_sec - id = "cc-tenth_sec_delay" - build_path = /obj/item/integrated_circuit/time/delay/tenth_sec - -/datum/design/circuit/integrated_circuit/time/delay/custom - id = "cc-custom_delay" - build_path = /obj/item/integrated_circuit/time/delay/custom - -/datum/design/circuit/integrated_circuit/time/ticker - id = "cc-ticker" - build_path = /obj/item/integrated_circuit/time/ticker - -/datum/design/circuit/integrated_circuit/time/ticker/slow - id = "cc-ticker_slow" - build_path = /obj/item/integrated_circuit/time/ticker/slow - -/datum/design/circuit/integrated_circuit/time/ticker/fast - id = "cc-ticker_fast" - build_path = /obj/item/integrated_circuit/time/ticker/fast - req_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4) - -/datum/design/circuit/integrated_circuit/time/clock - id = "cc-clock" - build_path = /obj/item/integrated_circuit/time/clock - /datum/design/circuit/tcom/exonet_node name = "exonet node" diff --git a/icons/obj/electronic_assemblies.dmi b/icons/obj/electronic_assemblies.dmi index 1e020c396aaf5968bd365b4e3de649eb92a98360..8fd1c4f5e103d398b2f5af104791ae27f98a10b7 100644 GIT binary patch literal 30877 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%0A6mD-+DvTFJQF#2f*XI=Qd%i!zV_LEu7i{>QW=1d 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 V5T-FAzMv7p;)vDZJk#@`{|7gHIxGMH literal 23986 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Π@6p)&jJB(feQh6tcZSCv~m*jF$ z=5ZiP!1KkF@$GWj>0I+F_OE;gthl z(OWqirZT1i6f|pcCJ!Fa7*1#;&nzbP#oiS z^f%xwp)~u);MvUZU|*5~K{frA8T=D6&{5!zqxO+Pm^naKI<6N`{sfItPzx_jXCWN(3} z$_%sp0_xAb$1GZ>KxwdBH17S zr3k`;nBG{6kY0nJ?xDN->(#L+LcVWf^gj`{|llLO~4*_Gzze@4-DL52T@`WGd=wm zApNQn_=HeMuN@Ppc_BtI!<~5*{1GN?28_`hMF5)HM1`fD&BZ8Y`VMCe{bHLVQawuA z@|DNAw7T(Xfwh!;m2-f}|2m1+OuD7q)IK1)(?G_HN{Rvz>Pt|)#TG_n?XPQ5SP(Eg zIIv`g0rrlznWg^6FLN00*da$Tl23NdQ89A26+S6gtkWyq06uP&!P&v#o~32pG}bE7 zbZeMH8124BQmER9XATbq%HivgF}xnPT2V;H;o9)hfj%qr1vVcZID>)%+hvqLe5B-S zpe;ac)E36=dyUul;cgo*msfN0{3oql!WQ;!LZoeM#-6v}N4K1B93 zI5IL)MAvN|mg&bp{D#OfJaL3P(YA%XKwhP%A_b;hDa0UyZh#i~5kxt}NQI1wp^X@+ zGzFXz!y#Dzofi{W^9z-xTRnHCi|4vALoE*}SKpX+h0-wJa`~fF>lD8sGv!jx5E#c@ zDKhL*4l6;K8l4)9j4`w{9y6#pI`%8;`T5D73lGI&6e}xF^e+eBK3MKb7bzY?>I*PP zf3abT5upZ9yQq}Zi=ZPPs+C!*Pe&1e1gE%5e91z+`wY^T{JgkQPN#8#DL|t2r4eI3 z1%A-f;zu8s;<&l`*3k+E%6;?2BS$TFTXs;G<4J^g$@7S8d|n?1Aa>^SoPq+Y;yy7q< zxn=a|S2b5-T;XyZ_xos_U&NZpu6O(TCbcGMHz|~4v4$i;%E7-$K(71pC8B~@xoz?> zJU>6*r23Tq@|+p5_;Oz3j$aU{vE*xK_@AmP|EI9dMuEPC0jOxh+vcp1?GAqL1Ncrr z+4!Plv{m50!V*z;NgrAL4uZ4IIV2C*82!uC_np<%rsKw)=XJ?9afd5KnXxLJgHVm% zu@e^E5BJpl@Ik1whBW+MOBq_tU{&$iemkovi&y|?+)+7Z)?Jl?G3*MNqR*7p%%3R` zuLD{en&gA0Sc4{^+8)s;!MpX^1fb#Gq&=dt5giZ1G#;*e43eP%S?kE4v~3E(dv!c= z&r21x{gpAs6P1FUo6=GUoSSsj7w+bXeB-N@&xvyjClVru2{cf=6Jg>DpMrmL9&X#x zfpjxtSnKCRoZ#lJ^(HwpLs{-B0H7sa7n{;%^QINb{}4aKswH+3lV#BG&5WANB{Mh+n|+@ar^!LT1y z@ktqdlI-q<8%=1_vW;HV=~F|lHofM5`=V|p@>w3t!7VR3OLDc%rxMPO%i;BOu+XmO zu(E@E<%9=8V=l&gJT(e3^T7#KHyX$+1ieW4vp_pfa-FTL?w8Yvdp*OWOB=d)eN?hG zr9Q)*3h~9)BPj^H$#WZtBPc1KP!1dt`vlD(aed@LG^TXi`ZxZE*M2Td%?jSnbp|yD z#h#f2Bs!~aIYCrj5vt(E6mgPIAN400hWl+JSsADO6sr`Pz+B$W;VDbP@DUMZg*+uE z!_|%3%|(5pdZ$*`(cfMs&wz!dUmb?XPS>5nIC$8zX1}3Ifw7 zDMXiThKR-ml+s!9yjm?y=!Er(F8<6z7)RJom1_AB7v(_caaHlF`5?cY&M7S_5~%@f z;v2RnLQCmLRy;l6&!zQv4mZeiO3`PC{Dl`z^4rNWymE7V=BQiT4hA%l#*U*T6A zDD%G;s{U0^=WjIiOl!T|5r5+L7_^bg4 zq-@QUooF*ez^q=WxZcqPg|D^lE8TM-kcbHQz4Da+xY?V2{gVA(#G;`{WPf+O_fe$j zjh{`zNcg z>yA3zGNWu>le-G^RhEr!jTGx{&-bs%GtCznAz8VN*yJWZB$THp7;t^k`^Vz^Yuqka>f880M{ zBAXQ^SQqL0%)ryA)F*IQY1Y%FVd-Vq(`W?>jnmiDsleX zKuc+{_IXPFK&P?c+=}t70cL^-kN?FdB8Uo0oV7!M&69?wQt>1*eVmbsZDkl9z7^b)~ll3bgp8T25|=)eNqxDP*aCcG8Y^C>1? zYp#`4;X!g8S|fnr(L3tT#=U{HCqakqfljBRE6~hQQ9p^{UXj?hiY;v!9)npwzt@6f zuUni!A4|YXTM?Wa25~?|9@y8X?J!+)Ha(Ld_fW#=p0%}rOEwk0PdhFy?qrAnszg?? zOCkaFSZ#E<dp6t&h9m=$#tSlh&oUa>AL#6S&Y^H8`btN)+7B^ne0(^Gft>Q*4Sr_NZ)@ zJoMHoscY_+*ZqP_mH=|F*>lS3(wKsEj*S zoA*UYT1>?{=3}F&nl1PjIttpdH@<=NsfOYntKoPS>8h>IBcvC>YP>SWj(G6moJqqn zJNlqfr13I*cC4~DHuImnoN(i|O57EQwC`1*JEr$X#Caj2E^We=CD&k|%7grasaIP+FMx#bhI1c;;5#L$WO-ZAi4V|@{>TpEHcG+4%I$V&*selq)T;e z_2)?!h$Ag<6>lDi{oC8%Kzijr)zAOlG5epwXfRD+s-$z(p-VdeL>20?M6dx|^}BQy zO~~OL!3$wtE4SbD3=6hx=9!UZT^Kw+sdMcpG863Mb4CVY5ILw;WOYK~Jgo{r=asUu z0>cBCs3%9@{>aJ+>2b#Etx8jV(49Mx;q8w(w5^V~OU*}dU)eHnt`;>l@8yK6x+d>& z5gJlptu@uEy88PKEo;Oac3HB_<*$lSxe}s305hXQT^1Hh{qGUt)uuFS@v1(1r>Nbp zG-Dg?nJ_T#%^$kVHo{sio_p9Qu5{-`Gy~AV^I;M-=RzBfG^o!i#|1=OeO5to{#4L6 zioiqI*5Kmk#@E+(odn+G(8nF)xjD#_3BC1Hx*#`Q8 zE!+pt?xw`4TM!hkB#mOZO}GgZ4aaYeb(Pi5`lrcJ381O`SLD-xFT*|brD`7Oj3AUY zBe6Y58|`wCT#!5XC6>^W2-_~VK1o|}cNx6TYW}A=h*&zSfLXny795*_TvtC21f&ol zM8mlP?evz@9psKWQ@17B)Nf0ij!m>JJ}jgTMaap-TcC{WNIlAFww;4w_V!Oi4)H(o z++E zhpF&srrh~wW8jFFByMQGX}5(o>5lEkoE}8mhRM&vVbfLod#$X$F3;ZoTi^})Y?Ty9 z6CO$Y@L)D&V*C&JbX{DpiYt7s!K@04ZtOVrg}D@>2kqgd4L~?blJO9n^*_*h;lJ0O zuu?EhIY8MK-8Q6ljY_5S?#T)qzfwUrAndj$5DmKeJjRW~#!dX_fsW%f$|J+A^5h9K zD0z`d11&0p5M8e5ARsX8XO(YUxWECLHD_s4V3^1snYYP`|81rXYVO|7msC<%j~C+^ z_2T1y7Zk4qT6({gv#o1dpMwW%kxh$TI^(L>zYE6s8vS%4uggd=>r04}^SyV6`#=I| z_de*AyzR06w4$oY(DUIGvD+Bx4thICZ?pPomge#Yb+gUiWyGEnV$F^{Wn82p%b70x z1_C)d2E}dco5FFZ=o|2>FwAgf-TYwAky>R2rWQLZ48MIMM%nytoB8L8)IF!@nW!bZiwTK^x(lAXhscts2 z`}cRWZ);~UNNHOu*^Q8NmOz*Pw(oaZ+ey6kSy6y3(xE-@kP1i3WG4jHaTr zRCwUM%=>58FP?b?ZV4!H{Zdq}FLlK_q`-AO3eF28`czgZh#s2MRa=A}QE^!MEKBM# zE+FnPLJ)f)@&5vxKY!lF$tfY^4@gR-Uyu7t!MpdI6olAdi9Y$QG_&AAVgMu*NFZQe zw_g2ZG63eJq1Ehk0}g1;xF7GZ4!jIaZy9L&B~|6T)CZCbxI`%5r-yqviOc-obU#GZ zjbK;vOpCZJ%960U``h(97TA-$s&ulETshqNGjE6y9I*lDA}BjLV2ka}RKHBz1YisP zBi_Jd%^w&v`?rcS|Jl+kBswthP((O&} zb`J#IAr}>44US6#vV)v}oq^Kuzb&*PukVlz9UzSB_5HUh$6ZGC45TM%t_<(%q}+MX z2hG6=0czNFw`sSYoAb+)y`^4v0WY)I~vhZhU> zX#=f}7A~8d28}4+M+8OOkYhQMU0JEe5De~V>8ndbWgtcYLk*0+6J#+KC*S-z2OPVa zk{c3~4V1nJDY$2dZ}dB^tHOe`NPUe@`Kc_=72v)ZygkZM{?G73L%JfUCKCc^c}^$W zoE_|2lcbu$?@}Eq`kb={Z4hZ3&TUnEQ;TbxeGmb+Hb>FqzESNbh_UdR%4$5azSrGW z|Dg{Zu%=<^R(a8hic8#N_5%s05NMf?GATbX`2# z4F`P<6D0CSzh4Fc;o^z^$=@(zA)Tfha8NtkARN50p~y4Vm~QzKEu$2EUPvE;`smo> zj)du{bbkzOZ$P8!z29qJus?bYR+}zdA`3O7UtuyCVV&V~HOt@Uk&24?hrdTb(Hx8Z zB9DLrAR_!^rTyU0Q1Cx>SRfBhnxh)k!sRs`YL}5A$D2Az&3j2@~HjSq1l-ZdquuBql?%x zJgt(gPPVo`{x9?{^pgCLV$isb{R4(pc_&V%$Y2Wws+)0|V2%b5o^7_~LquKmY>WT> z=6|Ri_x~ST75}GT8ZB4pL~| zb_hI7wf0Uf@C6v>t(ZyqxS8n45wCrZ@AzUG_h^mCZ;J|(Lg2qY*j$_m1bE)9tcYu$ z-+7tG3!va|Kj<3_MQarLbl3>QhkT7}r8iL*5FSn;xpPLydybAbzkdCi_P;8*@_4BB z{(l%-S-S|4rRA2g6cw_}=vJ;I(neuWawSX2a>ZCGx-GbcNy?}!Nlazm?ogr!&De^v z3}xSj!7yWH{644c-sknae!t)A`ETZ&@AsVZ-9O9w{eBOAZ_$!P;p1!aEG8USb7jlk zFbJmL;DN$JNI>j0;GNr;vD0to!vbpL&t0K#lLTG176>T3z{geXOEXfG4o+O%%7_gg zX~{T1P34Eq>rS(ooxKL~$QA9V4j>WpxwI9~+=D(ponJ;-%tp*I(NP+zi@)JNaA@jS(!d@s9Tbd@^$Qu*fb-F=6{_KOvug(IjpVu21b+5d7t8I@O@oZ7W+C*~lPNe~`EgXzqR2 z`oy|!k(3m9E4K!$PP@?Dr(N8&#wV|PJjBMB!l7&rHBNe8i+Q=y{A>haP{}^IOe!}o zmhZ;QaVWcxoz)(x?es$KNT)HZ-bsp zAwHy;5sSArn|;Z8!M;x5Omy(IyCoK>#tb<%!h$Pp^7TmZc`@iTh=jv7rsY&72a{r5 zk#}cOkLqu%0pQ+r=3*fikX3;H3F;=-k_|B6JCt*ie4@jug%#|RyLK=& z76hoowW@d-pzF&;&a!-qCu{Ns=tbTs8~9c_rRg3e4g7%yVwQB!^nrzav4t415Z6o+ z|I^foBHpgs8&;JSUY!kp{ieq9xs8v3EL6JK%+MBl2S#s0x$lpIYag8uPAF0R`coS2?A2O`Fe!`pg)5a zq-$mB;asn)@2%Z~q^rt&+)`HkF3Sxq3gszBC>avZii+OX_a{A|pInLy{fj%h*h!m! zEg(s-_qL6hXDKqP@GQKNMkEo!7fX5Qq(K~EG7She`BqbEh8k=r6kZp9q*zS9Y8Pup zECD2RN_nlmD^5oo<(dd)&}jsprCEg%l2V#HHVy}p38YRePk2&yTq52g4KxvG6R7Hr zcL!hG7}LLEBaguHU(AA9%0=N`O6osq5LgP;EMM(^7U8dfN{cG$JU-lmnzJcTwb&%i z?DPiEV0irG$qPq>Gh#3i#|~wW%ome7DFbZ#5S5m9>!TL-Wd+5(LUk3;uFSVTBWU{G z$NkJ$)3<(c&=Rg1-QJT?^`%p1TYZJCtkL0wJy;Wkj_g`4|9=25|I1tOF0lAM9+CO- zF`SX0R^Jg%nQx)M$gAH!VWpK)@08x=LnnZ1hJH2Yt=lG$%@K1uOuo0;UvR2nM^=_akkB&NNy6pMxfS8V;NJ z@6$)2f~2I*8{~a|xG=**#QqIIHL?Y8weUIGEp_9UL5~9PzDeRZig0-2-}CTlMxBP! zw{yx+;#-#*T+jHq>Ey)G%py>x`ZD=bUfUs0oj*G*-~Vmp9DUX%^aWV7DM=6Yu+wc( zy{I3)@c-&2XIifNX$`MuD^RyM+Eow_-@0ebpE9BnioFgpQ{^Q4n7>iJif(}7eONYP z>7~e{wzjl;x z_XzaxfsGYBHZkB_Z#=s~#dEo2%&SkRVpGly>kWB=pp(;lMmD#du#BwlO<8;w?4(NO zU6vF7u~FH=aeUb6&=v5fuIl>f$j%zR`V&9n~p`7Lq7-#)pAhcjD2$8n=tlO$x_ zAR!6)&tWcb6@6lXV*6HGV-5$OssQEo@)ZKGK^X`4U<-f9ib5-P5Bt1FN0mgRxCbbC*0Yvua{Z)V)ojBY=!q~|^JtkN7b^U3AW%RUh%@>pZben5U{p@`&bdlT6xS%Ru zZC){o_Q~~CqoeocPCAah)eMK5+qY-CC-kg8#-SQkIs*EOX);J7`5M}9Q6x&A%U=^hUN z9C(E}^YV)Lo~-<5ZZjuFg*iaLJDzN^Ihk6m8B}nl%TUz*(4j{oMXkDT@x0W%M*XWF zY@=pcr}Pt#yrA0j(XuNcaqBD?^3nO-$Z+m2*p0COc(b>Cdt%1+Hp7Yp&Sp23-1&N3ytc=cAoHhH3~@7Q_n!ntv-%^r~g0aJ%N;1dy$?xlmy}O%X;FK<1ZQjwBWcC zX_{f2^W=@Ob8X{?kdx2vbjh{lSc*|emvrLDy|%L>}L7r12u+yBs; z8Iu=EbocXP2OK<=>XV8|=+>HdkTzw#}-YdItN*&Ud;yosMUT+_YMuGA2Cw z0(&Cu$YSE>PV)oM*PRDrVaA@4c9YVf=se*_tq$6ONeGF|bPvC#XE^euy`i}o@@lm5 zWq`RJHku!_6KQK;n6nZGgPL=-erZt7y;D5?GsLocZyNMWbumsO@0pAb7{@c`30D#Y zp6oQ)UAt%7#i*T00%ha0wu=YH^n`v7%^i~!ZzTDv9||6KCTtHO+C5GwyI+rdF8ufz zUaAKXj0)33i2|0DTb$~vTDUDnC6cP_EKO&fQ&o0K=~{>DBf8e9@s8>>RZx-jp9-gO zkxj$J-V$4@*Dzh6#JHx-}TglROO zBuZ=}>*K8DELeAk?y49v8GDkD@$GdV1%yU|WXp9;Xa-CAG!xmTauKUBV;(iFaaU!1 z)wO^5f*zUHN`LIa0A|2c*SLJK({gT=@7QYw-z^hOP5{Zcx!4!aUhi~!4<-KsfZovP z!t7YPG}$RolQTDFL0PunJ;KhP*w&ViZB%dRI5r!fMKG-(*hSEJuc>I#2taRA5NM3z z^2_PGSb~D(&$pQ##ZfkJm~D>?>27l$(#~7n3=|uoOXdkg;>lOhk|0c#KpzPb_4FV& z8q)3?4;`01`<$&UTy@wWe6#H=>A1$wsikobZ2oIs)IMCe4$v9T(>R}i z%TwhjjSoep1Wn%Kj>0NGc8s{${BZ|2GZo~5rq$4sAFPG6(tO6~=u3d&t`1*QPU6+; zJwEr!=>`F8$zQ2*ol?)5xOPfyue#1Fq@ei;x2tX+1y(*Jb%;VXLAcS`TqdigvV1p~ zhTA2*d;zaqj2fqB_M+>y zvBq~x*8!^wVr^in?H9#qas;cO_1hS6L+ieq&aZuqFk0H$djP|oOO5{eB97CXvYF`P z8wG3k-oOF93GST(1k63-AZp@}Yx55W>4AjpEomja-ANc605(w!JU~fSCEs`b?qKOq z`Wn=uC6v}&Pq%2sv#Dkkfyu7Ln#^WODBbL-zXf?Dj@21+hUinDHxNElA67EHom0tV zocK%H$2;OUpU@okTP};rm|LPV_`7cjZL|Javc4QBSA{_g)7 zbEEZfBQ>9auXD3Om!g7f37T|lKX7#u5AkCU5HEhB!^Y4P{8*s6)RPPJmJPxv4=lPVx`$(#%OfEBtYq=inwCe_|fAfxSdZm0bH%Zczxz;^V? zqkhR|25@9w)3;SlOwh-qHf zj~CN@eoUrDbGpQXTK;?GtakT}~54yPsvBTCE5 z2PR%2K&d=eO+>KjW^QiBX0gfx`^v7+!8h2|=sK#Bc0MM&2hSG-?GrYn+B9l*Mq|>- zTI*n+dTqP$lyCMhurfYviN1@gyPWXW)?L_u{kVZhxXYY(i#(_^kSP-^A>qL5F|_H^)LA{V!f3wKinvxw!Fs6UR~eNGtIJ2 z$g=|Xeo9CpUh>Z6O`d+Y4?YflXt|=VCic2X31MU3(mJa^*ZU_bb56>LAj&hVdRy=ODn<9r5^lZ< zA7djC?okT87dmWg%>PV3r}D^D*c~n+%GKD&OwUb2_o7`53)4(!Z$;OtA%0fXl73~= zpZyFUYgq+2WtHVU>Xz|O*0o&Z5fVc!H#O*;F+-|qpL#`5jot->v5W=i(y5>{2T{7EJER-w8l*u|kVb}<4jF2wJN~}^ zx9(kc)|qwIS!b{F=6?3OpZ%u)1t-D53CsYCpRS>oysf9rJ4X*MM|U?6$R|4`b=hf? zmoTh$vy||tS|?kFfTC@|wO6@=uB7_}c?; zjWbgpiF;k2Jz$~XjO`|wvQMk){?b(#*ZpOxz^(hMI;veqi+Z&nmYL>DE16@xpAM}e z`*cm)Gevm+g@$j=UkytW*HbdZ#zg$G!j`W0nC+&1VEU1lcedOw;e-lTu*DA+kq4_E zOGP_-@i+6aPj^2HEnlS|hI7MyjGCwGyZ9vTquHL2hGRX ztPj47rY=qL0n-4O{=c0DOvIhimcJRAkP(Y7h?teqAtbOY>A+16;?Mf)NA$Tb@V=^K4<((J9L&>cwdFiEq z#a2=SALri19!6DCTH4+|ck|Ux&p^-My@9vE zdjf%jp&1QtJ%g)`_EKN}3j-Je>dL|b1@^lyC!1Qgvojpk=1=A)dkNLoF{CaY=Z}o9 z!P4TmZz-?D-SOqF%OBxi`Bv^De3z9aB>}~%odf;H5rkaHk@f4_Me`?u;jBhUYPFZB z#+=NYH*;y}YURmKcQ))hn#}9?#-xLjSx+IdQ>F5Uw$A~IAPE<3fi!{` zBwxsvjII!YpE3&K4pe=F)@5)v0M2~Sr=L(>5BMyc%i9PRYnApn^oH_U43?;6{nKZy zKavDZXx$&L-r~BI^d{BQu0#-)+fVII>IVsBH8@8DCCHDzjoNDG3x2^WG8;sk_shsN z<|Pe`49*fFuV&HF$V+Zo!pqFIoMYA?t{a?swL=F7O0H;- zEYok%${=E%R?9njdL6JV@k9l;z?@T}^JwH|TX#_%!Vgnc|5wqhyP}-%MAZea{9P1_ zNm+1tDA7l|HAv*0g#s`;XIhzTM;5}XU6#Qkuu4Lu`)bn%L%?cNn6-OL{5+Pa|6Zne zY4WXJgc2m3YH&PJ+x6`y^W8ySXS7$=B>KeW>Ibxz&%^j!KpYy?=~7SSVKlR zW+4irUnE2NMQ8wIR)mF|P^km=WoKDN-uC+Er zNbZm$urhvKkAL0>PAJ1iAGcr=;L(gIB)=}=0HcLg5EBx^G{CQ8c&O%VDj`n`G!WuZ+4o%OC6vs22)BKZp-cOy7|Cf*NX(7Go^P&R`4A7rT?%BXk3{YJIW=ujb2cxFmQM3{o12I@TfS59x0#@u)sF#T? z9SM~Blq0k)i8$D-b_YCswJxS=HgYslGzgp< z?EKaeRi-g@8b>nMF&#K`00gW547_NO!u~N;998x4vl3!X}r~XGe>j z47;LpQ(%4)Ew%c{g@zwK(`2QRs1j0s&zHh>l@kv4!Y+0P_$^V^ z+Hop9W^YmmUs=D;b}`~B)UHS|5)dy9LQi1EHD-t`@rOt|CVoatPPdS4c!)}T0yO8x1y!H9PoX-f?gBqQrn+ zz%TJVU>LVI0;)cH)*t#SZGq(dU?YQ9UnKtF{omwUZ(cd5-ftXhX&iUb%TE6AK6b$% zzwwM<5Ob8a{JG}$upB-wB1NQ-Y&X2cfO)bSGlN2GUA?Sk91gTtj9lQWuJTKL&97$= zJ0e|XV{An(Y(`C7S%_xE{>QyCY|__|3T2{bMWX0|M#!!-AEbYy-mb#lJXtnW83JJe zg<$fPFeqZ86rzyziYRdJYS*hq;%L@bbGbwW%~A_zsEWo`$bPyq{*Tn_V9#31QC zt|gJ!5UbLZ49lx8kO~wI-C%9Z5KJv%5DR)@h34iYE2p$(l;ex1A)nbAdBP}7>h*Ms zC`z@oAYi^%DEUu2)M;q&!#7!oqm-KhR@3c_mF3ap!C#oc^#J9sjdx|rtkQafU`;V0 zozIlNqFO3BBA$Gbw#8J2U~4hTfXF@>7iO@bfXAI!>M0!R=hUI13^HsSq4~p_*4V$w zP>3V*U+Fd320KwQS2#2Yl!K(vAmETf>16o?OAxbLO+6)=H9scUS{@|Lfc`1}CmSRY zBoDz#mS%ao32b|sBeN7OVKwNADKEF3H}oC9ZOCL!zzZ7uA*?;!@WOd-5J*n4o;^Hv z8>N9|r0TtvG%0+jZgbJt-p22V^SLQ0Ap<7|N?|ZVN9}h6(o7x9qQ|aoEuKP~{&dkQ zk<6qBbFqc;Py9@l!`$e^gIEreqf7j#I~$~fD>es!=YkbYe3fPrxk`F7u|QRCR_@=$ z4)i>(Yvu!ZGEQD=0x;?!YDQY_t@$hZn3w4dnpaHSZA=qmdg4+~l)5OlNos$;O)R2H zQ$e-(_0FjFLJR`@(_vxm?BxMTNb+yx4(zc2`%Ve&%^|4Qk>BJ{-?~Sq97iH#xB@$p z5P}Qf?+j+@>Q!p78@_Zb;|OI)DDvw*6xG){dSfUSIam2guzK)ZMXLOvP7Nc$#bKOF6~os;=HO;^ zG}@dczM$O(*Pgx)3Op-*oI;s3@0U3h-*_AX=CuPaXySNYozS_BSFXiyqHj7lm$D~+ zw=4MvGO!bgFS^c!m1jGyEqkamG`KI_V5b|=xlhh8$CUlY%&X3{zx1tNM{MfO7;lHK z3%<4+qSPphMEQC9gGxe=7!xHm?~&z9mNJU*d3H2(SIegdQ(*3ZgOfHsvW%ly*qID~ zJ$UZx`W=k&oF`c#Lr(shzY#a;r~IRE*oTm@JBCygI~R>)hBkXsY0~_D-TUk5{D_iE zd3HK22EPFYX#s~wLbl|cBKIx}t#a2t_9C6W%dW{(wHt)J33_D98rjm}71kbFMC$Ti z4fS;7PJY+*_>-(g%j?~#ZjcyhOO*hU2YD7mmTqcTs0l6-1YmJ2-xF8Y!~GXqZ)(a%0)+goJ2~iloVDuQJz(iQR7!yP$78 zrHF_vu-$M*Q8RDMO|%NA-Ny!lnJS|2^%No*ETwrP9PZMyoSnOb*1M)~)9`?gD3p66 z0%Eo41}1LS4G{Pfi;sCv1Ybyrr7+_C0ykGRn)66E8f-A%YHv+w6(KjyuS>niW1NaS{?bVuE)@MpQlEe<{fz6lfI&WpA?Jy!o`Ff zeGAEFmese$RE}&EoO4MkPOx20P8#ruJzJOAR$${v%r7JD30^bO(R8M1H6)h7gdb13 z`J6W|@1B}>5emV(8m5Wn8z+MNUvhJE|L@~nA%!D`eiZdbAay{2w67OuJf^|*N4a)L zdKK-=uNtxkcHu2rB^%uX304P*-4N|#HJML^mhJJhCb=@1Syd(Gkra`z?$T;JR#LQW z?MrqqdlWfd<|96r!8PIjzKcoI`)V)oX9=!oGcB8{(`jM4q|2-820H3YE`^3qNH08s z&2%({!l_tBp_TyOpNKC@nn$ALY|<-+(P%vnK{($k3MF=eN^23qWU!YOClB>Yi8{_c>_j?&HKIk(QxHD(afyS-NlR1mJ z)wj#BP`EpV!7ab&cPP8PjR`BL`cd1Y)K2p!r9vVkdmqpgcgNnhSLTbpH$D@BSP3pC z4y&NcH)9H0=>JxL#bVtS{FC&gRlrKh;_+G{y56YqNVZW54 z?jhu&ET{ry=ugY;a>l-j#vHx!5)~m@@+%aSr!qzX#n}dGFEFmy!`KMrNy#dDIu~>h zv!uUjfHDmw!7x_4qQH3Kp~{LQ+=W-G8{LjESEuV^>Xg?qW0MvjkSyln>O@x16Ov0g z04pPSz>D+pixDM(B{g)SQZhe-r^D`<3q{naN**8)a3mb9t47d0p2Cfp5!1c4mg(%uvesl7(wHIE8^nZ|QSvfU zxm53^e?3?D61;I8O67xGl|yNxDl)#loqdv@<6u*7*37^}5qNO#!gbjE)`H_{Mbv|U zy)_^jgGx&avgBXAU*|=v03WEA^sD(LCaw%mF-hUf*}?~S11+-6L;V2{Dfw9^tJkWc zlZco2&$2}V9jqdag7^BfVTiGSmYO+pe{I|a*1*c2VYm%$-51Dg`&nBWD69rUZ(Q&w zLHJrk1ynWZNVN@CUn5V%*iIw>Y`T8>P&hH4ZQ)h@q&%0v?uu?mfm5m_Z-T)wV_Awal0 z9q8Y=47=&?f7#c=bd3mux*rDo$!+-jaqPI!FHux*&n&wy7XS{}Y6s?_;RTHiD8 z5|3iN?1sm_=vJI*+CjN3a38-Fa%(u~J16Lvo4nQD+6cy!B`#)*W#e1gPJJo>r>bFl zN(e}H02%JTzVR5GOC)7EO{2{B563@nEo2}~c99w6YJbKKPap^sxh{4$^|2B(bADb& zkC^MU=r~e^pF>GAinABDHC{ihH;Xz zWsczEc!>Sp^3Ak84!?GF*y!@@2_gNtj?`}sKve3Y+K52ih|mpwQ9Qgou!P$pv|+|I z>9445SnERy6B@_Tv@?@8pAB>vN1*U+?|qwt=j~!DfofQqCb<&YrZ9aCgkGH3vAu{2zp= z6q+xOIVUzVyBK3(8QT|#e20$+u$3E^Wn8A{ceS_qTIxBnzUZiwEU&Gdv{glx(tRUe zddXe3k((zvToFs;Gdtl*FtRc)mG(Np|AHKl#FWIUQNkXbuw3`9z3p*Z#A)@L1l15; zIH)%M05Xv?;5qf)L3Q%9uSVQ$*Xj1Xv+KA)LP*Kx(U{0e z5PvZ`fsBVJOfLWcbImxp*eK2Tl(rvJwJW3isVN|0G31<*R7NpW-5sLv>AGt=^ zc{Wp1(5&oF%=M${zq-+VY-{pni%u$y^xXK@k>Z!ONBP{>Wq*Gj;+{FS zS&snPl}P1ZYR^MH*nS@vFrJUGs9DPRiDPtLNpJ5JfXxPaqa*4tmd^LDatkCFJl%r^ zI^uc2U=I-_L)|D5!Sv&P-xpqRIS29YVUU7?&MPt0Zke>mJ_u~Q(jD;RaUC|U#fD(m z@aZgEQ z7K4Be7j(T}S*v1@|8BDC)IgCP_L_Dfv>tpl0;_(*@znY`4Q2!t>$WZdHNUl`NuS+iS=i&zb59}$e znHxSAH%kPv zgd11AE)Zk&t(n{i{3s1VI;R~g&vW7hNbsCiGC=glj~{i;^Usk^`tc^S?c4dKjA&~+ z_(b)0#8*6m!kyZ@eDv>PIwBkUX-zyHi`cv*aBIbvC8ai<663rz2oH&dUZ1xKT& zY-sBA>%oRq(>rR!?`6oJ10=!)>}tfJwMK+{+PwS&PR$>7vIsT<{}eWyO(@uBxlv!; z4D^QnvA+4sQx~AjLJoaLJZWaWSDBk)@PSsD9~Mx5xMX7pzXX9Yd!CG^S+z{6psLXnlK8&B6POcB=vGe+$?5Y|6Uf*SY*e zASEdB*dVa-T42s*8u#{jdE2*u8w$hLQ&Tn@rL{NXk}CysU;obBjRk>S(Z}q16j5dk ztbUZ8^9F9<4%u`9{~`eb(bFCE50CQHOAKm|2tV|{VZ=nw0;7JfG3)q3m&NJ4>~yhs zjI_eKPmjX-9dih4Za0xZ_nn+e>%J_Fs}JF1RUo$ac=k!#!~PHDF-c$I292d~ve-fK z82r%@P>yAoi55q(pap}-$({y;#^6XT{imRPToB(k8$gQ_pQd=%)j=4j8n{_0u0_v& zj>be1=M_`}gR0P#WpQ=5b{fWCp;X@R*Q~;VE3ZV--5OkLwSFA;yBj#$bs!LEhJp7e zfnxMUnfC|@0lNkmLHx54GWBPN7~_*D)y}96LFCsPBf^a}c$S7*MCc>@Kh(3om&tt6 z{ICHz1ttO6_CIuoH^<(A)T3kHd<`E<12KUMa**XaW)zT*-I0#Z^?C%m@FB&RN43C) zcep9W_uCN)rkpc=>-v@U4ucNL$Bp27!!UeiQ4d{#-*dbkColhaDnV;LtE7dzeP$!H zh}79~J=enWW*D~ncI~PLm^v;nVrr78gz5hPj#b+qdlmtH*EC-mqPGGK)q#AUeOp31 z$-?*`KO=eKX@=Gb9)cOu?uI>cbm1L30vphdliuN2>WlkN69_uc+5r=A9*FyAQj$7t zE~p~Q{kpP6^X0Y0`}1)O7h#u9;bT~vr~L$aIw!$|%ERM2c`4!N6s50GuI8&Bzmm!U z7{r22S^-sYXm#^vF9LGFE#C4o^vPfseNOlZ2qZsh0+0UvHt2LcT*bw{bLQ zMTcwU4FVhuj_;U59Hx6%?2<7$6Xc4os1r;?DjljyczpXbY9m|7-#oQNZg|z~fJ>eJbN-w4Qj1(vw zp1F{0UCsnhX~cABbaz<}C5c}5d}=LywJiDg1%@cO?NPE=&-!B)K1py-Z#oS~(os4? zAG-oitPfHv`K&g?t|x2_u7%^e@8?ef{M}e%Sl2U6@ON)95XtYYlp2sFynoQOT+B)< z5y^h@-g3~}#&sF-FkJ)Tlh* z?@jL9wz#z!cVC|WVH1$H3o`iKO$$1mC%d{W8L|5wy-F9nvHv=P1_s0+@2xk902tKy zunTPNC_SLnN+Dp-UD#;{kn$OW2d{;@m4HcUl81h$x{NCpr{iWf)3cSxE|WYp-x%sJH<U~L#U8{akHBOM?830~ePbKd>&nobtjP#f4?}!)rHZ-7+wuc-+jJ9{d%Kl(-z2X-X16>qZa$X>_YYJH`jt25xQJz zO3|gfA`lP@_LlFA1*1ya*f8aq_~9V`(d_7Bmp8Uh(CHa8@OsWRZGA7rc<19x6MbW2 z<64~1AC%yr`$hW4kT`emwFaq&flD7Aqn4l-bJZFFyXg2??zTAg<~+zFD*`_U2Xb-m{=u!)5)f z#@al7)bVK*hg9>wYH3!2Mx|Vs&A)fn|4gcZbI&WHE+|h&>Owk>jglLV5k_i=(Af|W zaRDYn*G(?|D7(-^D-|zDHTy!$#pql>yai6aayI3hE(J(RIzZ_Bb{Q?;lwzxXIC+3; z(Sp;${MFrnA^fvd$B9S4-;pl%q|1iwdNIYq!d>4+uhqC`AUSAtP7KXE7?}e$KAQRB zr`fB{c#J<5`)$IbqM{#E1!O)DyUiBnq3}*d@O0i^EydceUaID0)Fz6AuR8EsNXZd? z7<`Ge^H+BphK(B~7AXDH@6N@$HX3+qf2))mUvPN%JJ|N`&G|a54+Hdh-{c~XrQ}HJ zbDZ7-%DODL06D7UFH#vL(L=;m4v7-2lMD!pq*=g1Kjx2@p}O;Tdl!kd$c9D|nMv+0 zwBW~`19Cg4IxNck-H8g(Jqn0GQh3_yh$SoUuFdh*{qaI2VoFi6U> z!9qHVh@fptiBjkyC??adJ2$iWV4LjPTBG65(jehyvP%WtT_!9~x3)n~S7`zB%A5Uu zXU&+5^4Xx%zR$}~YUCFeJ1%(p4^nj0uBh$1A4NCroum&qT6F;v4GH>i z6NfO@t(p3@Sq{jjp5(O1CcOn-gDhO!GKPe&*ofp5(dHtI0DPIEtRR0dj?(q`h*aS2 z-{B{gFuo~?@cK6<$M$ciqyV>g$E=K#egD<)7-yIGvv;(EW#y5$;buIw-*;GnxYt(_ zB_}q|TCX%7DL_CLk-q`n*szF_s?1{rH2v}CV?VTVuN^I)q16Ww z`KLqyC(}-MNB5iNjm$sxuli@2np*u=J44jx%n*Be=e@xa&=NW2v7Is7deo%t_Fy@9UZiu_PMkFy?~Kn(k!JooqByR~n+`T$!`5d5 zu%Vqmb#*I4M%wOTWcc!LGLN1AGbXp>BpoBbmW!*rP@A&{~W@X7I z!jQ#ym%)!#7PEJ?^_sw3HE%b0WTeXXvH z9+~`0es{Irf8IP@=d5T|^|Jx+_O=KLy=g3+d; zZU>k8f9h#e6EFi{QK4|S3QROi*X-l{FYmsL{F9fmIpv}t(`PQSZ5>Gwrg;F88K}ui z3~Gl)+lN4_!6MqXA0|G)9&k4`>bcJ|PyZf1YxFK5_YV0t&OLqxcf|ocXy0VWk|N~H z1SX0uMlu#2#KHfw1y2Ufih@6oJ-I40p79lS-13ekf^qgASwbVK%;&|><5+F-GOkGz z_w9>oFNESzMSFYE?fo3k62}Oug}LDlULm>;-fq*Be~Tx1p#*H~dweH=!L-ur z*Q*y7e3Xsn)$U3qh&aZGeZd=N#@C-`uKK4wLNMZ-?1@eKzIPoUil|$h1BGgGu%#}j zLjCR)$uSP)u5YHj5hhzIFh^X8?fXB-wbuJ7$$gA0p`xrZt~ww*3cii)4D-&4x| z2&J4?56wfw$aV!W#Va0l7oQiOz*~mXpfi+yKW-;4a4JvapCMx&z~4wYr1wWg_rJ0l z|9*d8RjM1zP2sjH9a17}>Ah^&*r>oC1TKf)4m2J065LE-VBaEQZFcR?CAU=aFhh=D zPc0C*2b2Kvv#^;9@R7Sa3oNhO^uiUd6$W z_ZktGxTDhIE@Dg2VC&-s1wO_OfBW()w-4{XiTNh*fKuD>w%DCU?j^}z6&SafnUrmH z<3&RzeA$KD3(14sk889LE2ffV>q z3it2a=Zzop@JC;Cf&b&6?C)>seDW<30!7QSi+`j>Gd@27ypHFt^G=ByCwcrf@{6efVbRd{jBUe?%QBlK%TRKsN-%Dfu53)NZsS#b=_wO5Q5RbSd-gxYgrjZfW(+Gx; zIRe?lzJw6Kcu`muldV{jjH;qS8aq{%lsVha-F6Q3a1YrIQF{A@A5xGtX`|yhuB5ls zxRZn2YIDk)iw#y%V1~5wFu;S+>TUX%+FjP8w;)m-$s4-f6?<` zTAQKq#Zgjqy0vK(#{bKv0y=7Ts0Vup{r&xYejHiqbOC$(cqva&GeQ$ob$)sZmyG$( zkxj-o!ul~!r}CtSH|%{h=39Elu5Jy?LLX*l8NNWYzDUQgqGNqjW+ycYBaSU>ErK9P zsL5KBv<69}BQZ?8%TRh8zupj{v^5B9lf;_n<4X^QwYmB!GrHwvSl z_lDC401?s8+lSADZOx*`Q`1? zh~mjca1o8%bAm{x8hzs6FfchT!0M)eXv!vJXU3rZjZ~j0Ci=Jl4wWURGPJt-cTBr!&-;_x?14^#Xm} zh>%7-?b!h#1SI~XY4WXvN3t~%179U?*t~Zc{ItJ^Feman;|%LtC&f2Gm83F0e+Z%3zxZ*P7PZt7zGS(!QhDt@@IvJ03v0V4QvC^WV_lUg$$=+~{I&j9xoUZiaaw z%I(&I4ob5=`WGM}pK~2qTqlbn`*mI$alXB;dUh{d8LHXv<30ppr0?;P%U+_@3*k04 zuMsGumMv;>xj%tc+ptXk7n}TRNu_EIY=C&(lnThSNz&~@)5(O8`3%50x%_| zcv#UPHE9=QxBs3o7qU=aMut4Bu(5U}(^qxu4ZFW*6f1ISE2um$8J~9!6uUfu#k*Vl zbv+E%r(W0-24zbIKC$-QQ7QY^P2^#QW8G7!hl&1)orlD^vd+ql8e}Pr_K`+!sz49@pWgY`ACbx0(zC>z{BX^n){_msi%Ds*#r8-_Rv|0}kg&-akXz%R7E z8i-hPTP29=+xyn)WVo~QW&#;KL!rKf4gTsH_dnjj*U=NcC>8}J8_8{c%wSu~QjjUzJ{{ui(Bp3hy delta 12141 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 WfbU?PR11LMuMbiRk`>}c0sjwP{loqM diff --git a/tgstation.dme b/tgstation.dme index 1c1ca76e67031..5b2b43bc38ccd 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -724,6 +724,7 @@ #include "code\game\objects\items\weapons\implants\implant_storage.dm" #include "code\game\objects\items\weapons\implants\implantcase.dm" #include "code\game\objects\items\weapons\implants\implantchair.dm" +#include "code\game\objects\items\weapons\implants\implantcircuits.dm" #include "code\game\objects\items\weapons\implants\implanter.dm" #include "code\game\objects\items\weapons\implants\implantpad.dm" #include "code\game\objects\items\weapons\implants\implantuplink.dm" @@ -846,6 +847,21 @@ #include "code\LINDA\LINDA_fire.dm" #include "code\LINDA\LINDA_system.dm" #include "code\LINDA\LINDA_turf_tile.dm" +#include "code\modules\integrated_electronics\_defines.dm" +#include "code\modules\integrated_electronics\arithmetic.dm" +#include "code\modules\integrated_electronics\assemblies.dm" +#include "code\modules\integrated_electronics\converters.dm" +#include "code\modules\integrated_electronics\coordinate.dm" +#include "code\modules\integrated_electronics\data_transfer.dm" +#include "code\modules\integrated_electronics\input_output.dm" +#include "code\modules\integrated_electronics\logic.dm" +#include "code\modules\integrated_electronics\manipulation.dm" +#include "code\modules\integrated_electronics\memory.dm" +#include "code\modules\integrated_electronics\reagents.dm" +#include "code\modules\integrated_electronics\time.dm" +#include "code\modules\integrated_electronics\tools.dm" +#include "code\modules\integrated_electronics\trig.dm" +#include "code\modules\integrated_electronics\~defines.dm" #include "code\modules\admin\admin.dm" #include "code\modules\admin\admin_investigate.dm" #include "code\modules\admin\admin_memo.dm" @@ -1134,19 +1150,6 @@ #include "code\modules\hydroponics\grown\tobacco.dm" #include "code\modules\hydroponics\grown\tomato.dm" #include "code\modules\hydroponics\grown\towercap.dm" -#include "code\modules\integrated_electronics\_defines.dm" -#include "code\modules\integrated_electronics\arithmetic.dm" -#include "code\modules\integrated_electronics\assemblies.dm" -#include "code\modules\integrated_electronics\converters.dm" -#include "code\modules\integrated_electronics\coordinate.dm" -#include "code\modules\integrated_electronics\data_transfer.dm" -#include "code\modules\integrated_electronics\input_output.dm" -#include "code\modules\integrated_electronics\logic.dm" -#include "code\modules\integrated_electronics\manipulation.dm" -#include "code\modules\integrated_electronics\memory.dm" -#include "code\modules\integrated_electronics\time.dm" -#include "code\modules\integrated_electronics\tools.dm" -#include "code\modules\integrated_electronics\~defines.dm" #include "code\modules\library\lib_items.dm" #include "code\modules\library\lib_machines.dm" #include "code\modules\library\lib_readme.dm" @@ -1535,6 +1538,7 @@ #include "code\modules\reagents\Chemistry-Holder.dm" #include "code\modules\reagents\Chemistry-Machinery.dm" #include "code\modules\reagents\Chemistry-Readme.dm" +#include "code\modules\reagents\Chemistry-Reagents-Helpers.dm" #include "code\modules\reagents\Chemistry-Reagents.dm" #include "code\modules\reagents\Chemistry-Recipes.dm" #include "code\modules\reagents\reagent_containers.dm" From 90269ab43443f12445e23385211244c602a2f597 Mon Sep 17 00:00:00 2001 From: Stakks Date: Mon, 23 Apr 2018 13:40:12 -0500 Subject: [PATCH 6/9] Stage 6 --- .../integrated_electronics/_defines.dm | 420 +++--------------- .../{ => core}/assemblies.dm | 160 +++++-- .../integrated_electronics/core/helpers.dm | 55 +++ .../core/integrated_circuit.dm | 282 ++++++++++++ .../integrated_electronics/core/pins.dm | 139 ++++++ .../{ => core}/tools.dm | 0 .../integrated_electronics/data_transfer.dm | 79 ---- .../integrated_electronics/passive/passive.dm | 7 + .../integrated_electronics/passive/power.dm | 109 +++++ .../{ => subtypes}/arithmetic.dm | 0 .../{ => subtypes}/converters.dm | 0 .../subtypes/data_transfer.dm | 179 ++++++++ .../{ => subtypes}/input_output.dm | 207 ++++++++- .../{ => subtypes}/logic.dm | 0 .../{ => subtypes}/manipulation.dm | 0 .../{ => subtypes}/memory.dm | 0 .../integrated_electronics/subtypes/power.dm | 80 ++++ .../{ => subtypes}/reagents.dm | 0 .../integrated_electronics/subtypes/smart.dm | 33 ++ .../{ => subtypes}/time.dm | 0 .../{ => subtypes}/trig.dm | 0 .../{ => ~defines}/~defines.dm | 0 icons/obj/electronic_assemblies.dmi | Bin 30877 -> 32741 bytes tgstation.dme | 33 +- 24 files changed, 1287 insertions(+), 496 deletions(-) rename code/modules/integrated_electronics/{ => core}/assemblies.dm (50%) create mode 100644 code/modules/integrated_electronics/core/helpers.dm create mode 100644 code/modules/integrated_electronics/core/integrated_circuit.dm create mode 100644 code/modules/integrated_electronics/core/pins.dm rename code/modules/integrated_electronics/{ => core}/tools.dm (100%) delete mode 100644 code/modules/integrated_electronics/data_transfer.dm create mode 100644 code/modules/integrated_electronics/passive/passive.dm create mode 100644 code/modules/integrated_electronics/passive/power.dm rename code/modules/integrated_electronics/{ => subtypes}/arithmetic.dm (100%) rename code/modules/integrated_electronics/{ => subtypes}/converters.dm (100%) create mode 100644 code/modules/integrated_electronics/subtypes/data_transfer.dm rename code/modules/integrated_electronics/{ => subtypes}/input_output.dm (75%) rename code/modules/integrated_electronics/{ => subtypes}/logic.dm (100%) rename code/modules/integrated_electronics/{ => subtypes}/manipulation.dm (100%) rename code/modules/integrated_electronics/{ => subtypes}/memory.dm (100%) create mode 100644 code/modules/integrated_electronics/subtypes/power.dm rename code/modules/integrated_electronics/{ => subtypes}/reagents.dm (100%) create mode 100644 code/modules/integrated_electronics/subtypes/smart.dm rename code/modules/integrated_electronics/{ => subtypes}/time.dm (100%) rename code/modules/integrated_electronics/{ => subtypes}/trig.dm (100%) rename code/modules/integrated_electronics/{ => ~defines}/~defines.dm (100%) diff --git a/code/modules/integrated_electronics/_defines.dm b/code/modules/integrated_electronics/_defines.dm index e2cb92ea00dc4..c7478ba924224 100644 --- a/code/modules/integrated_electronics/_defines.dm +++ b/code/modules/integrated_electronics/_defines.dm @@ -8,6 +8,50 @@ #define IC_SPAWN_DEFAULT 1 // If the circuit comes in the default circuit box. #define IC_SPAWN_RESEARCH 2 // If the circuit design will be autogenerated for RnD. +#define IC_FORMAT_STRING "\" +#define IC_FORMAT_NUMBER "\" +#define IC_FORMAT_REF "\" +#define IC_FORMAT_LIST "\" +#define IC_FORMAT_ANY "\" +#define IC_FORMAT_PULSE "\" + +//Some colors + +#define COLOR_WHITE "#ffffff" +#define COLOR_SILVER "#c0c0c0" +#define COLOR_GRAY "#808080" +#define COLOR_BLACK "#000000" +#define COLOR_RED "#ff0000" +#define COLOR_RED_LIGHT "#b00000" +#define COLOR_MAROON "#800000" +#define COLOR_YELLOW "#ffff00" +#define COLOR_AMBER "#ffbf00" +#define COLOR_OLIVE "#808000" +#define COLOR_LIME "#00ff00" +#define COLOR_GREEN "#008000" +#define COLOR_CYAN "#00ffff" +#define COLOR_TEAL "#008080" +#define COLOR_BLUE "#0000ff" +#define COLOR_BLUE_LIGHT "#33ccff" +#define COLOR_NAVY "#000080" +#define COLOR_PINK "#ff00ff" +#define COLOR_PURPLE "#800080" +#define COLOR_ORANGE "#ff9900" +#define COLOR_LUMINOL "#66ffff" +#define COLOR_BEIGE "#ceb689" +#define COLOR_BLUE_GRAY "#6a97b0" +#define COLOR_BROWN "#b19664" +#define COLOR_DARK_BROWN "#917448" +#define COLOR_DARK_ORANGE "#b95a00" +#define COLOR_GREEN_GRAY "#8daf6a" +#define COLOR_RED_GRAY "#aa5f61" +#define COLOR_PALE_BLUE_GRAY "#8bbbd5" +#define COLOR_PALE_GREEN_GRAY "#aed18b" +#define COLOR_PALE_RED_GRAY "#cc9090" +#define COLOR_PALE_PURPLE_GRAY "#bda2ba" +#define COLOR_PURPLE_GRAY "#a2819e" +#define COLOR_SUN "#ec8b2f" + var/list/all_integrated_circuits = list() /proc/initialize_integrated_circuits_list() @@ -20,377 +64,19 @@ var/list/all_integrated_circuits = list() icon = 'icons/obj/electronic_assemblies.dmi' icon_state = "template" w_class = 1 + var/obj/item/device/electronic_assembly/assembly = null // Reference to the assembly holding this circuit, if any. var/extended_desc = null var/list/inputs = list() var/list/outputs = list() var/list/activators = list() var/next_use = 0 //Uses world.time - var/complexity = 1 //This acts as a limitation on building machines, more resource-intensive components cost more 'space'. - var/cooldown_per_use = 1 SECONDS - var/spawn_flags = null // Used for world initializing, see the #defines above. - var/category_text = "NO CATEGORY" // To show up on circuit printer, and perhaps other places. - var/autopulse = -1 // When input is received, the circuit will pulse itself if set to 1. 0 means it won't. -1 means it is permanently off. - -/obj/item/integrated_circuit/examine(mob/user) - ..() - user << "This board has [inputs.len] input pin\s and [outputs.len] output pin\s." - for(var/datum/integrated_io/input/I in inputs) - if(I.linked.len) - user << "\The [I.name] is connected to [I.get_linked_to_desc()]." - for(var/datum/integrated_io/output/O in outputs) - if(O.linked.len) - user << "\The [O.name] is connected to [O.get_linked_to_desc()]." - for(var/datum/integrated_io/activate/A in activators) - if(A.linked.len) - user << "\The [A.name] is connected to [A.get_linked_to_desc()]." - - interact(user) - -/obj/item/integrated_circuit/New() - setup_io(inputs, /datum/integrated_io/input) - setup_io(outputs, /datum/integrated_io/output) - setup_io(activators, /datum/integrated_io/activate) - ..() - -/obj/item/integrated_circuit/proc/setup_io(var/list/io_list, var/io_type) - var/list/io_list_copy = io_list.Copy() - io_list.Cut() - for(var/io_entry in io_list_copy) - io_list.Add(new io_type(src, io_entry, io_list_copy[io_entry])) - -/obj/item/integrated_circuit/proc/on_data_written() //Override this for special behaviour when new data gets pushed to the circuit. - return - -/obj/item/integrated_circuit/Destroy() - for(var/datum/integrated_io/I in inputs) - qdel(I) - for(var/datum/integrated_io/O in outputs) - qdel(O) - for(var/datum/integrated_io/A in activators) - qdel(A) - . = ..() - -/obj/item/integrated_circuit/proc/nano_host() - if(istype(src.loc, /obj/item/device/electronic_assembly)) - var/obj/item/device/electronic_assembly/assembly = loc - return assembly.resolve_nano_host() - return ..() - -/obj/item/integrated_circuit/emp_act(severity) - for(var/datum/integrated_io/io in inputs + outputs + activators) - io.scramble() - -/obj/item/integrated_circuit/verb/rename_component() - set name = "Rename Circuit" - set category = "Object" - set desc = "Rename your circuit, useful to stay organized." - - var/mob/M = usr - //if(!CanInteract(M,src)) - // return - - var/input = sanitize_text(input("What do you want to name the circuit?", "Rename", src.name) as null|text, MAX_NAME_LEN) - if(src && input && CanInteract(M, src)) - M << "The circuit '[src.name]' is now labeled '[input]'." - name = input - -/obj/item/integrated_circuit/proc/get_pin_ref(var/pin_type, var/pin_number) - switch(pin_type) - if(IC_INPUT) - if(pin_number > inputs.len) - return null - return inputs[pin_number] - if(IC_OUTPUT) - if(pin_number > outputs.len) - return null - return outputs[pin_number] - if(IC_ACTIVATOR) - if(pin_number > activators.len) - return null - return activators[pin_number] - return null - -/obj/item/integrated_circuit/interact(mob/user) - //if(!CanInteract(user,src)) - // return - - var/window_height = 350 - var/window_width = 600 - - //var/table_edge_width = "[(window_width - window_width * 0.1) / 4]px" - //var/table_middle_width = "[(window_width - window_width * 0.1) - (table_edge_width * 2)]px" - var/table_edge_width = "30%" - var/table_middle_width = "40%" - - var/HTML = list() - HTML += "[src.name]" - HTML += "
" - HTML += "" - - HTML += "
\[Refresh\] | " - HTML += "\[Rename\] | " - HTML += "\[Remove\]
" - - HTML += "" - //HTML += "" - //HTML += "" - //HTML += "" - HTML += "" - HTML += "" - HTML += "" - HTML += "" - - var/column_width = 3 - var/row_height = max(inputs.len, outputs.len, 1) - - for(var/i = 1 to row_height) - HTML += "" - for(var/j = 1 to column_width) - var/datum/integrated_io/io = null - var/words = list() - var/height = 1 - switch(j) - if(1) - io = get_pin_ref(IC_INPUT, i) - if(io) - if(io.linked.len) - words += "[io.name] [io.display_data()]
" - for(var/datum/integrated_io/linked in io.linked) - words += "\[[linked.name]\] \ - @ [linked.holder]
" - else - words += "[io.name] [io.display_data()]
" - for(var/datum/integrated_io/linked in io.linked) - words += "\[[linked.name]\] \ - @ [linked.holder]
" - if(outputs.len > inputs.len) - height = 1 - if(2) - if(i == 1) - words += "[src.name]

[src.desc]" - height = row_height - else - continue - if(3) - io = get_pin_ref(IC_OUTPUT, i) - if(io) - if(io.linked.len) - words += "[io.name] [io.display_data()]
" - for(var/datum/integrated_io/linked in io.linked) - words += "\[[linked.name]\] \ - @ [linked.holder]
" - else - words += "[io.name] [io.display_data()]
" - for(var/datum/integrated_io/linked in io.linked) - words += "\[[linked.name]\] \ - @ [linked.holder]
" - if(inputs.len > outputs.len) - height = 1 - HTML += "" - HTML += "" - - for(var/activator in activators) - var/datum/integrated_io/io = activator - var/words = list() - if(io.linked.len) - words += "[io.name]
" - for(var/datum/integrated_io/linked in io.linked) - words += "\[[linked.name]\] \ - @ [linked.holder]
" - else - words += "[io.name]
" - for(var/datum/integrated_io/linked in io.linked) - words += "\[[linked.name]\] \ - @ [linked.holder]
" - HTML += "" - HTML += "" - HTML += "" - - HTML += "
[jointext(words, null)]
[jointext(words, null)]
" - HTML += "
" - - if(autopulse != -1) - HTML += "
Meta Variables;" - HTML += "
\[Autopulse\] = [autopulse ? "ON" : "OFF"]" - HTML += "
" - - HTML += "
Complexity: [complexity]" - HTML += "
[extended_desc]" - - HTML += "" - user << browse(jointext(HTML, null), "window=circuit-\ref[src];size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1") - - onclose(user, "circuit-\ref[src]") - -/obj/item/integrated_circuit/Topic(href, href_list) - if(..()) - return 1 - var/pin = locate(href_list["pin"]) in inputs + outputs + activators - - var/obj/held_item = usr.get_active_hand() - if(href_list["wire"]) - if(istype(held_item, /obj/item/device/integrated_electronics/wirer)) - var/obj/item/device/integrated_electronics/wirer/wirer = held_item - if(pin) - wirer.wire(pin, usr) - - else if(istype(held_item, /obj/item/device/integrated_electronics/debugger)) - var/obj/item/device/integrated_electronics/debugger/debugger = held_item - if(pin) - debugger.write_data(pin, usr) - else - usr << "You can't do a whole lot without the proper tools." - - if(href_list["examine"]) - examine(usr) - - if(href_list["rename"]) - rename_component(usr) - - if(href_list["autopulse"]) - if(autopulse != -1) - autopulse = !autopulse - - if(href_list["remove"]) - if(istype(held_item, /obj/item/weapon/screwdriver)) - disconnect_all() - var/turf/T = get_turf(src) - forceMove(T) - playsound(T, 'sound/items/Crowbar.ogg', 50, 1) - usr << "You pop \the [src] out of the case, and slide it out." - else - usr << "You need a screwdriver to remove components." - var/obj/item/device/electronic_assembly/ea = loc - if(istype(ea)) - ea.interact(usr) - return - - interact(usr) // To refresh the UI. - -/datum/integrated_io - var/name = "input/output" - var/obj/item/integrated_circuit/holder = null - var/weakref/data = null // This is a weakref, to reduce typecasts. Note that oftentimes numbers and text may also occupy this. - var/list/linked = list() - var/io_type = DATA_CHANNEL - -/datum/integrated_io/New(var/newloc, var/name, var/data) - ..() - src.name = name - src.data = data - holder = newloc - if(!istype(holder)) - message_admins("ERROR: An integrated_io ([src.name]) spawned without a valid holder! This is a bug.") - -/datum/integrated_io/Destroy() - disconnect() - data = null - holder = null - . = ..() - -/datum/integrated_io/proc/nano_host() - return holder.nano_host() - - -/datum/integrated_io/proc/data_as_type(var/as_type) - if(!isweakref(data)) - return - var/weakref/w = data - var/output = w.resolve() - return istype(output, as_type) ? output : null - -/datum/integrated_io/proc/display_data() - if(isnull(data)) - return "(null)" // Empty data means nothing to show. - if(istext(data)) - return "(\"[data]\")" // Wraps the 'string' in escaped quotes, so that people know it's a 'string'. - if(isweakref(data)) - var/weakref/w = data - var/atom/A = w.resolve() - //return A ? "([A.name] \[Ref\])" : "(null)" // For refs, we want just the name displayed. - return A ? "(\ref[A] \[Ref\])" : "(null)" - return "([data])" // Nothing special needed for numbers or other stuff. - -/datum/integrated_io/activate/display_data() - return "(\[pulse\])" - -/datum/integrated_io/proc/scramble() - if(isnull(data)) - return - if(isnum(data)) - write_data_to_pin(rand(-10000, 10000)) - if(istext(data)) - write_data_to_pin("ERROR") - push_data() - -/datum/integrated_io/activate/scramble() - push_data() - -/datum/integrated_io/proc/write_data_to_pin(var/new_data) - if(isnull(new_data) || isnum(new_data) || istext(new_data) || isweakref(new_data)) // Anything else is a type we don't want. - data = new_data - holder.on_data_written() - -/datum/integrated_io/proc/push_data() - for(var/datum/integrated_io/io in linked) - io.write_data_to_pin(data) - -/datum/integrated_io/activate/push_data() - for(var/datum/integrated_io/io in linked) - io.holder.check_then_do_work() - -/datum/integrated_io/proc/pull_data() - for(var/datum/integrated_io/io in linked) - write_data_to_pin(io.data) - -/datum/integrated_io/proc/get_linked_to_desc() - if(linked.len) - return "the [english_list(linked)]" - return "nothing" - -/datum/integrated_io/proc/disconnect() - //First we iterate over everything we are linked to. - for(var/datum/integrated_io/their_io in linked) - //While doing that, we iterate them as well, and disconnect ourselves from them. - for(var/datum/integrated_io/their_linked_io in their_io.linked) - if(their_linked_io == src) - their_io.linked.Remove(src) - else - continue - //Now that we're removed from them, we gotta remove them from us. - src.linked.Remove(their_io) - -/datum/integrated_io/input - name = "input pin" - -/datum/integrated_io/output - name = "output pin" - -/datum/integrated_io/activate - name = "activation pin" - io_type = PULSE_CHANNEL - -/obj/item/integrated_circuit/proc/push_data() - for(var/datum/integrated_io/output/O in outputs) - O.push_data() - -/obj/item/integrated_circuit/proc/pull_data() - for(var/datum/integrated_io/input/I in inputs) - I.push_data() - -/obj/item/integrated_circuit/proc/check_then_do_work() - if(world.time < next_use) // All intergrated circuits have an internal cooldown, to protect from spam. - return - next_use = world.time + cooldown_per_use - do_work() + var/complexity = 1 //This acts as a limitation on building machines, more resource-intensive components cost more 'space'. + var/cooldown_per_use = 1 SECONDS // Circuits are limited in how many times they can be work()'d by this variable. + var/power_draw_per_use = 0 // How much power is drawn when work()'d. + var/power_draw_idle = 0 // How much power is drawn when doing nothing. + var/spawn_flags = null // Used for world initializing, see the #defines above. + var/category_text = "NO CATEGORY THIS IS A BUG" // To show up on circuit printer, and perhaps other places. + var/autopulse = -1 // When input is received, the circuit will pulse itself if set to 1. 0 means it won't. -1 means it is permanently off. + var/removable = TRUE // Determines if a circuit is removable from the assembly. -/obj/item/integrated_circuit/proc/do_work() - return -/obj/item/integrated_circuit/proc/disconnect_all() - for(var/datum/integrated_io/input/I in inputs) - I.disconnect() - for(var/datum/integrated_io/output/O in outputs) - O.disconnect() - for(var/datum/integrated_io/activate/A in activators) - A.disconnect() \ No newline at end of file diff --git a/code/modules/integrated_electronics/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm similarity index 50% rename from code/modules/integrated_electronics/assemblies.dm rename to code/modules/integrated_electronics/core/assemblies.dm index 023c0b19abca3..21a729ebdbcc4 100644 --- a/code/modules/integrated_electronics/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -11,6 +11,7 @@ var/max_components = IC_COMPONENTS_BASE var/max_complexity = IC_COMPLEXITY_BASE var/opened = 0 + var/obj/item/weapon/stock_parts/cell/battery = null // Internal cell which most circuits need to work. /obj/item/device/electronic_assembly/medium name = "electronic mechanism" @@ -41,6 +42,32 @@ max_complexity = IC_COMPLEXITY_BASE / 2 var/obj/item/weapon/implant/integrated_circuit/implant = null +/obj/item/device/electronic_assembly/New() + ..() + battery = new(src) + SSmachine.processing |= src + +/obj/item/device/electronic_assembly/Destroy() + battery = null + SSmachine.processing -= src + for(var/atom/movable/AM in contents) + qdel(AM) + ..() + +/obj/item/device/electronic_assembly/process() + handle_idle_power() + +/obj/item/device/electronic_assembly/proc/handle_idle_power() + // First we generate power. + for(var/obj/item/integrated_circuit/passive/power/P in contents) + P.make_energy() + + // Now spend it. + for(var/obj/item/integrated_circuit/IC in contents) + if(IC.power_draw_idle) + if(!draw_power(IC.power_draw_idle)) + IC.power_fail() + /obj/item/device/electronic_assembly/implant/update_icon() ..() implant.icon_state = icon_state @@ -70,13 +97,18 @@ HTML += "
\[Refresh\] | " HTML += "\[Rename\]
" HTML += "[total_parts]/[max_components] ([round((total_parts / max_components) * 100, 0.1)]%) space taken up in the assembly.
" - HTML += "[total_complexity]/[max_complexity] ([round((total_complexity / max_complexity) * 100, 0.1)]%) maximum complexity." + HTML += "[total_complexity]/[max_complexity] ([round((total_complexity / max_complexity) * 100, 0.1)]%) maximum complexity.
" + if(battery) + HTML += "[round(battery.charge, 0.1)]/[battery.maxcharge] ([round(battery.percent(), 0.1)]%) cell charge. \[Remove\]" + else + HTML += "No powercell detected!" HTML += "

" HTML += "Components;
" for(var/obj/item/integrated_circuit/circuit in contents) HTML += "[circuit.name] | " HTML += "\[Rename\] | " - HTML += "\[Remove\]" + if(circuit.removable) + HTML += "\[Remove\]" HTML += "
" HTML += "" @@ -89,6 +121,16 @@ if(href_list["rename"]) rename(usr) + if(href_list["remove_cell"]) + if(!battery) + to_chat(usr, "There's no power cell to remove from \the [src].") + else + var/turf/T = get_turf(src) + battery.forceMove(T) + playsound(T, 'sound/items/Crowbar.ogg', 50, 1) + to_chat(usr, "You pull \the [battery] out of \the [src]'s power supplier.") + battery = null + interact(usr) // To refresh the UI. /obj/item/device/electronic_assembly/verb/rename() @@ -120,36 +162,69 @@ /obj/item/device/electronic_assembly/examine(mob/user) . = ..(user, 1) if(.) - for(var/obj/item/integrated_circuit/output/screen/S in contents) - if(S.stuff_to_display) - user << "There's a little screen labeled '[S.name]', which displays '[S.stuff_to_display]'." + for(var/obj/item/integrated_circuit/IC in contents) + IC.external_examine(user) + // for(var/obj/item/integrated_circuit/output/screen/S in contents) + // if(S.stuff_to_display) + // to_chat(user, "There's a little screen labeled '[S.name]', which displays '[S.stuff_to_display]'.") if(opened) interact(user) +/obj/item/device/electronic_assembly/proc/get_part_complexity() + . = 0 + for(var/obj/item/integrated_circuit/part in contents) + . += part.complexity + +/obj/item/device/electronic_assembly/proc/get_part_size() + . = 0 + for(var/obj/item/integrated_circuit/part in contents) + . += part.w_class + +// Returns true if the circuit made it inside. +/obj/item/device/electronic_assembly/proc/add_circuit(var/obj/item/integrated_circuit/IC, var/mob/user) + if(!opened) + to_chat(user, "\The [src] isn't opened, so you can't put anything inside. Try using a crowbar.") + return FALSE + + if(IC.w_class > src.w_class) + to_chat(user, "\The [IC] is way too big to fit into \the [src].") + return FALSE + + var/total_part_size = get_part_size() + var/total_complexity = get_part_complexity() + + if((total_part_size + IC.w_class) > max_components) + to_chat(user, "You can't seem to add the '[IC.name]', as there's insufficient space.") + return FALSE + if((total_complexity + IC.complexity) > max_complexity) + to_chat(user, "You can't seem to add the '[IC.name]', since this setup's too complicated for the case.") + return FALSE + + if(!IC.forceMove(src)) + return FALSE + + IC.assembly = src + + return TRUE + +/obj/item/device/electronic_assembly/afterattack(atom/target, mob/user, proximity) + if(proximity) + var/scanned = FALSE + for(var/obj/item/integrated_circuit/input/sensor/S in contents) + S.set_pin_data(IC_OUTPUT, 1, weakref(target)) + S.check_then_do_work() + scanned = TRUE + if(scanned) + visible_message("\The [user] waves \the [src] around [target].") + /obj/item/device/electronic_assembly/attackby(var/obj/item/I, var/mob/user) if(istype(I, /obj/item/integrated_circuit)) - if(!opened) - user << "\The [src] isn't opened, so you can't put anything inside. Try using a crowbar." - return 0 - var/obj/item/integrated_circuit/IC = I - var/total_parts = 0 - var/total_complexity = 0 - for(var/obj/item/integrated_circuit/part in contents) - total_parts++ - total_complexity = total_complexity + part.complexity - - if( (total_parts + 1) > max_components) - user << "You can't seem to add this [IC.name], since there's no more room." - return 0 - if( (total_complexity + IC.complexity) > max_complexity) - user << "You can't seem to add this [IC.name], since this setup's too complicated for the case." + if(!user.unEquip(I)) return 0 - - user << "You slide \the [IC] inside \the [src]." - user.drop_item() - IC.forceMove(src) - playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) - interact(user) + if(add_circuit(I, user)) + to_chat(user, "You slide \the [I] inside \the [src].") + playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) + interact(user) else if(istype(I, /obj/item/weapon/crowbar)) playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1) opened = !opened @@ -159,8 +234,23 @@ if(opened) interact(user) else - user << "\The [src] isn't opened, so you can't fiddle with the internal components. \ - Try using a crowbar." + to_chat(user, "\The [src] isn't opened, so you can't fiddle with the internal components. \ + Try using a crowbar.") + else if(istype(I, /obj/item/weapon/stock_parts/cell)) + if(!opened) + to_chat(user, "\The [src] isn't opened, so you can't put anything inside. Try using a crowbar.") + return FALSE + if(battery) + to_chat(user, "\The [src] already has \a [battery] inside. Remove it first if you want to replace it.") + return FALSE + var/obj/item/weapon/stock_parts/cell = I + user.drop_item(cell) + cell.forceMove(src) + battery = cell + playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) + to_chat(user, "You slot \the [cell] inside \the [src]'s power supplier.") + interact(user) + else return ..() @@ -179,4 +269,16 @@ /obj/item/device/electronic_assembly/emp_act(severity) ..() for(var/atom/movable/AM in contents) - AM.emp_act(severity) \ No newline at end of file + AM.emp_act(severity) + +// Returns true if power was successfully drawn. +/obj/item/device/electronic_assembly/proc/draw_power(amount) + if(battery && battery.use(amount * CELLRATE)) + return TRUE + return FALSE + +// Ditto for giving. +/obj/item/device/electronic_assembly/proc/give_power(amount) + if(battery && battery.give(amount * CELLRATE)) + return TRUE + return FALSE \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/helpers.dm b/code/modules/integrated_electronics/core/helpers.dm new file mode 100644 index 0000000000000..c946a29e47c45 --- /dev/null +++ b/code/modules/integrated_electronics/core/helpers.dm @@ -0,0 +1,55 @@ +/obj/item/integrated_circuit/proc/setup_io(var/list/io_list, var/io_type) + var/list/io_list_copy = io_list.Copy() + io_list.Cut() + for(var/io_entry in io_list_copy) + io_list.Add(new io_type(src, io_entry, io_list_copy[io_entry])) + +/obj/item/integrated_circuit/proc/set_pin_data(var/pin_type, var/pin_number, var/new_data) + var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number) + return pin.write_data_to_pin(new_data) + +/obj/item/integrated_circuit/proc/get_pin_data(var/pin_type, var/pin_number) + var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number) + return pin.get_data() + +/obj/item/integrated_circuit/proc/get_pin_data_as_type(var/pin_type, var/pin_number, var/as_type) + var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number) + return pin.data_as_type(as_type) + +/obj/item/integrated_circuit/proc/activate_pin(var/pin_number) + var/datum/integrated_io/activate/A = activators[pin_number] + A.push_data() + +/datum/integrated_io/proc/get_data() + if(isnull(data)) + return + if(isweakref(data)) + return data.resolve() + return data + +/obj/item/integrated_circuit/proc/get_pin_ref(var/pin_type, var/pin_number) + switch(pin_type) + if(IC_INPUT) + if(pin_number > inputs.len) + return null + return inputs[pin_number] + if(IC_OUTPUT) + if(pin_number > outputs.len) + return null + return outputs[pin_number] + if(IC_ACTIVATOR) + if(pin_number > activators.len) + return null + return activators[pin_number] + return null + + +/mob/living/proc/isSynthetic() + return 0 + +/mob/living/carbon/human/isSynthetic() + // If they are 100% robotic, they count as synthetic. + for(var/obj/item/organ/limb/E in organsystem) + if(E.organtype < ORGAN_ROBOTIC) + return FALSE + return TRUE \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/integrated_circuit.dm b/code/modules/integrated_electronics/core/integrated_circuit.dm new file mode 100644 index 0000000000000..80ddb87f9b825 --- /dev/null +++ b/code/modules/integrated_electronics/core/integrated_circuit.dm @@ -0,0 +1,282 @@ +/* + Integrated circuits are essentially modular machines. Each circuit has a specific function, and combining them inside Electronic Assemblies allows +a creative player the means to solve many problems. Circuits are held inside an electronic assembly, and are wired using special tools. +*/ + +/obj/item/integrated_circuit/examine(mob/user) + . = ..() + external_examine(user) + +// This should be used when someone is examining while the case is opened. +/obj/item/integrated_circuit/proc/internal_examine(mob/user) + to_chat(user, "This board has [inputs.len] input pin\s, [outputs.len] output pin\s and [activators.len] activation pin\s.") + for(var/datum/integrated_io/input/I in inputs) + if(I.linked.len) + to_chat(user, "The '[I]' is connected to [I.get_linked_to_desc()].") + for(var/datum/integrated_io/output/O in outputs) + if(O.linked.len) + to_chat(user, "The '[O]' is connected to [O.get_linked_to_desc()].") + for(var/datum/integrated_io/activate/A in activators) + if(A.linked.len) + to_chat(user, "The '[A]' is connected to [A.get_linked_to_desc()].") + any_examine(user) + interact(user) + +// This should be used when someone is examining from an 'outside' perspective, e.g. reading a screen or LED. +/obj/item/integrated_circuit/proc/external_examine(mob/user) + any_examine(user) + +/obj/item/integrated_circuit/proc/any_examine(mob/user) + return + +/obj/item/integrated_circuit/New() + setup_io(inputs, /datum/integrated_io/input) + setup_io(outputs, /datum/integrated_io/output) + setup_io(activators, /datum/integrated_io/activate) + ..() + +/obj/item/integrated_circuit/proc/on_data_written() //Override this for special behaviour when new data gets pushed to the circuit. + return + +/obj/item/integrated_circuit/Destroy() + for(var/datum/integrated_io/I in inputs) + qdel(I) + for(var/datum/integrated_io/O in outputs) + qdel(O) + for(var/datum/integrated_io/A in activators) + qdel(A) + . = ..() + +/obj/item/integrated_circuit/proc/nano_host() + if(istype(src.loc, /obj/item/device/electronic_assembly)) + var/obj/item/device/electronic_assembly/assembly = loc + return assembly.resolve_nano_host() + return ..() + +/obj/item/integrated_circuit/emp_act(severity) + for(var/datum/integrated_io/io in inputs + outputs + activators) + io.scramble() + +/obj/item/integrated_circuit/verb/rename_component() + set name = "Rename Circuit" + set category = "Object" + set desc = "Rename your circuit, useful to stay organized." + + var/mob/M = usr + if(!CanInteract(M, src)) + return + + var/input = sanitize_text(input("What do you want to name the circuit?", "Rename", src.name) as null|text, MAX_NAME_LEN) + if(src && input && CanInteract(M, src)) + to_chat(M, "The circuit '[src.name]' is now labeled '[input]'.") + name = input + +/obj/item/integrated_circuit/interact(mob/user) + if(!CanInteract(user, src)) + return + + var/window_height = 350 + var/window_width = 600 + + //var/table_edge_width = "[(window_width - window_width * 0.1) / 4]px" + //var/table_middle_width = "[(window_width - window_width * 0.1) - (table_edge_width * 2)]px" + var/table_edge_width = "30%" + var/table_middle_width = "40%" + + var/HTML = list() + HTML += "[src.name]" + HTML += "
" + HTML += "" + + HTML += "
\[Refresh\] | " + HTML += "\[Rename\] | " + HTML += "\[Remove\]
" + + HTML += "" + //HTML += "" + //HTML += "" + //HTML += "" + HTML += "" + HTML += "" + HTML += "" + HTML += "" + + var/column_width = 3 + var/row_height = max(inputs.len, outputs.len, 1) + + for(var/i = 1 to row_height) + HTML += "" + for(var/j = 1 to column_width) + var/datum/integrated_io/io = null + var/words = list() + var/height = 1 + switch(j) + if(1) + io = get_pin_ref(IC_INPUT, i) + if(io) + if(io.linked.len) + words += "[io.name] [io.display_data()]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + else + words += "[io.name] [io.display_data()]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + if(outputs.len > inputs.len) + height = 1 + if(2) + if(i == 1) + words += "[src.name]

[src.desc]" + height = row_height + else + continue + if(3) + io = get_pin_ref(IC_OUTPUT, i) + if(io) + if(io.linked.len) + words += "[io.name] [io.display_data()]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + else + words += "[io.name] [io.display_data()]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + if(inputs.len > outputs.len) + height = 1 + HTML += "" + HTML += "" + + for(var/activator in activators) + var/datum/integrated_io/io = activator + var/words = list() + if(io.linked.len) + words += "[io.name]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + else + words += "[io.name]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + HTML += "" + HTML += "" + HTML += "" + + HTML += "
[jointext(words, null)]
[jointext(words, null)]
" + HTML += "
" + + if(autopulse != -1) + HTML += "
Meta Variables;" + HTML += "
\[Autopulse\] = [autopulse ? "ON" : "OFF"]" + HTML += "
" + + HTML += "
Complexity: [complexity]" + if(power_draw_idle) + HTML += "
Power Draw: [power_draw_idle] W (Idle)" + if(power_draw_per_use) + HTML += "
Power Draw: [power_draw_per_use] W (Active)" // Borgcode says that powercells' checked_use() takes joules as input. + HTML += "
[extended_desc]" + + HTML += "" + user << browse(jointext(HTML, null), "window=circuit-\ref[src];size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1") + + onclose(user, "circuit-\ref[src]") + +/obj/item/integrated_circuit/Topic(href, href_list) + if(..()) + return 1 + var/pin = locate(href_list["pin"]) in inputs + outputs + activators + + var/obj/held_item = usr.get_active_hand() + if(href_list["wire"]) + if(istype(held_item, /obj/item/device/integrated_electronics/wirer)) + var/obj/item/device/integrated_electronics/wirer/wirer = held_item + if(pin) + wirer.wire(pin, usr) + + else if(istype(held_item, /obj/item/device/integrated_electronics/debugger)) + var/obj/item/device/integrated_electronics/debugger/debugger = held_item + if(pin) + debugger.write_data(pin, usr) + else + to_chat(usr, "You can't do a whole lot without the proper tools.") + + if(href_list["examine"]) + examine(usr) + + if(href_list["rename"]) + rename_component(usr) + + if(href_list["autopulse"]) + if(autopulse != -1) + autopulse = !autopulse + + if(href_list["remove"]) + if(istype(held_item, /obj/item/weapon/screwdriver)) + if(!removable) + to_chat(usr, "\The [src] seems to be permanently attached to the case.") + return + disconnect_all() + var/turf/T = get_turf(src) + forceMove(T) + assembly = null + playsound(T, 'sound/items/Crowbar.ogg', 50, 1) + to_chat(usr, "You pop \the [src] out of the case, and slide it out.") + else + to_chat(usr, "You need a screwdriver to remove components.") + var/obj/item/device/electronic_assembly/ea = loc + if(istype(ea)) + ea.interact(usr) + return + + interact(usr) // To refresh the UI. + +/obj/item/integrated_circuit/proc/push_data() + for(var/datum/integrated_io/output/O in outputs) + O.push_data() + +/obj/item/integrated_circuit/proc/pull_data() + for(var/datum/integrated_io/input/I in inputs) + I.push_data() + +/obj/item/integrated_circuit/proc/draw_idle_power() + if(assembly) + return assembly.draw_power(power_draw_idle) + +// Override this for special behaviour when there's no power left. +/obj/item/integrated_circuit/proc/power_fail() + return + +// Returns true if there's enough power to work(). +/obj/item/integrated_circuit/proc/check_power() + if(!assembly) + return FALSE // Not in an assembly, therefore no power. + if(assembly.draw_power(power_draw_per_use)) + return TRUE // Battery has enough. + return FALSE // Not enough power. + +/obj/item/integrated_circuit/proc/check_then_do_work() + if(world.time < next_use) // All intergrated circuits have an internal cooldown, to protect from spam. + return + if(power_draw_per_use) + if(!check_power()) + power_fail() + return + next_use = world.time + cooldown_per_use + do_work() + +/obj/item/integrated_circuit/proc/do_work() + return + +/obj/item/integrated_circuit/proc/disconnect_all() + for(var/datum/integrated_io/input/I in inputs) + I.disconnect() + for(var/datum/integrated_io/output/O in outputs) + O.disconnect() + for(var/datum/integrated_io/activate/A in activators) + A.disconnect() diff --git a/code/modules/integrated_electronics/core/pins.dm b/code/modules/integrated_electronics/core/pins.dm new file mode 100644 index 0000000000000..9e2d0a4d06fe6 --- /dev/null +++ b/code/modules/integrated_electronics/core/pins.dm @@ -0,0 +1,139 @@ +/* + Pins both hold data for circuits, as well move data between them. Some also cause circuits to do their function. DATA_CHANNEL pins are the data holding/moving kind, +where as PULSE_CHANNEL causes circuits to work() when their pulse hits them. + + +A visualization of how pins work is below. Imagine the below image involves an addition circuit. +When the bottom pin, the activator, receives a pulse, all the numbers on the left (input) get added, and the answer goes on the right side (output). + +Inputs Outputs + +A [2]\ /[8] result +B [1]-\|++|/ +C [4]-/|++| +D [1]/ || + || + Activator + + + +*/ +/datum/integrated_io + var/name = "input/output" + var/obj/item/integrated_circuit/holder = null + var/weakref/data = null // This is a weakref, to reduce typecasts. Note that oftentimes numbers and text may also occupy this. + var/list/linked = list() + var/io_type = DATA_CHANNEL + +/datum/integrated_io/New(var/newloc, var/name, var/data) + ..() + src.name = name + src.data = data + holder = newloc + if(!istype(holder)) + message_admins("ERROR: An integrated_io ([src.name]) spawned without a valid holder! This is a bug.") + +/datum/integrated_io/Destroy() + disconnect() + data = null + holder = null + . = ..() + +/datum/integrated_io/proc/nano_host() + return holder.nano_host() + + +/datum/integrated_io/proc/data_as_type(var/as_type) + if(!isweakref(data)) + return + var/weakref/w = data + var/output = w.resolve() + return istype(output, as_type) ? output : null + +/datum/integrated_io/proc/display_data() + if(isnull(data)) + return "(null)" // Empty data means nothing to show. + if(istext(data)) + return "(\"[data]\")" // Wraps the 'string' in escaped quotes, so that people know it's a 'string'. + if(isweakref(data)) + var/weakref/w = data + var/atom/A = w.resolve() + //return A ? "([A.name] \[Ref\])" : "(null)" // For refs, we want just the name displayed. + return A ? "(\ref[A] \[Ref\])" : "(null)" + return "([data])" // Nothing special needed for numbers or other stuff. + +/datum/integrated_io/activate/display_data() + return "(\[pulse\])" + +/datum/integrated_io/proc/display_pin_type() + return IC_FORMAT_ANY + +/datum/integrated_io/activate/display_pin_type() + return IC_FORMAT_PULSE + +/datum/integrated_io/proc/scramble() + if(isnull(data)) + return + if(isnum(data)) + write_data_to_pin(rand(-10000, 10000)) + if(istext(data)) + write_data_to_pin("ERROR") + push_data() + +/datum/integrated_io/activate/scramble() + push_data() + +/datum/integrated_io/proc/write_data_to_pin(var/new_data) + if(isnull(new_data) || isnum(new_data) || istext(new_data) || isweakref(new_data)) // Anything else is a type we don't want. + data = new_data + holder.on_data_written() + +/datum/integrated_io/proc/push_data() + for(var/datum/integrated_io/io in linked) + io.write_data_to_pin(data) + +/datum/integrated_io/activate/push_data() + for(var/datum/integrated_io/io in linked) + io.holder.check_then_do_work() + +/datum/integrated_io/proc/pull_data() + for(var/datum/integrated_io/io in linked) + write_data_to_pin(io.data) + +/datum/integrated_io/proc/get_linked_to_desc() + if(linked.len) + return "the [english_list(linked)]" + return "nothing" + +/datum/integrated_io/proc/disconnect() + //First we iterate over everything we are linked to. + for(var/datum/integrated_io/their_io in linked) + //While doing that, we iterate them as well, and disconnect ourselves from them. + for(var/datum/integrated_io/their_linked_io in their_io.linked) + if(their_linked_io == src) + their_io.linked.Remove(src) + else + continue + //Now that we're removed from them, we gotta remove them from us. + src.linked.Remove(their_io) + +/datum/integrated_io/input + name = "input pin" + +/datum/integrated_io/output + name = "output pin" + +/datum/integrated_io/activate + name = "activation pin" + io_type = PULSE_CHANNEL + +/datum/integrated_io/list + name = "list pin" + +/datum/integrated_io/list/write_data_to_pin(var/new_data) + if(islist(new_data)) + data = new_data + holder.on_data_written() + +/datum/integrated_io/list/display_pin_type() + return IC_FORMAT_LIST \ No newline at end of file diff --git a/code/modules/integrated_electronics/tools.dm b/code/modules/integrated_electronics/core/tools.dm similarity index 100% rename from code/modules/integrated_electronics/tools.dm rename to code/modules/integrated_electronics/core/tools.dm diff --git a/code/modules/integrated_electronics/data_transfer.dm b/code/modules/integrated_electronics/data_transfer.dm deleted file mode 100644 index db9d046c396a5..0000000000000 --- a/code/modules/integrated_electronics/data_transfer.dm +++ /dev/null @@ -1,79 +0,0 @@ -/obj/item/integrated_circuit/transfer - category_text = "Data Transfer" - autopulse = 1 - -/obj/item/integrated_circuit/transfer/on_data_written() - if(autopulse == 1) - check_then_do_work() - -/obj/item/integrated_circuit/transfer/splitter - name = "splitter" - desc = "Splits incoming data into all of the output pins." - icon_state = "splitter" - complexity = 3 - inputs = list("data to split") - outputs = list("A","B") - -/obj/item/integrated_circuit/transfer/splitter/medium - name = "four splitter" - icon_state = "splitter4" - complexity = 5 - outputs = list("A","B","C","D") - -/obj/item/integrated_circuit/transfer/splitter/large - name = "eight splitter" - icon_state = "splitter8" - complexity = 9 - outputs = list("A","B","C","D","E","F","G","H") - -/obj/item/integrated_circuit/transfer/splitter/do_work() - var/datum/integrated_io/I = inputs[1] - for(var/datum/integrated_io/output/O in outputs) - O.data = I.data - -/obj/item/integrated_circuit/transfer/activator_splitter - name = "activator splitter" - desc = "Splits incoming activation pulses into all of the output pins." - icon_state = "splitter" - complexity = 3 - activators = list( - "incoming pulse", - "outgoing pulse A", - "outgoing pulse B" - ) - -/obj/item/integrated_circuit/transfer/activator_splitter/do_work() - for(var/datum/integrated_io/activate/A in outputs) - if(A == activators[1]) - continue - if(A.linked.len) - for(var/datum/integrated_io/activate/target in A.linked) - target.holder.check_then_do_work() - -/obj/item/integrated_circuit/transfer/activator_splitter/medium - name = "four activator splitter" - icon_state = "splitter4" - complexity = 5 - activators = list( - "incoming pulse", - "outgoing pulse A", - "outgoing pulse B", - "outgoing pulse C", - "outgoing pulse D" - ) - -/obj/item/integrated_circuit/transfer/activator_splitter/large - name = "eight activator splitter" - icon_state = "splitter4" - complexity = 9 - activators = list( - "incoming pulse", - "outgoing pulse A", - "outgoing pulse B", - "outgoing pulse C", - "outgoing pulse D", - "outgoing pulse E", - "outgoing pulse F", - "outgoing pulse G", - "outgoing pulse H" - ) \ No newline at end of file diff --git a/code/modules/integrated_electronics/passive/passive.dm b/code/modules/integrated_electronics/passive/passive.dm new file mode 100644 index 0000000000000..02f03d48d7c40 --- /dev/null +++ b/code/modules/integrated_electronics/passive/passive.dm @@ -0,0 +1,7 @@ +// 'Passive' components do not have any pins, and instead contribute in some form to the assembly holding them. +/obj/item/integrated_circuit/passive + inputs = list() + outputs = list() + activators = list() + power_draw_idle = 0 + power_draw_per_use = 0 \ No newline at end of file diff --git a/code/modules/integrated_electronics/passive/power.dm b/code/modules/integrated_electronics/passive/power.dm new file mode 100644 index 0000000000000..1b8128175fc3b --- /dev/null +++ b/code/modules/integrated_electronics/passive/power.dm @@ -0,0 +1,109 @@ + +/obj/item/integrated_circuit/passive/power + name = "power thingy" + desc = "Does power stuff." + complexity = 5 + origin_tech = list(TECH_POWER = 2, TECH_ENGINEERING = 2, TECH_DATA = 2) + category_text = "Power - Passive" + +/obj/item/integrated_circuit/passive/power/proc/make_energy() + return + +// For calculators. +/obj/item/integrated_circuit/passive/power/solar_cell + name = "tiny photovoltaic cell" + desc = "It's a very tiny solar cell, generally used in calculators." + extended_desc = "The cell generates 1W of energy per second in optimal lighting conditions. Less light will result in less power being generated." + icon_state = "solar_cell" + complexity = 8 + origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_DATA = 2) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + var/max_power = 1 + +/obj/item/integrated_circuit/passive/power/solar_cell/make_energy() + var/atom/movable/lighting_overlay/light = locate(/atom/movable/lighting_overlay) in get_turf(src) + var/light_amount = 1 // Unsimulated tiles are pretend-lit, so we need to be pretend too if that somehow happens. + if(light) + light_amount = (light.lum_r + light.lum_g + light.lum_b) / 3 + + var/adjusted_power = max(max_power * light_amount, 0) + adjusted_power = round(adjusted_power, 0.1) + if(adjusted_power) + if(assembly) + assembly.give_power(adjusted_power) + +// For implants. +/obj/item/integrated_circuit/passive/power/metabolic_siphon + name = "metabolic siphon" + desc = "A complicated piece of technology which converts bodily nutriments of a host into electricity." + extended_desc = "The siphon generates 10W of energy, so long as the siphon exists inside a biological entity. The entity will feel an increased \ + appetite and will need to eat more often due to this. This device will fail if used inside synthetic entities." + icon_state = "setup_implant" + complexity = 10 + origin_tech = list(TECH_POWER = 4, TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_BIO = 5) + spawn_flags = IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/passive/power/metabolic_siphon/proc/test_validity(var/mob/living/carbon/human/host) + if(!host || host.isSynthetic() || host.stat == DEAD || host.nutrition <= 10) + return FALSE // Robots and dead people don't have a metabolism. + return TRUE + +/obj/item/integrated_circuit/passive/power/metabolic_siphon/make_energy() + var/mob/living/carbon/human/host = null + if(assembly && istype(assembly, /obj/item/device/electronic_assembly/implant)) + var/obj/item/device/electronic_assembly/implant/implant_assembly = assembly + if(implant_assembly.implant.imp_in) + host = implant_assembly.implant.imp_in + if(host && test_validity(host)) + assembly.give_power(10) + host.nutrition = max(host.nutrition - HUNGER_FACTOR, 0) + +/obj/item/integrated_circuit/passive/power/metabolic_siphon/synthetic + name = "internal energy siphon" + desc = "A small circuit designed to be connected to an internal power wire inside a synthetic entity." + extended_desc = "The siphon generates 10W of energy, so long as the siphon exists inside a synthetic entity. The entity need to recharge \ + more often due to this. This device will fail if used inside organic entities." + icon_state = "setup_implant" + complexity = 10 + origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 4, TECH_DATA = 3) + spawn_flags = IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/passive/power/metabolic_siphon/synthetic/test_validity(var/mob/living/carbon/human/host) + if(!host || !host.isSynthetic() || host.stat == DEAD || host.nutrition <= 10) + return FALSE // This time we don't want a metabolism. + return TRUE + +// For fat machines that need fat power, like drones. +/obj/item/integrated_circuit/passive/power/relay + name = "tesla power relay" + desc = "A seemingly enigmatic device which connects to nearby APCs wirelessly and draws power from them." + w_class = 3 + extended_desc = "The siphon generates 250W of energy, so long as an APC is in the same room, with a cell that has energy. It will always drain \ + from the 'equipment' power channel." + icon_state = "power_relay" + complexity = 7 + origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_DATA = 2) + spawn_flags = IC_SPAWN_RESEARCH + var/power_amount = 250 + +// For really fat machines. +/obj/item/integrated_circuit/passive/power/relay/large + name = "large tesla power relay" + desc = "A seemingly enigmatic device which connects to nearby APCs wirelessly and draws power from them, now in industiral size!" + w_class = 4 + extended_desc = "The siphon generates 2 kW of energy, so long as an APC is in the same room, with a cell that has energy. It will always drain \ + from the 'equipment' power channel." + icon_state = "power_relay" + complexity = 15 + origin_tech = list(TECH_POWER = 6, TECH_ENGINEERING = 5, TECH_DATA = 4) + spawn_flags = IC_SPAWN_RESEARCH + power_amount = 2000 + +/obj/item/integrated_circuit/passive/power/relay/make_energy() + if(!assembly) + return + var/area/A = get_area(src) + if(A) + if(A.powered(EQUIP)) + A.use_power(power_amount, EQUIP) + assembly.give_power(power_amount) // give_power() handles CELLRATE on its own. diff --git a/code/modules/integrated_electronics/arithmetic.dm b/code/modules/integrated_electronics/subtypes/arithmetic.dm similarity index 100% rename from code/modules/integrated_electronics/arithmetic.dm rename to code/modules/integrated_electronics/subtypes/arithmetic.dm diff --git a/code/modules/integrated_electronics/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm similarity index 100% rename from code/modules/integrated_electronics/converters.dm rename to code/modules/integrated_electronics/subtypes/converters.dm diff --git a/code/modules/integrated_electronics/subtypes/data_transfer.dm b/code/modules/integrated_electronics/subtypes/data_transfer.dm new file mode 100644 index 0000000000000..8c01baf8b1472 --- /dev/null +++ b/code/modules/integrated_electronics/subtypes/data_transfer.dm @@ -0,0 +1,179 @@ +/obj/item/integrated_circuit/transfer + category_text = "Data Transfer" + autopulse = 1 + power_draw_per_use = 2 + +/obj/item/integrated_circuit/transfer/on_data_written() + if(autopulse == 1) + check_then_do_work() + +/obj/item/integrated_circuit/transfer/splitter + name = "splitter" + desc = "Splits incoming data into all of the output pins." + icon_state = "splitter" + complexity = 3 + inputs = list("data to split") + outputs = list("A","B") + +/obj/item/integrated_circuit/transfer/splitter/medium + name = "four splitter" + icon_state = "splitter4" + complexity = 5 + outputs = list("A","B","C","D") + power_draw_per_use = 4 + +/obj/item/integrated_circuit/transfer/splitter/large + name = "eight splitter" + icon_state = "splitter8" + complexity = 9 + outputs = list("A","B","C","D","E","F","G","H") + power_draw_per_use = 8 + +/obj/item/integrated_circuit/transfer/splitter/do_work() + var/datum/integrated_io/I = inputs[1] + for(var/datum/integrated_io/output/O in outputs) + O.data = I.data + +/obj/item/integrated_circuit/transfer/activator_splitter + name = "activator splitter" + desc = "Splits incoming activation pulses into all of the output pins." + icon_state = "splitter" + complexity = 3 + activators = list( + "incoming pulse", + "outgoing pulse A", + "outgoing pulse B" + ) + power_draw_per_use = 2 + +/obj/item/integrated_circuit/transfer/activator_splitter/do_work() + for(var/datum/integrated_io/activate/A in outputs) + if(A == activators[1]) + continue + if(A.linked.len) + for(var/datum/integrated_io/activate/target in A.linked) + target.holder.check_then_do_work() + +/obj/item/integrated_circuit/transfer/activator_splitter/medium + name = "four activator splitter" + icon_state = "splitter4" + complexity = 5 + activators = list( + "incoming pulse", + "outgoing pulse A", + "outgoing pulse B", + "outgoing pulse C", + "outgoing pulse D" + ) + power_draw_per_use = 4 + +/obj/item/integrated_circuit/transfer/activator_splitter/large + name = "eight activator splitter" + icon_state = "splitter4" + complexity = 9 + activators = list( + "incoming pulse", + "outgoing pulse A", + "outgoing pulse B", + "outgoing pulse C", + "outgoing pulse D", + "outgoing pulse E", + "outgoing pulse F", + "outgoing pulse G", + "outgoing pulse H" + ) + spawn_flags = IC_SPAWN_RESEARCH + power_draw_per_use = 8 + + +/obj/item/integrated_circuit/transfer/multiplexer + name = "two multiplexer" + desc = "This is what those in the business tend to refer to as a 'mux' or data selector. It moves data from one of the selected inputs to the output." + extended_desc = "The first input pin is used to select which of the other input pins which has its data moved to the output. If the input selection is outside the valid range then no output is given." + complexity = 2 + icon_state = "mux2" + inputs = list("input selection") + outputs = list("output") + activators = list("select") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + power_draw_per_use = 4 + var/number_of_inputs = 2 + +/obj/item/integrated_circuit/transfer/multiplexer/New() + for(var/i = 1 to number_of_inputs) + inputs += "input [i]" + complexity = number_of_inputs + ..() + desc += " It has [number_of_inputs] input pins." + extended_desc += " This multiplexer has a range from 1 to [inputs.len - 1]." + +/obj/item/integrated_circuit/transfer/multiplexer/do_work() + var/input_index = get_pin_data(IC_INPUT, 1) + var/output = null + + if(isnum(input_index) && (input_index >= 1 && input_index < inputs.len)) + output = get_pin_data(IC_INPUT, input_index + 1) + set_pin_data(IC_OUTPUT, 1, output) + +/obj/item/integrated_circuit/transfer/multiplexer/medium + name = "four multiplexer" + number_of_inputs = 4 + icon_state = "mux4" + +/obj/item/integrated_circuit/transfer/multiplexer/large + name = "eight multiplexer" + number_of_inputs = 8 + w_class = 2 + icon_state = "mux8" + +/obj/item/integrated_circuit/transfer/multiplexer/huge + name = "sixteen multiplexer" + icon_state = "mux16" + w_class = 2 + number_of_inputs = 16 + +/obj/item/integrated_circuit/transfer/demultiplexer + name = "two demultiplexer" + desc = "This is what those in the business tend to refer to as a 'demux'. It moves data from the input to one of the selected outputs." + extended_desc = "The first input pin is used to select which of the output pins is given the data from the second input pin. If the output selection is outside the valid range then no output is given." + complexity = 2 + icon_state = "dmux2" + inputs = list("output selection","input") + outputs = list() + activators = list("select") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + power_draw_per_use = 4 + var/number_of_outputs = 2 + +/obj/item/integrated_circuit/transfer/demultiplexer/New() + for(var/i = 1 to number_of_outputs) + outputs += "output [i]" + complexity = number_of_outputs + + ..() + desc += " It has [number_of_outputs] output pins." + extended_desc += " This demultiplexer has a range from 1 to [outputs.len]." + +/obj/item/integrated_circuit/transfer/demultiplexer/do_work() + var/output_index = get_pin_data(IC_INPUT, 1) + var/output = get_pin_data(IC_INPUT, 2) + + for(var/i = 1 to outputs.len) + set_pin_data(IC_OUTPUT, i, i == output_index ? output : null) + +/obj/item/integrated_circuit/transfer/demultiplexer/medium + name = "four demultiplexer" + icon_state = "dmux4" + number_of_outputs = 4 + +/obj/item/integrated_circuit/transfer/demultiplexer/large + name = "eight demultiplexer" + icon_state = "dmux8" + w_class = 2 + number_of_outputs = 8 + +/obj/item/integrated_circuit/transfer/demultiplexer/huge + name = "sixteen demultiplexer" + icon_state = "dmux16" + w_class = 2 + number_of_outputs = 16 \ No newline at end of file diff --git a/code/modules/integrated_electronics/input_output.dm b/code/modules/integrated_electronics/subtypes/input_output.dm similarity index 75% rename from code/modules/integrated_electronics/input_output.dm rename to code/modules/integrated_electronics/subtypes/input_output.dm index bcd8793902a17..3ab7d404932ac 100644 --- a/code/modules/integrated_electronics/input_output.dm +++ b/code/modules/integrated_electronics/subtypes/input_output.dm @@ -1,5 +1,6 @@ /obj/item/integrated_circuit/input var/can_be_asked_input = 0 + power_draw_per_use = 5 /obj/item/integrated_circuit/input/proc/ask_for_input(mob/user) return @@ -19,7 +20,22 @@ if(A.linked.len) for(var/datum/integrated_io/activate/target in A.linked) target.holder.check_then_do_work() - user << "You press the button labeled '[src.name]'." + to_chat(user, "You press the button labeled '[src.name]'.") + +/obj/item/integrated_circuit/input/toggle_button + name = "toggle button" + desc = "It toggles on, off, on, off..." + icon_state = "toggle_button" + complexity = 1 + inputs = list() + outputs = list("on" = 0) + activators = list("on toggle") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/input/toggle_button/ask_for_input(mob/user) // Ditto. + set_pin_data(IC_OUTPUT, 1, !get_pin_data(IC_OUTPUT, 1)) + activate_pin(1) + to_chat(user, "You toggle the button labeled '[src.name]' [get_pin_data(IC_OUTPUT, 1) ? "on" : "off"].") /obj/item/integrated_circuit/input/numberpad name = "number pad" @@ -30,6 +46,7 @@ inputs = list() outputs = list("number entered") activators = list("on entered") + power_draw_per_use = 4 /obj/item/integrated_circuit/input/numberpad/ask_for_input(mob/user) var/new_input = input(user, "Enter a number, please.","Number pad") as null|num @@ -49,6 +66,7 @@ inputs = list() outputs = list("string entered") activators = list("on entered") + power_draw_per_use = 4 /obj/item/integrated_circuit/input/textpad/ask_for_input(mob/user) var/new_input = input(user, "Enter some words, please.","Number pad") as null|text @@ -68,6 +86,7 @@ outputs = list("total health %", "total missing health") activators = list("scan") origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) + power_draw_per_use = 40 /obj/item/integrated_circuit/input/med_scanner/do_work() var/datum/integrated_io/I = inputs[1] @@ -105,6 +124,7 @@ ) activators = list("scan") origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4) + power_draw_per_use = 80 /obj/item/integrated_circuit/input/adv_med_scanner/do_work() var/datum/integrated_io/I = inputs[1] @@ -141,6 +161,7 @@ inputs = list() outputs = list("located ref") activators = list("locate") + power_draw_per_use = 20 /obj/item/integrated_circuit/input/local_locator/do_work() var/datum/integrated_io/O = outputs[1] @@ -162,6 +183,7 @@ inputs = list("desired type ref") outputs = list("located ref") activators = list("locate") + power_draw_per_use = 30 /obj/item/integrated_circuit/input/adjacent_locator/do_work() var/datum/integrated_io/I = inputs[1] @@ -197,6 +219,8 @@ outputs = list() activators = list("send signal","on signal received") origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNETS = 2) + power_draw_idle = 5 + power_draw_per_use = 40 var/frequency = 1457 var/code = 30 @@ -278,6 +302,7 @@ outputs = list("address received", "data received", "secondary text received") activators = list("send data", "on data received") origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNETS = 2, TECH_BLUESPACE = 2) + power_draw_per_use = 50 var/datum/exonet_protocol/exonet = null /obj/item/integrated_circuit/input/EPv2/New() @@ -311,6 +336,9 @@ data_received.write_data_to_pin(message) text_received.write_data_to_pin(text) + for(var/datum/integrated_io/output/O in outputs) + O.push_data() + //This circuit gives information on where the machine is. /obj/item/integrated_circuit/input/gps name = "global positioning system" @@ -321,6 +349,7 @@ outputs = list("X (abs)", "Y (abs)") activators = list("get coordinates") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + power_draw_per_use = 30 /obj/item/integrated_circuit/input/gps/do_work() var/turf/T = get_turf(src) @@ -349,7 +378,7 @@ outputs = list("speaker \", "message \") activators = list("on message received") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - + power_draw_per_use = 15 /* /obj/item/integrated_circuit/input/microphone/New() ..() @@ -364,16 +393,39 @@ var/datum/integrated_io/V = outputs[1] var/datum/integrated_io/O = outputs[2] var/datum/integrated_io/A = activators[1] - if(speaker = src) + if(speaker == src) return //msg = lang_treat(msg, M, message_langs, raw_message, spans) V.data = speaker.GetVoice() O.data = raw_message A.push_data() + for(var/datum/integrated_io/output/out in outputs) + out.push_data() + + A.push_data() +/obj/item/integrated_circuit/input/sensor + name = "sensor" + desc = "Scans and obtains a reference for any objects or persons near you. All you need to do is shove the machine in their face." + icon_state = "recorder" + complexity = 12 + inputs = list() + outputs = list("scanned ref \") + activators = list("on scanned") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + power_draw_per_use = 120 + +/obj/item/integrated_circuit/input/sensor/do_work() + // Because this gets called by attack(), all this needs to do is pulse the activator. + for(var/datum/integrated_io/output/O in outputs) + O.push_data() + var/datum/integrated_io/activate/A = activators[1] + A.push_data() + + /obj/item/integrated_circuit/output category_text = "Output" @@ -384,8 +436,18 @@ inputs = list("displayed data") outputs = list() activators = list("load data") + power_draw_per_use = 10 + autopulse = 1 var/stuff_to_display = null + +/obj/item/integrated_circuit/output/screen/disconnect_all() + ..() + stuff_to_display = null + +/obj/item/integrated_circuit/output/screen/any_examine(mob/user) + to_chat(user, "There is a little screen labeled '[name]', which displays [stuff_to_display ? "'[stuff_to_display]'" : "nothing"].") + /obj/item/integrated_circuit/output/screen/do_work() var/datum/integrated_io/I = inputs[1] if(isweakref(I.data)) @@ -399,28 +461,30 @@ name = "screen" desc = "This screen allows for people holding the device to see a piece of data." icon_state = "screen_medium" + power_draw_per_use = 20 /obj/item/integrated_circuit/output/screen/medium/do_work() ..() var/list/nearby_things = range(0, get_turf(src)) for(var/mob/M in nearby_things) - var/obj/O = istype(loc, /obj/item/device/electronic_assembly) ? loc : src + var/obj/O = assembly ? assembly : src visible_message("\icon[O] [stuff_to_display]") /obj/item/integrated_circuit/output/screen/large name = "large screen" desc = "This screen allows for people able to see the device to see a piece of data." icon_state = "screen_large" + power_draw_per_use = 40 /obj/item/integrated_circuit/output/screen/large/do_work() ..() - var/obj/O = istype(loc, /obj/item/device/electronic_assembly) ? loc : src + var/obj/O = assembly ? loc : assembly O.visible_message("\icon[O] [stuff_to_display]") /obj/item/integrated_circuit/output/light name = "light" desc = "This light can turn on and off on command." - icon_state = "light_adv" + icon_state = "light" complexity = 4 inputs = list() outputs = list() @@ -428,6 +492,10 @@ var/light_toggled = 0 var/light_brightness = 3 var/light_rgb = "#FFFFFF" + power_draw_idle = 0 // Adjusted based on brightness. + +/obj/item/integrated_circuit/output/light/Destroy() + ..() /obj/item/integrated_circuit/output/light/do_work() light_toggled = !light_toggled @@ -438,6 +506,7 @@ set_light(l_range = light_brightness, l_power = light_brightness, l_color = light_rgb) else set_light(0) + power_draw_idle = light_toggled ? light_brightness * 2 : 0 /obj/item/integrated_circuit/output/light/advanced/update_lighting() var/datum/integrated_io/R = inputs[1] @@ -455,6 +524,10 @@ ..() +/obj/item/integrated_circuit/output/light/power_fail() // Turns off the flashlight if there's no power left. + light_toggled = FALSE + update_lighting() + /obj/item/integrated_circuit/output/light/advanced name = "advanced light" desc = "This light can turn on and off on command, in any color, and in various brightness levels." @@ -467,6 +540,7 @@ "Brightness" ) outputs = list() + origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) /obj/item/integrated_circuit/output/light/advanced/on_data_written() update_lighting() @@ -484,6 +558,7 @@ ) outputs = list() activators = list("play sound") + power_draw_per_use = 20 var/list/sounds = list() /obj/item/integrated_circuit/output/text_to_speech @@ -500,7 +575,7 @@ /obj/item/integrated_circuit/output/text_to_speech/do_work() var/datum/integrated_io/text = inputs[1] if(istext(text.data)) - var/obj/O = istype(loc, /obj/item/device/electronic_assembly) ? loc : src + var/obj/O = assembly ? loc : assembly audible_message("\icon[O] \The [O.name] states, \"[text.data]\"") /obj/item/integrated_circuit/output/sound/New() @@ -552,4 +627,120 @@ "insult" = 'sound/voice/binsult.ogg', "radio" = 'sound/voice/bradio.ogg', "secure day" = 'sound/voice/bsecureday.ogg', - ) \ No newline at end of file + ) + spawn_flags = IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_ILLEGAL = 1) + +/obj/item/integrated_circuit/output/video_camera + name = "video camera circuit" + desc = "This small camera allows a remote viewer to see what it sees." + extended_desc = "The camera is linked to the Research camera network." + icon_state = "video_camera" + w_class = 2 + complexity = 10 + inputs = list("camera name" = "video camera circuit", "camera active" = 0) + outputs = list() + activators = list() + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + power_draw_idle = 5 // Raises to 80 when on. + var/obj/machinery/camera/camera + +/obj/item/integrated_circuit/output/video_camera/New() + ..() + camera = new(src) + on_data_written() + +/obj/item/integrated_circuit/output/video_camera/Destroy() + qdel(camera) + ..() + +/obj/item/integrated_circuit/output/video_camera/proc/set_camera_status(var/status) + if(camera) + camera.status = status + power_draw_idle = camera.status ? 80 : 5 + if(camera.status) // Ensure that there's actually power. + if(!draw_idle_power()) + power_fail() + +/obj/item/integrated_circuit/output/video_camera/on_data_written() + if(camera) + var/datum/integrated_io/cam_name = inputs[1] + var/datum/integrated_io/cam_active = inputs[2] + if(istext(cam_name.data)) + camera.c_tag = cam_name.data + if(isnum(cam_active.data)) + set_camera_status(cam_active.data) + +/obj/item/integrated_circuit/output/video_camera/power_fail() + if(camera) + set_camera_status(0) + var/datum/integrated_io/cam_active = inputs[2] + cam_active.data = FALSE + +/obj/item/integrated_circuit/output/led + name = "light-emitting diode" + desc = "This a LED that is lit whenever there is TRUE-equivalent data on its input." + extended_desc = "TRUE-equivalent values are: Non-empty strings, non-zero numbers, and valid refs." + complexity = 0.1 + icon_state = "led" + inputs = list("lit") + outputs = list() + activators = list() + power_draw_idle = 0 // Raises to 1 when lit. + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + var/led_color + +/obj/item/integrated_circuit/output/led/on_data_written() + power_draw_idle = get_pin_data(IC_INPUT, 1) ? 1 : 0 + +/obj/item/integrated_circuit/output/led/power_fail() + set_pin_data(IC_INPUT, 1, FALSE) + +/obj/item/integrated_circuit/output/led/any_examine(mob/user) + var/text_output = list() + var/initial_name = initial(name) + + // Doing all this work just to have a color-blind friendly output. + text_output += "There is " + if(name == initial_name) + text_output += "\an [name]" + else + text_output += "\an ["\improper[initial_name]"] labeled '[name]'" + text_output += " which is currently [get_pin_data(IC_INPUT, 1) ? "lit ¤" : "unlit."]" + to_chat(user,jointext(text_output,null)) + +/obj/item/integrated_circuit/output/led/red + name = "red LED" + led_color = COLOR_RED + +/obj/item/integrated_circuit/output/led/orange + name = "orange LED" + led_color = COLOR_ORANGE + +/obj/item/integrated_circuit/output/led/yellow + name = "yellow LED" + led_color = COLOR_YELLOW + +/obj/item/integrated_circuit/output/led/green + name = "green LED" + led_color = COLOR_GREEN + +/obj/item/integrated_circuit/output/led/blue + name = "blue LED" + led_color = COLOR_BLUE + +/obj/item/integrated_circuit/output/led/purple + name = "purple LED" + led_color = COLOR_PURPLE + +/obj/item/integrated_circuit/output/led/cyan + name = "cyan LED" + led_color = COLOR_CYAN + +/obj/item/integrated_circuit/output/led/white + name = "white LED" + led_color = COLOR_WHITE + +/obj/item/integrated_circuit/output/led/pink + name = "pink LED" + led_color = COLOR_PINK diff --git a/code/modules/integrated_electronics/logic.dm b/code/modules/integrated_electronics/subtypes/logic.dm similarity index 100% rename from code/modules/integrated_electronics/logic.dm rename to code/modules/integrated_electronics/subtypes/logic.dm diff --git a/code/modules/integrated_electronics/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm similarity index 100% rename from code/modules/integrated_electronics/manipulation.dm rename to code/modules/integrated_electronics/subtypes/manipulation.dm diff --git a/code/modules/integrated_electronics/memory.dm b/code/modules/integrated_electronics/subtypes/memory.dm similarity index 100% rename from code/modules/integrated_electronics/memory.dm rename to code/modules/integrated_electronics/subtypes/memory.dm diff --git a/code/modules/integrated_electronics/subtypes/power.dm b/code/modules/integrated_electronics/subtypes/power.dm new file mode 100644 index 0000000000000..466368b46e6a5 --- /dev/null +++ b/code/modules/integrated_electronics/subtypes/power.dm @@ -0,0 +1,80 @@ +/obj/item/integrated_circuit/power/ + category_text = "Power - Active" + +/obj/item/integrated_circuit/power/transmitter + name = "power transmission circuit" + desc = "This can wirelessly transmit electricity from an assembly's battery towards a nearby machine." + icon_state = "power_transmitter" + extended_desc = "This circuit transmits 5 kJ of electricity every time the activator pin is pulsed. The input pin must be \ + a reference to a machine to send electricity to. This can be a battery, or anything containing a battery. The machine can exist \ + inside the assembly, or adjacent to it. The power is sourced from the assembly's power cell. If the target is outside of the assembly, \ + some power is lost due to ineffiency." + w_class = 2 + complexity = 16 + inputs = list("target ref") + outputs = list("target cell charge", "target cell max charge", "target cell percentage") + activators = list("transmit") + spawn_flags = IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNETS = 3) + power_draw_per_use = 500 // Inefficency has to come from somewhere. + var/amount_to_move = 5000 + +/obj/item/integrated_circuit/power/transmitter/large + name = "large power transmission circuit" + desc = "This can wirelessly transmit a lot of electricity from an assembly's battery towards a nearby machine. Warning: Do not operate in flammable enviroments." + extended_desc = "This circuit transmits 20 kJ of electricity every time the activator pin is pulsed. The input pin must be \ + a reference to a machine to send electricity to. This can be a battery, or anything containing a battery. The machine can exist \ + inside the assembly, or adjacent to it. The power is sourced from the assembly's power cell. If the target is outside of the assembly, \ + some power is lost due to ineffiency." + w_class = 4 + complexity = 32 + origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 6, TECH_MAGNETS = 5) + power_draw_per_use = 2000 + amount_to_move = 20000 + +/obj/item/integrated_circuit/power/transmitter/do_work() + set_pin_data(IC_OUTPUT, 1, null) + set_pin_data(IC_OUTPUT, 2, null) + set_pin_data(IC_OUTPUT, 3, null) + var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) + if(AM) + if(!assembly) + return FALSE // Pointless to do everything else if there's no battery to draw from. + + var/obj/item/weapon/stock_parts/cell/cell = null + if(istype(AM, /obj/item/weapon/stock_parts/cell)) // Is this already a cell? + cell = AM + else // If not, maybe there's a cell inside it? + for(var/obj/item/weapon/stock_parts/cell/C in AM.contents) + if(C) // Find one cell to charge. + cell = C + break + if(cell) + var/transfer_amount = amount_to_move + var/turf/A = get_turf(src) + var/turf/B = get_turf(AM) + if(A.Adjacent(B)) + if(AM.loc != assembly) + transfer_amount *= 0.8 // Losses due to distance. + + if(cell.charge >= cell.maxcharge) + return FALSE + + if(transfer_amount && assembly.draw_power(amount_to_move)) // CELLRATE is already handled in draw_power() + cell.give(transfer_amount * CELLRATE) + cell.update_icon() + + set_pin_data(IC_OUTPUT, 1, cell.charge) + set_pin_data(IC_OUTPUT, 2, cell.maxcharge) + set_pin_data(IC_OUTPUT, 3, cell.percent()) + return TRUE + return FALSE + +/obj/item/integrated_circuit/power/transmitter/large/do_work() + if(..()) // If the above code succeeds, do this below. + if(prob(2)) + var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread() + sparks.set_up(3, 0, get_turf(src)) + sparks.start() + visible_message("\The [assembly] makes some sparks!") + qdel(sparks) \ No newline at end of file diff --git a/code/modules/integrated_electronics/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm similarity index 100% rename from code/modules/integrated_electronics/reagents.dm rename to code/modules/integrated_electronics/subtypes/reagents.dm diff --git a/code/modules/integrated_electronics/subtypes/smart.dm b/code/modules/integrated_electronics/subtypes/smart.dm new file mode 100644 index 0000000000000..c159522e9743a --- /dev/null +++ b/code/modules/integrated_electronics/subtypes/smart.dm @@ -0,0 +1,33 @@ +/obj/item/integrated_circuit/smart + category_text = "Smart" + +/obj/item/integrated_circuit/smart/basic_pathfinder + name = "basic pathfinder" + desc = "This complex circuit is able to determine what direction a given target is." + extended_desc = "This circuit uses a miniturized, integrated camera to determine where the target is. If the machine \ + cannot see the target, it will not be able to calculate the correct direction." + icon_state = "numberpad" + complexity = 25 + inputs = list("target ref") + outputs = list("dir") + activators = list("calculate dir") + spawn_flags = IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 5) + power_draw_per_use = 40 + +/obj/item/integrated_circuit/smart/basic_pathfinder/do_work() + var/datum/integrated_io/I = inputs[1] + var/datum/integrated_io/O = outputs[1] + O.data = null + + if(!isweakref(I.data)) + return + var/atom/A = I.data.resolve() + if(!A) + return + if(!(A in view(get_turf(src)))) + return // Can't see the target. + var/desired_dir = get_dir(get_turf(src), A) + if(desired_dir) + O.data = desired_dir + O.push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/time.dm b/code/modules/integrated_electronics/subtypes/time.dm similarity index 100% rename from code/modules/integrated_electronics/time.dm rename to code/modules/integrated_electronics/subtypes/time.dm diff --git a/code/modules/integrated_electronics/trig.dm b/code/modules/integrated_electronics/subtypes/trig.dm similarity index 100% rename from code/modules/integrated_electronics/trig.dm rename to code/modules/integrated_electronics/subtypes/trig.dm diff --git a/code/modules/integrated_electronics/~defines.dm b/code/modules/integrated_electronics/~defines/~defines.dm similarity index 100% rename from code/modules/integrated_electronics/~defines.dm rename to code/modules/integrated_electronics/~defines/~defines.dm diff --git a/icons/obj/electronic_assemblies.dmi b/icons/obj/electronic_assemblies.dmi index 8fd1c4f5e103d398b2f5af104791ae27f98a10b7..81aa71eac773dda32062093e11546a517e6dc041 100644 GIT binary patch literal 32741 zcmbq)bySpJ+wKgFBA|#!BO;)PASpRuAV`Z!mr8f{3@D&Tw;%|D0!m8vfFLL>DLHfv zFmz0w&F_8RZ++)m>#VcRI)BW}Gf(Vi#~s&w-S>{r(Rz694BHt91aeMI_5NcBgiHy1 zcxb4=87JpaM+k&`$^VIg=Y1=W7w&eho^~$I5QuL^v4MK*{2fNcw$iuOCD5H`=Cwus zmFsOi=4DZ)oQ;2PY5%0cqA(%wP{xJlJ`@p3*maL&v>l?9h}}8rE?qxa={}|zX4@aB zHqx|N`15@z@sLMjU)bO)Odqu9M1W(r!0&SAf z2ipOb5T}U;3Gc$ZeycDQ=_XK)E!!H=Gxk9hjt!oTO3(@G3Pf6!pwuqV++8d}cN>?) zQAQ3*a~LyMXY-x?_2uP-3;dFvyf0&BI%;q4 zm0t2CWquaUkymNGXJl)9{-`{I{ai?tlKi$nvC?z-Kb13&R8)DB^>_@Ju5O1c zZ67P8khcreke?}cR15W3ob|r0q7qV-XZ5G*9ptjYz4O5=^p$E$j)4!2)uMQ_>At?q zxpP@dCi42W4ig zCsutqX2X#?Z)aaN_IYTE2KO_~eB-c^ShXtQD)na@j+Ae^nu4OOIT%Yo`#%*yKTts0 z)FuzNWL7oYc4NPg=@jtG?&oHDfB2C)lXqv_Qd1EI}G zo5H9+^bD-prs#lTXQm0uPnu&*Sy_FI&@*Z)MlDU(I9H$DW?PZdQVqJP(u3`y%-gAh zr$v`Tc3W(1FEPvZFl=>yoHI{&m^qgkP(Zok|xn0DLai};J#!JEYr>cYK) z>U$R}THaHZ+1;eEF4Rw` z8r=?dC9pH;QMJ+*yGBc#CzAK zR*GW2Prajv`N{RKbP23^8GtMMCN~XG55G$+Z?~ujnvQUIo5s06h@>;5*Ff^%-rYa z3s|9QYCM8!7ja(pp0X)Oq z&x;35BofEj%j4VkR4E&;=tNw3SEchv2~!nygpL*tGb-6V|5blT>b_E)(W)kHob7%Y zZp7)!mt%5rr?F9yb$#J1vztfh4f*slkxEI=M|j$E7~Lu3c~r^%_{(L%q{P!QGp92% zvl`_3J7ogAeY~x?Flk2{Jq~7=qaK2@*8Bc%7sL6T2 zl~4+LDkbojhL(da`1FPgcP>NDpFZL$3gHD8RAP}Qo+gSfg)_? zD>#BMp8f9!3g34@BK|a!Thwj6>62)Ks7Cia2$wm*#a$XOmmq3(KrjFMmBt4jx*)#` zdwRZc`#t4VSb9PwsE^bez?5cz&bviML3QqMT$)hlQ#Od7)Cgl%3W(qfZL>7i&3^iy zyHs7jt}|QJLF3q`(n!G?FcseOGSx+tyWj5XJw&XKZD%C2fv}wGYESE*_FP&Wa6`l%T;z@LR z&jN26>vb308>Nz8BU6%AtHGO%C`%zHm$n^F&}g(Kp??Z5V!z_F=+;)eMKVc8v>rlt zc_F`+r5kkX=f*x#;^wGl>&?%#qz^SH&_afet1xERD)iK*>@R6N{h`>L*Ersc1&$-| z7&FfDPY^PR#|wwwf7v1mNgEw-)p61qK?U8{HjuoqaY1b<yDsfLxJVa6TCxDUoePsL5*uVNBX@mRfv zq337TcP7tMNju*WCX`Ux)<63DkwJVdgU+1{%`DbJcz!m@963STaHWo^8U^P$>Bl@{ zdLoM?#$q0dzh}`bQ_&*Wlw#qZ_wsRD$*AswxKaY5@y461?yTbGCZj`7#Txu0s?|;^ zGlBJ%!KW7XB4`O|UU%G$GRJ>4%@!;fSw6ZjGGe`k50;i|@`S_an^k<*4sNV|0V=iE zS!zQ0EMR~W`GrnLYN`+7M@b-J_u{j+-r^5e*!IIMJyz}k1vWmEdw}51zGPr`rccG0 zmFKm3NVKak`OCq7M7{qZe&YOqHVrM?BdTA;CoA5}26e67kg*an@im__Si%7lFc8l1 zJC+5Hs4O&C%ZexQZM{IpcjFg=^;ok_2wKWWBplq+F07$&?&GNi`uzUaUka5|1M@iQ zKZeBuavz+CYiWhNJ-sF5_5Z77`fm*w@L!1d1y4P-cHha!d7h{JEx&|}R08cAyn-@* z?|Cmqn(9$Je^=GjZT>QkYQmzD?v(NrU)P^5+pg_X72fNJX4iwq{!9PuLilQpS|H~m z?k|FNBv;R;Lp{j^sTafB%dU2Y)Js;;ylE>bJ^E&*>nvhPxNujM5wxnK!W77&xJz76Hx)R2tNs%Lxbz zLbb2!=Ym@!qn+C|^3VP9(BJT%#j{T@bz$f(0_(|bf>2CqRY%sUX`Hjg8u27FlgF|3 zrrHHt`CZDOQ;d4WO%T1tPQge2&WthQ{!5YcfZbMZ`Zrcd%N_+q8^I>tM6DFS%SmW92%+dD27^RTDFEWs%FDYgy(308DoyExPNDb-tC0A9zP@hGPF!in*B)oDBc^1Z zkMAN{K1wY7@L7UVKQCs%N=9eg{E|qc5mFI{UUR=1!TS-0Zp8vTtz=6$4nBBACDvCId)#3FY)iihAp?>ai)Zg<4df9_t}HFN{Mt6 zN~&3uyEho^oirt&*Tk+AyUTO=C`^n{@z5d)i;l1EGOqxfmiHK z3|uf)qcaI{$0CL zGN$xI1XKFl#8ZoRM-#5XF&x^knfQekAf|UrseXz`+}m``Z#wfwII8iTF>XB8-Pf-? z-cF%*e9FnXZrX%ooiZ7T)qXSC=hJ?kM2YJ5Vked1ljeg+l>T<%2IUB#vC83_6N0DIc;5&LD~} z>;2OM==;-rxj|9J3qPVpMhta== zE}as4(ra{0xeuSg{0-3{7*GD>iz;^WO0hkB zl~4HLHNPj*%W4`n@J*O3h>mc1!$BDl57l#JT{GSB;FUW zJ(7KHbFlLF{M2w}_D{_mlYla*{JXMlFfu}BHgq8>mMA?#JK^UmU<<4^++y9j$9bBT zZ5y^LvA)5PB-FACouLL6T~$%f)92M;{buUr7vP18jm->kf23v)GqY*0gf2?g9YV#X zDN-DiGwjK__Zz0-0(rc1>G)tk39z!-m2wqpk&Jg=X_T-mEFKKaR?Hm@xklhFA3z6D z@00=@AXIk&IPK9HfX1P;UkIE6Rm;Z%|8gL2nN8}LBu+uDs$$#!hi_56Wc@CusPSfh z?l878G!Cz{K1r?0aM-ZW) zu{{mlq#gV9yrjD9@q}mNz-s{_t^NKcL zrtMO0ncB;i8PzyvE|5Z=AK07=27a~N+op6nBB1GBe}1{|1IAPtb5SGYB%hj6jrld+ zP>Qtm_4T5Ko2KdPTY4h>C8Vek_0Q&>lAUXiggV_#DrIjO|NVlid#non z5-PD=y*zI(@;yt>ffLZ?a@Co*P3h;@{WZhR@hS%v0&AHkvw=L9Hmi59s6x zQRB^|)$JdV%lR7UmRKuqcJYu>R(pGUjnYWR5bIl)HB;3MAr`yai3TKcwDLd>?%_gJ zVw?KON$1 z*xeFb)mz*H!}L`YqUkT;(d;J*Zis6^F8Q9lz3b{5&i6;$l6Us)sh5Snw(8S+&9*nP zd2*~P^)|9SdGaJXHF(gr?t8C>KsqsTs&JO7O z{y3G$cAFg)0qXUEj~2dP_qDXN|GIk0*=ORn>#XJW@0@?z{`~gv$Ou%FC8M4hzuNu$ z(lr{RI*-7Po%WzMH2>$7Oog6QY{&$uem z5hTa8Yu6ybhlk!nLrH<=_*d9=-Pw928c4NN0XHJt+Jd`mrd_jr&~4JGX09cK zJRDhU*2EU8aQJ@7kL8uQa=IX`kbX%LG`qa~!irC3EJJ_bdm6T9^~mTi$E2OWK$;c& z>Gi7apV7!W-Jt(3mo_|h7oTZ3XJ+^|Nwey$ z3%m&Os=}tr*D*i-U3&h5JnQ%05hySUjgM3B*4I;A^*KfBT+G@PRWudNr0!Avap6Dy zZ6)9BX>aED!y^@;xby%i^B&q2?^y$dT+p}MF}(kKdpYXxJ$_=b5=oe)hP4omP%iSB zQnP8$BKbSyuB!?DcN??YL$Xa%ip^Ei=S3d6Us|mqM#Zwj#eLnrJiU!egO(dyB6OcE zsasC3EDf~!!1wj&+WZSS_ZP?8b9UyC;aMASU?B5Cr3-UL{JHq!WzC{o3Fz9J2wc;6 z^Xsi6O3l%gA1fm5Vf_MRS;(gSrq8Kkj;nHWBB(fDRGFprplgk86FcDm-Tf)BKl}?s z@E2=#pc1>M-}zv}weH+36?PgKy>AwxaJ+BN``hGAO-*W9g@uK;1CLz;7uZp%Y}zLT z8}pNQD^{Bu8=eF%B{=RUA;*7YD2s%*@jC8G7NQinrFQhAG}DD2dANR4It5u%qfeN^ zOL`2gb}~_*9}Hr3OZ=9CIgzZF4mWXfEc`Ppw=xnWrktL*G$G+ZGD(>6vOwndug3Jv ztYrUEUpa;*qz-Lbm3;kr{?t4PDaZX`wt%Ay>jo|ZgUhG(O7LAApBkr`scGgg?Ngb{ z*K6LEmXvg~zNXe&7I^pJrJB*~aXrJ`ZE`+YD0u`q5p;2h0frwKB1${sDth%X+zS4c z=x+0;Pbn+O<&befQ{A`@{Z}jk>Dk}DeGAS^hguQ1kGO@@*=mY<{1E(I(vJ66e)v27 zEu%imqSYE6&HlZt*(}J1y-DAkYmCsfdt+&!$)@cYceW?cC+=4qu&&urW;5$;^y9<& zdfA80p{rFxT88Zgy!W0(w=)~d`E1=+Q;WdDw`W^FW5B;Boq7ZGV^`JAQV1yzyogl@ zpLA{z-gI%M=7!^N2P`3-LtQP_42ho0hT5aP zlvc0riPdMl{I6bNdlI)4*k!1d;2duq?CnEU`4U((1>lstKL_h3G!AX@1iQqc_&aP~ zi;w*)pc$Etsng|xA^rW&BQWT~kVFCP`e!jFzbgr0ZF4zC`EC7jw^=GkJDuDt&P@l; z>T+^;^8>a8={RLCzG2`FA88N;UN17i?T?LF62>|AXiZ$%>}1I5RrwX$q4m&O&1#4s z>O<$0VAf?OtFKxY%+P3VNy7w+C91btxl^v-#56DP zd^pft;On2vpiEuH?4~Ikm&PWy;onVPShfbdiQToC`>`xCezGV_(}K@MFo`bCcqvfx z;!?wU6e4lm{U~Cd-z&e^Y3unO%avu_*WBW%El1NrzlwQiR3)gP%g$u0Pne#3$Ff4= z8*}1b@hnv&E(L+df8V-^sJD2_n814bMwiSqDSv1hLbJ+1)-&q~d8`4aQsOHWOoFIJ z4q3r9eJWI?$$0O+mD#-w;q7ZtRN`|HJ;QfOd{l4YXVMCMYT;F-m_*IX+l+VL;sDLz zr+&rib+uYTurpF!nZ}KB^PWyc^use$QX%n;KZ=_rLm8hZ2iBg6x&x*MU}-?cs%yVK z1+z5QU!M8KFyJ+2YI9P(h{R1}9P_WOF;oMxQ*}p2RMTS2)F%^q6dcFP zDJN@OYP=Xf!~UK!FF(U3C{ntk!x}rbT1yKHBjH#8x*3x{^Ot>5PwiUUN?#qzIhc?=-Io}B&~t8 zSJ^=REdhEoe9a>s@s2xbgotlcknjnMDB-uJV$+@Bw?TW zClWO42TZo$_3PhrG;(TcSRyY8C$LhS7p~qSmuSLRB+&|KUiL5N3`}-A9M({0%gZ24 zZl1jhh^w%J7aeox2Jg9_ks=*GS^B6Kxwzix-y}j>Vd@#PH z{1%RVy$ti)eOZ!tS_LDg!Pgq2xCWtX7i^zjT5;k34{0OD3oqcuI{jj>GCbzKgEE2yY@@H}q zt;!#9ktJq|790KD1q!`+1R=HUBf3)iGkffe#EI_Qk|bm++dNsp8nEj1Up zX;i67Jgh;UgIpHnsc9S8o@;~hy(%y#?xq48?x{5-bmtGlZ>`Y?_z|A+K#;ERc=~(_ z+y);R!*M#h&VNY)dO9yVOQ%m@xQz-K&49LZ(z7naWtZ)_H{64O`H|U87wn3J6p@xh zgf&Z7R{!M6aKB{%$Tc-7Df{#1`@OsehlkI>GS~-yaot^1%aHdIvzr2DZNlC^7iEgz zA>(=c7eBebc5H91hmK$pNWhXH5zA%wI3M1wmOqlHGyE8IXqc3m`eNhn_w};2Hw=X~ zRVqjY(3{%1aQ4-F6ceeaPfJ1?^8QRx>8(x#=?Fm%>4T91J$-ywJ|lv>Brk1FzG+~? zQhAbL2;#1D`fQBR&%P~4N)cHh;3!Aeej}@OlnPJRYmoHe1!cTWQ>h%MOUgQb)#5MpFSU*s&PeUi&6eS>EnCw{YrP}(_6X3&zu#ZH zk##P~e9()9k#^}fX3lA3o(c3-D<>s#%84?!I77ZD9>Yp^5Ua0|S_`DF>O_qLaDW`Y zhLB);01y^%ePyn5cSlHziQ4nuP$rZoib{X!l2TImonrM(+`^Xl%QEn>nqdQtlhx)I zrGG1tmod~9e!{$4&{8s^EFxUk7MCE8ZZTE8uL8U0@jOEXVym;VCoZvYOJddrS4642 zM&E4R@l;3b(lc4lAxsG>9`cqD^p>TFTbw>}2F@;I!-_Yc*O(OVou#(XrHAX~lZmWF z>X>cSo4a9VGO?4mrKP_UM|H#0q-R-#LP<1A7?Fo1g;NtzCSJ_MH5iFW-}HdpHg-jy zuzbV9p7%I@g)9|6oVj_s5a}nq82+_(F<&8tkW;HxQZiaJor-;sIz^|nP`p(bc90%2 zlAdlDYu_@(X`G;g%@m~843cVn>$$M{!G5)$8@UM)*O&U)FqP(B_tr^$J+_*F^AXo&F2fV2^%U@tKghqQyt={5@}|qCg@9*B zz={DAlT%-B)O5Xog%!9!5izASyxGfOv6CjyCh+zDwS^X|Fp zck*n6RD}xC+(axqq2jken3JwrR#ed?@d+~~@!0;!NgY2VyvkOSX-E1bUyzTcLfqWG4XnJRdDkNLlr7=%_qv;JwRfK zWWOu%43DLYW7$HHD?r=m2ULQ30w({pcEyN)4xNvnT_$Di zR&zk5Dd8R?Pkp~m07ZwN9E@|c9KYkv-3ca=XODc?S*u`O!>cUF%p==Aqb%ef;^895 z$kXwiPY?mk2LRLhIlFT!NPqBT$m@qf;IZhV!o=?7D$+d$eA*~UTfu;ohL;YQ6VY5u z0jOWBtNVzblJ)eh6O&8?)8UtK%xB?fRCJlg_7`L=!5&iSJS}Uv zHuyybw$T?!7q@$V*ReMFdN%AYF;mWmOjR*=FRt`p@#(6XTWF%F-TH| zM;{czv3}>>l`pTwV$dp#62PGa?*DmsS=Lif5xaV|va<5?)SP}Dx)d&tUGwQgko7B0 z#z}mfi6uM45!$`6ujjPw$hswIZlG#!Z}wz5lQ|HL=9}h@V){m_^-rcFyUU^*PpTEC zR7iq!JO^6?TG{f{zgM&K5VsQkv|_^9om=`c8T@juUQ?=c3~EsCUdI~DszAZ4N&(AnfVHkU z`*4NZFI%Pn$3=|N~20)PM~X*3fc1(afuhz{(E^YfD%Wg5@~{rBgTs$EbqD8iOc zOtSP?OXqduNN{%v?1Qv1WO;a(UDD%Vzj9$U-rC}Z=%tR{@6QO2RYR z4vu!`RU<<%1g(EbCfN_j(m!bRp&7MOXAEbBeDQP-Ibk2<7q6Rzde$)XQ=cNsHlaT~ zv;P5%p%+E`IR7b82(4|EfwKgk<__B({%6&Ks|2KeH7D|>kI}U-1~lw%8S(Ww@N@Aw zL7e>ml6HLP5_+80AE-jiBAsOA)RLDr-y4&|H0oXKUg9qzS+rppq`;5f+k<|{FFpkY zg>`P;i)WaZ#3sTHxE&2ht>NJ3%y*)u0-YD226yAG+$)bcO3cDjph(0cE6AN7tOS?e z;`xWqRBm2MT1S! z)SMh0T~_5RBN~#5NN@vEM;S5ElCXjxd^i)#ubCcdH^{HE}pR@;!nEtS<6y?SP?3~%L!#fJxg#D@}m%;2aS7G9=CSKd&A&X zMa6@>F4wc0R75PgbYZt!#AhQmMd*>tMTFqRSBDx)U-Liy@aR`~L(S#e@;!+Uopq2! zJBsu<9nYh*Buo)$>i2cXBLQI{Au!^$^^wB!kw10x^;hnXKlWWtvl))oiKrji*=oSl zKc@Q0eI{&RcsQy23RYQD^BnNVehr2Qg{GA}t~_s1 z0w;KS8`QdfYP4*lQn&jRc9x|J1XYMZ(M_t+p`l!7yb6*$!m6x(>cotcMvN;WQT#L^ zK}e(`#3(`sjfx;3x}q6Bq^B=lxfgB$ywG)aB|}5Q3H`h0-M``O%s!GYLKPD~8^`2&T#hanW3kD4%6nf+@+ z`A?DFe(p>AYeRnAS6nV$LqF(P0J@`S&BebJK#jruXPVD6`#_sb6pvvZZ5YD^Xnddtf zVkgqvAbqr_i9O1KaMbp1Id~>Gj2$aQG#q51u}9^^bL2cu&`Rkm_4Dt9M4hMZaL9Vn z$a!z5vgKtHgfB(@R@&w6qMO)B_Jb(t>$8Al-k*_?u=uMFb3jlA8SbC(*{rN1LYbeH znh6U^dzZf(IW)JLC@HyROf;E9Ku3{eK)CzCtBuoZWA7Fr2&ZGND?x~$QQMXUHhmeo zXFoN4n6GtP(79dBYZuZP&Hl!!JLRj$rb}1lYifo*yKA>`*bN;31ieAyW^s5}@mwn?EOAK#X_?)3}$w+j8#>{U>tHJD#g? zvP3{?m09sWeSKKsbHcGC#`aqg0!&HaLBYTRjPyUEuwJr!xf(zpQLZ#`VtrTc zR2Q_f6f+aqS22_yBlTn5)nm!%vpgEW{Zh+#~;$F0EM_t=ki$DkulsX-(nq2TLRwe%yaRMYSfa%yW%MYs9; z>RO`+SP=qOMl5c_)&O@ajW;8iVJX!T9#h>isnwy{F#Ta;0|zu}Ue&v4tL-+-5%y@( zMWXoWsZo#{svtHUv1>Xok0Rh>NXvi9f*2q7T$TzstwapHDE@ycP5f^KK>xFXh`J7V zf5+*{cNe9K5CBea{7--&8ptLOC^2+pbv3`_n~nuHP%ilJqtkr^5vOL^LI;W@Yg>Tp zE(2B(xXX5Z(o9o8(4LUhHo4XKv=J#@mCqpyi3wbhD>*p(8PyDPf_VOU!18+{HJOYm z8tBl8DMhCRVTB%@wYs*pwlfV2!g`udHF$6S;3jTUn@>SR!3q5_grlMQ1ghG3`i2cw z3jseKk_u_s>yuMk`|@D{; zAK&}L=)F0y)YaIT1l^qOK=!6fs_W3#8`n4|+w`U{9V5cwIAT#yaLP?XUhQ;=>vn&E zv0O?>xX}Lmd(=?)-76qjH*U0TaFgFSdLEej?O#`8|C;Tnr`(M1{j7`FP0X6bp-9bi zkbLbd@Ah+iqpd)N-P5hRQ-rI>6k4#<1|;QD#O)jWuaLX@3#w;7^J&X->BA-!j#v zkC_sE{RrY-(d0e83-K?yjX<6)lv#DdHKaYn0B88-GP4z(DnU5Pb+mja3kH|7{a}*R z@BC7EwPvOND^sQS${qkbxivLoHBwtTf=Qlb=fds+O*sW7r?@QtqyHJOR&4-BUi~X` zYzN?(I*u&(MQ4o6r`tbw7COb7r-BbK=7a`Q)FY*Ag!UUA001 zs5!d}s#x0c!BZCl7Vr$f1AXuoZ zf9Yf3uA1Lyk>M-%mZyralf}doT$b3p1k zIAC*Yjb6ga%IfXU=LSvwlFz?i1`A@c0|OXo9jom#TD<))3^t0mVK$7s@bb&mRHwEZ zk2tAIh*hlAeDvQ6G$bl2qg<4`gD-(%H;N=aEMFzvs(QB%+0JWviJt?Q53p-zzZ`>% zBtrhnP004&!q~a*`rPVCmUnn=VO;X+*782A_FqMQg{Yz`Khb@VcKIlhxp8qtykGux zvXK5Mp-WBAp(J?mu}{16Mw~cj=sq=tG*Gox02==c4^!|EpyTI&vqfS1NAY0ydIe*q(q?`HU3>gOL`+&$)@Y8E(peq)O3&(-8x406a9rD5*+7iw zEtB|(vG%xWNM0Vv(BxLv;Om67C<($AR$M9sWcbIMJ)P!$gr%%lN)&rPoC26`3m*li zE)u?{r|s>`q@(Iy9A!gXdC z_}&GxG-7+(Sp0tdNi>^emn-NR6wuDMfcjBu*dW{w@?RfdTnILWnDTNlugS7`>2;Q& z;bA_+?r#Bz*qC3Qlf~}hZ`SV22*;uHuO!R1@YZ#yEce6lR5jZ*4Xxkkc(!Y&+(CEq zL9xr+M5z{W_blmfLLG@6DGjFFXGuVn(WMQ%{00h2hR^asX6sfywtes&(j!G9uuO`k zRbA3ZRJTh9Fb%Rn*vch2KUp{GfqwvIYYaC`F?R((Pk<6%YBk5gh?l#d3n1zN!s;$~ zvFqerN>jiQFMx2TAQ#w++`h?o$l~I2oSdAH;FG`I;ZX-*CeX;LB-yPzcyr@j{drWHur1r7`z3K1lWM zVWscdYiN#h%iQWxX=5HOHmK#%b3ZIsO8n)Vg*1rp)z}U^n8sqe5mS7ae zKSkh{c1DFYO8WGdAs{Fc@bvQfU1t_9Z_~#Cu=ZnHN5>>;1}?{L5=i0wZVNxB_r?xp zlLKTg!Tc;5rc2T{50Wf_!4=Bb-*U!YgFl)0;Byo$PZNhBSLBHMJ7)Bi1cDQ8z{J1@ zeIUoBB&o7GuffdU1+;Xk8P@#z(TZXD%ZNrF49aq*k-=^4OX~bgK#0x96Y-A$eP)C#pBcaK zZtJ5u9WMv_^M_mC?6G^lT$Z`+efjbQ5^T7V@mgCF)pR&E<6}PP1H)&L2~L-_dXR#d zh01RsIv}g%TpBa`=Q4uiim(M~h#n}oP6bj%HWx(9gq zhl8S&n=SyyQYA1HJi~Xb0IWVdHg=k0x%x2XKEU{pf~+cxH~vf!iHOB)Z6TKmrbLC<)gNTd8G`uY5Gw3z1)uOasFQG^6Jc3Mf z>MubR5J$w{o`ud;PZJDToTQdj=X1qMGO^ldgh;&Aj{ryqAJy+84b7wl1tr@Vr`7)C zrRRuxL*y-Uz(z!2ChR^sJGKL_wlg0o(ghrE@A^m#&hy2Kcc>_1ShTlchJQYcgwK;xcJL9@H&>u&VSStP_B8AWJPkWeN7Vq_*ZgJ; ziYm^QY`{90o>MlI-jh#Ze-{XVL4~#EpidaUI7i?nZ3H$^7A6kgJf5J_DG`K&2gJKXP)?tRAZ`F8bnvh@Ug>Bst{$#1Ubu-KDGc*}Azhtx?jcXi%kxd~JYQ`pgH_ zBzQe8*M*d^uZ~(}UqraLxI8NrbWU(^2${B35~lywR)wwxMK@r&)o>+C9kv&>rKRST z)h^t3OXP@tme-{2EnyVV(E+=cU`^ZoK)3leo952S{FeE(2rJ!`UUj_e@et+}s%L3` zg5QnYy^bOSenc=N&sKg-WvEy-_1}Y=M~@!e)C}0FTUnOx1=D+4IRa_R z(MezBr`~G&{w|=I%0R4PcpW(|Zqa0J7ydZCdLM)nhC66Wg1|bmvht$s7Poe7G4%Ze zOv!eO;nAa&0~-r>Q_>>@=QULw><&mq<-G8qUViq3ugT$SK`jF(r%xd&*)CbAPAgM3 zd9+Z%XJnKs^l;jlpq+6?mjLfqcu}sE%eex8SSypZyk!INpnLI&_+{El*p=unKYxr^ z@8cHw{kgM2VlXEshYSeCPY@To`J7>p~~G>Prg>f^T+Lqmkdfb(NDA ze<#KaBlPr`oEtW!dKzp$V#(t6P31PKC!J57_Ll>g?EuedNd*A$Kfy%19*pQ;y?AC0 z81!%cbv1{kxIubQZC8t3FT4%zG;wXEJWbe&+74t_&XlBFs;rE92zH3n8yPXuzoA@$ zz04} z$A2G<%+G)LQOb#pjh$2!!vsWAL)vLVq6*dJ2U+LxyYE_0OpVOJw~#Z?bTxR(>Q3>& zwp++wxnDoI8hcZ8$^6#4U1tfUgiAC)h~YZxup##xB6kv>Wu0KxduawtGw#;J#KhyS zY|g_z@%~w$0GDo=2+AFh^t*V}5_sOl9dxVF&~h2dDPur~0kAraLT@!}h|zJ}VFZ8I z1M=o3_G_N*!<$5gTnph&R4ud{FN5*h4rw6l4nN19H(Km%YQw(u1X6Uc8k81pe865z z0(zDE-R;g+oedouJMQ)RLT79)7-kRw79CxCo9*X=z2&c&E}NrBT>&%60@2g%CsZn( z3oSpX3JD(6e|WO>l7NEaHh%!4a%)v2ggO`$ecsoBkJ0kg7yl%eMSZLBm0PZ2x*5TF;6+{r(wA&?AOE{bi zTgnkcc<%g^Nq&GHv%V2kehF&{QlrnDr3wP2j7g7XbDIo5F`-e9svo3v{KiTfDS|C5 zzu6$?FL)+FR!=dHigwO-w_2=06d0U<>9p73hG9~2@-<2&@A7jhP@U>*K@|P|qr9#S z|6g8#|JogMw>>9sD3`)U&87cEj(sf7n@oY?^TaN=&BR+mcE2e|Q{E*IAk*g?aG z_)nN^xvqQpv^eF;Pm2H4tNi!PgMR&hI^61Jn%?`VP24@@LwWKg+Le}d=ebEXMZZ$WyQSi*~t3)^R$*W!6nDW}_X=__!s7~I+Z2-QOG*Fo> zF0d=@a?K~j9~NEUXnxkr^pH%uha$4bkB*wIr!~9yXqQ0p(}P@`A`+)aIh_@Om>N6$ z6)~Bji;pzN|A?P$b3uOmXM@oW#%>DiKa2$%h3;_Vp{)KH$q+fLRnU(DGP@ax z(!yhsH`M)h5zT+`|3rN_`AuReQ-N;<@1`e`cu>kIgaQ%b%xGp~W4!8p`mnnoObVHt z42?%@PE@%A1akKi<5uIIRzJZ^81b0kuv12aE_lsKf|6`8$nfy6!L3fn%Dcp<>fdT7 z8!DGNv`O#9vYRG<%M6;U5>L1FT-88QMkB@kRfn22#4dz!_7%fw*rCeOh^|_TV(|<%94efS`h`zZicMa8Hcfw*_76I%@uVqZTLvFgpLV`-LQp z80YD((lgRKZ%*Ttr4P>aYLH;S{AoGC2kHBnkp#6RRax?(mtO|=spHr(Ba_xZmis3L za#NLf6vp(ml_5^*>_#{@cDC~#((p8~01Es7m*?r}32GC&{+v7%%6-cnl}jnSPAXm* z;sV%iu04Y3^6lpoR191j1>zrIz+re~;W$1bh<+wsBTs3@H;!dlkk%q=5+^eGhAt}KZzK5dC#$T6wO8$B2ng-iul zQIytfK5XkHg*tFIcd)=9jWgBU{h9t#9;CB1o!>pQg&=>;NE0vu*yknc{7RFHUpOu_ z?MqJJ;vEa0wAWi>?t8Cf)>mqbQCpo`KZ7Sypp>lWbdDO zxJ>!n`xhJJ`dRqgnZ#88Eh70e;CxcmK|%yz+!YR_|=vNYZRiz+OB$x7B>aHRaRa+hOmF`c|LmhhMqWD5#s#3;F(GqyipHRZ8RF47PA_qOS! zr**x@{}seP167z08lcwm%>i3K(M~vM?EpS8j8)Hm_%)K7xGVraor-j}V82ad;Nblp zB6e)Rbq_Xvm_L2kbxVA>8R6GMJ+Neqz2z4xDJW<;7&DK> zz>gYgceD}ZcpJ|jARHK*oM3%F0l`gyS~3Z)>1{^h%Et9>ML8mdXd!cYyx~_h!a_23 zX%1H?t;Q}Rz%KLeD*uaanh~n=sUShr{*(k)OUl`H`YZWP=J&oIS7ivF&^$!R zN8lVth+l=-RGGpH#tG$F&U5*&RDVFsD}g$zJdLzhV8cUq(_ODageXh^4|uH z+w>YI2_B}49y=)Ch3MlRzqT^pInL&j{J^hNSu!r~MTl85B%Zv$uO0CRS+}>>hZ{X> zlS63J&AYQJt^|4yGUB_>j@>heSG??X7DiAxh$|-??EnVg6R=d@6_vtQ%d@~(K)Bcj z>g!I;>=8L*CO~`Cr>9P7(D^Q*QcoB}+~8C*Z!LAJ+!@Os#V#EiSZ z>YR^**s1xH=7LQZS->k?Rf%f(s+VtaR%!5Lti)6ZiQnz6UH?{SvKg9TcOsyf{@I(% zr=CIQ)&YjHi!>b@5GMo5j2}Zj=LL$JkWEZaN1tPt%5G?22h_qU2;Wo;Zd!djsjy1e zYFIIo0QLdmx^km{j(Dn9#E0mX6vb)Y{?={)TM-PW)us-`KOAQv`k!v@O*>FfM1QK~aG6nCI zl7DZ$pvWl_SBu!f z{tLG3^6vG%w^mqywU7e5plFbaFLh_!N#gxYC86xt@g?nPy?+%uV8Fveo>p2Hb| zSe0ew0A6XhY^-X6Hx#OweXYpyVlM9ew0!?_QNHJCk8d^o6m|p~4I)_WmB@Bgi(2&K zK>T`SyPhusToPSLUumQriXmsBjca*76lK4s(fp3z$72ldg#bppvG7~_n!_F^>7X?| zqzI>O(2UWo|EhQWq0IkpFyy%rusvOH`416(761&hw;V19i5R|f*^ilp3(WxnzH!cF z9oPy@PV>bV>yT`xA>PM;qu90eEbg8;pL}E^tVTofEYJG@9jl~YqFSVdP#umWGU35< z?qIbXYl;>5S{>ZPuj@`gG>8gn3u>@Kom-FJPEVo~GR(l?Q3ZmQ*RQ{!k0FgR_nLMZ zf!OFib3LLno+Wx5ygz^P?9(&kGTwEyQ(6Ok`}t=|^ak^Y5a8n1KlX)f1sr=2=4M^| z35{L%@E|!WKOJA3N5~d9i;f?n9>oEUILL!5e-ND;yp)7ezSJCj`pVq|Lxm~W?my)E z?9;LE;am4k`=ltdE(8@zOcU2o^IGfg9{{#N4#<`N3Owpx-C(`Tk+jGQIFsGH$P*n- zCoak_d=>*VQ~_-=$9)i4-?%8yoWxPEv}R^EcS1Sz)DYi94E*4!(3?L7eX6`ix=w&E z{QUhp+|?13ToBsAy#=o#d*&3_P2f|eNlw=UPS!u0tr zBjo`Nb<~EZRY2V(6h=wrUz)r2GPruveJMHY=ZZDp?}1JVvE0cX%Mc|49y!@Ta3 zUsA88Tpuj=xczPiEM!grM)4C-2Tm3`LjMB0D0fz=@ic^X&`^Vq>lxH-&H;5e7d0pqvV8;6L8+dIYgvQ96Hubg~e6fq@(MW5{UHalgO3tc#3LVJ++F?Jb>+H zG+DA9x`zJJ7wAe6v;+jP$$iFB*$1~hWX(My3uld;6z%=_bML+)#K~tS_=xu%Eo0th zIQ=1O>_QoHC^Dm+z*^xQLJN`z?g+UGn$x%`A{$UQJL=Uig+ZYqq3_>Pzp~~o@l1m< z1`KxN=X-t&J49;wfO-PJnqiy9t#Z=h#X)rvn<_lL#xIQ(4r1S!aYa zXmJn!%e!UA$}thWBrTf5<;)Ctw%HD+A*H#n;+`S+!I_qJrOLNqUZJx?1eeu85m0;1zm54S^B`Mx6h(pg#~Ifa{-%m(X932#nl`^ly@&u1Jx+zuolu*A(((j zMHt?L0(VS{kvA)vl<2-&k-QhEySSdp9yQON#K2T!enPIg@cO-Kc8Ku^=tv z%8O$oyWB4?QT&}NS>%g~_(ZlYBaQg1S7#1z zXYPq_s@Ir$G=@nDrG%X!Y<%;=ZVK$BXB<|t|+es3b8zlD6G~of8yCL4KFpZRx!mno2$B24=W$==~hP zmg;<}jwWqPFXFahC>zIpxb$2Sh_g8vA68=1jkIm0xM7WB-k`o3_P(LU=Z`QGn!@Dp z-y{a?>CGea?Hr;ofGf8%^NgA?t2K#RJkJM&V8pjeOIuxa!uHEz!$Rt73m)(Ro*4L8=Ki@Tg@Ew5kN7^m0#f;;{jKNKzbWgZh zbTOy9>LV^>$ys916uLI>U3zIg63>X`tfv!s2fG&VYq~0+rlw@&>EZDN3*=7}9^HF; zIA)yR;BzR~5P>Eo3R)C9BAA4s?x$5T2D73I1iRxg#GQlOt>S=;HO;l5m%>&}>6JC} zqc}FW-Z`Zrib9$xc=M*-Z@rwx#z=tj1AL*k+^oR+?!RtQO5!w0iUp~ZL zDTl$L1f{}lRH6W^P!b@mc?=2G4#c3b{w?t>RzU^W3MU|hQ$HM)g`t95L%2imLFk#t zG5h-9D*8x-NHtk-??(B84UD&`4Lm3tLbSRuT&rCrazC~!_Zv;Mj(7%;c4(6zxWDpF za&2*Ft_p2oiQqBaP!NMcpn~X}S#J#r2h7A)4j^#aP(C!Ab!KrK9TfW4ny{c$xF$mW z0o|JUHvU^ypWmka(HQI$UG48onP!I92c- z)f>>W(~cX-%1G1)mknt%!}*W@Khz-pXQ?8PaRjiD%)NYn<;no?+8T4oBBE$kd;$pl z6kp=|qmRaJohqYT9d)H`-pm8>&zt*ffDqdMGPR8p{_3g$pY;%bf#>DBcV9cl%X9E< zEQl+3oy`aYgTi2K+lMu;eXu(KEAO!_l*zePBtl`&Yh(o$jD6Mc1^flr`@rSPgWTEp zD6CaO3J!4Z*iRPBAnf3(BhSkO#&OXw&}f%GhfJ+`1<8H^%QX$od}J%eleIA&pb^G@ z_g-Ws$7L>aY{H*G$8ON!J@bO1J8y2xJBvRbRK(Q%*SAz}LjTQsSSK<^E`Wvq#~g{6 z4{)R*9Q{6mOxVw#w%{Icn0991zug3Tcs`HL*~>Qf9z(-=Tyg*O8b4H^1Voz_{&Q#l z*c3Y3M@iuXERDa9pyGakk{TOrmSEU;foDUIDo^we6zzW_{{BzC;b2FheT_5Jj=HyH zL+a{s8mKQ*?70kO!Zrj-dH^Tp3qe72lyBoOwscjoiCMJuTqD5`Jq;+Qd5(LCNQ8V7 z>c+)b{PCrX8?2C`z8L&meK&*c?nGd~zM`kG`iA$z4!U4c8iK%zzs^<}Q$#Z)58l}x z4D_TbQjEjv6l|iwa|SYefS)=-n3wTkDfVl9T%8^Hm~yC(mAMoT>e{WvuIUOSShD`U`J)1E z+ReB_KM;?{h~+3y=emS()n0<^SCERa6-cToU9z z08am=j?P#G^ybYzKgUpY)F}Euh?J1XSSmE)vT*b2$nd_$CvJIX(wFOzoUr;I=N}>; zn&o980qrEfIhBs4D=;Z7NQt*#CJ{l=;WDs1{;o~})R46z?AG+(S?n$W3$6s~UE!Nb zTi=B4Y&l-#dAgt=A`HjOdz)r(Hod-1=aR&M{xxri!PYvV+ivFWX6ebsKXVE8yeO(n zRaPYHOrwXZ5MP?YxdnQc`#_!pe|swPA(wpH;Uh21DunKgYq87Q<~ydph3WVBpAS;= zUU`m}80V9F>;8ztEj>5PXleD?9^69k(!j}LdepAZ&_b2w9yuS6%zL?SWr$Bk@&VX^ zwIsrlGfkv1ZYI)02=?~&6y9KiWS&J*mzUGJhdp;WFcdnE2bGqX$D8Wtzi-;Gy?n^h zW{?rJm1>GnHkY%NIv;R%)5lHOV0ks4#qYLyvgzd;rn}2lD=Gknxo(v;EXZPR;TYpSjRJ@KfS4CT_nTS=bmt=>EPIxWrX-y0?nRdO`>Y7O3 zYt;$X?5(r!H)FMGSx?G;39H|lwj_;+C<@b0o$v&pNXi(3HGORreS#%zL7A&4rk8VO zpG1W80*lIDiw*Hs#lFx#0@?&(@0|eeeHM^@L=t=~4}aVPsbd*IViU$czwVtoetTfo z99_tgYukUWi)0Sfa^ z4_@Kv)Fb~&@;MTTN#&5_F^D^})0XEwEHlQ@SXz{$GxMJFC}h3{ow@nW#4>1v9C3MB z1Mb{{9+#4Y7&Gc>n@o6r)R#InFa#5P5>9{QhDN)gHwWU*-nI@mtoaaKF1Tmabj;$C zgY<3#%Tr5ZUsvWd)IjP}jMrYs!4)Ln+zf**J8BK)ABVn3p;6bet%lM1fVJ2E(5w?y zRc5}m9zcw?%ThoZQV7;i;?gcd63<|*YE5Y(T|?(7vAXcF3gqB<8xvle4&kp08;xi~ zRgF}nSy`1J%y|r4C#P=l@J)Bo$G`P=%uIAerAWy=a}`(BK-mH*l?jv2X4*0OBa1I@KoAT$Gjy&MF*nF~AFkx_R9LXF*Ce}mC&C;_U5XPGDDwAOvK2RZl zePEWW4h&6nk)ds^`@w5kv}tnCdh9RU;@-D`x`m5&5B$|V(cF_y&s`&Y$-p9*%>9gW0TzG zX@QOy_1!xjeQFJPhF{~CA(T7RinSevw}Y!l4zoP(`t&qs2t41H ze&5r){~=dl-F~Zi#K$VXM4<%(yvY3~^bhN>s$lUm7XXwEJy^M<5q{; z-m6?H7X&?X;RYs1O3u}Bnye1bn_Jpm@F17TG5b)7dkve#$Yzz7!#uU^YkRL?r^o@&jV-S!Bk>dszY=*p5wKq{e_QU7Q^ ztQ{^E5G4pBe7Sz5 zzmP3@&-mzI)ffJB_5~=>nxmbp+%bl9qiacbf%CdZTkNeR8FYiPh;JH(yf|dC>hs#} zgnK&l%TC$$SDIHhu%2?z*$yIa3&E&m)NpM}qKKx7-R|g9ra77sduTANHEvJd1D?Mp zkIHu{0L9G!DG*(WUWOOx$Zv}PgnICYA!l@f+h35s!hedP{!M@Q-`CfdQ$d~0S0v^+ zUi?7yv;v6T@EgY^gNpW}XyF~RmqbNxfpWj>znyGUPQ&y#x|G9#q6!YVh`V!m`w55! z(!s6QcQJ_D;_&|LBxLZ=Z}vjC-s<+)-CQyRAow5ISZx)DTFHPRzikq#4sV5h?ai@b zh!EnV{!`Q$)$MFLI)E@JUuGYupKxGq^!(x0>kwWlA)88Cwdm*lTmY8l*mvt5yzFql zGYmr&NcR{@1VgJY4>`n!CxB>G*I@WMWL5qtUeK(Y4(b696FjCcY$k!{lL!nowgcI4 z&8hKph+7J%mv6y6=N_J4ngQ$VrvQks{qBvS>ho+!LjK%GFXTG3kZI*EeKC!|a&4A= z6cZlZu zs^6+~4?dL3pW3jfl;Zj{I?HVOoLf#o^zJ^-kN(f)!w$M?H4Ygl4wFY6|_tY(66O z6vrZU9n{lXDD0YA72+`VYt8}`BqaT}$QyPkmlqZ!=A*TGvlf%>2iy7t-v#K0(#}F6 zB5Wl+06zv~I8|BQz|fA44&yGa^JH4Py1F_iOmh47k3jkEZdN47{UIqjZLpbY2fw3w zQ|lm>X#oFi4n3Hj3hP!KfY!CX*Vt^CBoNQg0DoHJeaZOhdK9d&ecG85^oT!(gg>xA7pI<&$tQ##u*;bWij;WKJILd^=(ut?|S%t2X%(lOW!>zcfi$CgXCRSSDU3-5446UQ{AkhEkw45(*+rk6O_$#FRZers0`MC0 zSO7U3>+H-mmKIf3mKMm>@R2cQ5&N4XHnD4}|SV!PUC%LE?==PcH?{|!RN zH|Eax1!<;9H*Ee5UUpzhB9_%Dq_t(KnN^GqCUm4wn?-&|B_M|{Hi=-=IeIiBT^www zSj7QCFWOPNufKn}<@bIZ=cL>AV*rodRs*>k$ZPmhI^WtS%fTyMkIRfv*zIQB^&vW*3 zDoX=C5;$F*$=G8drT=JzB|hsL%0(GcmpRJyw!q2PcMB}x6n{?zF?Lf!+PZ0Yl-#BD z6%$7-^JgJ%m3^o7)X{mTYbqstI@#Iy9sGNw#?e zyJ>w#C=YAdgg!bf9#ALB8o>(x;x6w)Cqdttgk!99uX^pJP94HI^ql}P1pH?8n!m$I zAMPKva~0+7)hgR!e>>+XQcs>Zv4j|_7rf^yo}4Xc7J*NVC{_H7ThZkraSy8`y%$8q zuSdGQ`Tk}R29r)IagppZ${4>cb8Cr2xE+wkGjnB||kH#jT8EQ+2=W}4l&Ej%YibXfAb zal`TEP0@EYg6Zk$fxiPoMnbx>^e7+{*_!-XkM$;zL5Ly2*QA!(v35;8h}LxYx9gZk z$3i>kxl^b^tFgJ;kSx#X*$a~X+nIxv%Mo61%3*ybL_v23<+C`EGq0VAJ*uhYUW?RC zOL*Mece?{xBiP{%jB1K1TGpK;Ez^4YB?p(U_uPA~&gCAAwuJHz^7X^?bv&9)!g zL(5DTM`y5U6#methiYf038vUm70aU46jeA*>Jlz&atnAoSYTFRBTSy?2(0$rbL5~> z%ZICv$5i>+QD33&(DG|LmH^>13BhtEQ+1f~Mle!R?b~#xZ}=Mr%`0m2aQEjJf`Y1=`V9aEi|0;~8QJWsOAhY}Uo+LAO|FgxR+2C5nP zSx+Y)VlkL<(^o!8Hl$cxN`Ktp`lh`pw`N{wuPwKf6OU{OLm2cgkX~#4_D!sQHIq=; zm1{XfkeRQO%J1kn?R4xWu?KI#T#Rbqi+SoG#dFEdPG-sBc-bzsIbY}#s4%@NFON!1 zm7*^OK)yH}5^D~@GKi4xnm|LH_C9t~9$3QVoO~^&^U>-haE(+`2hs+pS0#kXt%)A42~`zvM`m--n&H9#j=` zGk%?!^AfWH#)oD{=#3lqs)SGYAszEsU~~)?tE}A5a9C1RQR!Cws!CfGY44I(Gd$WL zm6&*F>#lYPAhTaciCS5QyyxQbasH|(c{J2FfV7l zN4UGceywblt)qDLO2b}i9dAZ2!~oh-AUAk^d5f5YJxg@7)U9g?z(jXGDCx%YFioOC zXT4zyU=iPpC@Y$A3WcpJ(=h-j{{8oFr(pK$Lb-qdHC|ID_&?5bI1FSP;$?;Adn@As zTPFlyi4^x(fp&oFd?#)ZI~*3>P>T)^A}?0WW%^lZ{mo3WKT@(k9iEkz_WI$22aX{j z_HC*;8`thBdV%IiHFItGU1xV-+dzFb(hf=B0fElld6d%QSAf$B2%gD;};o z$lnhxKtQB~-B@OFYbOeZI-1!GbWMR!LRb{3y}f<+)=kAK*9TX=;x929ATB)+%K0ru z=^i;UU5Jp8xp60Dy!g-Y=+oHeXFdR|@+EyhDjZ!7yfhG=J?>K#W|$KSCekP%ECf=C zuV_CYEb`lo=H4f#e%MlX5_#KT+Css=34s8}Gq0?=`u^WACv4o{UnfS&X~C`fNY{8! zg_b}3Yk&^HNp-=KSPHX2N-lpH-T>y?^7<5RY&d{$<$Sk&*bIIaVx`%!vVdcTg5oi$ z%>Ko85(J%GAV7OD15$jj)?H$)PnEu$Rr<1XZR}aBlG*B3^%qjF(wR$)FnBfyM1kQy z0yK93BTd%k$9|$0DgTTQ<9VVT@U(8UxiUu4edz7n_Xk&VEq9NA67WaBJ2^{c%U9%D zwhJ0P3hO4l`M&xz>}uA>^;9Z#cCZ1e6|`#<>%5{=A{WYZr-vyU#Dix}@0NG;5CV1_ z)+igA_Sc(Ij7qS_a&Ze5g~%u2#XLX0slMbWVSFa(NQJIy!20I>Sfu!doD{d4n@z!e z8T7=PIeD~ zm{tvW2#9c$>&obN`%#|}(fs}Ri#*c=5srjFp2<}KBz$%KxFL3RO<5D(w0061kNvm? zeG$A{i1sT|+Ea)JeK_1Gez<=svjBKha<16N}^6>W1kBq1(Q@cjQNS5hDE3u zZmg8hMrSwXLv<9kMujZ+g|IDzrw{lf;>Jy)73)C5wv2iDPpT@wog|9{VJIIJepqX# zTh7%qhHhci90x7np2Dhya#&&u_H;2;g+DKtgcG0Voxc-AX5E@%pP6;=z~3`Zl2cB> z91^Cs@iRIGajk;qO4pQMu9L>uAwpLR(hF?gHM&em_Q===<+h@ZWENe@(m0wOS$GwX zR2~3MSe^!V3q5>z-pdvUm9Qtt{6NGQt~OLJXzi}`>rke();JX(WKhU@JVtCMde!dj zXMGIvVU$3u*EAY~GDYAzblMle)L`yb7sW_ylaS8J%#ms@>0PlfUa_Fe;t0R+%LQt+ z3RY*`{U#TfRz z$eXZnI#+c?j*yTLze&hfwvp>8Dn!5pKe<=y&k7n{*8J^XKRnU+GDONYDHG|4p6MOI zZJqZz&ocSUJTMDZ89qw&9bH{xfM`?cJ0&b3A#wLKACbl}0-&>J=rFbp;2tJ$U}HdR z2`1;lLIXz(%fm8D7_dPE_`&UF`BzlmQ>VmK`{tt`LeI2Oz{?5<2ne++6y3{4Mge2I zcOj*Yb)MYLq`S~u2v~83j!UX@z&B^|W^nmJ&ZUy7s+hPqA$c_C-_BdnsFb%->%OL2 zCVuwpSzxAr@1Miz1w{d{!^vUe4I?~b-D6?=luI}iMl%H-sbu+2wXx_0E}?jO_r`8W zd;=X^%w25V`@0E4!hc8*yZ`Q_^nd(%awI*+RXue-GGbA=O}hV2PqVu_U{2)Lz6WfZ z-NNRy?yq>aVUiOwQS4{2@jwt!;5ohTIShDu4{j*`0RXT+i2g02%av@N?+v_*%#oYf zPK=cm^-YnSD(ycH8_r4m=?u0N_hf`A8BG08b~gbl^-s}~sYVZrYG|u=;10D@_Y^smh2`s^{+Qw!60*F~PUK-o2V-*sK}BtZDeCaRGB)Iw19EJ+~#n zHF|LOw^>{BM{nB!!=(&cwHJ<*?dt7U7q5(&aA@hVJ<3+7t22z3{wh=^hoJr!E8 zszhIAWU9APnc5zx*Jyvn3_*bPki+uWEI$ft#(|i4qTaS%;x^dD`FYUk61M)q%6%i& zeMhW`5990#ka9dFMU@)D5FQ+$uUZe|RFB~vPm}wwg}iG}-WZMrBu8UcbnsOxr*8Mt z2HRj#&HIGLuBN>(=+ShZDn-5azSLgAxh?k!t4zf*aT?d5?N1KC=af5NcuJV3J7{ zm6rclZH4FUMH9>biA)os1tnx$cn?;D!ck5r>3+uscN+@`1?2=XXpIOJ*xrF-a>7j$ zxwNAP)9%%;>`Zw39g#{`ql+$DE#PcyhuZsnO9HvXccIP=`6s?{Hg zZ$f8TiO!H)D#jZ_Aa|j8sNzdORAfK0gBma^vK6*Vse;8n`*I&n@;TZCdOS=_{$!{( zvF8hN58L_^O;@#O!be@Q(Hz*v`cFxOUx;akKX?NMYQ&^_19?!h;|~YQ>hB(F|JPn0 z7V$D7fV~*Hnhus>-50(8n0)p$dPWwJjM{808{Yz)xUDD16oHURQ3vEA|4uceAa(@i zp6?+HNQMLE|Js)gY&!G_5y+>KX+8!-U4h^R>JxQh!e#3wZkyyXkGp;Q|Jos7bB3t! z)8U;HKJZ9G4iSWYBOq}u5ogYl-(gvpyq>G)_CAqgsf+&eeJ2WBDC~(}-6mL-QEtIU zp1u74F`*$j_Gt8t;ZlFWzna9qdXGVw&gJjXjeG#M8wd#d8-aqR6Z-J}JjVS+eadnj zDg#~DQ6!I%6y=4c)u$hhtH`Gq-<9R~6CrQd#0jtKV($yl1xjKSbNf8|&ssiv49jS` z$BFt^AK;j3jIct^)y~2LMM;ljOsm_IT{vJM-WgdQ8`(AB!3>uAeDyY_VVGAq=Ih-% z;7?-{Vo_3zBNC^431)Ov-#$KYQp|qz5p1M(G9F*Z^uk2D~@n z4yR~*%g_lMhdlsC7*x)9>)~DVo|vLYy}rXsTXmSwJFqevy3fJsSD!SdXTAnky90E;@&MJfC8Zg;?RvP##sfLU1FdNRwf4 z!<)Hdz{E?Lz^$&keSZy&k@W9UuP->H;g|2U$u|-9oCJF}L^segA=6hgKfABaSa4J- zeO2Xy@Rcs8^djs`nYR#_jz_?mejZ|jT2&!OiNo2Txftk?gsxhl@(i*UHhSL2vR8`98 zCq#N#XEy(Qn@d9{f`0ePT(fLP@hx|mthEOjA8etOd{RYY;1cGPeDA4gjIySZCh-7PP6Nnyv-qV9D!nZd9^MRSNC! z+oBx_&kA)JagT~1m9}+d@gi(I#iau4!gzeYA6Je8dmqiS)3$%toge~% zXJ?jc2QE1}{}=luUwrFm97wQ_f@+n}TuMrc)$Xm17yHUL+gAL0^dX|je>A0C2pBQl zV2Y?kmhOk1e2bwLK=FBGo^SQ)TsXZQ_0RV~D5c4Dp^vl|HZB%ZzDfF};y*SloF1kc z(e>Z14vBc~sQ)mo&?W4kl$1@(s#?`|j9D@g5JF5Hs;9 z0a|}`6-z!Vi}ko@%*X_$EV1Wv)Rizxq+$p&k-;ROZ$EzkCRS($0jrHZ;bWVNyh|lW z!VcwS!KU4A0lNWy2V{D;zx1G8931r@5N8S`G8E>J`JXBsQMfIH0O2DYvssd-jR?Rd z4p;Z<(;D+&z`B{PX;qGqT$~n=y9UrJ@AX>HH2qD>pR8F)Bf#>NG2}Z$mPzp~9`6Qu z8-F{jEA|qI93^!5@9YkWT5f|`B4MsmrQMoBX)mfCrGVt1pdGe8690H}OfOin9~-+o__GmkyORg03GeyRV07YFDuIO*#W%-RMjdOD1Oly4Eybj<)p-F+;r zMx_b4?*m$A=8MBzJu}QJk^|QHd=)GO-+On&H2{<4ul3`c0PDRR_EjVp17EK&O^>@r z1wt&?baozIi!RrQlrLg-X2iN8@n6Z9u8b5OtVsg$doFX20j76K*90WNnrL;$^nO*?F(yo_J4zIVZq1CoW>E-p}XNaftidm}S(uG|2eiAahMo;py z-v1;8{KR4B(f6R;jl=~!o#ZC}YjRw6B7 z<94$Z$L;o+^~PCLW6vyu;Xz0m&VwMv@S59)pWkGUV_45AF8z1{?i|opW+c1lT`Qc`;zv4#~#vl!z_+)m)O60R>4uSBWs|vSzvI^9u)uRXHc_+w*{47~FCM zb}GN;$Q|NtVVNV{#hBZ-r9gC+?BWp=^$UbJ~InEb6jMrj;d|$NTdPulqhXWbS;*+^kg;|Od z13lJJG-v%Lrg4FKf6%XGS`p^wEX!9Y}|j!oN4NUZk*>0 z1^8xA5&;Y7OR~ZUwP(jb!ujh39^*Bs-Qe?CvT#Vjc>CgNs`ieG1Cm)jirI6xNHoll zZ{{rL>F_n2Um7mWunQIRm5^j`pLL&q^}Z1>T>D0~9$53h9B&-uhdqUoBVSwvznds; zCkuJ!@$z896ByJ%xP`%B&k^53il4C`V5eYb z8bCOt#-W%`3t-Wz{5~{L-tsgwROUFXpLutf%e9I_6wCEU)X-n4TSl&-hvS1jys!BX zS#Psj_OP&V6o_SZ>froRo{;ht*Qahd7r6`_e%bN5lx4l*^5C?xef$=Bpax111KOj< z$q=@@{oIZa*nCJ*ZToOMRj@ZTK%t#5lCd77gQSYDSg3G5Zyqtdi@l}J5vZQoS;CN6 zu%G6a&%^V9rB_Sh?xLhi!rI4&))n&~@1ANmHg8{slR%Cx1O;(2f70_^J=9JiBc#E; z)hQ^B1ec2-nPuBq5kr;pxF{j^IFa#eZNR@&y}KwBdnOAIKa2yps<%nX=RqTEg8>Gd r*v9^Vt)6V!9W314v4WN(zG_Ev0nKPzoplf^V>_lySjW_BSmbS;?aAE*1UY_Wm za<$1zLwM4rXxv{$`bqc6^Hd?$!H%ot<9kc$ZEv_HZ7^)l9WVT1H%k zxE_-@3)e2QcU%uLANyit8d}wKtD35crO8q5DKFX2@7JlL2AiH<3y)p1si8_% zV$fzKoJ$t2qw}P0e6*^~)^oFIll*J0ha)5G)uT%e^s5bfZzMYDs*BaiC|-CdYVOVT zb?Tp~imea4YnJV#Q~60KKkjm*Z%4I>bgxzQ;kWf-QTx@y^1~R!y@&53G@c#5@8L!) zzFlqpMQhHvEKqocmA9TD`QkO{i|ZLhN|eXkJ+69xBp0iRuHSo%jztlROC`bBH0qD-deqZ4T68c3y==(5UZ1vnZEmLg>Z0@)cS^dbwiku+-{(?FxHZjW zR0OcnGre;XPLj@*tBHq%LD^lUxH78}LV^~ZN5L8DdBIWx?CnoU*a8;Ig{RAw53Pj? zLuRu?b2|+De_JrHY;%ehGPdjm+`qkcm%0CMd_jLhTOp%rZu5E(cZ+c)SAd3*Z#tTQ z73Q#fm}~E(hClpT)>N4IR9?>%{yX8gUF?}@ZgRp`YlU6<B^Oe5%|5R*7}uQoW(M@5n887H;!$)wZkVan5ra{o=3A)2m(0$SbBw4e*7D zj%`TKc=&3#lY(rTu52iY&wg_V(TO&7nT^tPhjYvdZX&pAHp2SPNlv-f_1*cR%jV+3 zyFdH(JZ}G6jGY8){%m8^dZ?QZ{{CackLsM4*O88uIWP0%c4x?Q60Uwf?n`g;`$>HM zR)WRm^V{u}$Jvf|pDpB>KbS?AH)4CZoJzR26?il`98{_W%>MiH!W}aLVNSOsXEe?llFWC9-%U;*ZnTxPZR{)$?xVi?3JtSI@Ge0h zFo>p#(nIgGjfMd43rh_o(#+Y*`v?aXH>L!NOd zRPLQviN=k0Y;4KRd`%5NmpYb>r>7^6%D?RG@&EG@BgS!$hXoeOq)fxy(H1NW;Q}wu zGE)8f2?GWAoGX+jj0{|vltX_(PH*J;`2=$MG1J_we{K(VeS8MiZ};%vGi-lQ4^99V z)ZEcs=c_7){nt92R3l<0mHYnv98P$()SE;Wp_cPPHJYcFFG2fS`j_i}_PY5J7T;Xe z^yJ`@#`>KhG~vD~{rfvaoRGC*uJJZ);m}`I^%OS<%efgsh|gs zmHOBNwUHjvgefY+5sV&sgz_O{iOYLFFX5AS7U-_`=iVc+uuP{k8g&1FPXEb>CJNl5fkQ9^ zQ^-)#j1Uh*Yhjd86^EUi+Lmb-4`!$q<*I$II`RHq5gu zQV)y<84;1}Nl^-A#2>c!b4T-G4Mo~;eDbXXolyAT!QaWu5@8h=6f;tmT?CGA#hB*r z9xX}Yey4ogz!Mv~1NUcQudN9uA!QXm?Vc6)Jr9vKMJXW%&s#!>7vv5K%#ah%3>tLu z=&g4&s0l#^Mgl*3(trZ0H7*)~9IKn(|K)P?Zhp}dG~RH>kMLET;>`?EO=Sc1aUE{f zYD7v$5Zx6BJMBH&a4X&+4IUPUyOfDSS`Ca+X1s}gqD#`S_ZkubHfgwqV4@|#ly?j_ zq+70Z5;O$OMCia)@vXDh!fn`?bpma47yRx!kyi1m3U7DcPBDC+Al-c^9sHQ|94q87 zJ$RgkwC7eJ!mw0;eo3%tGn*Q+#M`ZsWeFIzI>HR8F^opl0gZs+=+O;eS z0Vl#xOAkg&Yl4I>3W0N|#2Un;9DbKAFs9!6xu&bL4FXJpGh2mw&ijwu9RYRj_c2~A z9YVS9Vy_5BV>u9JWYP;0zf)T}ioGGULL*MT0?|L) zj_v$rRS=l+Xqf4Xp5ea63p3_*u)?%?0SW^<{=eYZfD`=m*Xwf=TAb?m>nstW6K`0u zOQs|Gyim})#d5Eca_LG5C3vOUrx-JJk+}Eg>=nxsQ%W0;d7oWXFC-Gb6;~T|il+QOPYpZ0L4G0cj!!y$r zvFtH_{t$Jpyox33mr+eTeD^?B{;lG+QOL`Fq}9RwPy~j3`sTGYFKJwfmk-Ha#W`%E z4cE!-d%{5wK)Rs1OX~P8Hb4!brLEnPm|}mvZCU6${DB6d!H|%xW_`J6Ik1>a!|Xn{ zyGhOqNsZs%2I=t3Y+jISACdGp#pa|l%ooEeEBSPo?%l{zb#`_>AoMT>K(da^o()5t zwx;L&X&?{x$@(G-$IWl)P>51|#4Y*4D(U&*zCTE_qrVx$Co$c48)_7@1Bf-ClTSVhj=T>8sCZaqOxKJi ziltRTF&le|vJf`f&*ux@5QW*SZU_(2V77wqH`J(ncH4M}Ta8L5caC`YYhAREsDCZc zz&ed6d=q_p?=5|GH$ITmoo+ZX+3QDJdP zOD2Z%`(pOGm@M3swzZMT<}NeYo5CXDfZ6yC7f zZm+W(!kBg{jAlQlW=0Oip%vklER?i=IYwp8<&Tcd?${{e4+^f($r^OM5B`CZ%y=8Q zL^EIQjmFzdA{NsV69}C7Uu{8fek#XoYxV>i#X?6n!{-u|Rkt%qJB*^V#Aq5;J6 zprIY2vG`IkxF_(L3?%#;`8_Z4H7^Luiev+Bcg)4QVQ@Hv_2gqb_F%9qmj8TQaMos7 z?K{>VxEDuN1R*ZF6N-RI5SmA7Abl0+L)kj(_AzP|r$cn{{a8Kt2&pZR|6E*BBGU`m zk8c`pIumdQXfMCEysrA(_4D(~5=TVE(1{w}Itl&&#lN4B4M6ul7 zE|!t+{IJB;=CANbVCBhd*9GVGc=azTP^%~nP2bpGel2N)7nmY8vA9cD9LMVxj>!Hr z#fh-l=kOHi`B$21lx?>#{467huvtBLYvSU*kS>K6VcYJbR>Tkj9H@XB_%3-ei=a}0 zdan>Zo2f36`k9n96s#7cVLCwy)I2Ngy~SVcv!}@7=>AFrtS4Gtj=#dh{HjA$rAD6R zrFJI8z}uDOz@$wIB%C%LM1ac)sg@hU-Y`6?wnW+E%;VMa=fUh!D-6g!GCe&<1rw&hVeA0Tit&H-A3Pa{y}$7f zqO|y5A{(ZeK(OS1y^qCRr|C*iKTGS%6L87sy4ote2y)<>4g?DuGiJ)1FDjO$Bg ztV+2!GoDnwXkZe4_&bKj1W_Z#quB~QAwjhzsy%s?TdkRwfgc~FkSARZI_iMhb_Y|= zM!(p0CEe7hA-5t)(ZvLsG~6vSsrUY}^uwk*MLdHb9| zmGN!Gx-~agxZJ59aVu+ZJuopz_DE@Y%i4vc4S&2xA)imRISRfIK|#%6oYJG)%B_J0Xtod)GMqUj#@VcTCk!k=V{1X;uW`9$ zkS%qr$NGpHg2zYI#Kc7R7>zA)c~wkLP(DXqVa+`R`?0PaK8iFV)9}|kKf&bom8L6+ zvw2WFXy36$@=iK^ZUxhcaS4U^nEPc#Z)X2UcCpsgjr=YvU@k~2@$+OygI5;vFpnUj z)s%K(m0gi|AK`sUe`@g&ImX#={?xXBG^oMFT67;82|p#R`*1R z8aAL7M?A*~x#zJU`$6d=7xSB=BsP0z=Pk*tKdCOd#~WDMU%!(X&|Obk6`${ZVL39% z{`|RfSK{`|wGb`Yq;A`Sn~+;RDy$;`lRiupvtMqHO^W~A!Q0$4t>jy%_Fnr`;6F_* zcFZbd%5$>G`!pGjYJ6;H`1-b0YgS&~nMaQvCA{8S?oDiy?3feN#!>@HfAyJhzR=STaM&bQr|KLl{suRbeq~Cu28?8R!=Bs;gBDyliLHA;3 zXJ_BcOqAc&cXi~SWZNt8{l7{5>QIx*zH>F5oMoHql3TCVOR*1DlQDY`p32`O`taMo zV8O67!&@2pr*>L)k}TD&GS)C5Ij;(1if+6A-~q)CQ`bL6f1liZ`)COE>^N$Ny&#Su z@`n`yCj_ya2(stLbaSF9q>3rIoKp}LXP|j`d5u(D2}&6u`4cfU}OL=E+i8DPc^W)ds&vdvK0ma>pf z3Xi9~M1`px939CZ*U<7Tfl2flPEJA+&&T>)R(My_ls;VNKvF_I^?rMn9T09H#O?y` z{L*XVhvb@{x+i2CPv<%g7r2HDRI~Pfd|Xe6en%s;Zq^!w7|N;Gy=b%)u9mag884`V zHmh~#A2@Tvg1HjW;ys+n7W-p&sZ-NfMeSoIX^AqScYg%!fBZuFHV@fq8l{!%6Zb1{ zGZ7zcnKR|scRD%`;fmL8=s7D{F9{y0oxAnj z%cNP}Mu&krRq1TM%k`sjv2-gL_p&QD?{pL%7TT(d*Ojx?a&t2wb^%v`p;c`s zkug8Gv><3So}yvbt2~#pwt4$$b9ki)#PlzCL31-xq6Bj&FgQPm6H1j*cM850702*q z98EV3rKv4$vlg*<-DUBRJQ|J0rGH4Y8#%Q2n^0=>dVO?TlYLt<#VbS%opU4U&mWsj zaj&h%ztd%nPJ}Dz?F8?I;_F#N7U?yZq*lA0q^U#0y&ru3X^B7DNs@57?Ca}mFk@tB z2xh{3G?3W%K{OplU?lE9UnN%M8S z3Df+@Vw9d<^g-he-N>KYx~ylVMPg^74W_%OobiT*>kUU6g%4hPc#IZA9&&V>t^anZ zJMS=flpl$CTT7>=x}VOQTyc)#_EF*I&u6PDE8BI0nZC+e1|uu%8gJYDW&``E5gQ6} zjdx|m#oDWsg&Fii>O5e&^MB`l5fXScIhItOW-L!OG6gd#u7=X`@lGvuC3bB$o|N_x zS&=7Sg+^DPVm6W6>xldJ$tuZY6_Nuc)_n_%La0Sj6a@qX0y%4$uLrm=X7FhySLZhS zp>Et8bx~9|7aA$Ugw)oqe?bDeWf;&c=-a;UmO9id6aet}$m%oS`wDi~ojtfVzB)g@ zHIDjygl8@P+Y3gbD)IVT#^YbCsNcMKQ#m*HE9`;7_Sl!Zsk*B084d2+B8xmUK7dqm z+ip0_C-iK`q56d=I1`zGIE7T*E*oA z+4Nor(t-WM4)5e`xh{P_j%IUn6DlVCp5_xHZ0|Bwvk)oX!Zd&VaO!3B0w#!+my|^i zc*`o1An4J%BkejHxC9T`o5#2kcFlSMdH$Hlt_YA`caehm-EA&ti7E_xos`5+y1kS? zVrp8P!5;pFI$A@{H0Wp&=e?-7MhOCrBgM4rA%Q`&hxN2JAZ-rihW#k!>mWPDT^jWD z%YjGz5fWflnr@nE=VJakWCzfPZ|Z8qXxv^8FvmNP-J&BOnzSUFeWJaZDplFFhlC~L z)g&!Tpl_A|n)Ic*H#;Zka6Xc9kHY+8E79{q?z@SK{cfS>NUmlX)4xxaE=@65`=Udb zbPCpO?-yj2kC^i6m*I7%6HWq|xP$%eU-!d%o4a4inw>L*%s%VXDC5^Uw|ENv z7P*|^3YEIfx)sbG{$FnO3V}oTlza{67^7~cs=*-Z7TR`+xKXrcdO{AmoB+UkjOF=A zRcAE8^LX4gvq~N#yImjBohoTHS?yG+tGv%z4LDG$%hH3CR?AH{KDznsu5N4qLJ80^ zGB+ig!o7DV=3Cw_x$jY77i+Tg6#nxCf$Eb$<73Hs?I4wEYunUOJ@orY7qmHY<4fD$ z9@*`&jM1VvDB%@gkz#@(OCY%w6)e;YSK2RA8q@Nm{r3Cwn;kNq$#Ib(P!0Dk@I0$`yZ(Hv_E0Y%LhfOQg1o# z_@Rc`C+BN=t+Ca3;_Nd~XwX3m?AitTQ(D!b$Zd zKHK$sy7*}ffpaF{&>Z+t%niTmnidet>1fo39r9XRG_;13=B9DEqOgE~^8Neo6I54M zSDV6_uT?_S^NNb-%+1aD2R%JJzB}M{CVL^FF*i?#ncr*B2`JFZ)LkW!@pa!;pNL-A zH8`<1Es`VQ_xOZ_T9y(KrSD_`ob-HTdoaD%3y%iJAP$Lpb>yD-;T`~xU<0s0&h#Sif$<74=N zD(N9PLx`8tNhb=&V#6fx!Z{QF#hBj7$*HigP|@5x{SWE57ZsI?^gX|*9@KXu>)SUe zYgC#-K<&Z}HZx*D0c_}7R}~^wqEk`c6>_8&u+5ps8CXwlOyHlTwxhfp=%N^*eTt1! zs33)-340WG<~a)67#XDKln2uBCE7(FZEmKy7h)&3H6h#;=rHz;Z6%d*=MAZw-g`PX z(Zh>f29|3XpKc($-}>$*i=OdrF%BItzz{zBjg}HIguKcNX1*9!>RAj+IV#WjDoXaGgpxp*_;ID}OzJq!$ zweJ-MH6Do7^X49sko200noA?AYKChLHk<-vj(U+AN}FEU8I|wGDa8hKtey*WTt}}% zcvfU}f)C<;&K)_am)BDm&-f*r-1QKj*GjonO)2Gh_FF(SnwX;=JwILafnr*4rLIL^ zl{6Dg-`=02e&62x(*>3q+_D#HL7tWv*~-_k(FVRd;5;Xgb51i#2LANRB1%TJ-WgDWd`Vt#VFu=!v=0nl1W%NTmB+ zk+BEj!vk?rgwqlUZq}+(`1)+2!c;1u(5M3X723#*3PA@b1`>^4;CRVT(#b&WLzW^I zl&h$CQZd`~8WQMC_84D2vYFGv(j|fk+njV!wO_r|O?rhuDXpXC9#Q?QM%R!u?c%=D zYXi8JOT|TZss7`%?`QNGsrMQ`immd;-F-#H&7TR4b_H~$NCcRgqTOVA@fa<>@u=s> zU+#wZQVJ&Vg)d0L)uCZ?jLV87(pK??PD<#=h@lp*6#VKh9n@cBp^hLgnLm9}Ewwl6 z_WVH}PL$An*j8@4MoD{=N!Bq$%kmfgpNUT%{JREQs$AwD`&}Y!ec5-(Aj899{WBI* z%a}8v3h@)STe}GTv826Edr~_bVla!o!NCOq2wOXHlq@`DM?d7;LZ6GuGex|@mp(o8 zBT+P-~lW6VDYeyQR7cAe@z~UZk+Ij)f@E&s{zoMEPU&8DobQr z*tokQhIVZA*N@2YP7?>c7kKGH;}nC^2np!&F*z-97*x8t~aodJ^D^EQ&F+W*Bh1IJ5MK35+hDrqvdd)x^WaH zOO95DVc4K84ErdV&#Z-{kSCr7w}~RJ$2*n*P->3il&!23C+xr7AEofwq73Jw7Y`?9jba?6@iull zuk1sj-(OSr#qoJ!XB`iy9}f=?vq?NpIygRF&Xkmgfn0`SFkk1_dKo$@DvDw3SnvgI z)oUG7VMXn{x$*-zE}v!Ir>;ZPD(A>O4~UYlp{EaNvxoaoj!sc?}$;X1mne{5$`?o&tD?t{#8$GLe!*@IYrrD5%SY^$5*~ zD_+Xo7hvHqJGiAhWUShW14&p%_!(N%1%(+Q3&^6)P!cZHkoF?1q@#`IjY(I$@wHoL zzFqm#9i&TeSeE5=cX$7$a10IsE78YijhFZf^{e}5u4dd##CWQQq8!LXPH|_`iJ6(% zATfI&ocYmF9eQtu^fi-kvoGWZVV|`kGdzea{7l-+`0Q}JTjI%Fq)Wv$K<37X~fW_?X{{`O)m)!rMstvsV`^o@(WkPNWsL&t|6QC{+Z~f&6qh?Z^hCaGh@=LbL;5xCxpqify{m(4K~mFLGUtwoQ|~!cZrCSMF+JTt{w>57=M%PZT5Y^-L^=dL46R z1SMd&26u#10JQkMu#iSoRdr=`wg2@swa6a;y&2?huB|B>85wm}0tCl)`zht6o5nC% zTEL-FbYi~frOR9_&`rN5tD~t&3z?0Q-2%Ea+** zRQBDlTTgyc4h;=i9`7zCiP=W|p%42t;eP&xw(BN(vwG5CWV+M$)vqU~Bnp9#V#^@B z7zO5vW*kAGj7dFfa4Sgc)?yh02x1wc4dZv#yght8g9Eb&YD4KaIh~1()56I}dSo`H z$--|_{IS=xN5SFTys zAs76e3yX^4M#~V}eCJG!jCkP(V^;hN`?CI`$wLeZHW-Rd87cGa$7LjKYLyZ6PsLJH zAR0A-LXM(Zso$G}6Tv3#@DRQss4`_+BEnN{K2?StIe@c@ZsQA@BFCFax;l| zvb_MtIFt481vnGG=E^s(PM;iZtAjTf6e%E0)=Sr{`XU;M^Oh5?sjmJA_#ntF!0Y+1 zn_)U@)4tmFIv@$Sv89diuVZKwdh-|}m7&-Br#p3UYj&Y6x_3p|@1Xcnx#=q`1|PtY4S=PnYAo&MIHX)PFcL) zA+WT=CY{YNt!h^m$7{Q8_U5({<-0`*j$SOh}QXMMYY&LF;0)Yt#I=>~VL< z<1d#a`E{OeD&B%y8X(JvKqRKUn9Jk}gw* z3`ny~JFFVD=#sjV+I9|SZQ@pkwJj#8n~>1Q-3U>J?muoJNE5>;XF~EC#<=a(W0G0* z^V@{y644y{UH6tRJR->v&59_B8Y9`6%2IUFsK6Bbe0~3d(i1sExbbNI1I-c0)$P<} z!G3(yK`pj37n@cIEPcHP4CD010ysg_ECU#ZZvf?U*5NV)v|z=naCi3wuo&UZKE|OX z+-8p{iSY~3w&%*(*~b&v&_X17dVCEv{P|HaX~s!NlcgtJc69qIw6II(-wFAdQQK26 zN$SyKgR}6)9&f$=-2_yr^1)D=Xh^f=omXVIy7Ww ze@nc|=1M+C0S>!vl}IO2-?yW*^j`gH6C>*AuKM0u;@rOQ=eNSOzyTMN9s(0Q^`jWt zQ(u2xo9m;?&j=7afYsgx{@APx#1F^*BHz)dNBe_q3vS22xTRkHi7ZK+pqu!n;HmFI zD~lq^wZ7x9bu>0Kq%ujkZ)CJA6!xbxEbKgRvtr?O0e+^gdJRXJ}a+n%&0us64X@o!AlFoNhc z_b`&B@dyg~@3It%QI6PN`fyqc zjKszb@&j_obuqVj6?&+`6;StMlk>h+`u)#k@b)o>&1KZzS*1~Hxc6Te;BO5Q0=mUV zErGW*Y12!S>VF^iPgs;MMlF{Ur{lV?P#~m?Ix7)#e^AZYnd{}(dQjKglWEzMp`2s% zJ)z!|OdaJvwf59w6Vm+YpRT9I{a06cgAI^z|L;1>{{bKWXsOc3E(Sh!Yq?l@HAQ*% zU+BQggJ#qJ_g8l*{wuX2or<^G13%{FUC)y){r;W(y+(5!$uJuu3l}>TdQx4v8^+K= zB%IuKU+GgM03XNryDWi=X2_$rl0f~CY7v;b5^IxKBFe#ge2IFaYZq-G7# zWcn%6crWr&s)Q5E*39>pys;fTKj+F_B_XFZ-6O&_D$^|m%#)rck~$5*8P1rWbGI1P zC;*%QNayf%mTqGp3xsl&Iv zZeG}l+-~sipluLbHn2a)^XIyOTz7Z(gkKFW#{a;N+54M0N&DG3 zMd!Lr2>?wrPM%xa0{D?6>s5-oPc@at#0!$ePY(*_hdw>9FW~3rCxcA6wQ)iMjSvCD zpGu(}&qS>`jMLlbK)`wf?#qvqbzfn+p`8?%l5+VbqVdYhKfn9aaN&MGLupHa{huB< z5{{IJI%XZTO&a@zy7v7c>8nlmz2rY(aQu@I0@r_4sgP`Ih>S0qPrP0d*22RcfmJvaWkg(TZPTD7dl#_7|9|{-Z~)G~;f}v7(R8{P~?60zjtV;-eF5O-;=SR>&z3 zrh9i?H(e%vXNejIB{`Ngyw1qT_%R^`Trx@dGYY+KCeOtYwtA}w_5LJy7?&yTm~hG8 z)Lb(DR2B&;R?1zz>TG(R4VguZMpi%%X0)%d8~IeTlvrq*%42x-E_TjADhNp;WbBiD z`utg0Pmj^m)D&_wx|OgMW?^6u>@61s>YChFqfg-|E9qsge1W-je%+eB&&g&@0Ds6D zW7sd_TK7-YB_SKnTX5Tq>lnY_Vw8BhW>|W_FMbD3*2jePvTxaGL;9t;$EmH7+4lP9 zPm2kBj zpSm^>H~Y5Hm`CR$eTV0)c^biBC2e&(v+KBU;1Oew`{9f8rRTwh38)wdq;kJH#Gnv;*ZDpH6=L8Du6ub z5vZS8ko#lfGx3YO#^68;;9mB+tV&El2`lOc_om(ss?Rd8i>mk`9y~a|wz2VHbB4-m z(y8VN08!bmUsIXLL!_|i{|mTtTO1Vwc~YAZSlxecU6AD(0^Lwwhzbah*{Lf*)geJx z$^-BsEkagznrwr7zF@vHu@0iW%1Qp?RUn@4?-p#ycsZ9y+D$~yilC0QIzc%ylXMJ? z^ml%iIk>XTS+nOT>*m{I{}@HUdLJ((K1g^UVRvVutYc~Zt%#>N$!ltdB`|tnF0Ab- ziAVq&u{&%;(nBx51R@)a88iuc%eJTP8%XeW+OPe1*-Ky-sh=$+iZmWQ9rSp4g60t~ z`po>r%ji=<-}XEBg3~wMNd~NxCORE}YFV0=1vjVVbcFz!KRxMhR|gAzN$Ccxq8}`C ziaw*+xDq;WEGsK}-^}c7Pmk{AS7HNlrL}DSj>o4q9Zsr8B;4kbDq($n@EyjUFo^{q z^Q8KTmsia}!((`!%Tw{Aq>uH=sknTP3c~P47;fVoV3W98P$p%2#@l|=-zuPqN~M_} zb&7h56g0HWtJ&9R$EDo0ZW=~~L9f0A_r5M|#I1eUUAf<89)KNAl74Bk0ycsBlHlP- zn#SVPcDP{<29C~K4qQRiqmSRQbi0gKwCsN!m-Fn02JY+aasVKmaML8%ZK1X4Kg;rX zN&aGwN2vgLt<|SwD2M}b10_>{8>d4f{n*#h8@r;D*zG%zJ2=&zqPA~B;0^>rW815=w9d3%1tJ5pBHlPtO1E_@tS&+CBU%!D4D#dL6ji? zjxT`Up8*vzCm&tB?r2K{oD=7??#20Rx8UXH%;~377OglJ^}5Z|BX|*2I*P`4#B}_- zHdCsn#k;Y#g5wO3A0K9V8Tm1*VldBjM9UqDK^pDxGohaRzswt&^a|aKFp+hETfGG~ zmJfl>LC>%Zkk~~mN%~HG*Z12VA-{#UVb6@700cXHf&$ugW@} zu?(boDcj&;%5e+w9Mi}-S>vLYJo7&&d>3#c5C~ugqVQ`ZtwPSvk-yv*(vIFe_MUqc z#kdhIw@ZUO`URCqF+$V#W6LlW7DMPph4iE85i}>7c?4~6`g9eoFz(rY>p}bh*OcD{ zC@JlvHPVMpZgx?Sz@z5ppH{j!v~5&We8|qIs8H{pA;uh-q#HHFE&Wawvu|*K zN35;=>SLT9AvH&wuj*xl%So)u;p{B}u#fN?w(ytcq*jkNpc|)8hlWS8eT?z}NZq?C zA}cCH)8MG9AkF$JUcWz}#VOyFRamGoxw^3Pt=?zPMmy(wzhT!(M0_}hcg1>bb2@oYg}c<4}hE@#(La? zVD#{z)Bz}$`WTQvY;0*boOvs4^t;~zVxX|zHto0FaEb?VHc@l0Sf7rSKLMmCn{fSK z<=<)2=K-mbNy0BzP3mCp613pLR~W27fkNz1UsIj&prBJ##4fv{H=;Y)KTJ)&S{7JLMW%*M zRhO0BS-DngTeNmq%*Y&e44vnjeF@aGDE$mGMsJyWmzt);YdM7ifsoei>ISbKU(Ff#fp+2ClIy$07SK1n|Q!l;c-qQf0xx<1$92VtaiHPA*k|^cn z*RJqXmj5?Fx&>nXKtFNiqKlV;o&GM3;PhcPIcE_KR%PUP#AvSEKI!%IxpEMGoxt(z$a1 zN}B*o$7tWE8YK<(1&Xvi{r0ryO37Z%Bu;W&^TVDb=Dw?NlOJ?uGPo5A`omgjr*d7%Y-@Hu z>54d0xL5q|8C*HB<)r(MN2g*Ts%q~U;NF0p-xWdQD~d_yt3ga~V8GS^=zsBW+6!^I zotV1aduG=CCs?C38>7uux7f=2hR}n&#u`(S!)!LnIEi%AROhy2zx&vIFL zF5S~+ybk;QXqFnB>rHXU&QBLlA$Tw zTG3BI3y?C+4$FTt#s6bZPfQw6l4j5@LOou#!1e!6Eq}3tcdjERUD9xjKVQv43;*H9 zW4)RaDNo93l}@P1{~2JB(@N{?q{}M+*Wd+T@05}=3Gx?~p$O}ZP7vHGQaOglyD(ip=xkhvP15L-Kiwf?7l1M^*sRZ|7k;F#s&NlL^NnA$R1HV7Ko;V)cY)@ zc5YjAD}2Z&{-I7mL|=$|wwY7_Cwf4v%M$a_w}Dg#TkQX@QfLjQmUCbF3d6Nz?Vmjg zx7&-9+4~FXhYyjDUk&J?^od`tE1K0LYURQ+@t`Nl?rtcO3=GozyIOMRMN9lA1Wl*n z>HG4s`iMg!#u7iy=hr}wA|0Y!aMOVJlXJ6U4Fq!P6JaXb%(QoU{`2SA6#S)n(xgL% zi;TJ$<^BfdS(Pk7RNi3E3O)aO>PUCZy{0dc2eMjtD`}zD+a_Ou_M`oR4Hx97bXaswW5K{X&yR zPJ-gAL!|bC9Pbh=?DU4I-No*pBeL15kr3~>-(o)rBGaRhoPMT|AJ~J@Z9lWR^IU>D zfuL2a4`i?hPt)n9%XZ_-X0Bt9y+RYq1*Y=>I2@kvK!}hiD=nSMYTB1LOMpdroVZk1S z;z>5#k@rbI(SFouE?fO-YYrnkm^H&+?HhW>7Oo2Zn)5t(H;)6g);Q`nD`{i0pQ&{s z>S0m*GW!IZw!YOQTb8Z{dI2)h&V*i$-vJ}0q^35UUn+$5SqJr_Nbo=kNFZ3yJv!xy ziHXOyibDZeB^-*Mc-F&%(c?mE!En_x61cqESc zMpffEl_Kg+PS~ej9nFD5p3V1%L7N;)sL77{@G-Bz#O--8F#J3C3BOIi4xK54X96{y z8KMp*%PB>bB!k>fPG~KQL4{Zx7tY0n2I5O?q+h^UJo}nVqmA>JNxs4DmoR z^1BUX0!Ys+4!8Tk%+2WPQyY^7yML=blq$M)JT6`PYn9n0J>gStN& zcug-Z9QBE2mGCjYn8aH;Vn%Q4<9&Nr8^RXKyym{Fkr;Q++9@G`-uA;rCW3Oc<^dys zLqJph3p@dha(sQTp5-%~@u$X3uk#8MtH(sGgP%K|3^}o3obVMy=_NN1v$_W9Fyee@fU|2lv zOZgV^G3k?lt!N?hS zr{aYaMDMHRUu^RBd_-)XER$)10^9yu7{LbH=R(?EdM7!fsH*x3^Z>EakE30sB7w|y zVSjZH_?>Sh^x-*^t|htYZ{EHogVZ25td2Ae$LThXil6~^mR>Ruqahc{5F%5jlTR}y zW#OR#d#QyZ0iIf*6~rKwY(KqxpY0@2T{ci3Dln@u zT$c~k%Ww@BY7xC*Q2)j0pS!{Hr*wE)Z7r>=v7l}w8E`DL`dA`a`{x2M!;dp`jFqJ=S+ zYW8w11`t?kK%{>u^s&eAqv{G~-3WkcPaQh&rcDv&d7lq|Z{W>N@gNt=0A;OjcYY}o z=kbObr?HnYN$%aF=`o|O2gpFBRN07*UNwl7>JWc*CM4k5#LDE@A= zlQ>PM9~Bv5y8`VNFc_ZSWxat%tCE7z6E|}iRH9MXZUY) z;OG@)BpT2iiRS~?5DmWKr^PMsBlZ{}lM2ey`Vs}B+$~E`E{1c{uQAew957zEiFvI> z!}aQouYo!E031)a6(wBb^(V5@*3bc9=!fYI|0|X zJpB(7B#st6M)`lG#?M9RS@8Z20EHv}-P-jJbKRY;ZM^YMxQ-qTHC{*V-|nC$DF*4> z0$p?O!Q(90q;bMBep}&H3Htw6F8F_Fy*_Qxt_B@3_9WJJfq&53SnJ#KOoZe0Xc7At z4fN_{8hwISD}iX@ET@RB;{I|O>UqS8wbWU~V2hnBfXxh6yxqt@!b$i6HBD!G`}gRR z6Sj~2|66Nc0uJT-?mzZDvLsoCB9%fEr5IE~Wu#EVv?vixS(0sDQI-@!BxwlIhRVJT zE!H%aBqqkbZ)2M=+xve;-|zRF-}#?&o%27}zpKkT^UgER`@GM4KllB4?)(1Sle^P1 zQ9+%Te}9UbhfwR!G=uBQlbv2VDTntd)Pd=h@N!Vj;ov9W$^%INhc~asumW6yj0DoCQz_Po_i9IH+7dd=+y0@4=pLJX2 zGud%uDZA)eSGjZe%+@Do{6#yF%Vvg(O&VYu*`8%_oAOnbYa5>R=^Os|RxSi^Vr>T5 zVp$+5&-6rX8>g~G&Xzwkj?kucZCZ7N8v~|Y%^aKa4<}s5AY^oO^oNiogFEEx$152i z)V;u?*&foC{OPSMQyoxpK$Sx=_nfi13%tq? zv8EmAKYn1q4Bi!z(gp;KAWAf5X%C`c5WO{lHYiJono_NHzS98`qa$SHB#!#kB3c7TuY-+&tpda- zPtUL8ZJAE8-(pa!CnbT){S$~$-vo)_DqPmU;Pp8-RKHn!4m?zl>bd{X6WRES4_Rmr z#bE5A=EMr^&Fkp`@#Kb2_e7k?d_y}CyQh~LKU;8Ob(}{4{Hyn>0;%OY5}hDgR=dD3 z$Gq(K%6fu`1Y#<>{pFJW?x|=2#JF`{O>A2HFyQ(>M@in{VAh{`PSGb)^~xN~wmmX0 z)ohsTd^3`uj=l(W-vqpuR?qg` z0kFyO>O9vrMOzR@yaR3l#4M#uLt{A`rPeTU#KFaHx*41|anFC26|g~UPRs_=NLIM;RSaX4Dq7kLaZ4tk1_{9}g?onQqH=>eH@Ae+l7yr*aFi36U!>4CK$vSV zO5JobH6kf#!+txZ4kLYieGS%0A6mD-+DvTFJQF#2f*XI=Qd%i!zV_LEu7i{>QW=1d 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 V5T-FAzMv7p;)vDZJk#@`{|7gHIxGMH diff --git a/tgstation.dme b/tgstation.dme index 5b2b43bc38ccd..b32dad21490b8 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -848,20 +848,27 @@ #include "code\LINDA\LINDA_system.dm" #include "code\LINDA\LINDA_turf_tile.dm" #include "code\modules\integrated_electronics\_defines.dm" -#include "code\modules\integrated_electronics\arithmetic.dm" -#include "code\modules\integrated_electronics\assemblies.dm" -#include "code\modules\integrated_electronics\converters.dm" #include "code\modules\integrated_electronics\coordinate.dm" -#include "code\modules\integrated_electronics\data_transfer.dm" -#include "code\modules\integrated_electronics\input_output.dm" -#include "code\modules\integrated_electronics\logic.dm" -#include "code\modules\integrated_electronics\manipulation.dm" -#include "code\modules\integrated_electronics\memory.dm" -#include "code\modules\integrated_electronics\reagents.dm" -#include "code\modules\integrated_electronics\time.dm" -#include "code\modules\integrated_electronics\tools.dm" -#include "code\modules\integrated_electronics\trig.dm" -#include "code\modules\integrated_electronics\~defines.dm" +#include "code\modules\integrated_electronics\core\assemblies.dm" +#include "code\modules\integrated_electronics\core\helpers.dm" +#include "code\modules\integrated_electronics\core\integrated_circuit.dm" +#include "code\modules\integrated_electronics\core\pins.dm" +#include "code\modules\integrated_electronics\core\tools.dm" +#include "code\modules\integrated_electronics\passive\passive.dm" +#include "code\modules\integrated_electronics\passive\power.dm" +#include "code\modules\integrated_electronics\subtypes\arithmetic.dm" +#include "code\modules\integrated_electronics\subtypes\converters.dm" +#include "code\modules\integrated_electronics\subtypes\data_transfer.dm" +#include "code\modules\integrated_electronics\subtypes\input_output.dm" +#include "code\modules\integrated_electronics\subtypes\logic.dm" +#include "code\modules\integrated_electronics\subtypes\manipulation.dm" +#include "code\modules\integrated_electronics\subtypes\memory.dm" +#include "code\modules\integrated_electronics\subtypes\power.dm" +#include "code\modules\integrated_electronics\subtypes\reagents.dm" +#include "code\modules\integrated_electronics\subtypes\smart.dm" +#include "code\modules\integrated_electronics\subtypes\time.dm" +#include "code\modules\integrated_electronics\subtypes\trig.dm" +#include "code\modules\integrated_electronics\~defines\~defines.dm" #include "code\modules\admin\admin.dm" #include "code\modules\admin\admin_investigate.dm" #include "code\modules\admin\admin_memo.dm" From 9baf20a7eac12b8bb60eff5a63e7e2ba932c5247 Mon Sep 17 00:00:00 2001 From: Stakks Date: Tue, 24 Apr 2018 13:00:34 -0500 Subject: [PATCH 7/9] Stage 7 --- .../items/weapons/implants/implantcircuits.dm | 5 +- .../integrated_electronics/_defines.dm | 2 +- .../integrated_electronics/core/assemblies.dm | 12 +- .../core/integrated_circuit.dm | 19 +- .../integrated_electronics/core/tools.dm | 32 +- .../subtypes/arithmetic.dm | 121 ++++---- .../subtypes/converters.dm | 164 +++++----- .../subtypes/input_output.dm | 285 ++++++++---------- .../integrated_electronics/subtypes/logic.dm | 33 +- .../subtypes/manipulation.dm | 9 +- .../integrated_electronics/subtypes/power.dm | 6 +- .../subtypes/reagents.dm | 41 +-- .../integrated_electronics/subtypes/smart.dm | 15 +- .../integrated_electronics/subtypes/time.dm | 51 ++-- .../integrated_electronics/subtypes/trig.dm | 116 +++---- .../~defines/~defines.dm | 32 +- 16 files changed, 524 insertions(+), 419 deletions(-) diff --git a/code/game/objects/items/weapons/implants/implantcircuits.dm b/code/game/objects/items/weapons/implants/implantcircuits.dm index 2843c4f28c534..d6930438599c9 100644 --- a/code/game/objects/items/weapons/implants/implantcircuits.dm +++ b/code/game/objects/items/weapons/implants/implantcircuits.dm @@ -41,4 +41,7 @@ if(istype(O, /obj/item/weapon/crowbar) || istype(O, /obj/item/device/integrated_electronics) || istype(O, /obj/item/integrated_circuit) || istype(O, /obj/item/weapon/screwdriver) ) IC.attackby(O, user) else - ..() \ No newline at end of file + ..() + +/obj/item/weapon/implant/integrated_circuit/attack_self(mob/user) + IC.attack_self(user) \ No newline at end of file diff --git a/code/modules/integrated_electronics/_defines.dm b/code/modules/integrated_electronics/_defines.dm index c7478ba924224..56617b014f8c8 100644 --- a/code/modules/integrated_electronics/_defines.dm +++ b/code/modules/integrated_electronics/_defines.dm @@ -8,7 +8,7 @@ #define IC_SPAWN_DEFAULT 1 // If the circuit comes in the default circuit box. #define IC_SPAWN_RESEARCH 2 // If the circuit design will be autogenerated for RnD. -#define IC_FORMAT_STRING "\" +#define IC_FORMAT_STRING "\" #define IC_FORMAT_NUMBER "\" #define IC_FORMAT_REF "\" #define IC_FORMAT_LIST "\" diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index 21a729ebdbcc4..49b153f585731 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -24,8 +24,8 @@ name = "electronic machine" icon_state = "setup_large" w_class = 4 - max_components = IC_COMPONENTS_BASE * 3 - max_complexity = IC_COMPLEXITY_BASE * 3 + max_components = IC_COMPONENTS_BASE * 4 + max_complexity = IC_COMPLEXITY_BASE * 4 /obj/item/device/electronic_assembly/drone name = "electronic drone" @@ -107,6 +107,7 @@ for(var/obj/item/integrated_circuit/circuit in contents) HTML += "[circuit.name] | " HTML += "\[Rename\] | " + HTML += "\[Scan with Debugger\] | " if(circuit.removable) HTML += "\[Remove\]" HTML += "
" @@ -211,9 +212,10 @@ if(proximity) var/scanned = FALSE for(var/obj/item/integrated_circuit/input/sensor/S in contents) - S.set_pin_data(IC_OUTPUT, 1, weakref(target)) - S.check_then_do_work() - scanned = TRUE +// S.set_pin_data(IC_OUTPUT, 1, weakref(target)) +// S.check_then_do_work() + if(S.scan(target)) + scanned = TRUE if(scanned) visible_message("\The [user] waves \the [src] around [target].") diff --git a/code/modules/integrated_electronics/core/integrated_circuit.dm b/code/modules/integrated_electronics/core/integrated_circuit.dm index 80ddb87f9b825..f87a19e00422f 100644 --- a/code/modules/integrated_electronics/core/integrated_circuit.dm +++ b/code/modules/integrated_electronics/core/integrated_circuit.dm @@ -6,6 +6,7 @@ a creative player the means to solve many problems. Circuits are held inside an /obj/item/integrated_circuit/examine(mob/user) . = ..() external_examine(user) + interact(user) // This should be used when someone is examining while the case is opened. /obj/item/integrated_circuit/proc/internal_examine(mob/user) @@ -90,12 +91,10 @@ a creative player the means to solve many problems. Circuits are held inside an HTML += "
\[Refresh\] | " HTML += "\[Rename\] | " + HTML += "\[Scan with Debugger\] | " HTML += "\[Remove\]
" HTML += "" - //HTML += "" - //HTML += "" - //HTML += "" HTML += "" HTML += "" HTML += "" @@ -212,6 +211,16 @@ a creative player the means to solve many problems. Circuits are held inside an if(href_list["rename"]) rename_component(usr) + if(href_list["scan"]) + if(istype(held_item, /obj/item/device/integrated_electronics/debugger)) + var/obj/item/device/integrated_electronics/debugger/D = held_item + if(D.accepting_refs) + D.afterattack(src, usr, TRUE) + else + to_chat(usr, "The Debugger's 'ref scanner' needs to be on.") + else + to_chat(usr, "You need a Debugger set to 'ref' mode to do that.") + if(href_list["autopulse"]) if(autopulse != -1) autopulse = !autopulse @@ -260,10 +269,10 @@ 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() +/obj/item/integrated_circuit/proc/check_then_do_work(var/ignore_power = FALSE) if(world.time < next_use) // All intergrated circuits have an internal cooldown, to protect from spam. return - if(power_draw_per_use) + if(power_draw_per_use && !ignore_power) if(!check_power()) power_fail() return diff --git a/code/modules/integrated_electronics/core/tools.dm b/code/modules/integrated_electronics/core/tools.dm index b0ddf29e38884..8a9b8fa7a43c4 100644 --- a/code/modules/integrated_electronics/core/tools.dm +++ b/code/modules/integrated_electronics/core/tools.dm @@ -11,6 +11,7 @@ used for power or data transmission." icon = 'icons/obj/electronic_assemblies.dmi' icon_state = "wirer-wire" + item_state = "wirer" flags = CONDUCT w_class = 2 var/datum/integrated_io/selected_io = null @@ -20,6 +21,9 @@ icon_state = "wirer-[mode]" /obj/item/device/integrated_electronics/wirer/proc/wire(var/datum/integrated_io/io, mob/user) + if(!io.holder.assembly) + to_chat(user, "\The [io.holder] needs to be secured inside an assembly first.") + return if(mode == WIRE) selected_io = io user << "You attach a data wire to \the [selected_io.holder]'s [selected_io.name] data channel." @@ -110,8 +114,8 @@ /obj/item/device/integrated_electronics/debugger/attack_self(mob/user) var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref", "null") - //if(!CanInteract(user,src)) - // return + if(!CanInteract(user,src)) + return var/new_data = null switch(type_to_use) @@ -153,8 +157,8 @@ data_to_show = A.name 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() - user << "You pulse \the [io.holder]'s [io]." + io.holder.check_then_do_work(ignore_power = TRUE) + to_chat(user, "You pulse \the [io.holder]'s [io].") io.holder.interact(user) // This is to update the UI. @@ -191,6 +195,7 @@ new /obj/item/weapon/storage/bag/circuits/mini/reagents(src) new /obj/item/weapon/storage/bag/circuits/mini/transfer(src) new /obj/item/weapon/storage/bag/circuits/mini/converter(src) + new /obj/item/weapon/storage/bag/circuits/mini/power(src) new /obj/item/device/electronic_assembly(src) new /obj/item/device/integrated_electronics/wirer(src) @@ -202,11 +207,24 @@ /obj/item/weapon/storage/bag/circuits/all/New() ..() spawn(2 SECONDS) // So the list has time to initialize. - for(var/obj/item/integrated_circuit/IC in all_integrated_circuits) - for(var/i = 1 to 10) - new IC.type(src) + new /obj/item/weapon/storage/bag/circuits/mini/arithmetic/all(src) + new /obj/item/weapon/storage/bag/circuits/mini/trig/all(src) + new /obj/item/weapon/storage/bag/circuits/mini/input/all(src) + new /obj/item/weapon/storage/bag/circuits/mini/output/all(src) + new /obj/item/weapon/storage/bag/circuits/mini/memory/all(src) + new /obj/item/weapon/storage/bag/circuits/mini/logic/all(src) + new /obj/item/weapon/storage/bag/circuits/mini/smart/all(src) + new /obj/item/weapon/storage/bag/circuits/mini/manipulation/all(src) + new /obj/item/weapon/storage/bag/circuits/mini/time/all(src) + new /obj/item/weapon/storage/bag/circuits/mini/reagents/all(src) + new /obj/item/weapon/storage/bag/circuits/mini/transfer/all(src) + new /obj/item/weapon/storage/bag/circuits/mini/converter/all(src) + new /obj/item/weapon/storage/bag/circuits/mini/power/all(src) new /obj/item/device/electronic_assembly(src) + new /obj/item/device/electronic_assembly/medium(src) + new /obj/item/device/electronic_assembly/large(src) + new /obj/item/device/electronic_assembly/drone(src) new /obj/item/device/integrated_electronics/wirer(src) new /obj/item/device/integrated_electronics/debugger(src) new /obj/item/weapon/crowbar(src) diff --git a/code/modules/integrated_electronics/subtypes/arithmetic.dm b/code/modules/integrated_electronics/subtypes/arithmetic.dm index 9200fa1c00005..bf7b347d801a2 100644 --- a/code/modules/integrated_electronics/subtypes/arithmetic.dm +++ b/code/modules/integrated_electronics/subtypes/arithmetic.dm @@ -1,11 +1,21 @@ //These circuits do simple math. /obj/item/integrated_circuit/arithmetic complexity = 1 - inputs = list("A","B","C","D","E","F","G","H") - outputs = list("result") - activators = list("compute") + inputs = list( + "\ A", + "\ B", + "\ C", + "\ D", + "\ E", + "\ F", + "\ G", + "\ H" + ) + outputs = list("\ result") + activators = list("\ compute", "\ on computed") category_text = "Arithmetic" autopulse = 1 + power_draw_per_use = 5 // Math is pretty cheap. /obj/item/integrated_circuit/arithmetic/on_data_written() if(autopulse == 1) @@ -28,9 +38,9 @@ if(isnum(I.data)) result = result + I.data - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // -Subtracting- // @@ -55,9 +65,9 @@ if(isnum(I.data)) result = result - I.data - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // *Multiply* // @@ -82,9 +92,9 @@ if(isnum(I.data)) result = result * I.data - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // /Division/ // @@ -109,9 +119,9 @@ if(isnum(I.data) && I.data != 0) //No runtimes here. result = result / I.data - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) //^ Exponent ^// @@ -128,9 +138,9 @@ if(isnum(A.data) && isnum(B.data)) result = A.data ** B.data - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // +-Sign-+ // @@ -152,9 +162,9 @@ else result = 0 - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // Round // @@ -175,9 +185,9 @@ else result = round(A.data) - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // Absolute // @@ -195,9 +205,9 @@ if(isnum(I.data)) result = abs(I.data) - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // Averaging // @@ -219,9 +229,9 @@ if(inputs_used) result = result / inputs_used - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // Pi, because why the hell not? // /obj/item/integrated_circuit/arithmetic/pi @@ -231,30 +241,31 @@ inputs = list() /obj/item/integrated_circuit/arithmetic/pi/do_work() - var/datum/integrated_io/output/O = outputs[1] - O.data = 3.14159 - O.push_data() + set_pin_data(IC_OUTPUT, 1, 3.14159) + push_data() + activate_pin(2) // Random // /obj/item/integrated_circuit/arithmetic/random name = "random number generator circuit" desc = "This gives a random (integer) number between values A and B inclusive." extended_desc = "'Inclusive' means that the upper bound is included in the range of numbers, e.g. L = 1 and H = 3 will allow \ - for outputs of 1, 2, or 3. L being the higher number is not strictly required." + for outputs of 1, 2, or 3. H being the higher number is not strictly required." icon_state = "random" - inputs = list("L","H") + inputs = list("\ L","\ H") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/arithmetic/random/do_work() var/result = 0 - var/datum/integrated_io/L = inputs[1] - var/datum/integrated_io/H = inputs[2] + var/L = get_pin_data(IC_INPUT, 1) + var/H = get_pin_data(IC_INPUT, 2) - if(isnum(L.data) && isnum(H.data)) - result = rand(L.data, H.data) + if(isnum(L) && isnum(H)) + result = rand(L, H) - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // Square Root // @@ -262,7 +273,7 @@ name = "square root circuit" desc = "This outputs the square root of a number you put in." icon_state = "square_root" - inputs = list("A") + inputs = list("\ A") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/arithmetic/square_root/do_work() @@ -272,9 +283,9 @@ if(isnum(I.data)) result = sqrt(I.data) - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // % Modulo % // @@ -282,17 +293,17 @@ name = "modulo circuit" desc = "Gets the remainder of A / B." icon_state = "modulo" - inputs = list("A", "B") + inputs = list("\ A", "\ B") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/arithmetic/modulo/do_work() var/result = 0 - var/datum/integrated_io/input/A = inputs[1] - var/datum/integrated_io/input/B = inputs[2] - if(isnum(A.data) && isnum(B.data) && B.data != 0) - result = A.data % B.data - - for(var/datum/integrated_io/output/O in outputs) - O.data = result - O.push_data() + var/A = get_pin_data(IC_INPUT, 1) + var/B = get_pin_data(IC_INPUT, 2) + if(isnum(A) && isnum(B) && B != 0) + result = A % B + + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm index 12c7221cfc9a7..59e8cddb947a7 100644 --- a/code/modules/integrated_electronics/subtypes/converters.dm +++ b/code/modules/integrated_electronics/subtypes/converters.dm @@ -3,9 +3,10 @@ complexity = 2 inputs = list("input") outputs = list("output") - activators = list("convert") + activators = list("\ convert", "\ on convert") category_text = "Converter" autopulse = 1 + power_draw_per_use = 10 /obj/item/integrated_circuit/converter/on_data_written() if(autopulse == 1) @@ -15,84 +16,110 @@ name = "number to string" desc = "This circuit can convert a number variable into a string." icon_state = "num-string" + inputs = list("\ input") + outputs = list("\ output") /obj/item/integrated_circuit/converter/num2text/do_work() var/result = null - var/datum/integrated_io/incoming = inputs[1] - var/datum/integrated_io/outgoing = outputs[1] - if(incoming.data && isnum(incoming.data)) - result = num2text(incoming.data) + pull_data() + var/incoming = get_pin_data(IC_INPUT, 1) + if(incoming && isnum(incoming)) + result = num2text(incoming) - outgoing.data = result - outgoing.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) /obj/item/integrated_circuit/converter/text2num name = "string to number" desc = "This circuit can convert a string variable into a number." icon_state = "string-num" + inputs = list("\ input") + outputs = list("\ output") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/text2num/do_work() var/result = null - var/datum/integrated_io/incoming = inputs[1] - var/datum/integrated_io/outgoing = outputs[1] - if(incoming.data && istext(incoming.data)) - result = text2num(incoming.data) + pull_data() + var/incoming = get_pin_data(IC_INPUT, 1) + if(incoming && istext(incoming)) + result = text2num(incoming) - outgoing.data = result - outgoing.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) /obj/item/integrated_circuit/converter/ref2text name = "reference to string" desc = "This circuit can convert a reference to something else to a string, specifically the name of that reference." icon_state = "ref-string" + inputs = list("\ input") + outputs = list("\ output") /obj/item/integrated_circuit/converter/ref2text/do_work() var/result = null - var/datum/integrated_io/incoming = inputs[1] - var/datum/integrated_io/outgoing = outputs[1] - var/atom/A = incoming.data_as_type(/atom) - result = A && A.name + pull_data() + var/atom/A = get_pin_data(IC_INPUT, 1) + if(A && istype(A)) + result = A.name - outgoing.data = result - outgoing.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) /obj/item/integrated_circuit/converter/lowercase name = "lowercase string converter" desc = "this will cause a string to come out in all lowercase." icon_state = "lowercase" + inputs = list("\ input") + outputs = list("\ output") /obj/item/integrated_circuit/converter/lowercase/do_work() var/result = null - var/datum/integrated_io/incoming = inputs[1] - var/datum/integrated_io/outgoing = outputs[1] - if(incoming.data && istext(incoming.data)) - result = lowertext(incoming.data) + pull_data() + var/incoming = get_pin_data(IC_INPUT, 1) + if(incoming && istext(incoming)) + result = lowertext(incoming) - outgoing.data = result - outgoing.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) /obj/item/integrated_circuit/converter/uppercase name = "uppercase string converter" desc = "THIS WILL CAUSE A STRING TO COME OUT IN ALL UPPERCASE." icon_state = "uppercase" + inputs = list("\ input") + outputs = list("\ output") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/uppercase/do_work() var/result = null - var/datum/integrated_io/incoming = inputs[1] - var/datum/integrated_io/outgoing = outputs[1] - if(incoming.data && istext(incoming.data)) - result = uppertext(incoming.data) + pull_data() + var/incoming = get_pin_data(IC_INPUT, 1) + if(incoming && istext(incoming)) + result = uppertext(incoming) - outgoing.data = result - outgoing.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) /obj/item/integrated_circuit/converter/concatenatior name = "concatenatior" - desc = "This joins many strings together to get one big string." + desc = "This joins many strings or numbers together to get one big string." complexity = 4 - inputs = list("A","B","C","D","E","F","G","H") - outputs = list("result") - activators = list("concatenate") + inputs = list( + "\ A", + "\ B", + "\ C", + "\ D", + "\ E", + "\ F", + "\ G", + "\ H" + ) + outputs = list("\ result") + activators = list("\ concatenate", "\ on concatenated") /obj/item/integrated_circuit/converter/concatenatior/do_work() var/result = null @@ -100,70 +127,69 @@ I.pull_data() if(istext(I.data)) result = result + I.data + else if(!isnull(I.data) && num2text(I.data)) + result = result + num2text(I.data) var/datum/integrated_io/outgoing = outputs[1] outgoing.data = result outgoing.push_data() + activate_pin(2) /obj/item/integrated_circuit/converter/radians2degrees name = "radians to degrees converter" desc = "Converts radians to degrees." - inputs = list("radian") - outputs = list("degrees") + inputs = list("\ radian") + outputs = list("\ degrees") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/radians2degrees/do_work() var/result = null - var/datum/integrated_io/incoming = inputs[1] - var/datum/integrated_io/outgoing = outputs[1] - incoming.pull_data() - if(incoming.data && isnum(incoming.data)) - result = ToDegrees(incoming.data) + pull_data() + var/incoming = get_pin_data(IC_INPUT, 1) + if(incoming && isnum(incoming)) + result = ToDegrees(incoming) - outgoing.data = result - outgoing.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) /obj/item/integrated_circuit/converter/degrees2radians name = "degrees to radians converter" desc = "Converts degrees to radians." - inputs = list("degrees") - outputs = list("radians") + inputs = list("\ degrees") + outputs = list("\ radians") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/degrees2radians/do_work() var/result = null - var/datum/integrated_io/incoming = inputs[1] - var/datum/integrated_io/outgoing = outputs[1] - incoming.pull_data() - if(incoming.data && isnum(incoming.data)) - result = ToRadians(incoming.data) + pull_data() + var/incoming = get_pin_data(IC_INPUT, 1) + if(incoming && isnum(incoming)) + result = ToRadians(incoming) - outgoing.data = result - outgoing.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) /obj/item/integrated_circuit/converter/abs_to_rel_coords name = "abs to rel coordinate converter" desc = "Easily convert absolute coordinates to relative coordinates with this." complexity = 4 - inputs = list("X1 (abs)", "Y1 (abs)", "X2 (abs)", "Y2 (abs)") - outputs = list("X (rel)", "Y (rel)") - activators = list("compute rel coordinates") - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + inputs = list("\ X1", "\ Y1", "\ X2", "\ Y2") + outputs = list("\ X", "\ Y") + activators = list("\ compute rel coordinates", "\ on convert") /obj/item/integrated_circuit/converter/abs_to_rel_coords/do_work() - var/datum/integrated_io/x1 = inputs[1] - var/datum/integrated_io/y1 = inputs[2] - - var/datum/integrated_io/x2 = inputs[3] - var/datum/integrated_io/y2 = inputs[4] + var/x1 = get_pin_data(IC_INPUT, 1) + var/y1 = get_pin_data(IC_INPUT, 2) - var/datum/integrated_io/result_x = outputs[1] - var/datum/integrated_io/result_y = outputs[2] + var/x2 = get_pin_data(IC_INPUT, 3) + var/y2 = get_pin_data(IC_INPUT, 4) - if(x1.data && y1.data && x2.data && y2.data) - result_x.data = x1.data - x2.data - result_y.data = y1.data - y2.data + if(x1 && y1 && x2 && y2) + set_pin_data(IC_OUTPUT, 1, x1 - x2) + set_pin_data(IC_OUTPUT, 2, y1 - y2) - for(var/datum/integrated_io/output/O in outputs) - O.push_data() \ No newline at end of file + push_data() + activate_pin(2) \ No newline at end of file diff --git a/code/modules/integrated_electronics/subtypes/input_output.dm b/code/modules/integrated_electronics/subtypes/input_output.dm index 3ab7d404932ac..4503a6b7053aa 100644 --- a/code/modules/integrated_electronics/subtypes/input_output.dm +++ b/code/modules/integrated_electronics/subtypes/input_output.dm @@ -13,27 +13,26 @@ can_be_asked_input = 1 inputs = list() outputs = list() - activators = list("on pressed") + activators = list("\ on pressed") /obj/item/integrated_circuit/input/button/ask_for_input(mob/user) //Bit misleading name for this specific use. - var/datum/integrated_io/A = activators[1] - if(A.linked.len) - for(var/datum/integrated_io/activate/target in A.linked) - target.holder.check_then_do_work() to_chat(user, "You press the button labeled '[src.name]'.") + activate_pin(1) /obj/item/integrated_circuit/input/toggle_button name = "toggle button" desc = "It toggles on, off, on, off..." icon_state = "toggle_button" complexity = 1 + can_be_asked_input = 1 inputs = list() - outputs = list("on" = 0) - activators = list("on toggle") + outputs = list("\ on" = 0) + activators = list("\ on toggle") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/input/toggle_button/ask_for_input(mob/user) // Ditto. set_pin_data(IC_OUTPUT, 1, !get_pin_data(IC_OUTPUT, 1)) + push_data() activate_pin(1) to_chat(user, "You toggle the button labeled '[src.name]' [get_pin_data(IC_OUTPUT, 1) ? "on" : "off"].") @@ -44,18 +43,16 @@ complexity = 2 can_be_asked_input = 1 inputs = list() - outputs = list("number entered") - activators = list("on entered") + outputs = list("\ number entered") + activators = list("\ on entered") power_draw_per_use = 4 /obj/item/integrated_circuit/input/numberpad/ask_for_input(mob/user) var/new_input = input(user, "Enter a number, please.","Number pad") as null|num if(isnum(new_input) && CanInteract(user, src)) - var/datum/integrated_io/O = outputs[1] - O.data = new_input - O.push_data() - var/datum/integrated_io/A = activators[1] - A.push_data() + set_pin_data(IC_OUTPUT, 1, new_input) + push_data() + activate_pin(1) /obj/item/integrated_circuit/input/textpad name = "text pad" @@ -64,47 +61,41 @@ complexity = 2 can_be_asked_input = 1 inputs = list() - outputs = list("string entered") - activators = list("on entered") + outputs = list("\ string entered") + activators = list("\ on entered") power_draw_per_use = 4 /obj/item/integrated_circuit/input/textpad/ask_for_input(mob/user) var/new_input = input(user, "Enter some words, please.","Number pad") as null|text if(istext(new_input) && CanInteract(user, src)) - var/datum/integrated_io/O = outputs[1] - O.data = new_input - O.push_data() - var/datum/integrated_io/A = activators[1] - A.push_data() + set_pin_data(IC_OUTPUT, 1, new_input) + push_data() + activate_pin(1) /obj/item/integrated_circuit/input/med_scanner name = "integrated medical analyser" desc = "A very small version of the common medical analyser. This allows the machine to know how healthy someone is." icon_state = "medscan" complexity = 4 - inputs = list("target ref") - outputs = list("total health %", "total missing health") - activators = list("scan") + inputs = list("\ target") + outputs = list("\ total health %", "\ total missing health") + activators = list("\ scan", "\ on scanned") origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) power_draw_per_use = 40 /obj/item/integrated_circuit/input/med_scanner/do_work() - var/datum/integrated_io/I = inputs[1] - var/mob/living/carbon/human/H = I.data_as_type(/mob/living/carbon/human) + 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.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range. - var/total_health = round(H.health/H.maxHealth, 0.1)*100 - var/missing_health = H.maxHealth - H.health + var/total_health = round(H.health/H.getMaxHealth(), 0.1)*100 + var/missing_health = H.getMaxHealth() - H.health - var/datum/integrated_io/total = outputs[1] - var/datum/integrated_io/missing = outputs[2] + set_pin_data(IC_OUTPUT, 1, total_health) + set_pin_data(IC_OUTPUT, 2, missing_health) - total.data = total_health - missing.data = missing_health - - for(var/datum/integrated_io/output/O in outputs) - O.push_data() + push_data() + activate_pin(2) /obj/item/integrated_circuit/input/adv_med_scanner name = "integrated advanced medical analyser" @@ -112,47 +103,38 @@ This type is much more precise, allowing the machine to know much more about the target than a normal analyzer." icon_state = "medscan_adv" complexity = 12 - inputs = list("target ref") + inputs = list("\ target") outputs = list( - "total health %", - "total missing health", - "brute damage", - "burn damage", - "tox damage", - "oxy damage", - "clone damage" + "\ total health %", + "\ total missing health", + "\ brute damage", + "\ burn damage", + "\ tox damage", + "\ oxy damage", + "\ clone damage" ) - activators = list("scan") + activators = list("\ scan", "\ on scanned") origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4) power_draw_per_use = 80 /obj/item/integrated_circuit/input/adv_med_scanner/do_work() - var/datum/integrated_io/I = inputs[1] - var/mob/living/carbon/human/H = I.data_as_type(/mob/living/carbon/human) + 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.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range. - var/total_health = round(H.health/H.maxHealth, 0.1)*100 - var/missing_health = H.maxHealth - H.health - - var/datum/integrated_io/total = outputs[1] - var/datum/integrated_io/missing = outputs[2] - var/datum/integrated_io/brute = outputs[3] - var/datum/integrated_io/burn = outputs[4] - var/datum/integrated_io/tox = outputs[5] - var/datum/integrated_io/oxy = outputs[6] - var/datum/integrated_io/clone = outputs[7] - - total.data = total_health - missing.data = missing_health - brute.data = H.getBruteLoss() - burn.data = H.getFireLoss() - tox.data = H.getToxLoss() - oxy.data = H.getOxyLoss() - clone.data = H.getCloneLoss() - - for(var/datum/integrated_io/output/O in outputs) - O.push_data() + var/total_health = round(H.health/H.getMaxHealth(), 0.1)*100 + var/missing_health = H.getMaxHealth() - H.health + + set_pin_data(IC_OUTPUT, 1, total_health) + set_pin_data(IC_OUTPUT, 2, missing_health) + set_pin_data(IC_OUTPUT, 3, H.getBruteLoss()) + set_pin_data(IC_OUTPUT, 4, H.getFireLoss()) + set_pin_data(IC_OUTPUT, 5, H.getToxLoss()) + set_pin_data(IC_OUTPUT, 6, H.getOxyLoss()) + set_pin_data(IC_OUTPUT, 7, H.getCloneLoss()) + + push_data() + activate_pin(2) /obj/item/integrated_circuit/input/local_locator name = "local locator" @@ -166,8 +148,7 @@ /obj/item/integrated_circuit/input/local_locator/do_work() var/datum/integrated_io/O = outputs[1] O.data = null - if(istype(src.loc, /obj/item/device/electronic_assembly)) // Check to make sure we're actually in a machine. - var/obj/item/device/electronic_assembly/assembly = src.loc + if(assembly) if(istype(assembly.loc, /mob/living)) // Now check if someone's holding us. O.data = weakref(assembly.loc) @@ -192,7 +173,7 @@ if(!isweakref(I.data)) return - var/atom/A = I.data + var/atom/A = I.data.resolve() if(!A) return var/desired_type = A.type @@ -215,10 +196,10 @@ Meaning the default frequency is expressed as 1457, not 145.7. To send a signal, pulse the 'send signal' activator pin." icon_state = "signal" complexity = 4 - inputs = list("frequency","code") + inputs = list("\ frequency","\ code") outputs = list() - activators = list("send signal","on signal received") - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNETS = 2) + activators = list("\ send signal","\ on signal sent", "\ on signal received") + origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2) power_draw_idle = 5 power_draw_per_use = 40 @@ -229,11 +210,9 @@ /obj/item/integrated_circuit/input/signaler/initialize() ..() set_frequency(frequency) - var/datum/integrated_io/new_freq = inputs[1] - var/datum/integrated_io/new_code = inputs[2] // Set the pins so when someone sees them, they won't show as null - new_freq.data = frequency - new_code.data = code + set_pin_data(IC_INPUT, 1, frequency) + set_pin_data(IC_INPUT, 2, code) /obj/item/integrated_circuit/input/signaler/Destroy() if(radio_controller) @@ -242,12 +221,12 @@ . = ..() /obj/item/integrated_circuit/input/signaler/on_data_written() - var/datum/integrated_io/new_freq = inputs[1] - var/datum/integrated_io/new_code = inputs[2] - if(isnum(new_freq.data) && new_freq.data > 0) - set_frequency(new_freq.data) - if(isnum(new_code.data)) - code = new_code.data + var/new_freq = get_pin_data(IC_INPUT, 1) + var/new_code = get_pin_data(IC_INPUT, 2) + if(isnum(new_freq) && new_freq > 0) + set_frequency(new_freq) + if(isnum(new_code)) + code = new_code /obj/item/integrated_circuit/input/signaler/do_work() // Sends a signal. @@ -259,6 +238,7 @@ signal.encryption = code signal.data["message"] = "ACTIVATE" radio_connection.post_signal(src, signal) + activate_pin(2) /obj/item/integrated_circuit/input/signaler/proc/set_frequency(new_frequency) if(!frequency) @@ -272,11 +252,11 @@ radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT) /obj/item/integrated_circuit/input/signaler/receive_signal(datum/signal/signal) - var/datum/integrated_io/new_code = inputs[2] + var/new_code = get_pin_data(IC_INPUT, 2) var/code = 0 - if(isnum(new_code.data)) - code = new_code.data + if(isnum(new_code)) + code = new_code if(!signal) return 0 if(signal.encryption != code) @@ -284,8 +264,7 @@ if(signal.source == src) // Don't trigger ourselves. return 0 - var/datum/integrated_io/A = activators[2] - A.push_data() + activate_pin(3) for(var/mob/O in hearers(1, get_turf(src))) O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2) @@ -298,10 +277,10 @@ will pulse whatever's connected to it. Pulsing the first activation pin will send a message." icon_state = "signal" complexity = 4 - inputs = list("target EPv2 address", "data to send", "secondary text") - outputs = list("address received", "data received", "secondary text received") - activators = list("send data", "on data received") - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNETS = 2, TECH_BLUESPACE = 2) + inputs = list("\ target EPv2 address", "\ data to send", "\ secondary text") + outputs = list("\ address received", "\ data received", "\ secondary text received") + activators = list("\ send data", "\ on data received") + origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2, TECH_BLUESPACE = 2) power_draw_per_use = 50 var/datum/exonet_protocol/exonet = null @@ -309,7 +288,7 @@ ..() exonet = new(src) exonet.make_address("EPv2_circuit-\ref[src]") - desc += "
This circuit's EPv2 address is: [exonet.address]." + desc += "
This circuit's EPv2 address is: [exonet.address]" /obj/item/integrated_circuit/input/EPv2/Destroy() if(exonet) @@ -318,54 +297,47 @@ ..() /obj/item/integrated_circuit/input/EPv2/do_work() - var/datum/integrated_io/target_address = inputs[1] - var/datum/integrated_io/message = inputs[2] - var/datum/integrated_io/text = inputs[3] - if(istext(target_address.data)) - exonet.send_message(target_address.data, message.data, text.data) - -/obj/item/integrated_circuit/input/receive_exonet_message(var/atom/origin_atom, var/origin_address, var/message, var/text) - var/datum/integrated_io/message_received = outputs[1] - var/datum/integrated_io/data_received = outputs[2] - var/datum/integrated_io/text_received = outputs[3] + var/target_address = get_pin_data(IC_INPUT, 1) + var/message = get_pin_data(IC_INPUT, 2) + var/text = get_pin_data(IC_INPUT, 3) - var/datum/integrated_io/A = activators[2] - A.push_data() + if(target_address && istext(target_address)) + exonet.send_message(target_address, message, text) - message_received.write_data_to_pin(origin_address) - data_received.write_data_to_pin(message) - text_received.write_data_to_pin(text) +/obj/item/integrated_circuit/input/receive_exonet_message(var/atom/origin_atom, var/origin_address, var/message, var/text) + set_pin_data(IC_OUTPUT, 1, origin_address) + set_pin_data(IC_OUTPUT, 2, message) + set_pin_data(IC_OUTPUT, 3, text) - for(var/datum/integrated_io/output/O in outputs) - O.push_data() + push_data() + activate_pin(2) //This circuit gives information on where the machine is. /obj/item/integrated_circuit/input/gps name = "global positioning system" desc = "This allows you to easily know the position of a machine containing this device." + extended_desc = "The GPS's coordinates it gives is absolute, not relative." icon_state = "gps" complexity = 4 inputs = list() - outputs = list("X (abs)", "Y (abs)") - activators = list("get coordinates") + outputs = list("\ X", "\ Y") + activators = list("\ get coordinates", "\ on get coordinates") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 30 /obj/item/integrated_circuit/input/gps/do_work() var/turf/T = get_turf(src) - var/datum/integrated_io/result_x = outputs[1] - var/datum/integrated_io/result_y = outputs[2] - result_x.data = null - result_y.data = null + set_pin_data(IC_OUTPUT, 1, null) + set_pin_data(IC_OUTPUT, 2, null) if(!T) return - result_x.data = T.x - result_y.data = T.y + set_pin_data(IC_OUTPUT, 1, T.x) + set_pin_data(IC_OUTPUT, 2, T.y) - for(var/datum/integrated_io/output/O in outputs) - O.push_data() + push_data() + activate_pin(2) /obj/item/integrated_circuit/input/microphone @@ -375,8 +347,8 @@ flags = HEAR complexity = 8 inputs = list() - outputs = list("speaker \", "message \") - activators = list("on message received") + outputs = list("\ speaker", "\ message") + activators = list("\ on message received", "\ on translation") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 15 /* @@ -410,21 +382,25 @@ /obj/item/integrated_circuit/input/sensor name = "sensor" desc = "Scans and obtains a reference for any objects or persons near you. All you need to do is shove the machine in their face." + extended_desc = "If 'ignore storage' pin is set to 1, the sensor will disregard scanning various storage containers such as backpacks." icon_state = "recorder" complexity = 12 - inputs = list() - outputs = list("scanned ref \") - activators = list("on scanned") + inputs = list("\ ignore storage" = 1) + outputs = list("\ scanned") + activators = list("\ on scanned") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 120 -/obj/item/integrated_circuit/input/sensor/do_work() - // Because this gets called by attack(), all this needs to do is pulse the activator. - for(var/datum/integrated_io/output/O in outputs) - O.push_data() - var/datum/integrated_io/activate/A = activators[1] - A.push_data() +/obj/item/integrated_circuit/input/sensor/proc/scan(var/atom/A) + var/ignore_bags = get_pin_data(IC_INPUT, 1) + if(ignore_bags) + if(istype(A, /obj/item/weapon/storage)) + return FALSE + set_pin_data(IC_OUTPUT, 1, weakref(A)) + push_data() + activate_pin(1) + return TRUE /obj/item/integrated_circuit/output category_text = "Output" @@ -433,9 +409,9 @@ name = "small screen" desc = "This small screen can display a single piece of data, when the machine is examined closely." icon_state = "screen" - inputs = list("displayed data") + inputs = list("\ displayed data") outputs = list() - activators = list("load data") + activators = list("\ load data") power_draw_per_use = 10 autopulse = 1 var/stuff_to_display = null @@ -468,7 +444,7 @@ var/list/nearby_things = range(0, get_turf(src)) for(var/mob/M in nearby_things) var/obj/O = assembly ? assembly : src - visible_message("\icon[O] [stuff_to_display]") + to_chat(M, "\icon[O] [stuff_to_display]") /obj/item/integrated_circuit/output/screen/large name = "large screen" @@ -488,7 +464,7 @@ complexity = 4 inputs = list() outputs = list() - activators = list("toggle light") + activators = list("\ toggle light") var/light_toggled = 0 var/light_brightness = 3 var/light_rgb = "#FFFFFF" @@ -509,18 +485,18 @@ power_draw_idle = light_toggled ? light_brightness * 2 : 0 /obj/item/integrated_circuit/output/light/advanced/update_lighting() - var/datum/integrated_io/R = inputs[1] - var/datum/integrated_io/G = inputs[2] - var/datum/integrated_io/B = inputs[3] - var/datum/integrated_io/brightness = inputs[4] - - if(isnum(R.data) && isnum(G.data) && isnum(B.data) && isnum(brightness.data)) - R.data = Clamp(R.data, 0, 255) - G.data = Clamp(G.data, 0, 255) - B.data = Clamp(B.data, 0, 255) - brightness.data = Clamp(brightness.data, 0, 6) - light_rgb = rgb(R.data, G.data, B.data) - light_brightness = brightness.data + var/R = get_pin_data(IC_INPUT, 1) + var/G = get_pin_data(IC_INPUT, 2) + var/B = get_pin_data(IC_INPUT, 3) + var/brightness = get_pin_data(IC_INPUT, 4) + + if(isnum(R) && isnum(G) && isnum(B) && isnum(brightness)) + R = Clamp(R, 0, 255) + G = Clamp(G, 0, 255) + B = Clamp(B, 0, 255) + brightness = Clamp(brightness, 0, 6) + light_rgb = rgb(R, G, B) + light_brightness = brightness ..() @@ -534,10 +510,10 @@ icon_state = "light_adv" complexity = 8 inputs = list( - "R", - "G", - "B", - "Brightness" + "\ R", + "\ G", + "\ B", + "\ Brightness" ) outputs = list() origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) @@ -552,9 +528,9 @@ complexity = 8 cooldown_per_use = 4 SECONDS inputs = list( - "sound ID", - "volume", - "frequency" + "\ sound ID", + "\ volume", + "\ frequency" ) outputs = list() activators = list("play sound") @@ -571,6 +547,7 @@ inputs = list("text") outputs = list() activators = list("to speech") + power_draw_per_use = 60 /obj/item/integrated_circuit/output/text_to_speech/do_work() var/datum/integrated_io/text = inputs[1] diff --git a/code/modules/integrated_electronics/subtypes/logic.dm b/code/modules/integrated_electronics/subtypes/logic.dm index 838cf4f4e94bb..7d90add7c3d23 100644 --- a/code/modules/integrated_electronics/subtypes/logic.dm +++ b/code/modules/integrated_electronics/subtypes/logic.dm @@ -4,41 +4,48 @@ extended_desc = "Logic circuits will treat a null, 0, and a \"\" string value as FALSE and anything else as TRUE." complexity = 3 outputs = list("result") - activators = list("compare", "on true result") + activators = list("\ compare") autopulse = 1 + power_draw_per_use = 1 /obj/item/integrated_circuit/logic/on_data_written() if(autopulse == 1) check_then_do_work() /obj/item/integrated_circuit/logic/do_work() - var/datum/integrated_io/O = outputs[1] - var/datum/integrated_io/P = activators[2] - O.push_data() - if(O.data) - P.push_data() + push_data() /obj/item/integrated_circuit/logic/binary - inputs = list("A","B") + inputs = list("\ A","\ B") + activators = list("\ compare", "\ on true result", "\ on false result") /obj/item/integrated_circuit/logic/binary/do_work() + pull_data() var/datum/integrated_io/A = inputs[1] var/datum/integrated_io/B = inputs[2] var/datum/integrated_io/O = outputs[1] O.data = do_compare(A, B) ? TRUE : FALSE + + if(get_pin_data(IC_OUTPUT, 1)) + activate_pin(2) + else + activate_pin(3) ..() /obj/item/integrated_circuit/logic/binary/proc/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) return FALSE /obj/item/integrated_circuit/logic/unary - inputs = list("A") + inputs = list("\ A") + activators = list("\ compare", "\ on compare") /obj/item/integrated_circuit/logic/unary/do_work() + pull_data() var/datum/integrated_io/A = inputs[1] var/datum/integrated_io/O = outputs[1] O.data = do_check(A) ? TRUE : FALSE ..() + activate_pin(2) /obj/item/integrated_circuit/logic/unary/proc/do_check(var/datum/integrated_io/A) return FALSE @@ -51,6 +58,14 @@ /obj/item/integrated_circuit/logic/binary/equals/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) return A.data == B.data +/obj/item/integrated_circuit/logic/binary/not_equals + name = "not equal gate" + desc = "This gate compares two values, and outputs the number one if both are different." + icon_state = "not_equal" + +/obj/item/integrated_circuit/logic/binary/not_equals/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) + return A.data != B.data + /obj/item/integrated_circuit/logic/binary/and name = "and gate" desc = "This gate will output 'one' if both inputs evaluate to true." @@ -105,4 +120,4 @@ icon_state = "not" /obj/item/integrated_circuit/logic/unary/not/do_check(var/datum/integrated_io/A) - return !A.data \ No newline at end of file + return !A.data diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm index d202f5c299001..f260190e67e56 100644 --- a/code/modules/integrated_electronics/subtypes/manipulation.dm +++ b/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -7,14 +7,16 @@ normal limitations to firearms, such as ammunition requirements and firing delays, still hold true if fired by the mechanism." complexity = 20 inputs = list( - "target X rel", - "target Y rel" + "\ target X rel", + "\ target Y rel" ) outputs = list() activators = list( - "fire" + "\ fire" ) var/obj/item/weapon/gun/installed_gun = null + origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4) + power_draw_per_use = 50 // The targeting mechanism uses this. The actual gun uses its own cell for firing if it's an energy weapon. /obj/item/integrated_circuit/manipulation/weapon_firing/Destroy() qdel(installed_gun) @@ -106,6 +108,7 @@ inputs = list("dir num") outputs = list() activators = list("step towards dir") + power_draw_per_use = 100 /obj/item/integrated_circuit/manipulation/locomotion/do_work() ..() diff --git a/code/modules/integrated_electronics/subtypes/power.dm b/code/modules/integrated_electronics/subtypes/power.dm index 466368b46e6a5..c33695b4a2eca 100644 --- a/code/modules/integrated_electronics/subtypes/power.dm +++ b/code/modules/integrated_electronics/subtypes/power.dm @@ -11,9 +11,9 @@ some power is lost due to ineffiency." w_class = 2 complexity = 16 - inputs = list("target ref") - outputs = list("target cell charge", "target cell max charge", "target cell percentage") - activators = list("transmit") + inputs = list("\ target") + outputs = list("\ target cell charge", "\ target cell max charge", "\ target cell percentage") + activators = list("\ transmit") spawn_flags = IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNETS = 3) power_draw_per_use = 500 // Inefficency has to come from somewhere. diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm index 67794a7f3f8b9..e3b69d31cd4f0 100644 --- a/code/modules/integrated_electronics/subtypes/reagents.dm +++ b/code/modules/integrated_electronics/subtypes/reagents.dm @@ -23,6 +23,7 @@ spawn_flags = IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 3) volume = 100 + power_draw_per_use = 20 /obj/item/integrated_circuit/reagent/smoke/do_work() playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3) @@ -42,38 +43,39 @@ flags = OPENCONTAINER complexity = 20 cooldown_per_use = 6 SECONDS - inputs = list("target ref", "injection amount" = 5) + inputs = list("\ target", "\ injection amount" = 5) outputs = list() - activators = list("inject") + activators = list("\ inject") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH volume = 30 + power_draw_per_use = 15 /obj/item/integrated_circuit/reagent/injector/proc/inject_amount() - var/datum/integrated_io/amount = inputs[2] - if(isnum(amount.data)) - return Clamp(amount.data, 0, 30) + var/amount = get_pin_data(IC_INPUT, 2) + if(isnum(amount)) + return Clamp(amount, 0, 30) /obj/item/integrated_circuit/reagent/injector/do_work() set waitfor = 0 // Don't sleep in a proc that is called by a processor without this set, otherwise it'll delay the entire thing - var/datum/integrated_io/target = inputs[1] - var/atom/movable/AM = target.data_as_type(/atom/movable) + var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) if(!istype(AM)) //Invalid input return if(!reagents.total_volume) // Empty return if(AM.can_be_injected_by(src)) if(isliving(AM)) + var/mob/living/L = AM var/turf/T = get_turf(AM) - T.visible_message("[src] is trying to inject [AM]!") + T.visible_message("[src] is trying to inject [L]!") sleep(3 SECONDS) - if(!AM.can_be_injected_by(src)) + if(!L.can_be_injected_by(src)) return var/contained = reagents.get_reagents() - var/trans = reagents.trans_to(target, inject_amount()) - message_admins("[src] injected \the [AM] with [trans]u of [contained].") + var/trans = reagents.trans_to_mob(L, inject_amount(), CHEM_BLOOD) + message_admins("[src] injected \the [L] with [trans]u of [contained].") to_chat(AM, "You feel a tiny prick!") - visible_message("[src] injects [AM]!") + visible_message("[src] injects [L]!") else reagents.trans_to(AM, inject_amount()) @@ -86,12 +88,13 @@ outside the machine if it is next to the machine. Note that this cannot be used on entities." flags = OPENCONTAINER complexity = 8 - inputs = list("source ref", "target ref", "injection amount" = 10) + inputs = list("\ source", "\ target", "\ injection amount" = 10) outputs = list() - activators = list("transfer reagents") + activators = list("\ transfer reagents", "\ on transfer") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) var/transfer_amount = 10 + power_draw_per_use = 10 /obj/item/integrated_circuit/reagent/pump/on_data_written() var/datum/integrated_io/amount = inputs[3] @@ -100,10 +103,9 @@ transfer_amount = amount.data /obj/item/integrated_circuit/reagent/pump/do_work() - var/datum/integrated_io/A = inputs[1] - var/datum/integrated_io/B = inputs[2] - var/atom/movable/source = A.data_as_type(/atom/movable) - var/atom/movable/target = B.data_as_type(/atom/movable) + var/atom/movable/source = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) + var/atom/movable/target = get_pin_data_as_type(IC_INPUT, 2, /atom/movable) + if(!istype(source) || !istype(target)) //Invalid input return var/turf/T = get_turf(src) @@ -114,10 +116,11 @@ return if(!source.is_open_container() || !target.is_open_container()) return - if(!source.reagents.get_free_space() || !target.reagents.get_free_space()) + if(!target.reagents.get_free_space()) return source.reagents.trans_to(target, transfer_amount) + activate_pin(2) /obj/item/integrated_circuit/reagent/storage name = "reagent storage" diff --git a/code/modules/integrated_electronics/subtypes/smart.dm b/code/modules/integrated_electronics/subtypes/smart.dm index c159522e9743a..a90a3f57a36a3 100644 --- a/code/modules/integrated_electronics/subtypes/smart.dm +++ b/code/modules/integrated_electronics/subtypes/smart.dm @@ -8,17 +8,16 @@ cannot see the target, it will not be able to calculate the correct direction." icon_state = "numberpad" complexity = 25 - inputs = list("target ref") - outputs = list("dir") - activators = list("calculate dir") + inputs = list("\ target") + outputs = list("\ dir") + activators = list("\ calculate dir", "\ on calculated") spawn_flags = IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 5) power_draw_per_use = 40 /obj/item/integrated_circuit/smart/basic_pathfinder/do_work() var/datum/integrated_io/I = inputs[1] - var/datum/integrated_io/O = outputs[1] - O.data = null + set_pin_data(IC_OUTPUT, 1, null) if(!isweakref(I.data)) return @@ -28,6 +27,6 @@ if(!(A in view(get_turf(src)))) return // Can't see the target. var/desired_dir = get_dir(get_turf(src), A) - if(desired_dir) - O.data = desired_dir - O.push_data() \ No newline at end of file + + set_pin_data(IC_OUTPUT, 1, desired_dir) + push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/subtypes/time.dm b/code/modules/integrated_electronics/subtypes/time.dm index db8fde4b10d40..55323dc8900c3 100644 --- a/code/modules/integrated_electronics/subtypes/time.dm +++ b/code/modules/integrated_electronics/subtypes/time.dm @@ -11,14 +11,14 @@ This circuit is set to send a pulse after a delay of two seconds." icon_state = "delay-20" var/delay = 2 SECONDS - activators = list("incoming pulse","outgoing pulse") + activators = list("\ incoming","\ outgoing") + power_draw_per_use = 2 /obj/item/integrated_circuit/time/delay/do_work() set waitfor = 0 // Don't sleep in a proc that is called by a processor. It'll delay the entire thing - var/datum/integrated_io/out_pulse = activators[2] sleep(delay) - out_pulse.push_data() + activate_pin(2) /obj/item/integrated_circuit/time/delay/five_sec name = "five-sec delay circuit" @@ -56,10 +56,9 @@ inputs = list("delay time") /obj/item/integrated_circuit/time/delay/custom/do_work() - var/datum/integrated_io/delay_input = inputs[1] - if(delay_input.data && isnum(delay_input.data) ) - var/new_delay = min(delay_input.data, 1) - new_delay = max(new_delay, 36000) //An hour. + var/delay_input = get_pin_data(IC_INPUT, 1) + if(delay_input && isnum(delay_input) ) + var/new_delay = between(1, delay_input, 36000) //An hour. delay = new_delay ..() @@ -72,8 +71,9 @@ var/ticks_to_pulse = 4 var/ticks_completed = 0 var/is_running = FALSE - inputs = list("enable ticking") - activators = list("outgoing pulse") + inputs = list("\ enable ticking" = 0) + activators = list("\ outgoing pulse") + power_draw_per_use = 4 /obj/item/integrated_circuit/time/ticker/Destroy() if(is_running) @@ -81,8 +81,8 @@ . = ..() /obj/item/integrated_circuit/time/ticker/on_data_written() - var/datum/integrated_io/do_tick = inputs[1] - if(do_tick.data && !is_running) + var/do_tick = get_pin_data(IC_INPUT, 1) + if(do_tick && !is_running) is_running = TRUE SSmachine.processing |= src else if(is_running) @@ -98,8 +98,7 @@ ticks_completed -= ticks_to_pulse else ticks_completed = 0 - var/datum/integrated_io/pulser = activators[1] - pulser.push_data() + activate_pin(1) /obj/item/integrated_circuit/time/ticker/fast name = "fast ticker" @@ -107,6 +106,7 @@ icon_state = "tick-f" complexity = 12 ticks_to_pulse = 2 + power_draw_per_use = 8 /obj/item/integrated_circuit/time/ticker/slow name = "slow ticker" @@ -114,24 +114,23 @@ icon_state = "tick-s" complexity = 4 ticks_to_pulse = 6 + power_draw_per_use = 2 /obj/item/integrated_circuit/time/clock name = "integrated clock" desc = "Tells you what the local time is, specific to your station or planet." icon_state = "clock" inputs = list() - outputs = list("time (string)", "hours (number)", "minutes (number)", "seconds (number)") + outputs = list("\ time", "\ hours", "\ minutes", "\ seconds") + activators = list("\ get time","\ on time got") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + power_draw_per_use = 4 /obj/item/integrated_circuit/time/clock/do_work() - var/datum/integrated_io/time = outputs[1] - var/datum/integrated_io/hour = outputs[2] - var/datum/integrated_io/min = outputs[3] - var/datum/integrated_io/sec = outputs[4] - - time.data = time2text(world.time, "hh:mm:ss") - hour.data = text2num(time2text(world.time, "hh")) - min.data = text2num(time2text(world.time, "mm")) - sec.data = text2num(time2text(world.time, "ss")) - - for(var/datum/integrated_io/output/O in outputs) - O.push_data() \ No newline at end of file + set_pin_data(IC_OUTPUT, 1, time2text(world.time, "hh:mm:ss") ) + set_pin_data(IC_OUTPUT, 2, text2num(time2text(world.time, "hh") ) ) + set_pin_data(IC_OUTPUT, 3, text2num(time2text(world.time, "mm") ) ) + set_pin_data(IC_OUTPUT, 4, text2num(time2text(world.time, "ss") ) ) + + push_data() + activate_pin(2) \ No newline at end of file diff --git a/code/modules/integrated_electronics/subtypes/trig.dm b/code/modules/integrated_electronics/subtypes/trig.dm index e8e2e09ca9eee..72d779b62189b 100644 --- a/code/modules/integrated_electronics/subtypes/trig.dm +++ b/code/modules/integrated_electronics/subtypes/trig.dm @@ -1,12 +1,22 @@ //These circuits do not-so-simple math. /obj/item/integrated_circuit/trig complexity = 1 - inputs = list("A","B","C","D","E","F","G","H") - outputs = list("result") - activators = list("compute") + inputs = list( + "\ A", + "\ B", + "\ C", + "\ D", + "\ E", + "\ F", + "\ G", + "\ H" + ) + outputs = list("\ result") + activators = list("\ compute", "\ on computed") category_text = "Trig" extended_desc = "Input and output are in degrees." autopulse = 1 + power_draw_per_use = 1 // Still cheap math. /obj/item/integrated_circuit/trig/on_data_written() if(autopulse == 1) @@ -18,19 +28,19 @@ name = "sin circuit" desc = "Has nothing to do with evil, unless you consider trigonometry to be evil. Outputs the sine of A." icon_state = "sine" - inputs = list("A") + inputs = list("\ A") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/trig/sine/do_work() + pull_data() var/result = null - var/datum/integrated_io/input/A = inputs[1] - A.pull_data() - if(isnum(A.data)) - result = sin(A.data) + var/A = get_pin_data(IC_INPUT, 1) + if(isnum(A)) + result = sin(A) - var/datum/integrated_io/output/O = outputs[1] - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // Cosine // @@ -38,19 +48,19 @@ name = "cos circuit" desc = "Outputs the cosine of A." icon_state = "cosine" - inputs = list("A") + inputs = list("\ A") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/trig/cosine/do_work() + pull_data() var/result = null - var/datum/integrated_io/input/A = inputs[1] - A.pull_data() - if(isnum(A.data)) - result = cos(A.data) + var/A = get_pin_data(IC_INPUT, 1) + if(isnum(A)) + result = cos(A) - var/datum/integrated_io/output/O = outputs[1] - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // Tangent // @@ -58,19 +68,19 @@ name = "tan circuit" desc = "Outputs the tangent of A. Guaranteed to not go on a tangent about its existance." icon_state = "tangent" - inputs = list("A") + inputs = list("\ A") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/trig/tangent/do_work() + pull_data() var/result = null - var/datum/integrated_io/input/A = inputs[1] - A.pull_data() - if(isnum(A.data)) - result = Tan(A.data) + var/A = get_pin_data(IC_INPUT, 1) + if(isnum(A)) + result = Tan(A) - var/datum/integrated_io/output/O = outputs[1] - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // Cosecant // @@ -78,19 +88,19 @@ name = "csc circuit" desc = "Outputs the cosecant of A." icon_state = "cosecant" - inputs = list("A") + inputs = list("\ A") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/trig/cosecant/do_work() + pull_data() var/result = null - var/datum/integrated_io/input/A = inputs[1] - A.pull_data() - if(isnum(A.data)) - result = Csc(A.data) + var/A = get_pin_data(IC_INPUT, 1) + if(isnum(A)) + result = Csc(A) - var/datum/integrated_io/output/O = outputs[1] - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // Secant // @@ -99,37 +109,37 @@ name = "sec circuit" desc = "Outputs the secant of A. Has nothing to do with the security department." icon_state = "secant" - inputs = list("A") + inputs = list("\ A") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/trig/secant/do_work() + pull_data() var/result = null - var/datum/integrated_io/input/A = inputs[1] - A.pull_data() - if(isnum(A.data)) - result = Sec(A.data) + var/A = get_pin_data(IC_INPUT, 1) + if(isnum(A)) + result = Sec(A) - var/datum/integrated_io/output/O = outputs[1] - O.data = result - O.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) // Cotangent // /obj/item/integrated_circuit/trig/cotangent name = "cot circuit" - desc = "Outputs the cotangent of A. Has nothing to do with the security department." + desc = "Outputs the cotangent of A." icon_state = "cotangent" - inputs = list("A") + inputs = list("\ A") spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/trig/cotangent/do_work() + pull_data() var/result = null - var/datum/integrated_io/input/A = inputs[1] - A.pull_data() - if(isnum(A.data)) - result = Cot(A.data) - - var/datum/integrated_io/output/O = outputs[1] - O.data = result - O.push_data() \ No newline at end of file + var/A = get_pin_data(IC_INPUT, 1) + if(isnum(A)) + result = Cot(A) + + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) \ No newline at end of file diff --git a/code/modules/integrated_electronics/~defines/~defines.dm b/code/modules/integrated_electronics/~defines/~defines.dm index 7aea6dabbb938..90aa05acf1938 100644 --- a/code/modules/integrated_electronics/~defines/~defines.dm +++ b/code/modules/integrated_electronics/~defines/~defines.dm @@ -3,4 +3,34 @@ #undef IC_ACTIVATOR #undef DATA_CHANNEL -#undef PULSE_CHANNEL \ No newline at end of file +#undef PULSE_CHANNEL + +#undef IC_SPAWN_DEFAULT +//#undef IC_SPAWN_RESEARCH // Research designs depend on this unfortunately. + +#undef IC_FORMAT_ANY +#undef IC_FORMAT_STRING +#undef IC_FORMAT_CHAR +#undef IC_FORMAT_COLOR +#undef IC_FORMAT_NUMBER +#undef IC_FORMAT_DIR +#undef IC_FORMAT_BOOLEAN +#undef IC_FORMAT_REF +#undef IC_FORMAT_LIST + +#undef IC_FORMAT_PULSE + +#undef IC_PINTYPE_ANY +#undef IC_PINTYPE_STRING +#undef IC_PINTYPE_CHAR +#undef IC_PINTYPE_COLOR +#undef IC_PINTYPE_NUMBER +#undef IC_PINTYPE_DIR +#undef IC_PINTYPE_BOOLEAN +#undef IC_PINTYPE_REF +#undef IC_PINTYPE_LIST + +#undef IC_PINTYPE_PULSE_IN +#undef IC_PINTYPE_PULSE_OUT + +#undef IC_MAX_LIST_LENGTH \ No newline at end of file From 7ad5c08acc38f9790a28258d3105b41d59de67d3 Mon Sep 17 00:00:00 2001 From: Stakks Date: Fri, 27 Apr 2018 10:48:53 -0500 Subject: [PATCH 8/9] Stage 8 --- .../items/weapons/implants/implantcircuits.dm | 1 + .../integrated_electronics/_defines.dm | 40 +- .../integrated_electronics/coordinate.dm | 4 +- .../integrated_electronics/core/assemblies.dm | 82 +++- .../integrated_electronics/core/device.dm | 84 ++++ .../integrated_electronics/core/helpers.dm | 36 +- .../core/integrated_circuit.dm | 249 +++++++--- .../integrated_electronics/core/pins.dm | 94 +++- .../integrated_electronics/core/printer.dm | 206 +++++++++ .../core/special_pins/boolean_pin.dm | 25 ++ .../core/special_pins/char_pin.dm | 27 ++ .../core/special_pins/color_pin.dm | 51 +++ .../core/special_pins/dir_pin.dm | 33 ++ .../core/special_pins/list_pin.dm | 150 +++++++ .../core/special_pins/number_pin.dm | 18 + .../core/special_pins/ref_pin.dm | 14 + .../core/special_pins/string_pin.dm | 29 ++ .../integrated_electronics/core/tools.dm | 111 ++++- .../subtypes/arithmetic.dm | 63 +-- .../subtypes/built_in.dm | 28 ++ .../subtypes/converters.dm | 145 ++++-- .../subtypes/data_transfer.dm | 113 +---- .../subtypes/{input_output.dm => input.dm} | 425 +++--------------- .../integrated_electronics/subtypes/lists.dm | 89 ++++ .../integrated_electronics/subtypes/logic.dm | 26 +- .../subtypes/manipulation.dm | 194 +++++--- .../integrated_electronics/subtypes/memory.dm | 90 ++-- .../integrated_electronics/subtypes/output.dm | 339 ++++++++++++++ .../integrated_electronics/subtypes/power.dm | 11 +- .../subtypes/reagents.dm | 31 +- .../integrated_electronics/subtypes/smart.dm | 6 +- .../integrated_electronics/subtypes/time.dm | 37 +- .../integrated_electronics/subtypes/trig.dm | 49 +- code/modules/research/designs.dm | 26 +- code/world.dm | 3 +- icons/obj/electronic_assemblies.dmi | Bin 32741 -> 35959 bytes sound/voice/medbot/mapple.ogg | Bin 0 -> 17269 bytes sound/voice/medbot/mcatch.ogg | Bin 0 -> 22994 bytes sound/voice/medbot/mcoming.ogg | Bin 0 -> 13341 bytes sound/voice/medbot/mdelicious.ogg | Bin 0 -> 7843 bytes sound/voice/medbot/mfeelbetter.ogg | Bin 0 -> 11877 bytes sound/voice/medbot/mflies.ogg | Bin 0 -> 29036 bytes sound/voice/medbot/mhelp.ogg | Bin 0 -> 10968 bytes sound/voice/medbot/minjured.ogg | Bin 0 -> 14977 bytes sound/voice/medbot/minsult.ogg | Bin 0 -> 90336 bytes sound/voice/medbot/mlive.ogg | Bin 0 -> 9075 bytes sound/voice/medbot/mlost.ogg | Bin 0 -> 26355 bytes sound/voice/medbot/mno.ogg | Bin 0 -> 10894 bytes sound/voice/medbot/mpatchedup.ogg | Bin 0 -> 8670 bytes sound/voice/medbot/mradar.ogg | Bin 0 -> 11177 bytes sound/voice/medbot/msurgeon.ogg | Bin 0 -> 23357 bytes tgstation.dme | 57 ++- 52 files changed, 2108 insertions(+), 878 deletions(-) create mode 100644 code/modules/integrated_electronics/core/device.dm create mode 100644 code/modules/integrated_electronics/core/printer.dm create mode 100644 code/modules/integrated_electronics/core/special_pins/boolean_pin.dm create mode 100644 code/modules/integrated_electronics/core/special_pins/char_pin.dm create mode 100644 code/modules/integrated_electronics/core/special_pins/color_pin.dm create mode 100644 code/modules/integrated_electronics/core/special_pins/dir_pin.dm create mode 100644 code/modules/integrated_electronics/core/special_pins/list_pin.dm create mode 100644 code/modules/integrated_electronics/core/special_pins/number_pin.dm create mode 100644 code/modules/integrated_electronics/core/special_pins/ref_pin.dm create mode 100644 code/modules/integrated_electronics/core/special_pins/string_pin.dm create mode 100644 code/modules/integrated_electronics/subtypes/built_in.dm rename code/modules/integrated_electronics/subtypes/{input_output.dm => input.dm} (50%) create mode 100644 code/modules/integrated_electronics/subtypes/lists.dm create mode 100644 code/modules/integrated_electronics/subtypes/output.dm create mode 100644 sound/voice/medbot/mapple.ogg create mode 100644 sound/voice/medbot/mcatch.ogg create mode 100644 sound/voice/medbot/mcoming.ogg create mode 100644 sound/voice/medbot/mdelicious.ogg create mode 100644 sound/voice/medbot/mfeelbetter.ogg create mode 100644 sound/voice/medbot/mflies.ogg create mode 100644 sound/voice/medbot/mhelp.ogg create mode 100644 sound/voice/medbot/minjured.ogg create mode 100644 sound/voice/medbot/minsult.ogg create mode 100644 sound/voice/medbot/mlive.ogg create mode 100644 sound/voice/medbot/mlost.ogg create mode 100644 sound/voice/medbot/mno.ogg create mode 100644 sound/voice/medbot/mpatchedup.ogg create mode 100644 sound/voice/medbot/mradar.ogg create mode 100644 sound/voice/medbot/msurgeon.ogg diff --git a/code/game/objects/items/weapons/implants/implantcircuits.dm b/code/game/objects/items/weapons/implants/implantcircuits.dm index d6930438599c9..0dc18fff7eac2 100644 --- a/code/game/objects/items/weapons/implants/implantcircuits.dm +++ b/code/game/objects/items/weapons/implants/implantcircuits.dm @@ -1,5 +1,6 @@ /obj/item/weapon/implant/integrated_circuit name = "electronic implant" + desc = "It's a case, for building very tiny electronics with." icon = 'icons/obj/electronic_assemblies.dmi' icon_state = "setup_implant" var/obj/item/device/electronic_assembly/implant/IC = null diff --git a/code/modules/integrated_electronics/_defines.dm b/code/modules/integrated_electronics/_defines.dm index 56617b014f8c8..52aeed3558c55 100644 --- a/code/modules/integrated_electronics/_defines.dm +++ b/code/modules/integrated_electronics/_defines.dm @@ -2,19 +2,44 @@ #define IC_OUTPUT "output" #define IC_ACTIVATOR "activator" +// Pin functionality. #define DATA_CHANNEL "data channel" #define PULSE_CHANNEL "pulse channel" -#define IC_SPAWN_DEFAULT 1 // If the circuit comes in the default circuit box. -#define IC_SPAWN_RESEARCH 2 // If the circuit design will be autogenerated for RnD. +// Methods of obtaining a circuit. +#define IC_SPAWN_DEFAULT 1 // If the circuit comes in the default circuit box and able to be printed in the IC printer. +#define IC_SPAWN_RESEARCH 2 // If the circuit design will be available in the IC printer after upgrading it. +// Displayed along with the pin name to show what type of pin it is. +#define IC_FORMAT_ANY "\" #define IC_FORMAT_STRING "\" +#define IC_FORMAT_CHAR "\" +#define IC_FORMAT_COLOR "\" #define IC_FORMAT_NUMBER "\" +#define IC_FORMAT_DIR "\" +#define IC_FORMAT_BOOLEAN "\" #define IC_FORMAT_REF "\" #define IC_FORMAT_LIST "\" #define IC_FORMAT_ANY "\" #define IC_FORMAT_PULSE "\" +// Used inside input/output list to tell the constructor what pin to make. +#define IC_PINTYPE_ANY /datum/integrated_io +#define IC_PINTYPE_STRING /datum/integrated_io/string +#define IC_PINTYPE_CHAR /datum/integrated_io/char +#define IC_PINTYPE_COLOR /datum/integrated_io/color +#define IC_PINTYPE_NUMBER /datum/integrated_io/number +#define IC_PINTYPE_DIR /datum/integrated_io/dir +#define IC_PINTYPE_BOOLEAN /datum/integrated_io/boolean +#define IC_PINTYPE_REF /datum/integrated_io/ref +#define IC_PINTYPE_LIST /datum/integrated_io/list + +#define IC_PINTYPE_PULSE_IN /datum/integrated_io/activate +#define IC_PINTYPE_PULSE_OUT /datum/integrated_io/activate/out + +// Data limits. +#define IC_MAX_LIST_LENGTH 200 + //Some colors #define COLOR_WHITE "#ffffff" @@ -52,6 +77,8 @@ #define COLOR_PURPLE_GRAY "#a2819e" #define COLOR_SUN "#ec8b2f" +var/global/list/alphabet_uppercase = list("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z") + var/list/all_integrated_circuits = list() /proc/initialize_integrated_circuits_list() @@ -67,16 +94,19 @@ var/list/all_integrated_circuits = list() var/obj/item/device/electronic_assembly/assembly = null // Reference to the assembly holding this circuit, if any. var/extended_desc = null var/list/inputs = list() + var/list/inputs_default = list() // Assoc list which will fill a pin with data upon creation. e.g. "2" = 0 will set input pin 2 to equal 0 instead of null. var/list/outputs = list() + var/list/outputs_default = list() // Ditto, for output. var/list/activators = list() var/next_use = 0 //Uses world.time var/complexity = 1 //This acts as a limitation on building machines, more resource-intensive components cost more 'space'. + var/size = null //This acts as a limitation on building machines, bigger components cost more 'space'. -1 for size 0 var/cooldown_per_use = 1 SECONDS // Circuits are limited in how many times they can be work()'d by this variable. var/power_draw_per_use = 0 // How much power is drawn when work()'d. var/power_draw_idle = 0 // How much power is drawn when doing nothing. var/spawn_flags = null // Used for world initializing, see the #defines above. var/category_text = "NO CATEGORY THIS IS A BUG" // To show up on circuit printer, and perhaps other places. - var/autopulse = -1 // When input is received, the circuit will pulse itself if set to 1. 0 means it won't. -1 means it is permanently off. var/removable = TRUE // Determines if a circuit is removable from the assembly. - - + var/displayed_name = "" + var/allow_multitool = 1 // Allows additional multitool functionality + // Used as a global var, (Do not set manually in children). diff --git a/code/modules/integrated_electronics/coordinate.dm b/code/modules/integrated_electronics/coordinate.dm index b97a1c1546938..732a97dd3b14c 100644 --- a/code/modules/integrated_electronics/coordinate.dm +++ b/code/modules/integrated_electronics/coordinate.dm @@ -21,7 +21,7 @@ result_x.data = T.x result_y.data = T.y - for(var/datum/integrated_io/output/O in outputs) + for(var/datum/integrated_io/O in outputs) O.push_data() /obj/item/integrated_circuit/abs_to_rel_coords @@ -46,5 +46,5 @@ result_x.data = x1.data - x2.data result_y.data = y1.data - y2.data - for(var/datum/integrated_io/output/O in outputs) + for(var/datum/integrated_io/O in outputs) O.push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index 49b153f585731..8f41daec1fa30 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -16,6 +16,7 @@ /obj/item/device/electronic_assembly/medium name = "electronic mechanism" icon_state = "setup_medium" + desc = "It's a case, for building medium-sized electronics with." w_class = 3 max_components = IC_COMPONENTS_BASE * 2 max_complexity = IC_COMPLEXITY_BASE * 2 @@ -23,6 +24,7 @@ /obj/item/device/electronic_assembly/large name = "electronic machine" icon_state = "setup_large" + desc = "It's a case, for building large electronics with." w_class = 4 max_components = IC_COMPONENTS_BASE * 4 max_complexity = IC_COMPLEXITY_BASE * 4 @@ -30,6 +32,7 @@ /obj/item/device/electronic_assembly/drone name = "electronic drone" icon_state = "setup_drone" + desc = "It's a case, for building mobile electronics with." w_class = 3 max_components = IC_COMPONENTS_BASE * 1.5 max_complexity = IC_COMPLEXITY_BASE * 1.5 @@ -37,6 +40,7 @@ /obj/item/device/electronic_assembly/implant name = "electronic implant" icon_state = "setup_implant" + desc = "It's a case, for building very tiny electronics with." w_class = 1 max_components = IC_COMPONENTS_BASE / 2 max_complexity = IC_COMPLEXITY_BASE / 2 @@ -45,11 +49,11 @@ /obj/item/device/electronic_assembly/New() ..() battery = new(src) - SSmachine.processing |= src + SSobj.processing |= src /obj/item/device/electronic_assembly/Destroy() battery = null - SSmachine.processing -= src + SSobj.processing -= src for(var/atom/movable/AM in contents) qdel(AM) ..() @@ -82,14 +86,19 @@ /obj/item/device/electronic_assembly/implant/resolve_nano_host() return implant -/obj/item/device/electronic_assembly/interact(mob/user) +/obj/item/device/electronic_assembly/proc/check_interactivity(mob/user) if(!CanInteract(user, src)) + return 0 + return 1 + +/obj/item/device/electronic_assembly/interact(mob/user) + if(!check_interactivity(user)) return var/total_parts = 0 var/total_complexity = 0 for(var/obj/item/integrated_circuit/part in contents) - total_parts++ + total_parts += part.size total_complexity = total_complexity + part.complexity var/HTML = list() @@ -103,14 +112,30 @@ else HTML += "No powercell detected!" HTML += "

" - HTML += "Components;
" + HTML += "Components:
" + HTML += "Built in:
" + + +//Put removable circuits in separate categories from non-removable + for(var/obj/item/integrated_circuit/circuit in contents) + if(!circuit.removable) + HTML += "[circuit.displayed_name] | " + HTML += "\[Rename\] | " + HTML += "\[Scan with Debugger\] | " + HTML += "\[Move to Bottom\]" + HTML += "
" + + HTML += "
" + HTML += "Removable:
" + for(var/obj/item/integrated_circuit/circuit in contents) - HTML += "[circuit.name] | " - HTML += "\[Rename\] | " - HTML += "\[Scan with Debugger\] | " if(circuit.removable) - HTML += "\[Remove\]" - HTML += "
" + HTML += "[circuit.displayed_name] | " + HTML += "\[Rename\] | " + HTML += "\[Scan with Debugger\] | " + HTML += "\[Remove\] | " + HTML += "\[Move to Bottom\]" + HTML += "
" HTML += "" user << browse(jointext(HTML,null), "window=assembly-\ref[src];size=600x350;border=1;can_resize=1;can_close=1;can_minimize=1") @@ -140,7 +165,7 @@ set desc = "Rename your circuit, useful to stay organized." var/mob/M = usr - if(!CanInteract(M, src)) + if(!check_interactivity(M)) return var/input = sanitize_text(input("What do you want to name this?", "Rename", src.name) as null|text, MAX_NAME_LEN) @@ -179,7 +204,7 @@ /obj/item/device/electronic_assembly/proc/get_part_size() . = 0 for(var/obj/item/integrated_circuit/part in contents) - . += part.w_class + . += part.size // Returns true if the circuit made it inside. /obj/item/device/electronic_assembly/proc/add_circuit(var/obj/item/integrated_circuit/IC, var/mob/user) @@ -194,7 +219,7 @@ var/total_part_size = get_part_size() var/total_complexity = get_part_complexity() - if((total_part_size + IC.w_class) > max_components) + if((total_part_size + IC.size) > max_components) to_chat(user, "You can't seem to add the '[IC.name]', as there's insufficient space.") return FALSE if((total_complexity + IC.complexity) > max_complexity) @@ -222,16 +247,18 @@ /obj/item/device/electronic_assembly/attackby(var/obj/item/I, var/mob/user) if(istype(I, /obj/item/integrated_circuit)) if(!user.unEquip(I)) - return 0 + return FALSE if(add_circuit(I, user)) to_chat(user, "You slide \the [I] inside \the [src].") playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) interact(user) + return TRUE else if(istype(I, /obj/item/weapon/crowbar)) playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1) opened = !opened user << "You [opened ? "opened" : "closed"] \the [src]." update_icon() + return TRUE else if(istype(I, /obj/item/device/integrated_electronics/wirer) || istype(I, /obj/item/device/integrated_electronics/debugger) || istype(I, /obj/item/weapon/screwdriver)) if(opened) interact(user) @@ -252,20 +279,38 @@ playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) to_chat(user, "You slot \the [cell] inside \the [src]'s power supplier.") interact(user) - + return TRUE else return ..() /obj/item/device/electronic_assembly/attack_self(mob/user) + if(!check_interactivity(user)) + return if(opened) interact(user) + var/list/input_selection = list() var/list/available_inputs = list() for(var/obj/item/integrated_circuit/input/input in contents) if(input.can_be_asked_input) available_inputs.Add(input) - var/obj/item/integrated_circuit/input/choice = input(user, "What do you want to interact with?", "Interaction") as null|anything in available_inputs - if(choice && CanInteract(user, src)) + var/i = 0 + for(var/obj/item/integrated_circuit/s in available_inputs) + if(s.name == input.name && s.displayed_name == input.displayed_name && s != input) + i++ + var/disp_name= "[input.displayed_name] \[[input.name]\]" + if(i) + disp_name += " ([i+1])" + input_selection.Add(disp_name) + + var/obj/item/integrated_circuit/input/choice + if(available_inputs) + var/selection = input(user, "What do you want to interact with?", "Interaction") as null|anything in input_selection + if(selection) + var/index = input_selection.Find(selection) + choice = available_inputs[index] + + if(choice) choice.ask_for_input(user) /obj/item/device/electronic_assembly/emp_act(severity) @@ -283,4 +328,5 @@ /obj/item/device/electronic_assembly/proc/give_power(amount) if(battery && battery.give(amount * CELLRATE)) return TRUE - return FALSE \ No newline at end of file + return FALSE + diff --git a/code/modules/integrated_electronics/core/device.dm b/code/modules/integrated_electronics/core/device.dm new file mode 100644 index 0000000000000..38044595b7b35 --- /dev/null +++ b/code/modules/integrated_electronics/core/device.dm @@ -0,0 +1,84 @@ +/obj/item/device/assembly/electronic_assembly + name = "electronic device" + desc = "It's a case for building electronics with. It can be attached to other small devices." + icon_state = "setup_device" + var/opened = 0 + + var/obj/item/device/electronic_assembly/device/EA + +/obj/item/device/assembly/electronic_assembly/New() + EA = new(src) + EA.holder = src + ..() + +/obj/item/device/assembly/electronic_assembly/attackby(obj/item/I as obj, mob/user as mob) + if (istype(I, /obj/item/weapon/crowbar)) + toggle_open(user) + else if (opened) + EA.attackby(I, user) + else + ..() + +/obj/item/device/assembly/electronic_assembly/proc/toggle_open(mob/user) + playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1) + opened = !opened + EA.opened = opened + to_chat(user, "You [opened ? "opened" : "closed"] \the [src].") + secured = 1 + update_icon() + +/obj/item/device/assembly/electronic_assembly/update_icon() + if(EA) + icon_state = initial(icon_state) + else + icon_state = initial(icon_state)+"0" + if(opened) + icon_state = icon_state + "-open" + +/obj/item/device/assembly/electronic_assembly/attack_self(mob/user as mob) + if(EA) + EA.attack_self(user) + +/obj/item/device/assembly/electronic_assembly/pulsed(var/radio = 0) //Called when another assembly acts on this one, var/radio will determine where it came from for wire calcs + if(EA) + for(var/obj/item/integrated_circuit/built_in/device_input/I in EA.contents) + I.do_work() + return + +/obj/item/device/assembly/electronic_assembly/examine(mob/user) + .=..(user, 1) + if(EA) + for(var/obj/item/integrated_circuit/IC in EA.contents) + IC.external_examine(user) + +/obj/item/device/assembly/electronic_assembly/verb/toggle() + set src in usr + set category = "Object" + set name = "Open/Close Device Assembly" + set desc = "Open or close device assembly!" + + toggle_open(usr) + + +/obj/item/device/electronic_assembly/device + name = "electronic device" + icon_state = "setup_device" + desc = "It's a tiny electronic device with specific use for attaching to other devices." + var/obj/item/device/assembly/electronic_assembly/holder + w_class = 1 + max_components = IC_COMPONENTS_BASE * 3/4 + max_complexity = IC_COMPLEXITY_BASE * 3/4 + + +/obj/item/device/electronic_assembly/device/New() + ..() + var/obj/item/integrated_circuit/built_in/device_input/input = new(src) + var/obj/item/integrated_circuit/built_in/device_output/output = new(src) + input.assembly = src + output.assembly = src + +/obj/item/device/electronic_assembly/device/check_interactivity(mob/user) + if(!CanInteract(user,src)) + return 0 + return 1 + diff --git a/code/modules/integrated_electronics/core/helpers.dm b/code/modules/integrated_electronics/core/helpers.dm index c946a29e47c45..a0f60b6390eb0 100644 --- a/code/modules/integrated_electronics/core/helpers.dm +++ b/code/modules/integrated_electronics/core/helpers.dm @@ -1,8 +1,22 @@ -/obj/item/integrated_circuit/proc/setup_io(var/list/io_list, var/io_type) +/obj/item/integrated_circuit/proc/setup_io(var/list/io_list, var/io_type, var/list/io_default_list) var/list/io_list_copy = io_list.Copy() io_list.Cut() + var/i = 0 for(var/io_entry in io_list_copy) - io_list.Add(new io_type(src, io_entry, io_list_copy[io_entry])) + var/default_data = null + var/io_type_override = null + // Override the default data. + if(io_default_list && io_default_list.len) // List containing special pin types that need to be added. + default_data = io_default_list["[i]"] // This is deliberately text because the index is a number in text form. + // Override the pin type. + if(io_list_copy[io_entry]) + io_type_override = io_list_copy[io_entry] + + if(io_type_override) + // world << "io_type_override is now [io_type_override] on [src]." + io_list.Add(new io_type_override(src, io_entry, default_data)) + else + io_list.Add(new io_type(src, io_entry, default_data)) /obj/item/integrated_circuit/proc/set_pin_data(var/pin_type, var/pin_number, var/new_data) var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number) @@ -43,6 +57,19 @@ return activators[pin_number] return null +/obj/item/integrated_circuit/proc/handle_wire(var/datum/integrated_io/pin, var/obj/item/device/integrated_electronics/tool) + if(istype(tool, /obj/item/device/integrated_electronics/wirer)) + var/obj/item/device/integrated_electronics/wirer/wirer = tool + if(pin) + wirer.wire(pin, usr) + return 1 + + else if(istype(tool, /obj/item/device/integrated_electronics/debugger)) + var/obj/item/device/integrated_electronics/debugger/debugger = tool + if(pin) + debugger.write_data(pin, usr) + return 1 + return 0 /mob/living/proc/isSynthetic() return 0 @@ -52,4 +79,7 @@ for(var/obj/item/organ/limb/E in organsystem) if(E.organtype < ORGAN_ROBOTIC) return FALSE - return TRUE \ No newline at end of file + return TRUE + +/proc/get_random_colour() + return pick(list("FF0000", "FF7F00", "FFFF00", "00FF00", "0000FF", "4B0082", "8F00FF")) \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/integrated_circuit.dm b/code/modules/integrated_electronics/core/integrated_circuit.dm index f87a19e00422f..1be2a0af8657c 100644 --- a/code/modules/integrated_electronics/core/integrated_circuit.dm +++ b/code/modules/integrated_electronics/core/integrated_circuit.dm @@ -4,17 +4,17 @@ a creative player the means to solve many problems. Circuits are held inside an */ /obj/item/integrated_circuit/examine(mob/user) - . = ..() - external_examine(user) interact(user) + external_examine(user) + . = ..() // This should be used when someone is examining while the case is opened. /obj/item/integrated_circuit/proc/internal_examine(mob/user) to_chat(user, "This board has [inputs.len] input pin\s, [outputs.len] output pin\s and [activators.len] activation pin\s.") - for(var/datum/integrated_io/input/I in inputs) + for(var/datum/integrated_io/I in inputs) if(I.linked.len) to_chat(user, "The '[I]' is connected to [I.get_linked_to_desc()].") - for(var/datum/integrated_io/output/O in outputs) + for(var/datum/integrated_io/O in outputs) if(O.linked.len) to_chat(user, "The '[O]' is connected to [O.get_linked_to_desc()].") for(var/datum/integrated_io/activate/A in activators) @@ -31,8 +31,11 @@ a creative player the means to solve many problems. Circuits are held inside an return /obj/item/integrated_circuit/New() - setup_io(inputs, /datum/integrated_io/input) - setup_io(outputs, /datum/integrated_io/output) + displayed_name = name + if(!size) size = w_class + if(size == -1) size = 0 + setup_io(inputs, /datum/integrated_io, inputs_default) + setup_io(outputs, /datum/integrated_io, outputs_default) setup_io(activators, /datum/integrated_io/activate) ..() @@ -58,23 +61,32 @@ a creative player the means to solve many problems. Circuits are held inside an for(var/datum/integrated_io/io in inputs + outputs + activators) io.scramble() +/obj/item/integrated_circuit/proc/check_interactivity(mob/user) + if(assembly) + return assembly.check_interactivity(user) + else if(!CanInteract(user, src)) + return 0 + return 1 + /obj/item/integrated_circuit/verb/rename_component() set name = "Rename Circuit" set category = "Object" set desc = "Rename your circuit, useful to stay organized." var/mob/M = usr - if(!CanInteract(M, src)) + if(!check_interactivity(M)) return var/input = sanitize_text(input("What do you want to name the circuit?", "Rename", src.name) as null|text, MAX_NAME_LEN) - if(src && input && CanInteract(M, src)) + if(src && input && assembly.check_interactivity(M)) to_chat(M, "The circuit '[src.name]' is now labeled '[input]'.") - name = input + displayed_name = input /obj/item/integrated_circuit/interact(mob/user) - if(!CanInteract(user, src)) + if(!check_interactivity(user)) return +// if(!assembly) +// return var/window_height = 350 var/window_width = 600 @@ -85,14 +97,17 @@ a creative player the means to solve many problems. Circuits are held inside an var/table_middle_width = "40%" var/HTML = list() - HTML += "[src.name]" + HTML += "[src.displayed_name]" HTML += "
" - HTML += "" + HTML += "
" + + HTML += "
\[Return to Assembly\]" HTML += "
\[Refresh\] | " HTML += "\[Rename\] | " - HTML += "\[Scan with Debugger\] | " - HTML += "\[Remove\]
" + HTML += "\[Scan with Device\] | " + if(src.removable) + HTML += "\[Remove\]
" HTML += "" HTML += "" @@ -113,37 +128,31 @@ a creative player the means to solve many problems. Circuits are held inside an if(1) io = get_pin_ref(IC_INPUT, i) if(io) + words += "[io.display_pin_type()] [io.name] [io.display_data(io.data)]
" if(io.linked.len) - words += "[io.name] [io.display_data()]
" - for(var/datum/integrated_io/linked in io.linked) - words += "\[[linked.name]\] \ - @ [linked.holder]
" - else - words += "[io.name] [io.display_data()]
" for(var/datum/integrated_io/linked in io.linked) - words += "\[[linked.name]\] \ - @ [linked.holder]
" +// words += "\[[linked.name]\] + words += "[linked.name] \ + @ [linked.holder.displayed_name]
" + if(outputs.len > inputs.len) height = 1 if(2) if(i == 1) - words += "[src.name]

[src.desc]" + words += "[src.displayed_name]
[src.name != src.displayed_name ? "([src.name])":""]
[src.desc]" height = row_height else continue if(3) io = get_pin_ref(IC_OUTPUT, i) if(io) + words += "[io.display_pin_type()] [io.name] [io.display_data(io.data)]
" if(io.linked.len) - words += "[io.name] [io.display_data()]
" - for(var/datum/integrated_io/linked in io.linked) - words += "\[[linked.name]\] \ - @ [linked.holder]
" - else - words += "[io.name] [io.display_data()]
" for(var/datum/integrated_io/linked in io.linked) - words += "\[[linked.name]\] \ - @ [linked.holder]
" +// words += "\[[linked.name]\] + words += "[linked.name] \ + @ [linked.holder.displayed_name]
" + if(inputs.len > outputs.len) height = 1 HTML += "" @@ -152,16 +161,14 @@ a creative player the means to solve many problems. Circuits are held inside an for(var/activator in activators) var/datum/integrated_io/io = activator var/words = list() + + words += "[io.name] [io.data?"\":"\"]
" if(io.linked.len) - words += "[io.name]
" - for(var/datum/integrated_io/linked in io.linked) - words += "\[[linked.name]\] \ - @ [linked.holder]
" - else - words += "[io.name]
" for(var/datum/integrated_io/linked in io.linked) - words += "\[[linked.name]\] \ - @ [linked.holder]
" +// words += "\[[linked.name]\] + words += "[linked.name] \ + @ [linked.holder.displayed_name]
" + HTML += "" HTML += "" HTML += "" @@ -169,10 +176,8 @@ a creative player the means to solve many problems. Circuits are held inside an HTML += "
[jointext(words, null)]
[jointext(words, null)]
" HTML += "
" - if(autopulse != -1) - HTML += "
Meta Variables;" - HTML += "
\[Autopulse\] = [autopulse ? "ON" : "OFF"]" - HTML += "
" +// HTML += "
Meta Variables;" // If more meta vars get introduced, uncomment this. +// HTML += "
" HTML += "
Complexity: [complexity]" if(power_draw_idle) @@ -182,20 +187,95 @@ a creative player the means to solve many problems. Circuits are held inside an HTML += "
[extended_desc]" HTML += "" - user << browse(jointext(HTML, null), "window=circuit-\ref[src];size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1") + if(src.assembly) + user << browse(jointext(HTML, null), "window=assembly-\ref[src.assembly];size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1") + else + user << browse(jointext(HTML, null), "window=circuit-\ref[src];size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1") - onclose(user, "circuit-\ref[src]") + onclose(user, "assembly-\ref[src.assembly]") /obj/item/integrated_circuit/Topic(href, href_list) + if(!check_interactivity(usr)) + return if(..()) return 1 - var/pin = locate(href_list["pin"]) in inputs + outputs + activators + + var/update = 1 + var/obj/item/device/electronic_assembly/A = src.assembly + var/update_to_assembly = 0 + var/datum/integrated_io/pin = locate(href_list["pin"]) in inputs + outputs + activators + var/datum/integrated_io/linked = null + if(href_list["link"]) + linked = locate(href_list["link"]) in pin.linked var/obj/held_item = usr.get_active_hand() + + if(href_list["rename"]) + rename_component(usr) + if(href_list["from_assembly"]) + update = 0 + var/obj/item/device/electronic_assembly/ea = loc + if(istype(ea)) + ea.interact(usr) + + if(href_list["pin_name"]) + if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool) + href_list["wire"] = 1 + else + var/obj/item/device/multitool/M = held_item + M.wire(pin,usr) + + + + if(href_list["pin_data"]) + if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool) + href_list["wire"] = 1 + + else + var/datum/integrated_io/io = pin + io.ask_for_pin_data(usr) // The pins themselves will determine how to ask for data, and will validate the data. + /* + if(io.io_type == DATA_CHANNEL) + + var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number", "null") + if(!check_interactivity(usr)) + return + + var/new_data = null + switch(type_to_use) + if("string") + new_data = input("Now type in a string.","[src] string writing") as null|text + to_chat(usr, "You input [new_data] into the pin.") + //to_chat(user, "You write '[new_data]' to the '[io]' pin of \the [io.holder].") + if("number") + new_data = input("Now type in a number.","[src] number writing") as null|num + if(isnum(new_data) && check_interactivity(usr) ) + to_chat(usr, "You input [new_data] into the pin.") + if("null") + if(check_interactivity(usr)) + to_chat(usr, "You clear the pin's memory.") + + io.write_data_to_pin(new_data) + + else if(io.io_type == PULSE_CHANNEL) + io.holder.check_then_do_work(ignore_power = TRUE) + to_chat(usr, "You pulse \the [io.holder]'s [io] pin.") + */ + + + if(href_list["pin_unwire"]) + if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool) + href_list["wire"] = 1 + else + var/obj/item/device/multitool/M = held_item + M.unwire(pin, linked, usr) + if(href_list["wire"]) if(istype(held_item, /obj/item/device/integrated_electronics/wirer)) var/obj/item/device/integrated_electronics/wirer/wirer = held_item - if(pin) + if(linked) + wirer.wire(linked, usr) + else if(pin) wirer.wire(pin, usr) else if(istype(held_item, /obj/item/device/integrated_electronics/debugger)) @@ -206,10 +286,23 @@ a creative player the means to solve many problems. Circuits are held inside an to_chat(usr, "You can't do a whole lot without the proper tools.") if(href_list["examine"]) - examine(usr) - - if(href_list["rename"]) - rename_component(usr) + var/obj/item/integrated_circuit/examined + if(href_list["examined"]) + examined = href_list["examined"] + else + examined = src + examined.interact(usr) + update = 0 + + if(href_list["bottom"]) + var/obj/item/integrated_circuit/circuit = locate(href_list["bottom"]) in src.assembly.contents + var/assy = circuit.assembly + if(!circuit) + return + circuit.loc = null + circuit.loc = assy + . = 1 + update_to_assembly = 1 if(href_list["scan"]) if(istype(held_item, /obj/item/device/integrated_electronics/debugger)) @@ -219,38 +312,50 @@ a creative player the means to solve many problems. Circuits are held inside an else to_chat(usr, "The Debugger's 'ref scanner' needs to be on.") else - to_chat(usr, "You need a Debugger set to 'ref' mode to do that.") + to_chat(usr, "You need a multitool/debugger set to 'ref' mode to do that.") + + if(href_list["return"]) + if(A) + update_to_assembly = 1 + usr << browse(null, "window=circuit-\ref[src];border=1;can_resize=1;can_close=1;can_minimize=1") + else + to_chat(usr, "This circuit is not in an assembly!") - if(href_list["autopulse"]) - if(autopulse != -1) - autopulse = !autopulse if(href_list["remove"]) - if(istype(held_item, /obj/item/weapon/screwdriver)) - if(!removable) - to_chat(usr, "\The [src] seems to be permanently attached to the case.") - return - disconnect_all() - var/turf/T = get_turf(src) - forceMove(T) - assembly = null - playsound(T, 'sound/items/Crowbar.ogg', 50, 1) - to_chat(usr, "You pop \the [src] out of the case, and slide it out.") - else - to_chat(usr, "You need a screwdriver to remove components.") + if(!A) + to_chat(usr, "This circuit is not in an assembly!") + return + if(!removable) + to_chat(usr, "\The [src] seems to be permanently attached to the case.") + return var/obj/item/device/electronic_assembly/ea = loc + disconnect_all() + var/turf/T = get_turf(src) + forceMove(T) + assembly = null + playsound(T, 'sound/items/Crowbar.ogg', 50, 1) + to_chat(usr, "You pop \the [src] out of the case, and slide it out.") + if(istype(ea)) ea.interact(usr) + update = 0 return - interact(usr) // To refresh the UI. + if(update) + if(A && istype(A) && update_to_assembly) + A.interact(usr) + else + interact(usr) // To refresh the UI. + + /obj/item/integrated_circuit/proc/push_data() - for(var/datum/integrated_io/output/O in outputs) + for(var/datum/integrated_io/O in outputs) O.push_data() /obj/item/integrated_circuit/proc/pull_data() - for(var/datum/integrated_io/input/I in inputs) + for(var/datum/integrated_io/I in inputs) I.push_data() /obj/item/integrated_circuit/proc/draw_idle_power() @@ -283,9 +388,9 @@ a creative player the means to solve many problems. Circuits are held inside an return /obj/item/integrated_circuit/proc/disconnect_all() - for(var/datum/integrated_io/input/I in inputs) + for(var/datum/integrated_io/I in inputs) I.disconnect() - for(var/datum/integrated_io/output/O in outputs) + for(var/datum/integrated_io/O in outputs) O.disconnect() for(var/datum/integrated_io/activate/A in activators) A.disconnect() diff --git a/code/modules/integrated_electronics/core/pins.dm b/code/modules/integrated_electronics/core/pins.dm index 9e2d0a4d06fe6..98b013eddd19d 100644 --- a/code/modules/integrated_electronics/core/pins.dm +++ b/code/modules/integrated_electronics/core/pins.dm @@ -25,10 +25,11 @@ D [1]/ || var/list/linked = list() var/io_type = DATA_CHANNEL -/datum/integrated_io/New(var/newloc, var/name, var/data) +/datum/integrated_io/New(var/newloc, var/name, var/new_data) ..() src.name = name - src.data = data + if(new_data) + src.data = new_data holder = newloc if(!istype(holder)) message_admins("ERROR: An integrated_io ([src.name]) spawned without a valid holder! This is a bug.") @@ -50,17 +51,43 @@ D [1]/ || var/output = w.resolve() return istype(output, as_type) ? output : null -/datum/integrated_io/proc/display_data() - if(isnull(data)) +/datum/integrated_io/proc/display_data(var/input) + if(isnull(input)) return "(null)" // Empty data means nothing to show. - if(istext(data)) - return "(\"[data]\")" // Wraps the 'string' in escaped quotes, so that people know it's a 'string'. - if(isweakref(data)) - var/weakref/w = data + + if(istext(input)) + return "(\"[input]\")" // Wraps the 'string' in escaped quotes, so that people know it's a 'string'. + +/* +list[]( + "A", + "B", + "C" +) +*/ + + if(islist(input)) + var/list/my_list = input + var/result = "list\[[my_list.len]\](" + if(my_list.len) + result += "
" + var/pos = 0 + for(var/line in my_list) + result += "[display_data(line)]" + pos++ + if(pos != my_list.len) + result += ",
" + result += "
" + result += ")" + return result + + if(isweakref(input)) + var/weakref/w = input var/atom/A = w.resolve() //return A ? "([A.name] \[Ref\])" : "(null)" // For refs, we want just the name displayed. return A ? "(\ref[A] \[Ref\])" : "(null)" - return "([data])" // Nothing special needed for numbers or other stuff. + + return "([input])" // Nothing special needed for numbers or other stuff. /datum/integrated_io/activate/display_data() return "(\[pulse\])" @@ -117,23 +144,44 @@ D [1]/ || //Now that we're removed from them, we gotta remove them from us. src.linked.Remove(their_io) -/datum/integrated_io/input - name = "input pin" +/datum/integrated_io/proc/ask_for_data_type(mob/user, var/default, var/list/allowed_data_types = list("string","number","null")) + var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in allowed_data_types + if(!holder.check_interactivity(user)) + return -/datum/integrated_io/output - name = "output pin" + var/new_data = null + switch(type_to_use) + if("string") + new_data = input("Now type in a string.","[src] string writing", istext(default) ? default : null) as null|text + if(istext(new_data) && holder.check_interactivity(user) ) + to_chat(user, "You input [new_data] into the pin.") + return new_data + if("number") + new_data = input("Now type in a number.","[src] number writing", isnum(default) ? default : null) as null|num + if(isnum(new_data) && holder.check_interactivity(user) ) + to_chat(user, "You input [new_data] into the pin.") + return new_data + if("null") + if(holder.check_interactivity(user)) + to_chat(user, "You clear the pin's memory.") + return new_data + +// Basically a null check +/datum/integrated_io/proc/is_valid() + return !isnull(data) + +// This proc asks for the data to write, then writes it. +/datum/integrated_io/proc/ask_for_pin_data(mob/user) + var/new_data = ask_for_data_type(user) + 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) + to_chat(user, "You pulse \the [holder]'s [src] pin.") /datum/integrated_io/activate name = "activation pin" io_type = PULSE_CHANNEL -/datum/integrated_io/list - name = "list pin" - -/datum/integrated_io/list/write_data_to_pin(var/new_data) - if(islist(new_data)) - data = new_data - holder.on_data_written() - -/datum/integrated_io/list/display_pin_type() - return IC_FORMAT_LIST \ No newline at end of file +/datum/integrated_io/activate/out // All this does is just make the UI say 'out' instead of 'in' + data = 1 diff --git a/code/modules/integrated_electronics/core/printer.dm b/code/modules/integrated_electronics/core/printer.dm new file mode 100644 index 0000000000000..f850955259a16 --- /dev/null +++ b/code/modules/integrated_electronics/core/printer.dm @@ -0,0 +1,206 @@ + +/obj/item/device/integrated_circuit_printer + name = "integrated circuit printer" + desc = "A portable(ish) machine made to print tiny modular circuitry out of metal." + icon = 'icons/obj/electronic_assemblies.dmi' + icon_state = "circuit_printer" + w_class = 4 + var/metal = 0 + var/max_metal = 100 + var/metal_per_sheet = 10 // One sheet equals this much metal. + + var/upgraded = FALSE // When hit with an upgrade disk, will turn true, allowing it to print the higher tier circuits. + var/can_clone = FALSE // Same for above, but will allow the printer to duplicate a specific assembly. + var/static/list/recipe_list = list() + var/current_category = null + var/obj/item/device/electronic_assembly/assembly_to_clone = null + initialize() + +/obj/item/device/integrated_circuit_printer/upgraded + upgraded = TRUE + can_clone = TRUE + +/obj/item/device/integrated_circuit_printer/New() + ..() + initialize() + +/obj/item/device/integrated_circuit_printer/initialize() + ..() + if(!recipe_list.len) + // Unfortunately this needed a lot of loops, but it should only be run once at init. + + // First loop is to seperate the actual circuits from base circuits. + var/list/circuits_to_use = list() + for(var/obj/item/integrated_circuit/IC in all_integrated_circuits) + if((IC.spawn_flags & IC_SPAWN_DEFAULT) || (IC.spawn_flags & IC_SPAWN_RESEARCH)) + circuits_to_use.Add(IC) + + // Second loop is to find all categories. + var/list/found_categories = list() + for(var/obj/item/integrated_circuit/IC in circuits_to_use) + if(!(IC.category_text in found_categories)) + found_categories.Add(IC.category_text) + + // Third loop is to initialize lists by category names, then put circuits matching the category inside. + for(var/category in found_categories) + recipe_list[category] = list() + var/list/current_list = recipe_list[category] + for(var/obj/item/integrated_circuit/IC in circuits_to_use) + if(IC.category_text == category) + current_list.Add(IC) + + // Now for non-circuit things. + var/list/assembly_list = list() + assembly_list.Add( + new /obj/item/device/electronic_assembly(null), + new /obj/item/device/electronic_assembly/medium(null), + new /obj/item/device/electronic_assembly/large(null), + new /obj/item/device/electronic_assembly/drone(null), + new /obj/item/weapon/implant/integrated_circuit(null), + new /obj/item/device/assembly/electronic_assembly(null) + ) + recipe_list["Assemblies"] = assembly_list + + var/list/tools_list = list() + tools_list.Add( + new /obj/item/device/integrated_electronics/wirer(null), + new /obj/item/device/integrated_electronics/debugger(null) + ) + recipe_list["Tools"] = tools_list + + +/obj/item/device/integrated_circuit_printer/attackby(var/obj/item/O, var/mob/user) + if(istype(O,/obj/item/stack/sheet/metal)) + var/obj/item/stack/sheet/metal/stack = O + var/num = min((max_metal - metal) / metal_per_sheet, stack.amount) + if(num < 1) + to_chat(user, "\The [src] is too full to add more metal.") + return + if(stack.amount >= num) + stack.amount -= num + to_chat(user, "You add [num] sheet\s to \the [src].") + metal += num * metal_per_sheet + interact(user) + return TRUE + + if(istype(O,/obj/item/integrated_circuit)) + to_chat(user, "You insert the circuit into \the [src]. ") + user.unEquip(O) + metal = min(metal + O.w_class, max_metal) + qdel(O) + interact(user) + return TRUE + + if(istype(O,/obj/item/weapon/disk/integrated_circuit/upgrade/advanced)) + if(upgraded) + to_chat(user, "\The [src] already has this upgrade. ") + return TRUE + to_chat(user, "You install \the [O] into \the [src]. ") + upgraded = TRUE + interact(user) + return TRUE + + if(istype(O,/obj/item/weapon/disk/integrated_circuit/upgrade/clone)) + if(can_clone) + to_chat(user, "\The [src] already has this upgrade. ") + return TRUE + to_chat(user, "You install \the [O] into \the [src]. ") + can_clone = TRUE + interact(user) + return TRUE + + return ..() + +/obj/item/device/integrated_circuit_printer/attack_self(var/mob/user) + interact(user) + +/obj/item/device/integrated_circuit_printer/interact(mob/user) + var/window_height = 600 + var/window_width = 500 + + if(isnull(current_category)) + current_category = recipe_list[1] + + var/HTML = list() + + HTML += "

Integrated Circuit Printer


" + HTML += "Metal: [metal/metal_per_sheet]/[max_metal/metal_per_sheet] sheets.
" + HTML += "Circuits available: [upgraded ? "Regular":"Advanced"]." + HTML += "Assembly Cloning: [can_clone ? "Available": "Unavailable"]." + if(assembly_to_clone) + HTML += "Assembly '[assembly_to_clone.name]' loaded." + HTML += "Crossed out circuits mean that the printer is not sufficentally upgraded to create that circuit.
" + HTML += "
" + HTML += "Categories:" + for(var/category in recipe_list) + if(category != current_category) + HTML += " \[[category]\] " + else // Bold the button if it's already selected. + HTML += " \[[category]\] " + HTML += "
" + HTML += "

[current_category]

" + + var/list/current_list = recipe_list[current_category] + for(var/obj/O in current_list) + var/can_build = TRUE + if(istype(O, /obj/item/integrated_circuit)) + var/obj/item/integrated_circuit/IC = O + if((IC.spawn_flags & IC_SPAWN_RESEARCH) && (!(IC.spawn_flags & IC_SPAWN_DEFAULT)) && !upgraded) + can_build = FALSE + if(can_build) + HTML += "\[[O.name]\]: [O.desc]
" + else + HTML += "\[[O.name]\]: [O.desc]
" + + user << browse(jointext(HTML, null), "window=integrated_printer;size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1") + +/obj/item/device/integrated_circuit_printer/Topic(href, href_list) + if(..()) + return 1 + + add_fingerprint(usr) + + if(href_list["category"]) + current_category = href_list["category"] + + if(href_list["build"]) + var/build_type = text2path(href_list["build"]) + if(!build_type || !ispath(build_type)) + return 1 + + var/cost = 1 + if(ispath(build_type, /obj/item/device/electronic_assembly)) + var/obj/item/device/electronic_assembly/E = build_type + cost = round( (initial(E.max_complexity) + initial(E.max_components) ) / 4) + else if(ispath(build_type, /obj/item/integrated_circuit)) + var/obj/item/integrated_circuit/IC = build_type + cost = initial(IC.w_class) + + if(metal - cost < 0) + to_chat(usr, "You need [cost] metal to build that!.") + return 1 + metal -= cost + new build_type(get_turf(loc)) + + interact(usr) + +// FUKKEN UPGRADE DISKS +/obj/item/weapon/disk/integrated_circuit/upgrade + name = "integrated circuit printer upgrade disk" + desc = "Install this into your integrated circuit printer to enhance it." + icon = 'icons/obj/electronic_assemblies.dmi' + icon_state = "upgrade_disk" + item_state = "card-id" + w_class = 2 + origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 4) + +/obj/item/weapon/disk/integrated_circuit/upgrade/advanced + name = "integrated circuit printer upgrade disk - advanced designs" + desc = "Install this into your integrated circuit printer to enhance it. This one adds new, advanced designs to the printer." + +// To be implemented later. +/obj/item/weapon/disk/integrated_circuit/upgrade/clone + name = "integrated circuit printer upgrade disk - circuit cloner" + desc = "Install this into your integrated circuit printer to enhance it. This one allows the printer to duplicate assemblies." + icon_state = "upgrade_disk_clone" + origin_tech = list(TECH_ENGINEERING = 5, TECH_DATA = 6) \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/special_pins/boolean_pin.dm b/code/modules/integrated_electronics/core/special_pins/boolean_pin.dm new file mode 100644 index 0000000000000..baf3d029daebf --- /dev/null +++ b/code/modules/integrated_electronics/core/special_pins/boolean_pin.dm @@ -0,0 +1,25 @@ +// These pins only contain 0 or 1. Null is not allowed. +/datum/integrated_io/boolean + name = "boolean pin" + data = FALSE + +/datum/integrated_io/boolean/ask_for_pin_data(mob/user) // 'Ask' is a bit misleading, acts more like a toggle. + var/new_data = !data + write_data_to_pin(new_data) + +/datum/integrated_io/boolean/write_data_to_pin(var/new_data) + if(new_data == FALSE || new_data == TRUE) + data = new_data + holder.on_data_written() + +/datum/integrated_io/boolean/scramble() + write_data_to_pin(rand(FALSE,TRUE)) + push_data() + +/datum/integrated_io/boolean/display_pin_type() + return IC_FORMAT_BOOLEAN + +/datum/integrated_io/boolean/display_data(var/input) + if(data == TRUE) + return "(True)" + return "(False)" \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/special_pins/char_pin.dm b/code/modules/integrated_electronics/core/special_pins/char_pin.dm new file mode 100644 index 0000000000000..bd36d18495ec3 --- /dev/null +++ b/code/modules/integrated_electronics/core/special_pins/char_pin.dm @@ -0,0 +1,27 @@ +// These pins can only contain a 1 character string or null. +/datum/integrated_io/char + name = "char pin" + +/datum/integrated_io/char/ask_for_pin_data(mob/user) + var/new_data = input("Please type in one character.","[src] char writing") as null|text + if(holder.check_interactivity(user) ) + to_chat(user, "You input [new_data ? "new_data" : "NULL"] into the pin.") + write_data_to_pin(new_data) + +/datum/integrated_io/char/write_data_to_pin(var/new_data) + if(isnull(new_data) || istext(new_data)) + if(length(new_data) > 1) + return + data = new_data + holder.on_data_written() + +// This makes the text go from "A" to "%". +/datum/integrated_io/char/scramble() + if(!is_valid()) + return + var/list/options = list("!","@","#","$","%","^","&","*") + alphabet_uppercase + data = pick(options) + push_data() + +/datum/integrated_io/char/display_pin_type() + return IC_FORMAT_CHAR \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/special_pins/color_pin.dm b/code/modules/integrated_electronics/core/special_pins/color_pin.dm new file mode 100644 index 0000000000000..0fa82b45069a9 --- /dev/null +++ b/code/modules/integrated_electronics/core/special_pins/color_pin.dm @@ -0,0 +1,51 @@ +// These pins can only contain a color (in the form of #FFFFFF) or null. +/datum/integrated_io/color + name = "color pin" + +/datum/integrated_io/color/ask_for_pin_data(mob/user) + var/new_data = input("Please select a color.","[src] color writing") as null|color + if(holder.check_interactivity(user) ) + to_chat(user, "You input a new color into the pin.") + world << "new_data equals [new_data]." + write_data_to_pin(new_data) + +/datum/integrated_io/color/write_data_to_pin(var/new_data) + // Since this is storing the color as a string hex color code, we need to make sure it's actually one. + if(isnull(new_data) || istext(new_data)) + if(istext(new_data)) + new_data = uppertext(new_data) + if(length(new_data) != 7) // We can hex if we want to, we can leave your strings behind + world << "Wrong length." + return // Cause your strings don't hex and if they don't hex + var/friends = copytext(new_data, 2, 8) // Well they're are no strings of mine + world << "friends equal [friends]." + // I say, we can go where we want to, a place where they will never find + var/safety_dance = 1 + while(safety_dance >= 7) // And we can act like we come from out of this world.log + var/hex = copytext(friends, safety_dance, safety_dance+1) + world << "Checking [hex]." + if(!(hex in list("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"))) + world << "Hex [hex] failed" + return // Leave the fake one far behind, + safety_dance++ + + data = new_data // And we can hex + holder.on_data_written() + world << "Done." + world << "Rip." + +// This randomizes the color. +/datum/integrated_io/color/scramble() + if(!is_valid()) + return + var/new_data = get_random_colour(simple = FALSE, lower = 0, upper = 255) + data = new_data + push_data() + +/datum/integrated_io/color/display_pin_type() + return IC_FORMAT_COLOR + +/datum/integrated_io/color/display_data(var/input) + if(!isnull(data)) + return "([data])" + return ..() \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/special_pins/dir_pin.dm b/code/modules/integrated_electronics/core/special_pins/dir_pin.dm new file mode 100644 index 0000000000000..bbb00faa278a7 --- /dev/null +++ b/code/modules/integrated_electronics/core/special_pins/dir_pin.dm @@ -0,0 +1,33 @@ +// These pins can only contain directions (1,2,4,8...) or null. +/datum/integrated_io/dir + name = "dir pin" + +/datum/integrated_io/dir/ask_for_pin_data(mob/user) + var/new_data = input("Please type in a valid dir number. \ + Valid dirs are;\n\ + North/Fore = [NORTH],\n\ + South/Aft = [SOUTH],\n\ + East/Starboard = [EAST],\n\ + West/Port = [WEST],\n\ + Northeast = [NORTHEAST],\n\ + Northwest = [NORTHWEST],\n\ + Southeast = [SOUTHEAST],\n\ + Southwest = [SOUTHWEST],\n\ + Up = [UP],\n\ + Down = [DOWN]","[src] dir writing") as null|num + if(isnum(new_data) && holder.check_interactivity(user) ) + to_chat(user, "You input [new_data] into the pin.") + write_data_to_pin(new_data) + +/datum/integrated_io/dir/write_data_to_pin(var/new_data) + if(isnull(new_data) || new_data in alldirs + list(UP, DOWN)) + data = new_data + holder.on_data_written() + +/datum/integrated_io/dir/display_pin_type() + return IC_FORMAT_DIR + +/datum/integrated_io/dir/display_data(var/input) + if(!isnull(data)) + return "([dir2text(data)])" + return ..() \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/special_pins/list_pin.dm b/code/modules/integrated_electronics/core/special_pins/list_pin.dm new file mode 100644 index 0000000000000..a40557679dfb3 --- /dev/null +++ b/code/modules/integrated_electronics/core/special_pins/list_pin.dm @@ -0,0 +1,150 @@ +// These pins contain a list. Null is not allowed. +/datum/integrated_io/list + name = "list pin" + data = list() + + +/datum/integrated_io/list/ask_for_pin_data(mob/user) + interact(user) + +/datum/integrated_io/list/proc/interact(mob/user) + var/list/my_list = data + var/t = "

[src]


" + t += "List length: [my_list.len]
" + t += "\[Refresh\] | " + t += "\[Add\] | " + t += "\[Swap\] | " + t += "\[Clear\]
" + t += "
" + var/i = 0 + for(var/line in my_list) + i++ + t += "#[i] | [display_data(line)] | " + t += "\[Edit\] | " + t += "\[Remove\]
" + user << browse(t, "window=list_pin_\ref[src];size=500x400") + +/datum/integrated_io/list/proc/add_to_list(mob/user, var/new_entry) + if(!new_entry && user) + new_entry = ask_for_data_type(user) + if(is_valid(new_entry)) + Add(new_entry) + +/datum/integrated_io/list/proc/Add(var/new_entry) + var/list/my_list = data + if(my_list.len > IC_MAX_LIST_LENGTH) + my_list.Cut(Start=1,End=2) + my_list.Add(new_entry) + +/datum/integrated_io/list/proc/remove_from_list_by_position(mob/user, var/position) + var/list/my_list = data + if(!my_list.len) + to_chat(user, "The list is empty, there's nothing to remove.") + return + if(!position) + return + var/target_entry = my_list.Find(position) + if(target_entry) + my_list.Remove(target_entry) + +/datum/integrated_io/list/proc/remove_from_list(mob/user, var/target_entry) + var/list/my_list = data + if(!my_list.len) + to_chat(user, "The list is empty, there's nothing to remove.") + return + if(!target_entry) + target_entry = input("Which piece of data do you want to remove?", "Remove") as null|anything in my_list + if(target_entry) + my_list.Remove(target_entry) + +/datum/integrated_io/list/proc/edit_in_list(mob/user, var/target_entry) + var/list/my_list = data + if(!my_list.len) + to_chat(user, "The list is empty, there's nothing to modify.") + return + if(!target_entry) + target_entry = input("Which piece of data do you want to edit?", "Edit") as null|anything in my_list + if(target_entry) + var/edited_entry = ask_for_data_type(user, target_entry) + if(edited_entry) + target_entry = edited_entry + +/datum/integrated_io/list/proc/edit_in_list_by_position(mob/user, var/position) + var/list/my_list = data + if(!my_list.len) + to_chat(user, "The list is empty, there's nothing to modify.") + return + if(!position) + return + var/target_entry = my_list.Find(position) + if(target_entry) + var/edited_entry = ask_for_data_type(user, target_entry) + if(edited_entry) + target_entry = edited_entry + +/datum/integrated_io/list/proc/swap_inside_list(mob/user, var/first_target, var/second_target) + var/list/my_list = data + if(my_list.len <= 1) + to_chat(user, "The list is empty, or too small to do any meaningful swapping.") + return + if(!first_target) + first_target = input("Which piece of data do you want to swap? (1)", "Swap") as null|anything in my_list + + if(first_target) + if(!second_target) + second_target = input("Which piece of data do you want to swap? (2)", "Swap") as null|anything in my_list - first_target + + if(second_target) + var/first_pos = my_list.Find(first_target) + var/second_pos = my_list.Find(second_target) + my_list.Swap(first_pos, second_pos) + +/datum/integrated_io/list/proc/clear_list(mob/user) + var/list/my_list = data + my_list.Cut() + +/datum/integrated_io/list/scramble() + var/list/my_list = data + my_list = shuffle(my_list) + push_data() + +/datum/integrated_io/list/write_data_to_pin(var/new_data) + if(islist(new_data)) + var/list/new_list = new_data + data = new_list.Copy() + holder.on_data_written() + +/datum/integrated_io/list/display_pin_type() + return IC_FORMAT_LIST + +/datum/integrated_io/list/Topic(href, href_list) + if(!holder.check_interactivity(usr)) + return + if(..()) + return 1 + + if(href_list["add"]) + add_to_list(usr) + + if(href_list["swap"]) + swap_inside_list(usr) + + if(href_list["clear"]) + clear_list(usr) + + if(href_list["remove"]) + world << "Removing [href_list["pos"]]" + if(href_list["pos"]) + remove_from_list_by_position(usr, text2num(href_list["pos"])) + else + remove_from_list(usr) + + if(href_list["edit"]) + if(href_list["pos"]) + edit_in_list_by_position(usr, text2num(href_list["pos"])) + else + edit_in_list(usr) + + holder.interact(usr) // Refresh the main UI, + interact(usr) // and the list UI. + diff --git a/code/modules/integrated_electronics/core/special_pins/number_pin.dm b/code/modules/integrated_electronics/core/special_pins/number_pin.dm new file mode 100644 index 0000000000000..319ac2de06bd2 --- /dev/null +++ b/code/modules/integrated_electronics/core/special_pins/number_pin.dm @@ -0,0 +1,18 @@ +// These pins can only contain numbers (int and floating point) or null. +/datum/integrated_io/number + name = "number pin" +// data = 0 + +/datum/integrated_io/number/ask_for_pin_data(mob/user) + var/new_data = input("Please type in a number.","[src] number writing") as null|num + if(isnum(new_data) && holder.check_interactivity(user) ) + to_chat(user, "You input [new_data] into the pin.") + write_data_to_pin(new_data) + +/datum/integrated_io/number/write_data_to_pin(var/new_data) + if(isnull(new_data) || isnum(new_data)) + data = new_data + holder.on_data_written() + +/datum/integrated_io/number/display_pin_type() + return IC_FORMAT_NUMBER \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/special_pins/ref_pin.dm b/code/modules/integrated_electronics/core/special_pins/ref_pin.dm new file mode 100644 index 0000000000000..461965f254bcf --- /dev/null +++ b/code/modules/integrated_electronics/core/special_pins/ref_pin.dm @@ -0,0 +1,14 @@ +// These pins only contain weakrefs or null. +/datum/integrated_io/ref + name = "ref pin" + +/datum/integrated_io/ref/ask_for_pin_data(mob/user) // This clears the pin. + write_data_to_pin(null) + +/datum/integrated_io/ref/write_data_to_pin(var/new_data) + if(isnull(new_data) || isweakref(new_data)) + data = new_data + holder.on_data_written() + +/datum/integrated_io/ref/display_pin_type() + return IC_FORMAT_REF \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/special_pins/string_pin.dm b/code/modules/integrated_electronics/core/special_pins/string_pin.dm new file mode 100644 index 0000000000000..6128418c1f320 --- /dev/null +++ b/code/modules/integrated_electronics/core/special_pins/string_pin.dm @@ -0,0 +1,29 @@ +// These pins can only contain text and null. +/datum/integrated_io/string + name = "string pin" + +/datum/integrated_io/string/ask_for_pin_data(mob/user) + var/new_data = input("Please type in a string.","[src] string writing") as null|text + if(holder.check_interactivity(user) ) + to_chat(user, "You input [new_data ? "new_data" : "NULL"] into the pin.") + write_data_to_pin(new_data) + +/datum/integrated_io/string/write_data_to_pin(var/new_data) + if(isnull(new_data) || istext(new_data)) + data = new_data + holder.on_data_written() + +// This makes the text go "from this" to "#G&*!HD$%L" +/datum/integrated_io/string/scramble() + if(!is_valid()) + return + var/string_length = length(data) + var/list/options = list("!","@","#","$","%","^","&","*") + alphabet_uppercase + var/new_data = "" + while(string_length) + new_data += pick(options) + string_length-- + push_data() + +/datum/integrated_io/string/display_pin_type() + return IC_FORMAT_STRING diff --git a/code/modules/integrated_electronics/core/tools.dm b/code/modules/integrated_electronics/core/tools.dm index 8a9b8fa7a43c4..7cb2ba3df5b30 100644 --- a/code/modules/integrated_electronics/core/tools.dm +++ b/code/modules/integrated_electronics/core/tools.dm @@ -162,6 +162,89 @@ io.holder.interact(user) // This is to update the UI. + + + +/obj/item/device/multitool + var/datum/integrated_io/selected_io = null + var/mode = 0 + +/obj/item/device/multitool/attack_self(mob/user) + if(selected_io) + selected_io = null + to_chat(user, "You clear the wired connection from the multitool.") + else + ..() + update_icon() + +/obj/item/device/multitool/update_icon() + if(selected_io) + if(buffer) + icon_state = "multitool_tracking" + else + icon_state = "multitool_red" + else + if(buffer) + icon_state = "multitool_tracking_fail" + else + icon_state = "multitool" + +/obj/item/device/multitool/proc/wire(var/datum/integrated_io/io, mob/user) + if(!io.holder.assembly) + to_chat(user, "\The [io.holder] needs to be secured inside an assembly first.") + return + + if(selected_io) + if(io == selected_io) + to_chat(user, "Wiring \the [selected_io.holder]'s [selected_io.name] into itself is rather pointless.") + return + if(io.io_type != selected_io.io_type) + to_chat(user, "Those two types of channels are incompatable. The first is a [selected_io.io_type], \ + while the second is a [io.io_type].") + return + if(io.holder.assembly && io.holder.assembly != selected_io.holder.assembly) + to_chat(user, "Both \the [io.holder] and \the [selected_io.holder] need to be inside the same assembly.") + return + selected_io.linked |= io + io.linked |= selected_io + + to_chat(user, "You connect \the [selected_io.holder]'s [selected_io.name] to \the [io.holder]'s [io.name].") + selected_io.holder.interact(user) // This is to update the UI. + selected_io = null + + else + selected_io = io + to_chat(user, "You link \the multitool to \the [selected_io.holder]'s [selected_io.name] data channel.") + + update_icon() + + +/obj/item/device/multitool/proc/unwire(var/datum/integrated_io/io1, var/datum/integrated_io/io2, mob/user) + if(!io1.linked.len || !io2.linked.len) + to_chat(user, "There is nothing connected to the data channel.") + return + + if(!(io1 in io2.linked) || !(io2 in io1.linked) ) + to_chat(user, "These data pins aren't connected!") + return + else + io1.linked.Remove(io2) + io2.linked.Remove(io1) + to_chat(user, "You clip the data connection between the [io1.holder.displayed_name]'s \ + [io1.name] and the [io2.holder.displayed_name]'s [io2.name].") + io1.holder.interact(user) // This is to update the UI. + update_icon() + + + + + + + + + + + /obj/item/weapon/storage/bag/circuits name = "circuit kit" desc = "This kit's essential for any circuitry projects." @@ -195,7 +278,7 @@ new /obj/item/weapon/storage/bag/circuits/mini/reagents(src) new /obj/item/weapon/storage/bag/circuits/mini/transfer(src) new /obj/item/weapon/storage/bag/circuits/mini/converter(src) - new /obj/item/weapon/storage/bag/circuits/mini/power(src) +// new /obj/item/weapon/storage/bag/circuits/mini/power(src) new /obj/item/device/electronic_assembly(src) new /obj/item/device/integrated_electronics/wirer(src) @@ -207,19 +290,19 @@ /obj/item/weapon/storage/bag/circuits/all/New() ..() spawn(2 SECONDS) // So the list has time to initialize. - new /obj/item/weapon/storage/bag/circuits/mini/arithmetic/all(src) - new /obj/item/weapon/storage/bag/circuits/mini/trig/all(src) - new /obj/item/weapon/storage/bag/circuits/mini/input/all(src) - new /obj/item/weapon/storage/bag/circuits/mini/output/all(src) - new /obj/item/weapon/storage/bag/circuits/mini/memory/all(src) - new /obj/item/weapon/storage/bag/circuits/mini/logic/all(src) - new /obj/item/weapon/storage/bag/circuits/mini/smart/all(src) - new /obj/item/weapon/storage/bag/circuits/mini/manipulation/all(src) - new /obj/item/weapon/storage/bag/circuits/mini/time/all(src) - new /obj/item/weapon/storage/bag/circuits/mini/reagents/all(src) - new /obj/item/weapon/storage/bag/circuits/mini/transfer/all(src) - new /obj/item/weapon/storage/bag/circuits/mini/converter/all(src) - new /obj/item/weapon/storage/bag/circuits/mini/power/all(src) +// new /obj/item/weapon/storage/bag/circuits/mini/arithmetic/all(src) +// new /obj/item/weapon/storage/bag/circuits/mini/trig/all(src) +// new /obj/item/weapon/storage/bag/circuits/mini/input/all(src) +// new /obj/item/weapon/storage/bag/circuits/mini/output/all(src) +// new /obj/item/weapon/storage/bag/circuits/mini/memory/all(src) +// new /obj/item/weapon/storage/bag/circuits/mini/logic/all(src) +// new /obj/item/weapon/storage/bag/circuits/mini/smart/all(src) +// new /obj/item/weapon/storage/bag/circuits/mini/manipulation/all(src) +// new /obj/item/weapon/storage/bag/circuits/mini/time/all(src) +// new /obj/item/weapon/storage/bag/circuits/mini/reagents/all(src) +// new /obj/item/weapon/storage/bag/circuits/mini/transfer/all(src) +// new /obj/item/weapon/storage/bag/circuits/mini/converter/all(src) +// new /obj/item/weapon/storage/bag/circuits/mini/power/all(src) new /obj/item/device/electronic_assembly(src) new /obj/item/device/electronic_assembly/medium(src) diff --git a/code/modules/integrated_electronics/subtypes/arithmetic.dm b/code/modules/integrated_electronics/subtypes/arithmetic.dm index bf7b347d801a2..192d317baff39 100644 --- a/code/modules/integrated_electronics/subtypes/arithmetic.dm +++ b/code/modules/integrated_electronics/subtypes/arithmetic.dm @@ -2,25 +2,20 @@ /obj/item/integrated_circuit/arithmetic complexity = 1 inputs = list( - "\ A", - "\ B", - "\ C", - "\ D", - "\ E", - "\ F", - "\ G", - "\ H" + "A" = IC_PINTYPE_NUMBER, + "B" = IC_PINTYPE_NUMBER, + "C" = IC_PINTYPE_NUMBER, + "D" = IC_PINTYPE_NUMBER, + "E" = IC_PINTYPE_NUMBER, + "F" = IC_PINTYPE_NUMBER, + "G" = IC_PINTYPE_NUMBER, + "H" = IC_PINTYPE_NUMBER ) - outputs = list("\ result") - activators = list("\ compute", "\ on computed") + outputs = list("result" = IC_PINTYPE_NUMBER) + activators = list("compute" = IC_PINTYPE_PULSE_IN, "on computed" = IC_PINTYPE_PULSE_OUT) category_text = "Arithmetic" - autopulse = 1 power_draw_per_use = 5 // Math is pretty cheap. -/obj/item/integrated_circuit/arithmetic/on_data_written() - if(autopulse == 1) - check_then_do_work() - // +Adding+ // /obj/item/integrated_circuit/arithmetic/addition @@ -30,10 +25,11 @@ result = ((((A + B) + C) + D) ... ) and so on, until all pins have been added. \ Null pins are ignored." icon_state = "addition" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/arithmetic/addition/do_work() var/result = 0 - for(var/datum/integrated_io/input/I in inputs) + for(var/datum/integrated_io/I in inputs) I.pull_data() if(isnum(I.data)) result = result + I.data @@ -51,6 +47,7 @@ result = ((((A - B) - C) - D) ... ) and so on, until all pins have been subtracted. \ Null pins are ignored. Pin A must be a number or the circuit will not function." icon_state = "subtraction" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/arithmetic/subtraction/do_work() var/datum/integrated_io/A = inputs[1] @@ -58,7 +55,7 @@ return var/result = A.data - for(var/datum/integrated_io/input/I in inputs) + for(var/datum/integrated_io/I in inputs) if(I == A) continue I.pull_data() @@ -78,6 +75,7 @@ result = ((((A * B) * C) * D) ... ) and so on, until all pins have been multiplied. \ Null pins are ignored. Pin A must be a number or the circuit will not function." icon_state = "multiplication" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/arithmetic/multiplication/do_work() @@ -85,7 +83,7 @@ if(!isnum(A.data)) return var/result = A.data - for(var/datum/integrated_io/input/I in inputs) + for(var/datum/integrated_io/I in inputs) if(I == A) continue I.pull_data() @@ -105,6 +103,7 @@ result = ((((A / B) / C) / D) ... ) and so on, until all pins have been divided. \ Null pins, and pins containing 0, are ignored. Pin A must be a number or the circuit will not function." icon_state = "division" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/arithmetic/division/do_work() var/datum/integrated_io/A = inputs[1] @@ -112,7 +111,7 @@ return var/result = A.data - for(var/datum/integrated_io/input/I in inputs) + for(var/datum/integrated_io/I in inputs) if(I == A) continue I.pull_data() @@ -129,7 +128,8 @@ name = "exponent circuit" desc = "Outputs A to the power of B." icon_state = "exponent" - inputs = list("A", "B") + inputs = list("A" = IC_PINTYPE_NUMBER, "B" = IC_PINTYPE_NUMBER) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/arithmetic/exponent/do_work() var/result = 0 @@ -149,7 +149,8 @@ desc = "This will say if a number is positive, negative, or zero." extended_desc = "Will output 1, -1, or 0, depending on if A is a postive number, a negative number, or zero, respectively." icon_state = "sign" - inputs = list("A") + inputs = list("A" = IC_PINTYPE_NUMBER) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/arithmetic/sign/do_work() var/result = 0 @@ -173,7 +174,8 @@ desc = "Rounds A to the nearest B multiple of A." extended_desc = "If B is not given a number, it will output the floor of A instead." icon_state = "round" - inputs = list("A", "B") + inputs = list("A" = IC_PINTYPE_NUMBER, "B" = IC_PINTYPE_NUMBER) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/arithmetic/round/do_work() var/result = 0 @@ -196,11 +198,12 @@ name = "absolute circuit" desc = "This outputs a non-negative version of the number you put in. This may also be thought of as its distance from zero." icon_state = "absolute" - inputs = list("A") + inputs = list("A" = IC_PINTYPE_NUMBER) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/arithmetic/absolute/do_work() var/result = 0 - for(var/datum/integrated_io/input/I in inputs) + for(var/datum/integrated_io/I in inputs) I.pull_data() if(isnum(I.data)) result = abs(I.data) @@ -216,11 +219,12 @@ desc = "This circuit is of average quality, however it will compute the average for numbers you give it." extended_desc = "Note that null pins are ignored, where as a pin containing 0 is included in the averaging calculation." icon_state = "average" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/arithmetic/average/do_work() var/result = 0 var/inputs_used = 0 - for(var/datum/integrated_io/input/I in inputs) + for(var/datum/integrated_io/I in inputs) I.pull_data() if(isnum(I.data)) inputs_used++ @@ -239,6 +243,7 @@ desc = "Not recommended for cooking. Outputs '3.14159' when it receives a pulse." icon_state = "pi" inputs = list() + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/arithmetic/pi/do_work() set_pin_data(IC_OUTPUT, 1, 3.14159) @@ -252,7 +257,7 @@ extended_desc = "'Inclusive' means that the upper bound is included in the range of numbers, e.g. L = 1 and H = 3 will allow \ for outputs of 1, 2, or 3. H being the higher number is not strictly required." icon_state = "random" - inputs = list("\ L","\ H") + inputs = list("L" = IC_PINTYPE_NUMBER,"H" = IC_PINTYPE_NUMBER) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/arithmetic/random/do_work() @@ -273,12 +278,12 @@ name = "square root circuit" desc = "This outputs the square root of a number you put in." icon_state = "square_root" - inputs = list("\ A") + inputs = list("A" = IC_PINTYPE_NUMBER) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/arithmetic/square_root/do_work() var/result = 0 - for(var/datum/integrated_io/input/I in inputs) + for(var/datum/integrated_io/I in inputs) I.pull_data() if(isnum(I.data)) result = sqrt(I.data) @@ -293,7 +298,7 @@ name = "modulo circuit" desc = "Gets the remainder of A / B." icon_state = "modulo" - inputs = list("\ A", "\ B") + inputs = list("A" = IC_PINTYPE_NUMBER, "B" = IC_PINTYPE_NUMBER) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/arithmetic/modulo/do_work() diff --git a/code/modules/integrated_electronics/subtypes/built_in.dm b/code/modules/integrated_electronics/subtypes/built_in.dm new file mode 100644 index 0000000000000..05053eec4cb06 --- /dev/null +++ b/code/modules/integrated_electronics/subtypes/built_in.dm @@ -0,0 +1,28 @@ +/obj/item/integrated_circuit/built_in + name = "integrated circuit" + desc = "It's a tiny chip! This one doesn't seem to do much, however." + icon = 'icons/obj/electronic_assemblies.dmi' + icon_state = "template" + size = -1 + w_class = 1 + removable = FALSE // Determines if a circuit is removable from the assembly. + +/obj/item/integrated_circuit/built_in/device_input + name = "assembly input" + desc = "A built in chip for handling pulses from attached assembly items." + complexity = 0 //This acts as a limitation on building machines, more resource-intensive components cost more 'space'. + activators = list("on pulsed" = IC_PINTYPE_PULSE_OUT) + +/obj/item/integrated_circuit/built_in/device_input/do_work() + activate_pin(1) + +/obj/item/integrated_circuit/built_in/device_output + name = "assembly out" + desc = "A built in chip for pulsing attached assembly items." + complexity = 0 //This acts as a limitation on building machines, more resource-intensive components cost more 'space'. + activators = list("pulse attached" = IC_PINTYPE_PULSE_IN) + +/obj/item/integrated_circuit/built_in/device_output/do_work() + if(istype(assembly, /obj/item/device/electronic_assembly/device)) + var/obj/item/device/electronic_assembly/device/device = assembly + device.holder.pulse() \ No newline at end of file diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm index 59e8cddb947a7..b0cd8cb4594ac 100644 --- a/code/modules/integrated_electronics/subtypes/converters.dm +++ b/code/modules/integrated_electronics/subtypes/converters.dm @@ -3,28 +3,31 @@ complexity = 2 inputs = list("input") outputs = list("output") - activators = list("\ convert", "\ on convert") + activators = list("convert" = IC_PINTYPE_PULSE_IN, "on convert" = IC_PINTYPE_PULSE_OUT) category_text = "Converter" - autopulse = 1 power_draw_per_use = 10 /obj/item/integrated_circuit/converter/on_data_written() - if(autopulse == 1) - check_then_do_work() +// if(autopulse == 1) + check_then_do_work() /obj/item/integrated_circuit/converter/num2text name = "number to string" desc = "This circuit can convert a number variable into a string." + extended_desc = "Because of game limitations null/false variables will output a '0' string." icon_state = "num-string" - inputs = list("\ input") - outputs = list("\ output") + inputs = list("input" = IC_PINTYPE_NUMBER) + outputs = list("output" = IC_PINTYPE_STRING) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/num2text/do_work() var/result = null pull_data() var/incoming = get_pin_data(IC_INPUT, 1) - if(incoming && isnum(incoming)) + if(!isnull(incoming)) result = num2text(incoming) + else if(!incoming) + result = "0" set_pin_data(IC_OUTPUT, 1, result) push_data() @@ -34,15 +37,15 @@ name = "string to number" desc = "This circuit can convert a string variable into a number." icon_state = "string-num" - inputs = list("\ input") - outputs = list("\ output") + inputs = list("input" = IC_PINTYPE_STRING) + outputs = list("output" = IC_PINTYPE_NUMBER) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/text2num/do_work() var/result = null pull_data() var/incoming = get_pin_data(IC_INPUT, 1) - if(incoming && istext(incoming)) + if(!isnull(incoming)) result = text2num(incoming) set_pin_data(IC_OUTPUT, 1, result) @@ -53,8 +56,9 @@ name = "reference to string" desc = "This circuit can convert a reference to something else to a string, specifically the name of that reference." icon_state = "ref-string" - inputs = list("\ input") - outputs = list("\ output") + inputs = list("input" = IC_PINTYPE_REF) + outputs = list("output" = IC_PINTYPE_STRING) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/ref2text/do_work() var/result = null @@ -71,14 +75,15 @@ name = "lowercase string converter" desc = "this will cause a string to come out in all lowercase." icon_state = "lowercase" - inputs = list("\ input") - outputs = list("\ output") + inputs = list("input" = IC_PINTYPE_STRING) + outputs = list("output" = IC_PINTYPE_STRING) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/lowercase/do_work() var/result = null pull_data() var/incoming = get_pin_data(IC_INPUT, 1) - if(incoming && istext(incoming)) + if(!isnull(incoming)) result = lowertext(incoming) set_pin_data(IC_OUTPUT, 1, result) @@ -89,64 +94,97 @@ name = "uppercase string converter" desc = "THIS WILL CAUSE A STRING TO COME OUT IN ALL UPPERCASE." icon_state = "uppercase" - inputs = list("\ input") - outputs = list("\ output") + inputs = list("input" = IC_PINTYPE_STRING) + outputs = list("output" = IC_PINTYPE_STRING) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/uppercase/do_work() var/result = null pull_data() var/incoming = get_pin_data(IC_INPUT, 1) - if(incoming && istext(incoming)) + if(!isnull(incoming)) result = uppertext(incoming) set_pin_data(IC_OUTPUT, 1, result) push_data() activate_pin(2) -/obj/item/integrated_circuit/converter/concatenatior - name = "concatenatior" - desc = "This joins many strings or numbers together to get one big string." +/obj/item/integrated_circuit/converter/concatenator + name = "concatenator" + desc = "This joins many strings together to get one big string." complexity = 4 inputs = list( - "\ A", - "\ B", - "\ C", - "\ D", - "\ E", - "\ F", - "\ G", - "\ H" + "A" = IC_PINTYPE_STRING, + "B" = IC_PINTYPE_STRING, + "C" = IC_PINTYPE_STRING, + "D" = IC_PINTYPE_STRING, + "E" = IC_PINTYPE_STRING, + "F" = IC_PINTYPE_STRING, + "G" = IC_PINTYPE_STRING, + "H" = IC_PINTYPE_STRING ) - outputs = list("\ result") - activators = list("\ concatenate", "\ on concatenated") + outputs = list("result" = IC_PINTYPE_STRING) + activators = list("concatenate" = IC_PINTYPE_PULSE_IN, "on concatenated" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH -/obj/item/integrated_circuit/converter/concatenatior/do_work() +/obj/item/integrated_circuit/converter/concatenator/do_work() var/result = null - for(var/datum/integrated_io/input/I in inputs) + for(var/datum/integrated_io/I in inputs) I.pull_data() - if(istext(I.data)) + if(!isnull(I.data)) result = result + I.data - else if(!isnull(I.data) && num2text(I.data)) - result = result + num2text(I.data) - var/datum/integrated_io/outgoing = outputs[1] - outgoing.data = result - outgoing.push_data() + set_pin_data(IC_OUTPUT, 1, result) + push_data() activate_pin(2) +/obj/item/integrated_circuit/converter/separator + name = "separator" + desc = "This splits as single string into two at the relative split point." + extended_desc = "This circuits splits a given string into two, based on the string, and the index value. \ + The index splits the string after the given index, including spaces. So 'a person' with an index of '3' \ + will split into 'a p' and 'erson'." + complexity = 4 + inputs = list( + "string to split" = IC_PINTYPE_STRING, + "index" = IC_PINTYPE_NUMBER, + ) + outputs = list( + "before split" = IC_PINTYPE_STRING, + "after split" = IC_PINTYPE_STRING + ) + activators = list("separate" = IC_PINTYPE_PULSE_IN, "on separated" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + + +/obj/item/integrated_circuit/converter/separator/do_work() + var/text = get_pin_data(IC_INPUT, 1) + var/index = get_pin_data(IC_INPUT, 2) + + var/split = min(index+1, length(text)) + + var/before_text = copytext(text, 1, split) + var/after_text = copytext(text, split, 0) + + set_pin_data(IC_OUTPUT, 1, before_text) + set_pin_data(IC_OUTPUT, 2, after_text) + push_data() + + activate_pin(2) + + /obj/item/integrated_circuit/converter/radians2degrees name = "radians to degrees converter" desc = "Converts radians to degrees." - inputs = list("\ radian") - outputs = list("\ degrees") + inputs = list("radian" = IC_PINTYPE_NUMBER) + outputs = list("degrees" = IC_PINTYPE_NUMBER) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/radians2degrees/do_work() var/result = null pull_data() var/incoming = get_pin_data(IC_INPUT, 1) - if(incoming && isnum(incoming)) + if(!isnull(incoming)) result = ToDegrees(incoming) set_pin_data(IC_OUTPUT, 1, result) @@ -156,15 +194,15 @@ /obj/item/integrated_circuit/converter/degrees2radians name = "degrees to radians converter" desc = "Converts degrees to radians." - inputs = list("\ degrees") - outputs = list("\ radians") + inputs = list("degrees" = IC_PINTYPE_NUMBER) + outputs = list("radians" = IC_PINTYPE_NUMBER) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/degrees2radians/do_work() var/result = null pull_data() var/incoming = get_pin_data(IC_INPUT, 1) - if(incoming && isnum(incoming)) + if(!isnull(incoming)) result = ToRadians(incoming) set_pin_data(IC_OUTPUT, 1, result) @@ -176,9 +214,18 @@ name = "abs to rel coordinate converter" desc = "Easily convert absolute coordinates to relative coordinates with this." complexity = 4 - inputs = list("\ X1", "\ Y1", "\ X2", "\ Y2") - outputs = list("\ X", "\ Y") - activators = list("\ compute rel coordinates", "\ on convert") + inputs = list( + "X1" = IC_PINTYPE_NUMBER, + "Y1" = IC_PINTYPE_NUMBER, + "X2" = IC_PINTYPE_NUMBER, + "Y2" = IC_PINTYPE_NUMBER + ) + outputs = list( + "X" = IC_PINTYPE_NUMBER, + "Y" = IC_PINTYPE_NUMBER + ) + activators = list("compute rel coordinates" = IC_PINTYPE_PULSE_IN, "on convert" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/converter/abs_to_rel_coords/do_work() var/x1 = get_pin_data(IC_INPUT, 1) @@ -187,7 +234,7 @@ var/x2 = get_pin_data(IC_INPUT, 3) var/y2 = get_pin_data(IC_INPUT, 4) - if(x1 && y1 && x2 && y2) + if(!isnull(x1) && !isnull(y1) && !isnull(x2) && !isnull(y2)) set_pin_data(IC_OUTPUT, 1, x1 - x2) set_pin_data(IC_OUTPUT, 2, y1 - y2) diff --git a/code/modules/integrated_electronics/subtypes/data_transfer.dm b/code/modules/integrated_electronics/subtypes/data_transfer.dm index 8c01baf8b1472..7d23929f5ecd3 100644 --- a/code/modules/integrated_electronics/subtypes/data_transfer.dm +++ b/code/modules/integrated_electronics/subtypes/data_transfer.dm @@ -1,107 +1,25 @@ /obj/item/integrated_circuit/transfer category_text = "Data Transfer" - autopulse = 1 power_draw_per_use = 2 -/obj/item/integrated_circuit/transfer/on_data_written() - if(autopulse == 1) - check_then_do_work() - -/obj/item/integrated_circuit/transfer/splitter - name = "splitter" - desc = "Splits incoming data into all of the output pins." - icon_state = "splitter" - complexity = 3 - inputs = list("data to split") - outputs = list("A","B") - -/obj/item/integrated_circuit/transfer/splitter/medium - name = "four splitter" - icon_state = "splitter4" - complexity = 5 - outputs = list("A","B","C","D") - power_draw_per_use = 4 - -/obj/item/integrated_circuit/transfer/splitter/large - name = "eight splitter" - icon_state = "splitter8" - complexity = 9 - outputs = list("A","B","C","D","E","F","G","H") - power_draw_per_use = 8 - -/obj/item/integrated_circuit/transfer/splitter/do_work() - var/datum/integrated_io/I = inputs[1] - for(var/datum/integrated_io/output/O in outputs) - O.data = I.data - -/obj/item/integrated_circuit/transfer/activator_splitter - name = "activator splitter" - desc = "Splits incoming activation pulses into all of the output pins." - icon_state = "splitter" - complexity = 3 - activators = list( - "incoming pulse", - "outgoing pulse A", - "outgoing pulse B" - ) - power_draw_per_use = 2 - -/obj/item/integrated_circuit/transfer/activator_splitter/do_work() - for(var/datum/integrated_io/activate/A in outputs) - if(A == activators[1]) - continue - if(A.linked.len) - for(var/datum/integrated_io/activate/target in A.linked) - target.holder.check_then_do_work() - -/obj/item/integrated_circuit/transfer/activator_splitter/medium - name = "four activator splitter" - icon_state = "splitter4" - complexity = 5 - activators = list( - "incoming pulse", - "outgoing pulse A", - "outgoing pulse B", - "outgoing pulse C", - "outgoing pulse D" - ) - power_draw_per_use = 4 - -/obj/item/integrated_circuit/transfer/activator_splitter/large - name = "eight activator splitter" - icon_state = "splitter4" - complexity = 9 - activators = list( - "incoming pulse", - "outgoing pulse A", - "outgoing pulse B", - "outgoing pulse C", - "outgoing pulse D", - "outgoing pulse E", - "outgoing pulse F", - "outgoing pulse G", - "outgoing pulse H" - ) - spawn_flags = IC_SPAWN_RESEARCH - power_draw_per_use = 8 - - /obj/item/integrated_circuit/transfer/multiplexer name = "two multiplexer" desc = "This is what those in the business tend to refer to as a 'mux' or data selector. It moves data from one of the selected inputs to the output." - extended_desc = "The first input pin is used to select which of the other input pins which has its data moved to the output. If the input selection is outside the valid range then no output is given." + extended_desc = "The first input pin is used to select which of the other input pins which has its data moved to the output. \ + If the input selection is outside the valid range then no output is given." complexity = 2 icon_state = "mux2" - inputs = list("input selection") - outputs = list("output") - activators = list("select") + inputs = list("input selection" = IC_PINTYPE_NUMBER) + outputs = list("output" = IC_PINTYPE_ANY) + activators = list("select" = IC_PINTYPE_PULSE_IN, "on select" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 4 var/number_of_inputs = 2 /obj/item/integrated_circuit/transfer/multiplexer/New() for(var/i = 1 to number_of_inputs) - inputs += "input [i]" + inputs["input [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called. +// inputs += "input [i]" complexity = number_of_inputs ..() desc += " It has [number_of_inputs] input pins." @@ -111,9 +29,12 @@ var/input_index = get_pin_data(IC_INPUT, 1) var/output = null - if(isnum(input_index) && (input_index >= 1 && input_index < inputs.len)) + if(!isnull(input_index) && (input_index >= 1 && input_index < inputs.len)) output = get_pin_data(IC_INPUT, input_index + 1) + set_pin_data(IC_OUTPUT, 1, output) + push_data() + activate_pin(2) /obj/item/integrated_circuit/transfer/multiplexer/medium name = "four multiplexer" @@ -135,19 +56,21 @@ /obj/item/integrated_circuit/transfer/demultiplexer name = "two demultiplexer" desc = "This is what those in the business tend to refer to as a 'demux'. It moves data from the input to one of the selected outputs." - extended_desc = "The first input pin is used to select which of the output pins is given the data from the second input pin. If the output selection is outside the valid range then no output is given." + extended_desc = "The first input pin is used to select which of the output pins is given the data from the second input pin. \ + If the output selection is outside the valid range then no output is given." complexity = 2 icon_state = "dmux2" - inputs = list("output selection","input") + inputs = list("output selection" = IC_PINTYPE_NUMBER, "input" = IC_PINTYPE_ANY) outputs = list() - activators = list("select") + activators = list("select" = IC_PINTYPE_PULSE_IN, "on select" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 4 var/number_of_outputs = 2 /obj/item/integrated_circuit/transfer/demultiplexer/New() for(var/i = 1 to number_of_outputs) - outputs += "output [i]" + // outputs += "output [i]" + outputs["output [i]"] = IC_PINTYPE_ANY complexity = number_of_outputs ..() @@ -161,6 +84,8 @@ for(var/i = 1 to outputs.len) set_pin_data(IC_OUTPUT, i, i == output_index ? output : null) + activate_pin(2) + /obj/item/integrated_circuit/transfer/demultiplexer/medium name = "four demultiplexer" icon_state = "dmux4" diff --git a/code/modules/integrated_electronics/subtypes/input_output.dm b/code/modules/integrated_electronics/subtypes/input.dm similarity index 50% rename from code/modules/integrated_electronics/subtypes/input_output.dm rename to code/modules/integrated_electronics/subtypes/input.dm index 4503a6b7053aa..093d4c0af50d8 100644 --- a/code/modules/integrated_electronics/subtypes/input_output.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -1,5 +1,6 @@ /obj/item/integrated_circuit/input var/can_be_asked_input = 0 + category_text = "Input" power_draw_per_use = 5 /obj/item/integrated_circuit/input/proc/ask_for_input(mob/user) @@ -13,7 +14,8 @@ can_be_asked_input = 1 inputs = list() outputs = list() - activators = list("\ on pressed") + activators = list("on pressed" = IC_PINTYPE_PULSE_IN) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/input/button/ask_for_input(mob/user) //Bit misleading name for this specific use. to_chat(user, "You press the button labeled '[src.name]'.") @@ -26,8 +28,8 @@ complexity = 1 can_be_asked_input = 1 inputs = list() - outputs = list("\ on" = 0) - activators = list("\ on toggle") + outputs = list("on" = IC_PINTYPE_BOOLEAN) + activators = list("on toggle" = IC_PINTYPE_PULSE_IN) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/input/toggle_button/ask_for_input(mob/user) // Ditto. @@ -43,8 +45,9 @@ complexity = 2 can_be_asked_input = 1 inputs = list() - outputs = list("\ number entered") - activators = list("\ on entered") + outputs = list("number entered" = IC_PINTYPE_NUMBER) + activators = list("on entered" = IC_PINTYPE_PULSE_IN) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 4 /obj/item/integrated_circuit/input/numberpad/ask_for_input(mob/user) @@ -61,8 +64,9 @@ complexity = 2 can_be_asked_input = 1 inputs = list() - outputs = list("\ string entered") - activators = list("\ on entered") + outputs = list("string entered" = IC_PINTYPE_STRING) + activators = list("on entered" = IC_PINTYPE_PULSE_IN) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 4 /obj/item/integrated_circuit/input/textpad/ask_for_input(mob/user) @@ -78,8 +82,12 @@ icon_state = "medscan" complexity = 4 inputs = list("\ target") - outputs = list("\ total health %", "\ total missing health") - activators = list("\ scan", "\ on scanned") + outputs = list( + "total health %" = IC_PINTYPE_NUMBER, + "total missing health" = IC_PINTYPE_NUMBER + ) + activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) power_draw_per_use = 40 @@ -88,7 +96,7 @@ if(!istype(H)) //Invalid input return if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range. - var/total_health = round(H.health/H.getMaxHealth(), 0.1)*100 + var/total_health = round(H.health/H.getMaxHealth(), 0.01)*100 var/missing_health = H.getMaxHealth() - H.health set_pin_data(IC_OUTPUT, 1, total_health) @@ -105,15 +113,16 @@ complexity = 12 inputs = list("\ target") outputs = list( - "\ total health %", - "\ total missing health", - "\ brute damage", - "\ burn damage", - "\ tox damage", - "\ oxy damage", - "\ clone damage" + "total health %" = IC_PINTYPE_NUMBER, + "total missing health" = IC_PINTYPE_NUMBER, + "brute damage" = IC_PINTYPE_NUMBER, + "burn damage" = IC_PINTYPE_NUMBER, + "tox damage" = IC_PINTYPE_NUMBER, + "oxy damage" = IC_PINTYPE_NUMBER, + "clone damage" = IC_PINTYPE_NUMBER ) - activators = list("\ scan", "\ on scanned") + activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4) power_draw_per_use = 80 @@ -122,7 +131,7 @@ if(!istype(H)) //Invalid input return if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range. - var/total_health = round(H.health/H.getMaxHealth(), 0.1)*100 + var/total_health = round(H.health/H.getMaxHealth(), 0.01)*100 var/missing_health = H.getMaxHealth() - H.health set_pin_data(IC_OUTPUT, 1, total_health) @@ -142,7 +151,8 @@ that is holding the machine containing it." inputs = list() outputs = list("located ref") - activators = list("locate") + activators = list("locate" = IC_PINTYPE_PULSE_IN) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 20 /obj/item/integrated_circuit/input/local_locator/do_work() @@ -163,7 +173,8 @@ random." inputs = list("desired type ref") outputs = list("located ref") - activators = list("locate") + activators = list("locate" = IC_PINTYPE_PULSE_IN) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 30 /obj/item/integrated_circuit/input/adjacent_locator/do_work() @@ -196,9 +207,13 @@ Meaning the default frequency is expressed as 1457, not 145.7. To send a signal, pulse the 'send signal' activator pin." icon_state = "signal" complexity = 4 - inputs = list("\ frequency","\ code") + inputs = list("frequency" = IC_PINTYPE_NUMBER,"code" = IC_PINTYPE_NUMBER) outputs = list() - activators = list("\ send signal","\ on signal sent", "\ on signal received") + activators = list( + "send signal" = IC_PINTYPE_PULSE_IN, + "on signal sent" = IC_PINTYPE_PULSE_OUT, + "on signal received" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2) power_draw_idle = 5 power_draw_per_use = 40 @@ -277,9 +292,18 @@ will pulse whatever's connected to it. Pulsing the first activation pin will send a message." icon_state = "signal" complexity = 4 - inputs = list("\ target EPv2 address", "\ data to send", "\ secondary text") - outputs = list("\ address received", "\ data received", "\ secondary text received") - activators = list("\ send data", "\ on data received") + inputs = list( + "target EPv2 address" = IC_PINTYPE_STRING, + "data to send" = IC_PINTYPE_STRING, + "secondary text" = IC_PINTYPE_STRING + ) + outputs = list( + "address received" = IC_PINTYPE_STRING, + "data received" = IC_PINTYPE_STRING, + "secondary text received" = IC_PINTYPE_STRING + ) + activators = list("send data" = IC_PINTYPE_PULSE_IN, "on data received" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2, TECH_BLUESPACE = 2) power_draw_per_use = 50 var/datum/exonet_protocol/exonet = null @@ -294,7 +318,8 @@ if(exonet) exonet.remove_address() qdel(exonet) - ..() + exonet = null + return ..() /obj/item/integrated_circuit/input/EPv2/do_work() var/target_address = get_pin_data(IC_INPUT, 1) @@ -320,8 +345,8 @@ icon_state = "gps" complexity = 4 inputs = list() - outputs = list("\ X", "\ Y") - activators = list("\ get coordinates", "\ on get coordinates") + outputs = list("X"= IC_PINTYPE_NUMBER, "Y" = IC_PINTYPE_NUMBER) + activators = list("get coordinates" = IC_PINTYPE_PULSE_IN, "on get coordinates" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 30 @@ -343,12 +368,18 @@ /obj/item/integrated_circuit/input/microphone name = "microphone" desc = "Useful for spying on people or for voice activated machines." + extended_desc = "This will automatically translate most languages it hears to Galactic Common. \ + The first activation pin is always pulsed when the circuit hears someone talk, while the second one \ + is only triggered if it hears someone speaking a language other than Galactic Common." icon_state = "recorder" flags = HEAR complexity = 8 inputs = list() - outputs = list("\ speaker", "\ message") - activators = list("\ on message received", "\ on translation") + outputs = list( + "speaker" = IC_PINTYPE_STRING, + "message" = IC_PINTYPE_STRING + ) + activators = list("on message received" = IC_PINTYPE_PULSE_IN, "on translation" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 15 /* @@ -358,9 +389,8 @@ /obj/item/integrated_circuit/input/microphone/Destroy() listening_objects -= src - ..() + return ..() */ - /obj/item/integrated_circuit/input/microphone/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans) var/datum/integrated_io/V = outputs[1] var/datum/integrated_io/O = outputs[2] @@ -372,7 +402,7 @@ O.data = raw_message A.push_data() - for(var/datum/integrated_io/output/out in outputs) + for(var/datum/integrated_io/out in outputs) out.push_data() A.push_data() @@ -382,12 +412,12 @@ /obj/item/integrated_circuit/input/sensor name = "sensor" desc = "Scans and obtains a reference for any objects or persons near you. All you need to do is shove the machine in their face." - extended_desc = "If 'ignore storage' pin is set to 1, the sensor will disregard scanning various storage containers such as backpacks." + extended_desc = "If 'ignore storage' pin is set to true, the sensor will disregard scanning various storage containers such as backpacks." icon_state = "recorder" complexity = 12 - inputs = list("\ ignore storage" = 1) - outputs = list("\ scanned") - activators = list("\ on scanned") + inputs = list("ignore storage" = 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 = 120 @@ -402,322 +432,3 @@ activate_pin(1) return TRUE -/obj/item/integrated_circuit/output - category_text = "Output" - -/obj/item/integrated_circuit/output/screen - name = "small screen" - desc = "This small screen can display a single piece of data, when the machine is examined closely." - icon_state = "screen" - inputs = list("\ displayed data") - outputs = list() - activators = list("\ load data") - power_draw_per_use = 10 - autopulse = 1 - var/stuff_to_display = null - - -/obj/item/integrated_circuit/output/screen/disconnect_all() - ..() - stuff_to_display = null - -/obj/item/integrated_circuit/output/screen/any_examine(mob/user) - to_chat(user, "There is a little screen labeled '[name]', which displays [stuff_to_display ? "'[stuff_to_display]'" : "nothing"].") - -/obj/item/integrated_circuit/output/screen/do_work() - var/datum/integrated_io/I = inputs[1] - if(isweakref(I.data)) - var/datum/d = I.data_as_type(/datum) - if(d) - stuff_to_display = "[d]" - else - stuff_to_display = I.data - -/obj/item/integrated_circuit/output/screen/medium - name = "screen" - desc = "This screen allows for people holding the device to see a piece of data." - icon_state = "screen_medium" - power_draw_per_use = 20 - -/obj/item/integrated_circuit/output/screen/medium/do_work() - ..() - var/list/nearby_things = range(0, get_turf(src)) - for(var/mob/M in nearby_things) - var/obj/O = assembly ? assembly : src - to_chat(M, "\icon[O] [stuff_to_display]") - -/obj/item/integrated_circuit/output/screen/large - name = "large screen" - desc = "This screen allows for people able to see the device to see a piece of data." - icon_state = "screen_large" - power_draw_per_use = 40 - -/obj/item/integrated_circuit/output/screen/large/do_work() - ..() - var/obj/O = assembly ? loc : assembly - O.visible_message("\icon[O] [stuff_to_display]") - -/obj/item/integrated_circuit/output/light - name = "light" - desc = "This light can turn on and off on command." - icon_state = "light" - complexity = 4 - inputs = list() - outputs = list() - activators = list("\ toggle light") - var/light_toggled = 0 - var/light_brightness = 3 - var/light_rgb = "#FFFFFF" - power_draw_idle = 0 // Adjusted based on brightness. - -/obj/item/integrated_circuit/output/light/Destroy() - ..() - -/obj/item/integrated_circuit/output/light/do_work() - light_toggled = !light_toggled - update_lighting() - -/obj/item/integrated_circuit/output/light/proc/update_lighting() - if(light_toggled) - set_light(l_range = light_brightness, l_power = light_brightness, l_color = light_rgb) - else - set_light(0) - power_draw_idle = light_toggled ? light_brightness * 2 : 0 - -/obj/item/integrated_circuit/output/light/advanced/update_lighting() - var/R = get_pin_data(IC_INPUT, 1) - var/G = get_pin_data(IC_INPUT, 2) - var/B = get_pin_data(IC_INPUT, 3) - var/brightness = get_pin_data(IC_INPUT, 4) - - if(isnum(R) && isnum(G) && isnum(B) && isnum(brightness)) - R = Clamp(R, 0, 255) - G = Clamp(G, 0, 255) - B = Clamp(B, 0, 255) - brightness = Clamp(brightness, 0, 6) - light_rgb = rgb(R, G, B) - light_brightness = brightness - - ..() - -/obj/item/integrated_circuit/output/light/power_fail() // Turns off the flashlight if there's no power left. - light_toggled = FALSE - update_lighting() - -/obj/item/integrated_circuit/output/light/advanced - name = "advanced light" - desc = "This light can turn on and off on command, in any color, and in various brightness levels." - icon_state = "light_adv" - complexity = 8 - inputs = list( - "\ R", - "\ G", - "\ B", - "\ Brightness" - ) - outputs = list() - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) - -/obj/item/integrated_circuit/output/light/advanced/on_data_written() - update_lighting() - -/obj/item/integrated_circuit/output/sound - name = "speaker circuit" - desc = "A miniature speaker is attached to this component." - icon_state = "speaker" - complexity = 8 - cooldown_per_use = 4 SECONDS - inputs = list( - "\ sound ID", - "\ volume", - "\ frequency" - ) - outputs = list() - activators = list("play sound") - power_draw_per_use = 20 - var/list/sounds = list() - -/obj/item/integrated_circuit/output/text_to_speech - name = "text-to-speech circuit" - desc = "A miniature speaker is attached to this component." - extended_desc = "This unit is more advanced than the plain speaker circuit, able to transpose any valid text to speech." - icon_state = "speaker" - complexity = 12 - cooldown_per_use = 4 SECONDS - inputs = list("text") - outputs = list() - activators = list("to speech") - power_draw_per_use = 60 - -/obj/item/integrated_circuit/output/text_to_speech/do_work() - var/datum/integrated_io/text = inputs[1] - if(istext(text.data)) - var/obj/O = assembly ? loc : assembly - audible_message("\icon[O] \The [O.name] states, \"[text.data]\"") - -/obj/item/integrated_circuit/output/sound/New() - ..() - extended_desc = list() - extended_desc += "The first input pin determines which sound is used. The choices are; " - extended_desc += jointext(sounds, ", ") - extended_desc += ". The second pin determines the volume of sound that is played" - extended_desc += ", and the third determines if the frequency of the sound will vary with each activation." - extended_desc = jointext(extended_desc, null) - -/obj/item/integrated_circuit/output/sound/do_work() - var/datum/integrated_io/ID = inputs[1] - var/datum/integrated_io/vol = inputs[2] - var/datum/integrated_io/frequency = inputs[3] - if(istext(ID.data) && isnum(vol.data) && isnum(frequency.data)) - var/selected_sound = sounds[ID.data] - if(!selected_sound) - return - vol.data = Clamp(vol.data, 0, 100) - frequency.data = round(Clamp(frequency.data, 0, 1)) - playsound(get_turf(src), selected_sound, vol.data, frequency.data, -1) - -/obj/item/integrated_circuit/output/sound/beeper - name = "beeper circuit" - desc = "A miniature speaker is attached to this component. This is often used in the construction of motherboards, which use \ - the speaker to tell the user if something goes very wrong when booting up. It can also do other similar synthetic sounds such \ - as buzzing, pinging, chiming, and more." - sounds = list( - "beep" = 'sound/machines/twobeep.ogg', - "chime" = 'sound/machines/chime.ogg', - "buzz sigh" = 'sound/machines/buzz-sigh.ogg', - "buzz twice" = 'sound/machines/buzz-two.ogg', - "ping" = 'sound/machines/ping.ogg', - "synth yes" = 'sound/machines/synth_yes.ogg', - "synth no" = 'sound/machines/synth_no.ogg', - "warning buzz" = 'sound/machines/warning-buzzer.ogg' - ) - -/obj/item/integrated_circuit/output/sound/beepsky - name = "securitron sound circuit" - desc = "A miniature speaker is attached to this component. Considered by some to be the essential component for a securitron." - sounds = list( - "creep" = 'sound/voice/bcreep.ogg', - "criminal" = 'sound/voice/bcriminal.ogg', - "freeze" = 'sound/voice/bfreeze.ogg', - "god" = 'sound/voice/bgod.ogg', - "i am the law" = 'sound/voice/biamthelaw.ogg', - "insult" = 'sound/voice/binsult.ogg', - "radio" = 'sound/voice/bradio.ogg', - "secure day" = 'sound/voice/bsecureday.ogg', - ) - spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_ILLEGAL = 1) - -/obj/item/integrated_circuit/output/video_camera - name = "video camera circuit" - desc = "This small camera allows a remote viewer to see what it sees." - extended_desc = "The camera is linked to the Research camera network." - icon_state = "video_camera" - w_class = 2 - complexity = 10 - inputs = list("camera name" = "video camera circuit", "camera active" = 0) - outputs = list() - activators = list() - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_idle = 5 // Raises to 80 when on. - var/obj/machinery/camera/camera - -/obj/item/integrated_circuit/output/video_camera/New() - ..() - camera = new(src) - on_data_written() - -/obj/item/integrated_circuit/output/video_camera/Destroy() - qdel(camera) - ..() - -/obj/item/integrated_circuit/output/video_camera/proc/set_camera_status(var/status) - if(camera) - camera.status = status - power_draw_idle = camera.status ? 80 : 5 - if(camera.status) // Ensure that there's actually power. - if(!draw_idle_power()) - power_fail() - -/obj/item/integrated_circuit/output/video_camera/on_data_written() - if(camera) - var/datum/integrated_io/cam_name = inputs[1] - var/datum/integrated_io/cam_active = inputs[2] - if(istext(cam_name.data)) - camera.c_tag = cam_name.data - if(isnum(cam_active.data)) - set_camera_status(cam_active.data) - -/obj/item/integrated_circuit/output/video_camera/power_fail() - if(camera) - set_camera_status(0) - var/datum/integrated_io/cam_active = inputs[2] - cam_active.data = FALSE - -/obj/item/integrated_circuit/output/led - name = "light-emitting diode" - desc = "This a LED that is lit whenever there is TRUE-equivalent data on its input." - extended_desc = "TRUE-equivalent values are: Non-empty strings, non-zero numbers, and valid refs." - complexity = 0.1 - icon_state = "led" - inputs = list("lit") - outputs = list() - activators = list() - power_draw_idle = 0 // Raises to 1 when lit. - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - var/led_color - -/obj/item/integrated_circuit/output/led/on_data_written() - power_draw_idle = get_pin_data(IC_INPUT, 1) ? 1 : 0 - -/obj/item/integrated_circuit/output/led/power_fail() - set_pin_data(IC_INPUT, 1, FALSE) - -/obj/item/integrated_circuit/output/led/any_examine(mob/user) - var/text_output = list() - var/initial_name = initial(name) - - // Doing all this work just to have a color-blind friendly output. - text_output += "There is " - if(name == initial_name) - text_output += "\an [name]" - else - text_output += "\an ["\improper[initial_name]"] labeled '[name]'" - text_output += " which is currently [get_pin_data(IC_INPUT, 1) ? "lit ¤" : "unlit."]" - to_chat(user,jointext(text_output,null)) - -/obj/item/integrated_circuit/output/led/red - name = "red LED" - led_color = COLOR_RED - -/obj/item/integrated_circuit/output/led/orange - name = "orange LED" - led_color = COLOR_ORANGE - -/obj/item/integrated_circuit/output/led/yellow - name = "yellow LED" - led_color = COLOR_YELLOW - -/obj/item/integrated_circuit/output/led/green - name = "green LED" - led_color = COLOR_GREEN - -/obj/item/integrated_circuit/output/led/blue - name = "blue LED" - led_color = COLOR_BLUE - -/obj/item/integrated_circuit/output/led/purple - name = "purple LED" - led_color = COLOR_PURPLE - -/obj/item/integrated_circuit/output/led/cyan - name = "cyan LED" - led_color = COLOR_CYAN - -/obj/item/integrated_circuit/output/led/white - name = "white LED" - led_color = COLOR_WHITE - -/obj/item/integrated_circuit/output/led/pink - name = "pink LED" - led_color = COLOR_PINK diff --git a/code/modules/integrated_electronics/subtypes/lists.dm b/code/modules/integrated_electronics/subtypes/lists.dm new file mode 100644 index 0000000000000..84e0724bb933b --- /dev/null +++ b/code/modules/integrated_electronics/subtypes/lists.dm @@ -0,0 +1,89 @@ +//These circuits do things with lists, and use special list pins for stability. +/obj/item/integrated_circuit/list + complexity = 1 + inputs = list( + "input" = IC_PINTYPE_LIST + ) + outputs = list("result" = IC_PINTYPE_STRING) + activators = list("compute" = IC_PINTYPE_PULSE_IN, "on computed" = IC_PINTYPE_PULSE_OUT) + category_text = "Lists" + power_draw_per_use = 20 + +/obj/item/integrated_circuit/list/pick + name = "pick circuit" + desc = "This circuit will randomly 'pick' an element from a list that is inputted." + extended_desc = "Will output null if the list is empty. Input list is unmodified." + icon_state = "addition" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/list/pick/do_work() + var/result = null + var/list/input_list = get_pin_data(IC_INPUT, 1) // List pins guarantee that there is a list inside, even if just an empty one. + if(input_list.len) + result = pick(input_list) + + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) + + +/obj/item/integrated_circuit/list/append + name = "append circuit" + desc = "This circuit will add an element to a list." + extended_desc = "The new element will always be at the bottom of the list." + inputs = list( + "list to append" = IC_PINTYPE_LIST, + "input" = IC_PINTYPE_ANY + ) + outputs = list( + "appended list" = IC_PINTYPE_LIST + ) + icon_state = "addition" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/list/append/do_work() + var/list/input_list = get_pin_data(IC_INPUT, 1) + var/list/output_list = list() + var/new_entry = get_pin_data(IC_INPUT, 2) + output_list = input_list.Copy() + output_list.Add(new_entry) + + set_pin_data(IC_OUTPUT, 1, output_list) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/list/jointext + name = "join text circuit" + desc = "This circuit will add all elements of a list into one string, seperated by a character." + extended_desc = "Default settings will encode the entire list into a string." + inputs = list( + "list to join" = IC_PINTYPE_LIST, + "delimiter" = IC_PINTYPE_CHAR, + "start" = IC_PINTYPE_NUMBER, + "end" = IC_PINTYPE_NUMBER + ) + inputs_default = list( + "2" = ",", + "3" = 1, + "4" = 0 + ) + outputs = list( + "joined text" = IC_PINTYPE_STRING + ) + icon_state = "addition" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/list/jointext/do_work() + var/list/input_list = get_pin_data(IC_INPUT, 1) + var/delimiter = get_pin_data(IC_INPUT, 2) + var/start = get_pin_data(IC_INPUT, 3) + var/end = get_pin_data(IC_INPUT, 4) + + var/result = null + + if(input_list.len && delimiter && !isnull(start) && !isnull(end)) + result = jointext(input_list, delimiter, start, end) + + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) \ No newline at end of file diff --git a/code/modules/integrated_electronics/subtypes/logic.dm b/code/modules/integrated_electronics/subtypes/logic.dm index 7d90add7c3d23..4bbffede35f0a 100644 --- a/code/modules/integrated_electronics/subtypes/logic.dm +++ b/code/modules/integrated_electronics/subtypes/logic.dm @@ -4,20 +4,16 @@ extended_desc = "Logic circuits will treat a null, 0, and a \"\" string value as FALSE and anything else as TRUE." complexity = 3 outputs = list("result") - activators = list("\ compare") - autopulse = 1 + activators = list("compare" = IC_PINTYPE_PULSE_IN) + category_text = "Logic" power_draw_per_use = 1 -/obj/item/integrated_circuit/logic/on_data_written() - if(autopulse == 1) - check_then_do_work() - /obj/item/integrated_circuit/logic/do_work() push_data() /obj/item/integrated_circuit/logic/binary - inputs = list("\ A","\ B") - activators = list("\ compare", "\ on true result", "\ on false result") + inputs = list("A","B") + activators = list("compare" = IC_PINTYPE_PULSE_IN, "on true result" = IC_PINTYPE_PULSE_OUT, "on false result" = IC_PINTYPE_PULSE_OUT) /obj/item/integrated_circuit/logic/binary/do_work() pull_data() @@ -36,8 +32,8 @@ return FALSE /obj/item/integrated_circuit/logic/unary - inputs = list("\ A") - activators = list("\ compare", "\ on compare") + inputs = list("A") + activators = list("compare" = IC_PINTYPE_PULSE_IN, "on compare" = IC_PINTYPE_PULSE_OUT) /obj/item/integrated_circuit/logic/unary/do_work() pull_data() @@ -54,6 +50,7 @@ name = "equal gate" desc = "This gate compares two values, and outputs the number one if both are the same." icon_state = "equal" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/logic/binary/equals/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) return A.data == B.data @@ -62,6 +59,7 @@ name = "not equal gate" desc = "This gate compares two values, and outputs the number one if both are different." icon_state = "not_equal" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/logic/binary/not_equals/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) return A.data != B.data @@ -70,6 +68,7 @@ name = "and gate" desc = "This gate will output 'one' if both inputs evaluate to true." icon_state = "and" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/logic/binary/and/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) return A.data && B.data @@ -78,6 +77,7 @@ name = "or gate" desc = "This gate will output 'one' if one of the inputs evaluate to true." icon_state = "or" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/logic/binary/or/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) return A.data || B.data @@ -86,6 +86,7 @@ name = "less than gate" desc = "This will output 'one' if the first input is less than the second input." icon_state = "less_than" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/logic/binary/less_than/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) return A.data < B.data @@ -94,6 +95,7 @@ name = "less than or equal gate" desc = "This will output 'one' if the first input is less than, or equal to the second input." icon_state = "less_than_or_equal" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/logic/binary/less_than_or_equal/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) return A.data <= B.data @@ -102,6 +104,7 @@ name = "greater than gate" desc = "This will output 'one' if the first input is greater than the second input." icon_state = "greater_than" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/logic/binary/greater_than/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) return A.data > B.data @@ -110,6 +113,7 @@ name = "greater_than or equal gate" desc = "This will output 'one' if the first input is greater than, or equal to the second input." icon_state = "greater_than_or_equal" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/logic/binary/greater_than_or_equal/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) return A.data >= B.data @@ -118,6 +122,8 @@ name = "not gate" desc = "This gate inverts what's fed into it." icon_state = "not" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + activators = list("invert" = IC_PINTYPE_PULSE_IN, "on inverted" = IC_PINTYPE_PULSE_OUT) /obj/item/integrated_circuit/logic/unary/not/do_check(var/datum/integrated_io/A) return !A.data diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm index f260190e67e56..3cd5ad5b839fa 100644 --- a/code/modules/integrated_electronics/subtypes/manipulation.dm +++ b/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -1,3 +1,6 @@ +/obj/item/integrated_circuit/manipulation + category_text = "Manipulation" + /obj/item/integrated_circuit/manipulation/weapon_firing name = "weapon firing mechanism" desc = "This somewhat complicated system allows one to slot in a gun, direct it towards a position, and remotely fire it." @@ -6,15 +9,18 @@ The 'fire' activator will cause the mechanism to attempt to fire the weapon at the coordinates, if possible. Note that the \ normal limitations to firearms, such as ammunition requirements and firing delays, still hold true if fired by the mechanism." complexity = 20 + w_class = 3 + size = 3 inputs = list( - "\ target X rel", - "\ target Y rel" + "target X rel" = IC_PINTYPE_NUMBER, + "target Y rel" = IC_PINTYPE_NUMBER ) outputs = list() activators = list( - "\ fire" + "fire" = IC_PINTYPE_PULSE_IN ) var/obj/item/weapon/gun/installed_gun = null + spawn_flags = IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4) power_draw_per_use = 50 // The targeting mechanism uses this. The actual gun uses its own cell for firing if it's an energy weapon. @@ -31,6 +37,7 @@ user.remove_from_mob(gun) //user.drop_from_inventory(gun) installed_gun = gun + size += gun.w_class gun.forceMove(src) user << "You slide \the [gun] into the firing mechanism." playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) @@ -41,73 +48,73 @@ if(installed_gun) installed_gun.forceMove(get_turf(src)) user << "You slide \the [installed_gun] out of the firing mechanism." + size = initial(size) playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) installed_gun = null else user << "There's no weapon to remove from the mechanism." /obj/item/integrated_circuit/manipulation/weapon_firing/do_work() - if(..()) - if(!installed_gun) + if(!installed_gun) + return + + var/datum/integrated_io/target_x = inputs[1] + var/datum/integrated_io/target_y = inputs[2] + + if(src.assembly) + if(isnum(target_x.data)) + target_x.data = round(target_x.data) + if(isnum(target_y.data)) + target_y.data = round(target_y.data) + + var/turf/T = get_turf(src.assembly) + + if(target_x.data == 0 && target_y.data == 0) // Don't shoot ourselves. return - var/datum/integrated_io/target_x = inputs[1] - var/datum/integrated_io/target_y = inputs[2] - - if(target_x.data && target_y.data && isnum(target_x.data) && isnum(target_y.data)) - var/turf/T = get_turf(src) - - if(target_x.data == 0 && target_y.data == 0) // Don't shoot ourselves. - return - - // We need to do this in order to enable relative coordinates, as locate() only works for absolute coordinates. - var/i - if(target_x.data > 0) - i = abs(target_x.data) - while(i) - T = get_step(T, EAST) - i-- - else if(target_x.data < 0) - i = abs(target_x.data) - while(i) - T = get_step(T, WEST) - i-- - - if(target_y.data > 0) - i = abs(target_y.data) - while(i) - T = get_step(T, NORTH) - i-- - else if(target_y.data < 0) - i = abs(target_y.data) - while(i) - T = get_step(T, SOUTH) - i-- - - if(!T) - return - installed_gun.Fire_userless(T) + // We need to do this in order to enable relative coordinates, as locate() only works for absolute coordinates. + var/i + if(target_x.data > 0) + i = abs(target_x.data) + while(i > 0) + T = get_step(T, EAST) + i-- + else + i = abs(target_x.data) + while(i > 0) + T = get_step(T, WEST) + i-- + + i = 0 + if(target_y.data > 0) + i = abs(target_y.data) + while(i > 0) + T = get_step(T, NORTH) + i-- + else if(target_y.data < 0) + i = abs(target_y.data) + while(i > 0) + T = get_step(T, SOUTH) + i-- + + if(!T) + return + installed_gun.Fire_userless(T) /obj/item/integrated_circuit/manipulation/locomotion name = "locomotion circuit" desc = "This allows a machine to move in a given direction." icon_state = "locomotion" - extended_desc = "The circuit accepts a number as a direction to move towards.
\ - North/Fore = 1,
\ - South/Aft = 2,
\ - East/Starboard = 4,
\ - West/Port = 8,
\ - Northeast = 5,
\ - Northwest = 9,
\ - Southeast = 6,
\ - Southwest = 10
\ -
\ + extended_desc = "The circuit accepts a 'dir' number as a direction to move towards.
\ Pulsing the 'step towards dir' activator pin will cause the machine to move a meter in that direction, assuming it is not \ - being held, or anchored in some way." + being held, or anchored in some way. It should be noted that the ability to move is dependant on the type of assembly that this circuit inhabits." + w_class = 3 complexity = 20 - inputs = list("dir num") +// size = 5 + inputs = list("direction" = IC_PINTYPE_DIR) outputs = list() - activators = list("step towards dir") + activators = list("step towards dir" = IC_PINTYPE_PULSE_IN) + spawn_flags = IC_SPAWN_RESEARCH power_draw_per_use = 100 /obj/item/integrated_circuit/manipulation/locomotion/do_work() @@ -120,4 +127,81 @@ if(machine.loc == T) // Check if we're held by someone. If the loc is the floor, we're not held. var/datum/integrated_io/wanted_dir = inputs[1] if(isnum(wanted_dir.data)) - step(machine, wanted_dir.data) \ No newline at end of file + step(machine, wanted_dir.data) + +/obj/item/integrated_circuit/manipulation/grenade + name = "grenade primer" + desc = "This circuit comes with the ability to attach most types of grenades at prime them at will." + extended_desc = "Time between priming and detonation is limited to between 1 to 12 seconds but is optional. \ + If unset, not a number, or a number less than 1 then the grenade's built-in timing will be used. \ + Beware: Once primed there is no aborting the process!" + icon_state = "grenade" + complexity = 30 + size = 2 + inputs = list("detonation time" = IC_PINTYPE_NUMBER) + outputs = list() + activators = list("prime grenade" = IC_PINTYPE_PULSE_IN) + spawn_flags = IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4) + var/obj/item/weapon/grenade/attached_grenade + var/pre_attached_grenade_type + +/obj/item/integrated_circuit/manipulation/grenade/New() + ..() + if(pre_attached_grenade_type) + var/grenade = new pre_attached_grenade_type(src) + attach_grenade(grenade) + +/obj/item/integrated_circuit/manipulation/grenade/Destroy() + if(attached_grenade && !attached_grenade.active) + attached_grenade.loc = loc + detach_grenade() + . =..() + +/obj/item/integrated_circuit/manipulation/grenade/attackby(var/obj/item/weapon/grenade/G, var/mob/user) + if(istype(G)) + if(attached_grenade) + to_chat(user, "There is already a grenade attached!") + else if(user.unEquip(G, force=1)) + user.visible_message("\The [user] attaches \a [G] to \the [src]!", "You attach \the [G] to \the [src].") + attach_grenade(G) + G.forceMove(src) + else + ..() + +/obj/item/integrated_circuit/manipulation/grenade/attack_self(var/mob/user) + if(attached_grenade) + user.visible_message("\The [user] removes \an [attached_grenade] from \the [src]!", "You remove \the [attached_grenade] from \the [src].") + user.put_in_any_hand_if_possible(attached_grenade) || (attached_grenade.loc = loc) + detach_grenade() + else + ..() + +/obj/item/integrated_circuit/manipulation/grenade/do_work() + if(attached_grenade && !attached_grenade.active) + var/datum/integrated_io/detonation_time = inputs[1] + if(isnum(detonation_time.data) && detonation_time.data > 0) + attached_grenade.det_time = Clamp(detonation_time.data, 1, 12) SECONDS + attached_grenade.prime() +// var/atom/holder = loc +// log_and_message_admins("activated a grenade assembly. Last touches: Assembly: [holder.fingerprintslast] Circuit: [fingerprintslast] Grenade: [attached_grenade.fingerprintslast]") + +// These procs do not relocate the grenade, that's the callers responsibility +/obj/item/integrated_circuit/manipulation/grenade/proc/attach_grenade(var/obj/item/weapon/grenade/G) + attached_grenade = G +// destroyed_event.register(attached_grenade, src, /obj/item/integrated_circuit/manipulation/grenade/proc/detach_grenade) + size += G.w_class + desc += " \An [attached_grenade] is attached to it!" + +/obj/item/integrated_circuit/manipulation/grenade/proc/detach_grenade() + if(!attached_grenade) + return +// destroyed_event.unregister(attached_grenade, src, /obj/item/integrated_circuit/manipulation/grenade/proc/detach_grenade) + attached_grenade = null + size = initial(size) + desc = initial(desc) + +/obj/item/integrated_circuit/manipulation/grenade/frag + pre_attached_grenade_type = /obj/item/weapon/grenade + origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 10) + spawn_flags = null // Used for world initializing, see the #defines above. \ No newline at end of file diff --git a/code/modules/integrated_electronics/subtypes/memory.dm b/code/modules/integrated_electronics/subtypes/memory.dm index 0c3d038229703..b2b94a358831e 100644 --- a/code/modules/integrated_electronics/subtypes/memory.dm +++ b/code/modules/integrated_electronics/subtypes/memory.dm @@ -3,9 +3,20 @@ desc = "This tiny chip can store one piece of data." icon_state = "memory" complexity = 1 - inputs = list("input pin 1") - outputs = list("output pin 1") - activators = list("set") + inputs = list() + outputs = list() + activators = list("set" = IC_PINTYPE_PULSE_IN, "on set" = IC_PINTYPE_PULSE_OUT) + category_text = "Memory" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + power_draw_per_use = 1 + var/number_of_pins = 1 + +/obj/item/integrated_circuit/memory/New() + for(var/i = 1 to number_of_pins) + inputs["input [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called. + outputs["output [i]"] = IC_PINTYPE_ANY + complexity = number_of_pins + ..() /obj/item/integrated_circuit/memory/examine(mob/user) ..() @@ -26,81 +37,33 @@ var/datum/integrated_io/I = inputs[i] var/datum/integrated_io/O = outputs[i] O.data = I.data + O.push_data() + activate_pin(2) /obj/item/integrated_circuit/memory/medium name = "memory circuit" desc = "This circuit can store four pieces of data." icon_state = "memory4" - complexity = 4 - inputs = list("input pin 1","input pin 2","input pin 3","input pin 4") - outputs = list("output pin 1","output pin 2","output pin 3","output pin 4") + power_draw_per_use = 2 + number_of_pins = 4 /obj/item/integrated_circuit/memory/large name = "large memory circuit" desc = "This big circuit can hold eight pieces of data." icon_state = "memory8" - complexity = 8 - inputs = list( - "input pin 1", - "input pin 2", - "input pin 3", - "input pin 4", - "input pin 5", - "input pin 6", - "input pin 7", - "input pin 8") - outputs = list( - "output pin 1", - "output pin 2", - "output pin 3", - "output pin 4", - "output pin 5", - "output pin 6", - "output pin 7", - "output pin 8") origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) + power_draw_per_use = 4 + number_of_pins = 8 /obj/item/integrated_circuit/memory/huge name = "large memory stick" desc = "This stick of memory can hold up up to sixteen pieces of data." icon_state = "memory16" - complexity = 16 - inputs = list( - "input pin 1", - "input pin 2", - "input pin 3", - "input pin 4", - "input pin 5", - "input pin 6", - "input pin 7", - "input pin 8", - "input pin 9", - "input pin 10", - "input pin 11", - "input pin 12", - "input pin 13", - "input pin 14", - "input pin 15", - "input pin 16" - ) - outputs = list( - "output pin 1", - "output pin 2", - "output pin 3", - "output pin 4", - "output pin 5", - "output pin 6", - "output pin 7", - "output pin 8", - "output pin 9", - "output pin 10", - "output pin 11", - "output pin 12", - "output pin 13", - "output pin 14", - "output pin 15", - "output pin 16") + w_class = 3 + spawn_flags = IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4) + power_draw_per_use = 8 + number_of_pins = 16 /obj/item/integrated_circuit/memory/constant name = "constant chip" @@ -108,9 +71,10 @@ icon_state = "memory" complexity = 1 inputs = list() - outputs = list("output pin") - activators = list("push data") + outputs = list("output pin" = IC_PINTYPE_ANY) + activators = list("push data" = IC_PINTYPE_PULSE_IN) var/accepting_refs = 0 + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/memory/constant/do_work() var/datum/integrated_io/O = outputs[1] diff --git a/code/modules/integrated_electronics/subtypes/output.dm b/code/modules/integrated_electronics/subtypes/output.dm new file mode 100644 index 0000000000000..4e9da97d2ad2c --- /dev/null +++ b/code/modules/integrated_electronics/subtypes/output.dm @@ -0,0 +1,339 @@ +/obj/item/integrated_circuit/output + category_text = "Output" + +/obj/item/integrated_circuit/output/screen + name = "small screen" + desc = "This small screen can display a single piece of data, when the machine is examined closely." + icon_state = "screen" + inputs = list("displayed data" = IC_PINTYPE_ANY) + outputs = list() + activators = list("load data" = IC_PINTYPE_PULSE_IN) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + power_draw_per_use = 10 + var/stuff_to_display = null + + +/obj/item/integrated_circuit/output/screen/disconnect_all() + ..() + stuff_to_display = null + +/obj/item/integrated_circuit/output/screen/any_examine(mob/user) + to_chat(user, "There is a little screen labeled '[name]', which displays [!isnull(stuff_to_display) ? "'[stuff_to_display]'" : "nothing"].") + +/obj/item/integrated_circuit/output/screen/do_work() + var/datum/integrated_io/I = inputs[1] + if(isweakref(I.data)) + var/datum/d = I.data_as_type(/datum) + if(d) + stuff_to_display = "[d]" + else + stuff_to_display = I.data + +/obj/item/integrated_circuit/output/screen/medium + name = "screen" + desc = "This screen allows for people holding the device to see a piece of data." + icon_state = "screen_medium" + power_draw_per_use = 20 + +/obj/item/integrated_circuit/output/screen/medium/do_work() + ..() + var/list/nearby_things = range(0, get_turf(src)) + for(var/mob/M in nearby_things) + var/obj/O = assembly ? assembly : src + to_chat(M, "\icon[O] [stuff_to_display]") + +/obj/item/integrated_circuit/output/screen/large + name = "large screen" + desc = "This screen allows for people able to see the device to see a piece of data." + icon_state = "screen_large" + power_draw_per_use = 40 + +/obj/item/integrated_circuit/output/screen/large/do_work() + ..() + var/obj/O = assembly ? loc : assembly + O.visible_message("\icon[O] [stuff_to_display]") + +/obj/item/integrated_circuit/output/light + name = "light" + desc = "This light can turn on and off on command." + icon_state = "light" + complexity = 4 + inputs = list() + outputs = list() + activators = list("toggle light" = IC_PINTYPE_PULSE_IN) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + var/light_toggled = 0 + var/light_brightness = 3 + var/light_rgb = "#FFFFFF" + power_draw_idle = 0 // Adjusted based on brightness. + +/obj/item/integrated_circuit/output/light/do_work() + light_toggled = !light_toggled + update_lighting() + +/obj/item/integrated_circuit/output/light/proc/update_lighting() + if(light_toggled) + if(assembly) + assembly.set_light(l_range = light_brightness, l_power = light_brightness, l_color = light_rgb) + else + if(assembly) + assembly.set_light(0) + power_draw_idle = light_toggled ? light_brightness * 2 : 0 + +/obj/item/integrated_circuit/output/light/advanced/update_lighting() + var/new_color = get_pin_data(IC_INPUT, 1) + var/brightness = get_pin_data(IC_INPUT, 2) + + if(new_color && isnum(brightness)) + brightness = Clamp(brightness, 0, 6) + light_rgb = new_color + light_brightness = brightness + + ..() + +/obj/item/integrated_circuit/output/light/power_fail() // Turns off the flashlight if there's no power left. + light_toggled = FALSE + update_lighting() + +/obj/item/integrated_circuit/output/light/advanced + name = "advanced light" + desc = "This light can turn on and off on command, in any color, and in various brightness levels." + icon_state = "light_adv" + complexity = 8 + inputs = list( + "color" = IC_PINTYPE_COLOR, + "brightness" = IC_PINTYPE_NUMBER + ) + outputs = list() + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) + +/obj/item/integrated_circuit/output/light/advanced/on_data_written() + update_lighting() + +/obj/item/integrated_circuit/output/sound + name = "speaker circuit" + desc = "A miniature speaker is attached to this component." + icon_state = "speaker" + complexity = 8 + cooldown_per_use = 4 SECONDS + inputs = list( + "sound ID" = IC_PINTYPE_STRING, + "volume" = IC_PINTYPE_NUMBER, + "frequency" = IC_PINTYPE_BOOLEAN + ) + outputs = list() + activators = list("play sound" = IC_PINTYPE_PULSE_IN) + power_draw_per_use = 20 + var/list/sounds = list() + +/obj/item/integrated_circuit/output/text_to_speech + name = "text-to-speech circuit" + desc = "A miniature speaker is attached to this component." + extended_desc = "This unit is more advanced than the plain speaker circuit, able to transpose any valid text to speech." + icon_state = "speaker" + complexity = 12 + cooldown_per_use = 4 SECONDS + inputs = list("text" = IC_PINTYPE_STRING) + outputs = list() + activators = list("to speech" = IC_PINTYPE_PULSE_IN) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + power_draw_per_use = 60 + +/obj/item/integrated_circuit/output/text_to_speech/do_work() + text = get_pin_data(IC_INPUT, 1) + if(!isnull(text)) + var/obj/O = assembly ? loc : assembly + audible_message("\icon[O] \The [O.name] states, \"[text]\"") + +/obj/item/integrated_circuit/output/sound/New() + ..() + extended_desc = list() + extended_desc += "The first input pin determines which sound is used. The choices are; " + extended_desc += jointext(sounds, ", ") + extended_desc += ". The second pin determines the volume of sound that is played" + extended_desc += ", and the third determines if the frequency of the sound will vary with each activation." + extended_desc = jointext(extended_desc, null) + +/obj/item/integrated_circuit/output/sound/do_work() + var/ID = get_pin_data(IC_INPUT, 1) + var/vol = get_pin_data(IC_INPUT, 2) + var/freq = get_pin_data(IC_INPUT, 3) + if(!isnull(ID) && !isnull(vol)) + var/selected_sound = sounds[ID] + if(!selected_sound) + return + vol = Clamp(vol, 0, 100) + playsound(get_turf(src), selected_sound, vol, freq, -1) + +/obj/item/integrated_circuit/output/sound/beeper + name = "beeper circuit" + desc = "A miniature speaker is attached to this component. This is often used in the construction of motherboards, which use \ + the speaker to tell the user if something goes very wrong when booting up. It can also do other similar synthetic sounds such \ + as buzzing, pinging, chiming, and more." + sounds = list( + "beep" = 'sound/machines/twobeep.ogg', + "chime" = 'sound/machines/chime.ogg', + "buzz sigh" = 'sound/machines/buzz-sigh.ogg', + "buzz twice" = 'sound/machines/buzz-two.ogg', + "ping" = 'sound/machines/ping.ogg', + "synth yes" = 'sound/machines/synth_yes.ogg', + "synth no" = 'sound/machines/synth_no.ogg', + "warning buzz" = 'sound/machines/warning-buzzer.ogg' + ) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/output/sound/beepsky + name = "securitron sound circuit" + desc = "A miniature speaker is attached to this component. Considered by some to be the essential component for a securitron." + sounds = list( + "creep" = 'sound/voice/bcreep.ogg', + "criminal" = 'sound/voice/bcriminal.ogg', + "freeze" = 'sound/voice/bfreeze.ogg', + "god" = 'sound/voice/bgod.ogg', + "i am the law" = 'sound/voice/biamthelaw.ogg', + "insult" = 'sound/voice/binsult.ogg', + "radio" = 'sound/voice/bradio.ogg', + "secure day" = 'sound/voice/bsecureday.ogg', + ) + spawn_flags = IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_ILLEGAL = 1) + +/obj/item/integrated_circuit/output/sound/medbot + name = "medbot sound circuit" + desc = "A miniature speaker is attached to this component, used to annoy patients while they get pricked by a medbot." + sounds = list( + "surgeon" = 'sound/voice/medbot/msurgeon.ogg', + "radar" = 'sound/voice/medbot/mradar.ogg', + "feel better" = 'sound/voice/medbot/mfeelbetter.ogg', + "patched up" = 'sound/voice/medbot/mpatchedup.ogg', + "injured" = 'sound/voice/medbot/minjured.ogg', + "insult" = 'sound/voice/medbot/minsult.ogg', + "coming" = 'sound/voice/medbot/mcoming.ogg', + "help" = 'sound/voice/medbot/mhelp.ogg', + "live" = 'sound/voice/medbot/mlive.ogg', + "lost" = 'sound/voice/medbot/mlost.ogg', + "flies" = 'sound/voice/medbot/mflies.ogg', + "catch" = 'sound/voice/medbot/mcatch.ogg', + "delicious" = 'sound/voice/medbot/mdelicious.ogg', + "apple" = 'sound/voice/medbot/mapple.ogg', + "no" = 'sound/voice/medbot/mno.ogg', + ) + spawn_flags = IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 1) + +/obj/item/integrated_circuit/output/video_camera + name = "video camera circuit" + desc = "This small camera allows a remote viewer to see what it sees." + extended_desc = "The camera is linked to the Research camera network." + icon_state = "video_camera" + w_class = 2 + complexity = 10 + inputs = list( + "camera name" = IC_PINTYPE_STRING, + "camera active" = IC_PINTYPE_BOOLEAN + ) + inputs_default = list("1" = "video camera circuit") + outputs = list() + activators = list() + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + power_draw_idle = 5 // Raises to 80 when on. + var/obj/machinery/camera/camera + +/obj/item/integrated_circuit/output/video_camera/New() + ..() + camera = new(src) + on_data_written() + +/obj/item/integrated_circuit/output/video_camera/Destroy() + qdel(camera) + return ..() + +/obj/item/integrated_circuit/output/video_camera/proc/set_camera_status(var/status) + if(camera) + camera.status = status + power_draw_idle = camera.status ? 80 : 5 + if(camera.status) // Ensure that there's actually power. + if(!draw_idle_power()) + power_fail() + +/obj/item/integrated_circuit/output/video_camera/on_data_written() + if(camera) + var/cam_name = get_pin_data(IC_INPUT, 1) + var/cam_active = get_pin_data(IC_INPUT, 2) + if(!isnull(cam_name)) + camera.c_tag = cam_name + set_camera_status(cam_active) + +/obj/item/integrated_circuit/output/video_camera/power_fail() + if(camera) + set_camera_status(0) + set_pin_data(IC_INPUT, 2, FALSE) + +/obj/item/integrated_circuit/output/led + name = "light-emitting diode" + desc = "This a LED that is lit whenever there is TRUE-equivalent data on its input." + extended_desc = "TRUE-equivalent values are: Non-empty strings, non-zero numbers, and valid refs." + complexity = 0.1 + icon_state = "led" + inputs = list("lit" = IC_PINTYPE_BOOLEAN) + outputs = list() + activators = list() + power_draw_idle = 0 // Raises to 1 when lit. + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + var/led_color + +/obj/item/integrated_circuit/output/led/on_data_written() + power_draw_idle = get_pin_data(IC_INPUT, 1) ? 1 : 0 + +/obj/item/integrated_circuit/output/led/power_fail() + set_pin_data(IC_INPUT, 1, FALSE) + +/obj/item/integrated_circuit/output/led/any_examine(mob/user) + var/text_output = list() + var/initial_name = initial(name) + + // Doing all this work just to have a color-blind friendly output. + text_output += "There is " + if(name == initial_name) + text_output += "\an [name]" + else + text_output += "\an ["\improper[initial_name]"] labeled '[name]'" + text_output += " which is currently [get_pin_data(IC_INPUT, 1) ? "lit ¤" : "unlit."]" + to_chat(user,jointext(text_output,null)) + +/obj/item/integrated_circuit/output/led/red + name = "red LED" + led_color = COLOR_RED + +/obj/item/integrated_circuit/output/led/orange + name = "orange LED" + led_color = COLOR_ORANGE + +/obj/item/integrated_circuit/output/led/yellow + name = "yellow LED" + led_color = COLOR_YELLOW + +/obj/item/integrated_circuit/output/led/green + name = "green LED" + led_color = COLOR_GREEN + +/obj/item/integrated_circuit/output/led/blue + name = "blue LED" + led_color = COLOR_BLUE + +/obj/item/integrated_circuit/output/led/purple + name = "purple LED" + led_color = COLOR_PURPLE + +/obj/item/integrated_circuit/output/led/cyan + name = "cyan LED" + led_color = COLOR_CYAN + +/obj/item/integrated_circuit/output/led/white + name = "white LED" + led_color = COLOR_WHITE + +/obj/item/integrated_circuit/output/led/pink + name = "pink LED" + led_color = COLOR_PINK diff --git a/code/modules/integrated_electronics/subtypes/power.dm b/code/modules/integrated_electronics/subtypes/power.dm index c33695b4a2eca..15e3cebf0d045 100644 --- a/code/modules/integrated_electronics/subtypes/power.dm +++ b/code/modules/integrated_electronics/subtypes/power.dm @@ -11,9 +11,13 @@ some power is lost due to ineffiency." w_class = 2 complexity = 16 - inputs = list("\ target") - outputs = list("\ target cell charge", "\ target cell max charge", "\ target cell percentage") - activators = list("\ transmit") + inputs = list("target" = IC_PINTYPE_REF) + outputs = list( + "target cell charge" = IC_PINTYPE_NUMBER, + "target cell max charge" = IC_PINTYPE_NUMBER, + "target cell percentage" = IC_PINTYPE_NUMBER + ) + activators = list("transmit" = IC_PINTYPE_PULSE_IN, "on transmit" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNETS = 3) power_draw_per_use = 500 // Inefficency has to come from somewhere. @@ -67,6 +71,7 @@ set_pin_data(IC_OUTPUT, 1, cell.charge) set_pin_data(IC_OUTPUT, 2, cell.maxcharge) set_pin_data(IC_OUTPUT, 3, cell.percent()) + activate_pin(2) return TRUE return FALSE diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm index e3b69d31cd4f0..960eb5d8747fd 100644 --- a/code/modules/integrated_electronics/subtypes/reagents.dm +++ b/code/modules/integrated_electronics/subtypes/reagents.dm @@ -13,13 +13,13 @@ desc = "Unlike most electronics, creating smoke is completely intentional." icon_state = "smoke" extended_desc = "This smoke generator creates clouds of smoke on command. It can also hold liquids inside, which will go \ - into the smoke clouds when activated." + into the smoke clouds when activated. The reagents are consumed when smoke is made." flags = OPENCONTAINER complexity = 20 cooldown_per_use = 30 SECONDS inputs = list() outputs = list() - activators = list("create smoke") + activators = list("create smoke" = IC_PINTYPE_PULSE_IN) spawn_flags = IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 3) volume = 100 @@ -43,9 +43,10 @@ flags = OPENCONTAINER complexity = 20 cooldown_per_use = 6 SECONDS - inputs = list("\ target", "\ injection amount" = 5) + inputs = list("target" = IC_PINTYPE_REF, "injection amount" = IC_PINTYPE_NUMBER) + inputs_default = list("2" = 5) outputs = list() - activators = list("\ inject") + activators = list("inject" = IC_PINTYPE_PULSE_IN) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH volume = 30 power_draw_per_use = 15 @@ -72,7 +73,7 @@ if(!L.can_be_injected_by(src)) return var/contained = reagents.get_reagents() - var/trans = reagents.trans_to_mob(L, inject_amount(), CHEM_BLOOD) + var/trans = reagents.trans_to(L, inject_amount()) message_admins("[src] injected \the [L] with [trans]u of [contained].") to_chat(AM, "You feel a tiny prick!") visible_message("[src] injects [L]!") @@ -88,19 +89,20 @@ outside the machine if it is next to the machine. Note that this cannot be used on entities." flags = OPENCONTAINER complexity = 8 - inputs = list("\ source", "\ target", "\ injection amount" = 10) + inputs = list("source" = IC_PINTYPE_REF, "target" = IC_PINTYPE_REF, "injection amount" = IC_PINTYPE_NUMBER) + inputs_default = list("3" = 5) outputs = list() - activators = list("\ transfer reagents", "\ on transfer") + activators = list("transfer reagents" = IC_PINTYPE_PULSE_IN, "on transfer" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) var/transfer_amount = 10 power_draw_per_use = 10 /obj/item/integrated_circuit/reagent/pump/on_data_written() - var/datum/integrated_io/amount = inputs[3] - if(isnum(amount.data)) - amount.data = Clamp(amount.data, 0, 50) - transfer_amount = amount.data + var/new_amount = get_pin_data(IC_INPUT, 3) + if(!isnull(new_amount)) + new_amount = Clamp(new_amount, 0, 50) + transfer_amount = new_amount /obj/item/integrated_circuit/reagent/pump/do_work() var/atom/movable/source = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) @@ -130,16 +132,15 @@ flags = OPENCONTAINER complexity = 4 inputs = list() - outputs = list("volume used") + outputs = list("volume used" = IC_PINTYPE_NUMBER) activators = list() 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/on_reagent_change() - var/datum/integrated_io/A = outputs[1] - A.data = reagents.total_volume - A.push_data() + set_pin_data(IC_OUTPUT, 1, reagents.total_volume) + push_data() /obj/item/integrated_circuit/reagent/storage/cryo name = "cryo reagent storage" diff --git a/code/modules/integrated_electronics/subtypes/smart.dm b/code/modules/integrated_electronics/subtypes/smart.dm index a90a3f57a36a3..14aa9b6eab49e 100644 --- a/code/modules/integrated_electronics/subtypes/smart.dm +++ b/code/modules/integrated_electronics/subtypes/smart.dm @@ -8,9 +8,9 @@ cannot see the target, it will not be able to calculate the correct direction." icon_state = "numberpad" complexity = 25 - inputs = list("\ target") - outputs = list("\ dir") - activators = list("\ calculate dir", "\ on calculated") + inputs = list("target" = IC_PINTYPE_REF) + outputs = list("dir" = IC_PINTYPE_DIR) + activators = list("calculate dir" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 5) power_draw_per_use = 40 diff --git a/code/modules/integrated_electronics/subtypes/time.dm b/code/modules/integrated_electronics/subtypes/time.dm index 55323dc8900c3..e5a943657d06f 100644 --- a/code/modules/integrated_electronics/subtypes/time.dm +++ b/code/modules/integrated_electronics/subtypes/time.dm @@ -4,6 +4,7 @@ complexity = 2 inputs = list() outputs = list() + category_text = "Time" /obj/item/integrated_circuit/time/delay name = "two-sec delay circuit" @@ -11,7 +12,8 @@ This circuit is set to send a pulse after a delay of two seconds." icon_state = "delay-20" var/delay = 2 SECONDS - activators = list("\ incoming","\ outgoing") + activators = list("incoming"= IC_PINTYPE_PULSE_IN,"outgoing" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 2 /obj/item/integrated_circuit/time/delay/do_work() @@ -26,6 +28,7 @@ This circuit is set to send a pulse after a delay of five seconds." icon_state = "delay-50" delay = 5 SECONDS + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/time/delay/one_sec name = "one-sec delay circuit" @@ -33,6 +36,7 @@ This circuit is set to send a pulse after a delay of one second." icon_state = "delay-10" delay = 1 SECONDS + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/time/delay/half_sec name = "half-sec delay circuit" @@ -40,6 +44,7 @@ This circuit is set to send a pulse after a delay of half a second." icon_state = "delay-5" delay = 5 + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/time/delay/tenth_sec name = "tenth-sec delay circuit" @@ -47,18 +52,20 @@ This circuit is set to send a pulse after a delay of 1/10th of a second." icon_state = "delay-1" delay = 1 + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/time/delay/custom name = "custom delay circuit" desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ This circuit's delay can be customized, between 1/10th of a second to one hour. The delay is updated upon receiving a pulse." icon_state = "delay" - inputs = list("delay time") + inputs = list("delay time" = IC_PINTYPE_NUMBER) + spawn_flags = IC_SPAWN_RESEARCH /obj/item/integrated_circuit/time/delay/custom/do_work() var/delay_input = get_pin_data(IC_INPUT, 1) if(delay_input && isnum(delay_input) ) - var/new_delay = between(1, delay_input, 36000) //An hour. + var/new_delay = Clamp(delay_input, 0, 36000) //An hour. delay = new_delay ..() @@ -71,27 +78,28 @@ var/ticks_to_pulse = 4 var/ticks_completed = 0 var/is_running = FALSE - inputs = list("\ enable ticking" = 0) - activators = list("\ outgoing pulse") + inputs = list("enable ticking" = IC_PINTYPE_BOOLEAN) + activators = list("outgoing pulse" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_RESEARCH power_draw_per_use = 4 /obj/item/integrated_circuit/time/ticker/Destroy() if(is_running) - SSmachine.processing -= src + SSobj.processing -= src . = ..() /obj/item/integrated_circuit/time/ticker/on_data_written() var/do_tick = get_pin_data(IC_INPUT, 1) if(do_tick && !is_running) is_running = TRUE - SSmachine.processing |= src + SSobj.processing |= src else if(is_running) is_running = FALSE - SSmachine.processing -= src + SSobj.processing -= src ticks_completed = 0 /obj/item/integrated_circuit/time/ticker/process() - var/process_ticks = SSmachine.priority //process_schedule_interval("obj") + var/process_ticks = SSobj.priority //process_schedule_interval("obj") ticks_completed += process_ticks if(ticks_completed >= ticks_to_pulse) if(ticks_to_pulse >= process_ticks) @@ -106,6 +114,7 @@ icon_state = "tick-f" complexity = 12 ticks_to_pulse = 2 + spawn_flags = IC_SPAWN_RESEARCH power_draw_per_use = 8 /obj/item/integrated_circuit/time/ticker/slow @@ -114,6 +123,7 @@ icon_state = "tick-s" complexity = 4 ticks_to_pulse = 6 + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 2 /obj/item/integrated_circuit/time/clock @@ -121,8 +131,13 @@ desc = "Tells you what the local time is, specific to your station or planet." icon_state = "clock" inputs = list() - outputs = list("\ time", "\ hours", "\ minutes", "\ seconds") - activators = list("\ get time","\ on time got") + outputs = list( + "time" = IC_PINTYPE_STRING, + "hours" = IC_PINTYPE_NUMBER, + "minutes" = IC_PINTYPE_NUMBER, + "seconds" = IC_PINTYPE_NUMBER + ) + activators = list("get time" = IC_PINTYPE_PULSE_IN, "on time got" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 4 diff --git a/code/modules/integrated_electronics/subtypes/trig.dm b/code/modules/integrated_electronics/subtypes/trig.dm index 72d779b62189b..daadf52d42960 100644 --- a/code/modules/integrated_electronics/subtypes/trig.dm +++ b/code/modules/integrated_electronics/subtypes/trig.dm @@ -2,40 +2,35 @@ /obj/item/integrated_circuit/trig complexity = 1 inputs = list( - "\ A", - "\ B", - "\ C", - "\ D", - "\ E", - "\ F", - "\ G", - "\ H" + "A" = IC_PINTYPE_NUMBER, + "B" = IC_PINTYPE_NUMBER, + "C" = IC_PINTYPE_NUMBER, + "D" = IC_PINTYPE_NUMBER, + "E" = IC_PINTYPE_NUMBER, + "F" = IC_PINTYPE_NUMBER, + "G" = IC_PINTYPE_NUMBER, + "H" = IC_PINTYPE_NUMBER ) - outputs = list("\ result") - activators = list("\ compute", "\ on computed") + outputs = list("result" = IC_PINTYPE_NUMBER) + activators = list("compute" = IC_PINTYPE_PULSE_IN, "on computed" = IC_PINTYPE_PULSE_OUT) category_text = "Trig" extended_desc = "Input and output are in degrees." - autopulse = 1 power_draw_per_use = 1 // Still cheap math. -/obj/item/integrated_circuit/trig/on_data_written() - if(autopulse == 1) - check_then_do_work() - // Sine // /obj/item/integrated_circuit/trig/sine name = "sin circuit" desc = "Has nothing to do with evil, unless you consider trigonometry to be evil. Outputs the sine of A." icon_state = "sine" - inputs = list("\ A") + inputs = list("A" = IC_PINTYPE_NUMBER) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/trig/sine/do_work() pull_data() var/result = null var/A = get_pin_data(IC_INPUT, 1) - if(isnum(A)) + if(!isnull(A)) result = sin(A) set_pin_data(IC_OUTPUT, 1, result) @@ -48,14 +43,14 @@ name = "cos circuit" desc = "Outputs the cosine of A." icon_state = "cosine" - inputs = list("\ A") + inputs = list("A" = IC_PINTYPE_NUMBER) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/trig/cosine/do_work() pull_data() var/result = null var/A = get_pin_data(IC_INPUT, 1) - if(isnum(A)) + if(!isnull(A)) result = cos(A) set_pin_data(IC_OUTPUT, 1, result) @@ -68,14 +63,14 @@ name = "tan circuit" desc = "Outputs the tangent of A. Guaranteed to not go on a tangent about its existance." icon_state = "tangent" - inputs = list("\ A") + inputs = list("A" = IC_PINTYPE_NUMBER) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/trig/tangent/do_work() pull_data() var/result = null var/A = get_pin_data(IC_INPUT, 1) - if(isnum(A)) + if(!isnull(A)) result = Tan(A) set_pin_data(IC_OUTPUT, 1, result) @@ -88,14 +83,14 @@ name = "csc circuit" desc = "Outputs the cosecant of A." icon_state = "cosecant" - inputs = list("\ A") + inputs = list("A" = IC_PINTYPE_NUMBER) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/trig/cosecant/do_work() pull_data() var/result = null var/A = get_pin_data(IC_INPUT, 1) - if(isnum(A)) + if(!isnull(A)) result = Csc(A) set_pin_data(IC_OUTPUT, 1, result) @@ -109,14 +104,14 @@ name = "sec circuit" desc = "Outputs the secant of A. Has nothing to do with the security department." icon_state = "secant" - inputs = list("\ A") + inputs = list("A" = IC_PINTYPE_NUMBER) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/trig/secant/do_work() pull_data() var/result = null var/A = get_pin_data(IC_INPUT, 1) - if(isnum(A)) + if(!isnull(A)) result = Sec(A) set_pin_data(IC_OUTPUT, 1, result) @@ -130,14 +125,14 @@ name = "cot circuit" desc = "Outputs the cotangent of A." icon_state = "cotangent" - inputs = list("\ A") + inputs = list("A" = IC_PINTYPE_NUMBER) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/trig/cotangent/do_work() pull_data() var/result = null var/A = get_pin_data(IC_INPUT, 1) - if(isnum(A)) + if(!isnull(A)) result = Cot(A) set_pin_data(IC_OUTPUT, 1, result) diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index 124ed773d9a6a..c13d7b0c3600a 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -457,7 +457,7 @@ other types of metals and chemistry for reagents). name = "Custom wirer tool" id = "wirer" req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) - materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 2500) + materials = list(MAT_METAL = 500, MAT_GLASS = 250) build_type = PROTOLATHE build_path = /obj/item/device/integrated_electronics/wirer category = list("Electronics") @@ -466,8 +466,10 @@ other types of metals and chemistry for reagents). name = "Custom circuit debugger tool" id = "debugger" req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) - materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 2500) + materials = list(MAT_METAL = 500, MAT_GLASS = 250) + build_type = PROTOLATHE build_path = /obj/item/device/integrated_electronics/debugger + category = list("Electronics") /datum/design/circuit/integrated_circuit/AssembleDesignName() ..() @@ -481,6 +483,26 @@ other types of metals and chemistry for reagents). ..() name = "Custom circuitry \[Arithmetic\] ([item_name])" +/datum/design/item/custom_circuit_printer + name = "Portable integrated circuit printer" + desc = "A portable(ish) printer for modular machines." + id = "ic_printer" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2, TECH_DATA = 2) + materials = list(MAT_METAL = 10000) + build_type = PROTOLATHE + build_path = /obj/item/device/integrated_circuit_printer + category = list("Electronics") + +/datum/design/item/custom_circuit_printer_upgrade + name = "Integrated circuit printer upgrade - advanced designs" + desc = "Allows the integrated circuit printer to create advanced circuits" + id = "ic_printer_upgrade_adv" + req_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 4) + materials = list(MAT_METAL = 2000) + build_type = PROTOLATHE + build_path = /obj/item/weapon/disk/integrated_circuit/upgrade/advanced + category = list("Electronics") + /datum/design/circuit/tcom/exonet_node name = "exonet node" diff --git a/code/world.dm b/code/world.dm index c94d8b833310c..f890481862460 100644 --- a/code/world.dm +++ b/code/world.dm @@ -31,7 +31,8 @@ changelog_hash = md5('html/changelog.html') //used for telling if the changelog has changed recently make_datum_references_lists() //initialises global lists for referencing frequently used datums (so that we only ever do it once) - + initialize_integrated_circuits_list() + load_configuration() load_mode() load_motd() diff --git a/icons/obj/electronic_assemblies.dmi b/icons/obj/electronic_assemblies.dmi index 81aa71eac773dda32062093e11546a517e6dc041..6ad2b65b2f92eb46c37a5abc9da34d2c515f70dd 100644 GIT binary patch literal 35959 zcmbTdcUY56`z;y_O^Sdhh)5AsP{1mcrXXw(^VS%J~C#jyOHqr|LS zTAjJO)Fa8a^Q?j|MkGC5>oV-vQ_#I3zWd7TtTjxMXI2JX6W46_DzHZrN4Z%;bFsNQ zoYktkL$$`!TJ71;@#@0iAqyo=N3wKBMf~#T7~R5r5vK7Ok1&zB_`93mJ*C)VKNwZH zUP`DNmSC zcs12kCog!+5&T{qPlx_v@tn{ieb@ZXnm*BGYC$M^;FiUw8-a+L1lF97EMeDN z`rfXyt{#|dO02+%xw4&aaIE`n+qRLW6>-!le$XCgrC$3%YmLkkrI|G*XJ^YGbS!Hb zYPGxMU)gnOs$Y06uNR9js5(1U{3j68u!WjtBzrZwXxvnB-K02^NwUWc{=L(zMO<1)^4;?XXGMhqAy{gIBMP0V%I(PGEVoXS?00#v$`J%1W zT|1+AGlQ=w&}KnptvThhCJlWK7ejj}eX`iPopu9Es_#nH-TNwQ8urKhQS?i%_YXIV zgiA%*Ev}@R%7q&qOw=v0yT}hjZ&D3!nK(DEB>%QEPC!(f3_^S52I{-Y|8rH)C0SR8 zqWVC)_C{@>F5+$`u3Gn@vP>Pyor}xkCb@Zb-7e$GGPfFbP`mcma=M#yOjKj4PjhSM zwxE^gs6*%bq84lRy^Wj*H6m9Ezbv)bGG)Nys}&1uSo+Dk=Q$R7w>!2UEZ$jsF8a5J zlG!aSk*qo8$}*&Y#~xEr>OOrhWbgW4{X=KHfqBh6`u!j}MLF(ds{T7e3S!rZN7d(2 zVh3RTYa+#t%imgMGTG&CbziCyQj@G=@MM?&{>$fWf0k8AH@}hH4e-_eRjXZez2ui; zSPp9HUE&wd#Y%09@@)0_yt29O-}>X;y)_q}nQCTrq7A-w9Y1=*tcqaB5E3{)VX`51 z&3l2eq5dfN+-HtUUX%Vs{J+~&TV^UQ=6rhahr+RgujVauZ0$AEVaoePMYA8A-4zli zO^JHu`$i+b)kiK|9%e~s6PEBNyx*|#e5JvrF@~o9YPh^Qc5HvJvGn5Lc+U2eolQ8f z*Ttks90K8n+*4C|?31zH5SVgdA$5!B7%JZ{5hTvEO$QZVzSJgFD#%;i{$+Gd`+NeU zfgGC=tHSS~pv$Hnd~yxvV$8ATeDAm)F^SrCbAEH29!Ld3uC-PeYN#= z&t5I$pUVYGs3`a(j4}B+M4j|LD^Ax$dcX7R71<@ydt|35gqL)$D;uTxKmQ~A;wFSP z{LW`niceVx>`E@_MT8Q~aa=&xDlc|3()6NOR$$xz@|^>k!?HUl{LWQZ3q3{~1Ddq> z#T2`Z18W1C+14Cx<7nM(>_!N}8DI19-}VR=*HLsSjGWbwk#Ez>L#b5U!xnH$yI(M6 z2QvKiIZOcuq+bVy-yhIH^AQB+*Lnq@H;N>0uo`~t5B0KYiu$)TFjmdHcTx~q%FxE5 zHz~bUKStF91%kk($R#@CH+TNiDY&g8`Sm@O3#`yt3)F*II@Qt!Hk$C(U%OtB0{SY6 zYSqFS*jy(UGs(+$amQYeJi5_7=8#KI2dD*9QjE~1f3^zY3?lealLha5x`kDSk?_9B zNjk`Axh->Adip|M>sPJxdAI7nhJJ}#a(`hpSj#j9NSdJx0|CXaqp$yd1JQstBr^E; zp9c3&5$RUNZG1PXa0(yuc^2y&Lb+e9{h-bd6h6M5fI}&cTubnDZiNrBi55bi^O@NM zm7aVF^xnNRUq;l%F5LLj7KdZ0T@bcJkFR;ix&8eL$A0dV>ZJ#NTFT`(3P6P$AcObz z4>5)EzZSe}ub6Eh-QC^IvLyImZ#x|AeKTA-G01a{82^NPUPG*rzZ&h zjBSB3h}kij>}E2wi5}}@ct)24?Y8Xc`&$k(G_4Lio!Vyq?IZu!5IJ0$*nSf|o;!45ZEy)@7<7FD{Q`sbwP?UQ2lSRa5Y{&(F?URFmjxF9?CF1Ig z{+7a@k}ZrNe{47ta#;Jg+5FE)IJdA#ywW-KB5g$D#XQ%hkmhID^^}7N3j8#7Asxb! ziy@z>;L;>E$qkWzTQWrM`1H}Os54h5>EqERfyn(+Kh)H2o$nQz3SzR!!nPaHeW=O= zSG45bA!60ki28dldxgB*#JmfuHAQjrXm^B-x_hOL+x_GpKXZdrt1u>VR&7=e?m;&L zW)4oxo}E^>46GUa(E@J88UwGTE#1-myN<>_eJUsYRouMBMIO4yvhTkpqSkTn_K!Wf z@1p|sTeuR*1#Qu$bcba25vgB&>RjxI(N;~8PHiJUO6Z<`K-7K2m>{pt4zV)f!{Xdj zJA!;o&*h4Gv06s|%%Y5$qDalf2rnNE>wt)paLb76r;wHM&&N;&+#a%eq3gbiqTiWf z0jTw$Gb`wt4|wYR#DagL5_L&dfmYl<;iwgHDTs*_!>Z~2f5fsDNYpYkHFc zq6X@%G8l~Pj~)bm=H~`?*XvSIh=9e<$No#!htVL|uvQh3>ACP)W$Y)pXWRB~mL6M_ zq->`DuvVcP371%uk&)>nI**s%oWsAAd~>+75h?UXgj-CV|H66R&WVMOomFJYB0-mx zpJk+Z?~^k=9f&j+T|RcrO1aQlL^CV`CX&|-4oy&rn~5GBm3LH}6`?@(BtqEpQ>DWuaD(wX5Z&ZMU% zhAhulC7b1b|&k^$dhr}rL>|@Vw zQ}NuInZD3|{5z8$h00xPa5%6OMxAKSdcv;B;7QK&glTW(i=OvkdjKib zO!0l3$Lkd{Y3MAAfEn5TV$PevAIf5Oh|C6$(K!L9w%Q&?g;$GTyyO??D9rL|-dLHY zaZoGTuRG3((mZ})WBJY>sjOs#)s0&*T?k+8FNo_~DAloKcKzsJ!Dn^LYLtR=tWQOP z(z@VQUN)vu$P=p_g-4X#Zq?;PGhBlb!3^iw**v$ku`_Zr)IJL)gmk_IajR2^Jdb(v zm{M?g#%kvkyOWF4oUnpBrTKZirY{#AtnAY~-iZw<8=@72J@qGh2q`+d59UH;eP^jc zRp6{4%d1qM`?}z)3b+?ak0D-J$M0kqyByv;{ygc;2Mch^YOQVd)q7v{-cqt{#7cP1 zT25EyDT_?~eY8C9<|;xJtq}Hp;n%2h>>AqF(>j?!rvChWbl5;U+)Loy8K=!nZy zB0oJtM_L{<`oGSe4!}3k=UHXYG`gMWlYN}|73*@=6Th^|xsWqpXGF)KT4Fo!RWe>) z)IHQkQTXSa>kbZmmX|ZO?%n2NX|nrfw%9M`*)Oz$&VSO?%m9W6Z02}PS7E%pDmzfq z4ht?puK&!O2mg&*i$iQv&{;RF3y03LvZ`*r;Fj`K@a?hn9r7_cC)4P$f9hmeyEo>{ z7mHNFZK&h@?^f=?r*6$wqIEUvC=b6nsk@b(Xa&+!>RCk!I(vWdk4nN+or&>QeN^?M zX6N>|rE+7I7P1tq>XIi*mrw#(+%Qg?Liv0LM7I{F`=jcU2QKIy0z>(WL+J}c!~3O- zBttg=;?d_TP84uIMAHekU>4qM_jsuc<1~oo)K)k+gu5vOp0nQbkG|lMyMfeN^&gE^ zDo!JiP4cTsquB$Sa(c7;Rb(SUSY4 z(WS7YrBWp$f)~4j_T`bnc9bw-;+fv#GhWSEhLjzD=dvWAHf1oA8=~~AYcPAtuJApW zfbbQhl|bCU{DwFGgO`K7bSd;~#pQ4==yIlmADd_$nvUisq~8zI4cR6w$TL>;rOA2Z=u+wXUp87@% z5HEQ*5R~PIw;kQ=MV#J}N$%#Efjzs#mfv;7lha6m z4Y6E9cJc6&=c!)-Pv@TFCT_O1v~QAO_PEXDvT4F1WGgn0VtZzA=m*S>PX;+p2(v zv|~)_g*Akct9jRYrovMOw)#!u&O80&u&cT(VI?YgzESVEm!eg-qfZ%fMXFO`^zw0yiyL3>4tvoH$o`sP%ljvRB`qKQr#%bxeBbo;Ese*`<(` zv3lOP?;9HCVVGmWRxCm>(0kSzw3g#>GlA}DUc3aPv$C{W_BNw#3#7n9m(pTYUgto; zeC96o)rBbi*j9ljrIhA1+gRJ}R^M`Q^VLtv399bfEgE1v^FQ?U^?>>&odpy_ zR-!@mRY7k6XOWl3IJZ=PsRp-MM_V~vKnV*B45U~S>7YxwK)oKdBbT5J5~kXM>xY}v zJc#rY#b3|X*JDoxCwLamhTlnprvyk|a(#!H_FyK5pf6H=rE&@pWxupHkq#lNwl%kt zQ9l#rxi&mTVB@DEPI+U5RtwjL2+3~S6c{SS}q}gnG;sqhdk`LsL+*@&hc~SP_ucge4r}Sf2)y41)|_wO3JZn! zLHC%gPMg&W3ykEx8zKqZ4?kyT^P(1R=zPc!>wUPr@Dk-A_U9 z-P@c75>Z~{@NA7(>AKp*!%JaIdXt(eno6>4eJPvqYPED`blT5E*J`H3??8%_~%fer`OjcoSz? zA(HYQF>yvzCXM*H@7t!o%%qFz_?jMdZFz{cgrub8e4wBkMXmZD<6cc8$V?hjZZV;5 zF|_!4zQ$aIKJP;ms;$(jvy}5K-v^%`eeNRZ$gxtZ&jW~AVOmz<3-=4wiLIOU&GV;FE-BPw5*o4kykB?ewVO;?I22yk=pm5UdQ@@p+bTCd=XA zMY05@blw7wJ!riCASv>J0W^4JF{HR@|3&0FnVCXTM~IOX=+8n+D|*qtp`jtEDk~Ni zulcfZ=?KShB)}w3AtwF1uGcRQ_oYdL1_7CI(P3DWk(}9v9hwu+GBexG{-Q`DXk$P% z72lG~$0Zkr%ZoA}D=S%U-@aXqKb&Z@`QZEWFH67ZP}+U+Zn8*b6y`KKzgOPYWdx>@z7D8Jq4nqh^O29WN_2qB(+fubo%nW`xAS zUDh9Oe-VDrsHyUF;=_(nGV{5Zrd1T49b%4cUa{ShipD^%+^2YMkjCXs0S6&EhVpq$ zh)6EpE-Z`orE2=<@bKb2#>X89tM^&E5iO@CPWQBkf#$V>Qn%$`QVmw-w+h|oe=$8E z=qR0BE9513j+iEo41UjItSipuZPZ6-V1s=7{ssqP4t2W2vAm)EY-AqLm|iX_MSTSVc;v!MPZPO=WNIszv{N zgTf#BI=8L-Cfa6_BemX~jE|42LB8eZx3mSa&b5?reGN&HUg|BOBVwLKF+9&g7Zz$g z-ZYd(?@}`H9ij8{X`Kh_gWJ#@4ePJi$vno`$vr(i|37; zrc}bvChn-X0RA*U)c!uEjPhv#aYJoo9u5TNYO8;5$@E7v(qce>oqjq-XFtk?d{)(GA<}$GkLRS9vD0IvT_JU`U_3^&RHY* zuoBOaB72w4H6`Fb4SLty&3>fxR-1wXO)sNM}O`Y^D$x`q4RR~YHoRJvZ z^{k!*%l5~RMX8RDz0r_A58=WG@*T=uAM_Hb=GtT1_g4nuAKn-spirpxNG9Ix3RIww zqudIfEAXVVD7m7lYGg;Oss4~QGbCUHvxOx3`yxzC(tD$?UY*<)s7mif)hqP9#_Qam zN*|M%Ou@*nE(9p;-POZB%089|x`ic0r3@*h=;VPw^ySN!13+MsWDc{PB3n85wcGY{xi6dPZ5ucB8NdV; z(T$Bth0Nt1VhNn_kKpiF)rfOe4mym|Z%ancOvDDtk;9e0Gs}yPGOV^Rz&t95i35aZ z6Hjm&v78&n1f2|7rsWQl^T-gi^Fi}_4y_<&K5gsFE20u z5@;&HiK#gqYf+e+dH8s*o@)=-w&Q=T%x&JOT;QZom~b~TM?CC6bE>4;rkC^aP$aQW)JmGF5Sx%xu)=;Tt@JK9A-pJZouzs$#oWZ$l zO9f&`v-xk_!M58qtllAPuS=qF!WnH^P*^A>NtxVQ{Jg~l1i}=K@M+MsCL5pU;yu3& zNxLk0=EWqq2=k((woTK0jux_~dE|G(--s*QZ#QKLJazwk@;H*(LXdHRn~W#(bkuP>0N8XW=SObX=!h&Zl~%8q;4C7&T-e94QeAgU|tH{EEh z=URX_Ca~(MvrB=RjJP=m2ZyiF(&Mik_mGbc$pk0?sp267xE#L@c$ICADGr{Y9p+@q zxkIiy+@5ej#ED!id_7r|o%@e-tg7D@=ql!<0xV)v!g0Q@P#wCNz};mFgNjCsj&bc> zHSn7Yl5=HN0Yg5^q@o6i9INP4xj$RYJbV3)EV0q4gvF+Dt^5r6f(tE!#p=wD#=y!W zXy>9~9T^VyY2~D1(i*QGTI|rGH9AFpbLwyU*2h*S-!DhqlT^PUUC-}d-*&s4cUCXx zkTp=y{8X0ahqbRs$D+D4?EE{J+je3vTr12 zcJqbJt2E9b?`1D2L|z~#fi$B>Y`Bp^lUy9f${`_NLdT0z*}CJo&5ancOJd>T%cT-8 z>u*SpvcctgSH0LgnDpc=X&IMA0%37TNV)xp@ab+cy1cMn9g1>5fS$t)xFrDW^gd+0 zr@meV4a5jq7*YZ$NpnZscXz&C!o-+khJjP@<;`Qa@m@$l(9Ktiny-Oe#DF(T4q=?7 z?uc+%GLB(n7xTBtHcb`b!_zgHr7I#Q8# z;?}vPuLO_%2gBR{gW<*CUY3oM+YGTaYhDKtdg@~I@fdNFyfV|vVX`OknHnMl)%ALrEJ&=bqN?%*y-L;d1 zSGK@fMQ=MGui|G@PA9$W<5%&B#}B(UYgS+L_|DZ*Bk# z{uAUA0Kwa31CEPF?iSM@&{J$R;+*awtgj$haz;4%GI#SsiyjEqkY@!RroJFdIMr!o zh`o4~=V@bI*46nFnkkn+pq-aYLGy@ z<}b2T%$7*1c@)E358&;*aWs{a^OX}$%pg)a*|PWFjRdw_HCPV9I3`*G;)B$Cv`HuR%=z` zd2Tlq6BCo+IddPf=&9jRclscP^C#NOztEb9a!^UVh~Ayu`#~#m$@nPA#HpEh%teH9 zA&#$togC-55ptDhXUy?B2n)MFsrDESiGZtSrIxRsK6(@kK%U&&q=z@eELy4Mn%>KL zu3pg2luxW&&(qHplnU(MD&*3fnv`-Jm&}lLz2lv_x@re$>XyOKL3|E|Ca1i1ug7bC ztgD;YmiN+q@+91LpudjA)7$&SkFc}U{;bvwvv<6MW2UQ5i{i6`wwqt z;dgQPmv(mV%-#ecm~Tm#`);E~%-*8t=rmkGJ}f7IL@c-K(km8KC^r2tUPPpR`;48P zov7FPQ{QP|`}6Pv)qFk!A&5FJ(96^Fys?Q0PBsJ5oKaJvg4jpD+ucKUspMF^> zdC}gVG-9ltCgRwu$*7F3LP+VweQ5^{*zGhfIu@dmt4sORxqgSTs1a*7aprcm=0e;l z0u9@stY7-zf6k=Jsf{;QaW;^$;DRpYb7MRjSZi8f)4JvQXvwkVl+(jZn)L~)$I}KP zGKEnb3M_TrTS>`M<3@6DVpd}*JMNH7KlcomS^Or^^2q5SMKOc&7b*hm$uVrdiA(nw zxf};G!K3t#o!x(Nor~xj8VY~S%xBT}`EDt32}YDFB90v}a#03M1a)+Dl<&FzjAHwm z&P{)kl}3Yk6_|t%DK;W!fl>wgvvNJ`UZ-eHY#N7AA;RdDXTi(uU0&yg$O29 z?eRJ^HGrw%kYo*8F+JTgGPu(*no{#A2y83f-w*i!OhS!^sld2`CSH>~Sh?w)My!xY zJt@@N4VxyW3r$aogpO4_gjGqyMf+rdHn_XEslLHhlQj2#*Qn zLykCE6`uH}?@#jojE~>yb?0UN>SUa-*qsH#^x=n8-JHfsDI6UgHE+CM-rRfzOdi@C z0KG$LPAMzBBs%UFTp65yDi9qFwAJ<$yP4&)=9>r`yhhBG<_N=_#%1`=8KJ}T9mLFE zK^$^!@X4Uq(Hv5p>3c^WwRO*oK{|%E~v8V!NU5<%{_a&Dxbw z3DbvB!Xj3~32f30A9Vo}Ts1`5gx`J3@|s=7Npfht?qwejNd&UpOCW>u#K(n-6dnZ+ zDp^iAQ=0ph9=-JsHiJkt9p*JP=0X0%$PxMR46<3oJI3&&>1ngUk&(HX=0P0?fXK#x zTHRE70yZ+O_UhuvIv2fpp*K#x%xLTq?G{ijb0W^;p2vv3(jXu<-v{K89V^w?jK zWp4}yEGuT`Tcgj?D)ehr!=r3{0;PsK&$A|XQp(C>rvJ+HvzfP}mayGej5@;voE_42Nr9yw zHTLtT>hen7mHjPf0P@4MSWnNMm%M@{r!|tW&!Y&9{M~4&6Z(AZ5l9z50d)2}173JlT9eA<(Po5;M z2pa0^Gka}}TaDA_#LNxoz#Q$S0)9Gm3P2Y<%vF#C%Qf;%bxJ`n?*Fk_4&*JmW9r&GMd?0l`bBI-jXtw0_upPs!mV%)<*H1)+wC6%>p z9T4i)4Jnm7RCH~+Qi5IQe*WG5+p^2i*spkY!9QM8jl3UP8=xyJ;t18eJ@lofh7I`h zB{{d8(*)KPxB~|BR0RY@_#1=Hob{-$ZU$eBKMBP z!-&KCUN36o?CGy~-fsmuBIy$Z2GeaD1p>_D@3GAuX7LqTJkdnKXItcvzB{+juT-%Y zl(n^b_)Nm?j0(TAzM|W_<|FLEt8;OS`MJhVYmNut2t*;>B}f#z%(;pe_I;t8a=$Li zI9*8+feVYEt-CLu+`b95l7d=GQEL{xp^zfLk z5X%+6yReBVvtbC@hws}J#FVJP@IOzHc|Hx7nkb(k@vq7cShy4;-&akBR89Nk^W(jw zOi~+2BOq9c-;9;;?YqnR#j5EXmr@kxe$H(V9GJqVW!75b_OCUs@!WWSubzNi+dbUf z5lA+)Zi?bLNyNQiu~ODIG>j;->0Q;%R30yy+RPw(s-dCLb8h=Qj(wfs4ox$1+INWz za_;Dg>XQWuqhwDW>U5<*c_r*JFJRGhT!H&c;}a7S>axk|w+%%!VECS6o!M|!mRzCS z!|X`Bfx2K76x%s~+?oW-lxeLF@JL}dGowqUzHyXRY z<8ys5mgkJPMtc=>Mb5{V^~r(zPPuSn)ubEk;rbY_%)}oZbUL9;`4R5y&Kavktq$c> z-%HYzA5{4%7*DMC6FN0O2rgoa-+04w$q;|6W zZ{L(19Sifs2Zx8pCC;VD&-D3k?8`o_>G&)8B$0KQ5}y3b?R8-+&pTlyV+L*~2L}@C zpC18mE@Y9yw)eyB6fk?!errPehle~YZx;f2`gPDxh%vYQMeC|qMMg$gGqV^`x|GVm zO$X%!=#y#zUF>@a$$6&4NPS$OIIfu*EWsS<>E$&GNcd=-x5%q=9B*VW0n9eN9};u@ z_U3kEfhaV;__*w0n&dr1Yg|7W#Gi^&>zfR^tW07_pK+I_$&Es>e+^H6;?ONyQ}09` zWX$lFQm=U=m7wGD6_Xm_y0j;1RcHkO$%otif~ElgZoWabgP{j*a}TrTWieKj`2V64 zU=vj+F6FrS-pb1^v8P8HsOc}A6tYgZ0=89#H*ot-nIHZ`;z9$9zdi>bR~B*VGwzs2 z#lYDrf;@Sk3J(gOhi%pG{lmZ(&c7C}ClV;lZ;5WyYgL{&*KJ5Ys6rne9(KIAmRfV% zuY;5WOZSG9c!MggUMO(rwMP%vT9?!^Xyd?Ec+gHAB$4b_k!c+r71zJqGr`q^+n_Ea z*6rvYDq8;Qau5d$F}eS$Te7b2AFAo5Ty^%mrc_JnR53@h#(&6Vnk7AH2M<)M;WL&z z$^Nb(WhbdZL=-ztr`~PW3#Q7=l=W|FB-)pryMT}?+{2lJ)#ecdWeX~HnhLI(e zxs*7JiI;r;erw4McHGRcow*gDK^`Pw(=+p$??dsIk05+zNZ7=D@~m{m!~k(^3=Qrl zaSq!(kl0!QA5!CqFIdCk5uH|mgIVyzi&i*kXhaBkHeqe>Wdy3{c>5NtPQ*bkw)e>^ zkp6$a=X)_;ZY%3L8@4GvG&BSWN_TE#gKV$nqZZ3n>NT&O2WU{bK8EA*lPAx?jkbFL zOORM8`5ChEii+oi)05JHt)tFPtrXGbQY6TjwzvlFu{8wcbkl95vnsV3#XW8Qp9T-gJ^RBI{`tq_e&}$(d^YYFDaR}M70XVe!p}r{)g*EmrfY@lMS&rEcVajWE7C|Pbzl* zfjj_)nwNJ!r7hba8jK{0mNERhu;{;uk1xEyuW=yD4xIOo%Ls)ifk#nU$lK^Ktjub% zOExemQLErY-kKN^W?>kyn5=fy?J;Q#s5#9I&@moarc$n{PwaE};@NEw6y`St$FGJK z=ofkxe4I2;a>^$-9H5Hk+=_@C3SKW8hmG55IviKzroI!$OHNOh^r^IwgtAP31H4~5 zW_=0MK~c@PmX(FHff4Voe?#WWo}Bc)40(9tz0XpnHw40J>hWm&1%!lIK2Z6&9B)7O zJps7%MR%H%E$TWz=qV3x>|obWofDnme!f=Z4i|o-Cb`P^8I}u-oVC5D+c(Zpe$tW8h1Ko#a(CZ*aUydE=Oq7C7zz{?KvBA zSdyDB^<=gHO5D4NATsl#&8g7_fA8^Kz#z*=9(vbnm1^#4tu!i{|qqwJj_yJf2pl8n?;H)g4`AJ&HSKeb%iu}y~xw3Nj zF}71@`*n@u~eZ#m$S- zsSnefG!iKvkl@+N{dqu$sL2D!Xk(>y)tju9!T=hQ4a7JdoLPr>;e$S%;{cl z`x8Uc@V_k)odXVg8^;hYFR#y^K3#R3Ff{eN*aIV;X6*54rCE0TCUxx0F^u-D|As`x zqCqjn>YNA%{9tD!&G`_Z|Kye>j6M2%E{xdtR4_?Q|9<+ID?2Dk^xYUS9uYJ+YNkbx zw1YbU=pY6D!h&9`HwINvWJFqDhb{a6RL``^Nv3oEQ)CnA{(n@v|KAb8|CG#MzZhhS zI9W)d)cUtlKJ*>Uzi{LY*?;SEBwE+bFwT;LB8);g`ODEfm*~cK9mKG-7yxR*0s6?X z%=`ZR2Z)nEp?K;V3+ zx9050a74|w)4f{7w);Hs+mpzRiV?rrX@E0HDzMKiWsp6pVYqLO%V@d?Hyy*F(CUB! z((@=j=lEtGq#(iPXv#aV1Fgn$^*+)pxiDoLhyPFmd}=L^3qn{$5jx5sjG7$82LB`Z z(had8>{j=O+Y@}I`(Ep#S9`$a;i3+9<)}YPhqCA1a@FQhn?*?hEnw$;>!?w{#}#*4 znUi$ttvZulpGdwqCF#syD}n(c>%JHzL=`V1^=RqVdp;fQ^brtM z|2LS!ABJW9ac5Nx)d#;($(^*=hjmHW2vq}mXU&!L@O{TayX1RDNzQ?5CbJ~|+j#`R z@B6P9O8k2sL8DR&tw6}g++ONR4c**yI`LFueSyZre*Jo5W3c`*+4-< z3lJzhlJknR@mFe27SqWfs7CB}BU8%PYCId4=IdgZ8u1&>_UZ#qo;*pBb~GNZ2hBZ9 z5hVlVCO}t9fgu|grTHGFn17=)9(_WTnexyd7mvMt__Sy5>IItDpxTtt@J!=H&A`88 zc_OzLh_}Luxh*so{Z+`_lQIcEc1%>p=6Ug3YAhiLY{PDB9%U_dW0D8&gww)M+>|QR zWVJ+N7_7c7)+~K!87?&0`NbPM>eYWwC5aQ1AXPm`RH>X{_+?u8O!08^MWZtkH}To; zd(|nsbA50=s!?8u`~J1_MN+;CCPWZL--i^I2X?kI(NPAPQqPuNd_(sTWf2@q8!-1t zy{q6tYc`)A*PEX@?0rhthG3-XLedckA3WjmKI>QbJtZUA*IC5VrP;!&=~ZYD0B;@L zu#S`c0r*2gxtpfdGKFsTuZ{z|qL8O=1C4mF8wV5Obaz!%q3?cQo86IxEMcdXDO3P( z0Wj`qh22G-cxn*5H#VP<4U^y;L{o&<>Y`Qg+!3yCd_0Yb+BbOa09CskvGzlmW1iL@ z7w1JPAk&S<-tAYioKfwgRb#ljB4UA5XVKn;Do@S0b#QOxVU)si5xB?S>3AW38=FOb zn>aTlBCv0NIwzz@U}D;;@EnKhv2)FaAz)QBbf_)NwXy|TniM@ushvGMEOs1`5hAw{ zp?nC4Pj)u5i4JV8mN??AUSfk>l~3v2k+~Rjk98CX$sY>~=>f=`nwkR6wW%-M7$;mtiE(~te7fH9&@|(r!#!*02S}~sBz>tPn+^9<;yL{-Zeu3eE3T5 zuOAB*TtRtQXWFB)7VCYdNG4EWpNzPj!=<9^x9xo}f6r&;6P4?Lp)+|L&E*$DV(>qU z!^qn($i4^B?A)EnL!GStASzBjMh4h1W2F)yYK=fo+?N2~a#k?wIWO+oG|;+%l*7iC zDb5IB|8AS%S|9|BO)4N)+1@_?Tg5cV{)vmdS+UC8AK4O?9eX3uwYA2eawEfYprdhN zE;)^TNI(DO(5FPt=wX;S0t3o;WPzK_b_BCE)`b!V)GCgQ{td5m=?JbMOOuSgu z;OP@QLh5^OzWM=fF)d={Xc%SmO0i}&F<-RK+iN@ltVuUY&55$RxrIR~Oh#UwO!m)d zQs|2Q<@uQwTH-4tmdy#f8tn#It|YGhe(wS%pmlbF00f&aH#BdqS=!wAT2b+&ajpcs zKC7@xtcO}-jVk_y!~K&Vn2<_=O~MWP{ZT#G6Kn#5H8C}uX@PNZ9pCxW$p>4FEgI{#8vRdX8h7XeRs=>)7f{55iew~q zAnOe6vd9gzHCySYUxP!#!yPj7kS3C6vP`=T5f4V-?YRPmev3zbMA|l(WgCqmu}y?! zfdC!v{^+;4l!fHPA=zaXN?M3Vm<9%BzSGx*R-&^=T;a$zW=VTuQF;{#lyCYCWDmrF zq*<~8$+8_9w5d5k!qq?%+q)In`j0|tF84nQDT%p}iZ_*4dlVZ=?{9I*x$bhC&LJBko?geKm3nVOjw8kh(!hX2X@^pPexLicX2sRISuLYcBkj zY7hLQ6hsN~hxTM|oX`Y)8F2i!UJ31mgPGR!>%-#4iDOHd5g*=)9CiUcQAX)h)DLm2 zI)Yaq(9pmcA$Am=Etop z4OfW_hOk>Um|Z!7FTLsxIB>u&=tff(%N>7)1p;_tBLL#A!v#jwC#~I0O5AQd@BH-b zoG~)R+Y~{^qT7Gt2EFlMJ_Ch>gl7MIQr+`HZZ}gM&xA7cn?ak9geBzcJE7#9svQA5 zbng)1E~4E7dwo;?>&%yAv-=b3(&az3YL`F11?k(W7WM=X45!AE5s2{5P=**1{o$rg zZxcYB_D1d0farFEQ+69Bh9pE(?{*06{84R65<<5R7Y?ryKfe`rvwZmNajv?6NiijU z`b47fRPtLv0Xd{gX-hHSyU#`?dgpJ%fSLba;sxb}pV39Qh=Qk&7;#&P!~rzXU-Em$ z3koa7QKd#x_bcL_T%uPq@DcB(5Znz6DH90rcNKnB2?+c~&|<(nvEWDW;I8<jOE4*1{}>3M@M8AEg7y3T z4?+o@lo`qNr#BaeI19s%XC4FP*4V(<``@aeI0<`Wa&W2voM0ImsHZJbm3ddI7(XQtVC7OzP+lh^0NElSvV0`sA18GmHGPB! zxNvh%QXNaLxBNayv|UTv!SGSf{`#q2BiP}n`66gVD{%qY_=SR)|Ahkl<2xT9qh?Hl z%8K8ejmLjfshy_M7JJ(Z_w$e1v~sLP^Sj~utZ}gRHjUZB@nC{<|J~j%Z@KXM3ah=Y z8atsV@?b+s_ymI0{2Vcv6HNvwKDg+73NjUMUBfo)xFd+a7vEdQ+~}c_DV0ytWJDbj z1f*l@`pWy_sjUiI^-%61^5l3j_V-xkr7xwXkf1y$ic7PBPlz3`e6S%m0!Nxon>A{Z zMI_u^+uEX%hUg!WH3sIbDBWDUVKoOa=lX-{Xu1dV?9>4PVB5Xdv*uGBAUrBn&T0`bM1&BM=>0*buy%&8qLlS#2?s zt@$&d2&&T)I-5`H?>+{9xe5W2<^z~G*U5tP{={1EiQq31x*_qrylA-3-|$!I+^j;z z*GT0b5SP`#n>B16Bxj#TU4-!-3Q>M_(ljxod819h-6L5nX(z%N8!{%iGhRZQ0wdphOa*tbp8E3Ig<-u8GxEJ>Dtbbf;|NNO}i+eVNR=5d>)}juhqR(8KDN>~DSxynK#@$5JuNEQx z+z!}+B0#&qgo!92*;RBoG+5u|W+E%K}q;KKSj?*H|?F z8y~&kCBg! zjlCYo)p-FJZv6(AR+_Gp`9*GFC>IcPCgs4 zCO(`l?Rfcvvn?6q89DcMD|4f1ofjYtc&j}DD#Hd~BpRH)t$bREYru$hfKs?~PgM@k zi;()$qq8B^3~!m<3T;n;iOw!*mdwQ-KWH}$JRREmGDie@#9ZIgF7GVv$P^gYR>Kje zyu7@4$Hxplt1cE`HDI^kzq3*P0((89c7Qk!9&SNx80;DWh5js% zJ2U`}1w=K#*Kg>F;X(#xY%JA&FO6Tq{5*IVjR&37ipMjT%FCnTma=4B&j2x)fP)JO z9s9{fbuRU`2Zor-LccB~S7xi7vy+T$V*y71Dcrb|I#G0LIgQ5s_6Ix3F(~Y@eYYVO z5jg39H!vscpsFsUiCIVS@B3-Po~`wDHC0vB@k&(f>aCidvhFNN+jsRGplsm#k^WH- zss8J_c8`*|0jCv|+a@dDLEF|eZ?Ad~c5k(lTv@L53`BXVcST8s5r+N2N|$(d#n9TW zyi|JC7bN-wN`*v%;Z`iC-prRPfM?Lb9VP`NGTjwGo+%Hk5K$}Z-X5$C>F7&X z&aYH50rG^{{=QY*m+;|CgmwIx^Hz{-seh{5u5rELftXY}q<)j~^Oq(q6=#(yNz~V) zzHs;7bLx8c=j;DH&Js3C`@fz0%;E3z4`aU>c>mKTThPU`y^4ELxqRs(h&!5p{~p{G zEzO9P+M^k6@cie%r&#z1YqQwUht_!Q)Gi7N}gb@Xfto~@pfBUi6h%vl7 zWZ6XQ7+q|H>vL&ktN-S2Wh$^Xjej=^g%IQ$`4ojee-bbX13P>& zZ|=}UqUA<+!uFRujWT|2tgDJ%+V_0Y8lZq1;A&n}m+PODTG^7~v?KSMq9?Ea8h7Yw zgX|)msiX*1naENC#YdeNTpJ`H0z8C6_Nq5XT(rr6&YeQ$QZ>Atn^dsyvufSb@sY+? z;k2yd*iZXdRkKZk!)bSO44?LN30;4dzRJ^2SD;mOWG}6n6kY8Dw+3a|sVxPPO@yz9 z4^p)LhVYxr&^ML&RYAevn=ptugPjN7rc^5;^q`N{Q$L>}^3?-Ycnz-X5u2aoN+B)F zFJ$5;jU@TMHxpjW9NH+0Ko@IG*8JPEA4VE3-MQ*X_MEcoifTc@6>wHcgty0S7rp(M zF1z)Co=D?IpKR75auqY&bwIN_8bMVD6y53{JYHodkpyr!;<-N?IB#r(2!5jq$|8;s2fw8Wy+ZfL6V3pR>5~ zTvD=ni7xz(g{7|oXwtQMf>mQhT_i|;=nOQK@iCi^T)o4`Zaz5nB5UlK|s zNrbYMQ7T0YS}1F>m1U5nMIrk(g9;%_C9-GDI+g6p*k#YY87rNyY?Yx~<5y;z`HBvk^xG!qOwoXoNVrdEyG z#SfT-n4Cs9sS$p^I;&bJ{@SmlOb!yHomhXF)RIhM3*-_Er>Op_(m zu_b$VTiMmEj}t33dOYca65pS$BPSK!^ZC#fY}OKL+|SD5 zpLQoh!O|E28`t}u)VW%oL&!TWIXf&u0VXdkjR9JX7X}kNQeD)3+ZG4PHncPh?Vw-Z zBRO&pr5XU_VlR7sNh4wpnop3k8rrm1UkCZtFt1G={a*Kq+&Mrp<@Bww?MztcCCXNG z2l3Aj12XKmQG zu$Ty`g3`M6tv+;hYEbIJo<0Z#hVMOVK})JEpP$kJWSYw$m&0T3IdhN$lo<@rR4#;z zi_2tY{FAzc-YkK=kSbLuZrV+b6$&V8wl#jsu9N8)DF-DP2HWsFx>%Pwc(E$CzkfCF zBK%nE;CTk$a}cnqRLYG8K-d#@#5W$)S8r&jt7$npz{TD9Q7)6(eSa%jqlSy)m`RJ2 zFLzqEIOmiQWHLmmpaujfXKY#zxVXAnPBpxIm#_#WyM47wU;t$-o|Bq2k;kv-nwh-< zwXm+&y&nOtt&M_0Z03R_c}Xq>gx<72!k5vn!w7=Pcc|L8#Cc&*1|dJ+f3^CpiQuO* zF|Vl0^TeQ2n1)za2EA4z(`>J_>(e^^rTagL2xM=yrC|^wv9p|e7Sg8Pg}_??V=l1U z=v9sTC{@l!N(jz4&W@a549Jo_Y*>>huY5TY z+N;`u$wJNMBY8(p5^-WqQmO89iMFNdG?m5a#LtuxUmw6gRzUK9jX{WP>YA8@78FQp zzCX+4fF>6^zgQGVIJuwA#oc{6nYxqQJwCpo4M_*t8w5B+i_)m;Q0kO650HZov zQ#%lxD-CVcIyWmh8LP@!?MfAw8DBgL3sHb!0nB&xOI9p!??}sS=*Vm69_~Q&&d`eh*SxDWICm0TK^l zI!O%x29n6-r%&rDkR+dmQKn&zuXu|!{Po)7CEygvtjyLwz6*>Uhw#SYVAV(j7au*h-nIG zM-{LLMSI>3S26UK=^wlAE+}*2Gt&rfqOQ0oU^yNEzz8<&WTh2jNctSjB;tXYm;|wu z`&S;HVsbK=mOeZIp}y3Fo%FU`&QzPGo+@-enV4~8Wq_X7?|xp>uR z-ugaBy2P0Hvz`@`sPdf~3l4&qUnASPWobvLr;fau8vNi^x(~t@&veU|<*Ui2^sDWn zb#Ll+;Xx`M*;DSYGFH~BFJmvxkh$5Ib^hG5+k78Ac{|@=Dps?zdNOg8NG}Ke;<710 zuSNZlJ~s4g>UM8(+vvW!kYdLeX4TD++T3286_|biDkN za=pGg8*nB0Zrw>znCSNLERS?-Kzz8@swBeMxytVamL&C-Bof5;fCLG0ffUw z@hzW_VzF;!$JVS|1`>21z|qTqHJb>!#AoLz4W0!$QKyB_uc^syWpu4wOe=BgU|cfy z)M@i`{x`+rQ`2q5YpM#k8~C4h1Ppn6ywzFl+0B^!LPRU_CZJGYMv5La7CjoYvVVL! zd}G7H{@UqqQSa5&p}UtI(^+Wa<6dphPZmF_CwcR5){mHXQrFON`Z=zSix+l-xv81) zl$&V&X`$D3AAl*Dq$pZsKFhO@y_w;=wwQanmtU_}5nee`y?k;gDgGuFmdV?ONYJrt2hkc?&R<4X_q*8EC0^UY`QNB9{fDhrw z!)@cB4kX$LG*33Hbd9G@>s9f3lleJmRisE&KVRLpH+l=t>`feKq>TnG`bT4)2lypU zrF%iQ2zE5u2{>vKOZQ)Nn*MX;N}?5FpD7e9%d{=XtU(K`tyq`@{W|hAxxU)62b9Vl z!mWfg`f$|k#@t~Cd?3YzaM*V%z@z}}u}Yt0kg<^Y{`w2ttL^gx8mHVTNmu;mLQ(Mn z(zShlblF0h0zMK9U+lHsEZS;f znaepalCmpzwQ|+;{ljCpoQVD8UwDv4z9A+DKZH<||KU9>y>#+k&hANVy{I4urtcuI z_KX%t#|Th+GBgs$eD2^+Gg&-2CwE8~D87U>Pfu+ld1&G;GjC;RidM*%MCV)5d?`=2 zV^nD|N;k)qTfsh9Zw#&vv(9xoiBLwJ_=PMZ-l6^?zW5}R%F8Zv7 z9n{j&ddIE;@&&8=>ar=e-S_n=43X@NECDKFvNAyG$4HNzPh5ktdCaEfN%=zN*Fg}3 zC*<VIETlo9zJ`B35VURPf4oLHhb^ z4i2EF)c+Q|$=8@bvRpKs0)ligTo4uxv}Wi)vO%(9Rt-`LLg5CxBqwT{QHyNX<>?CW z_vHn5BUU0D)M7KL^JsEaH8f?TW#?&23txCHc{l}wK*xc~Ow-2__v7AtKEpF5 zE0$x=x$V{nsygg3YJ$Ff-9o1hnN0F92H$2e2lWDF_d8-|WggN7tF z1f7}549>^3!&%egE-sYN{{zyqQ=w&K{{K~c`ZuMFzY=(V1UM?#Rd?0qXg}c62>7W( zvQ_Iqxy}u&stxz3{OdDqga+TIGyR4G#hkRcy!!$23_;7L26!mY`wS2;|9~ovNO4V- zI;eU5*3Qd9$CBTjwE%SoL&K7=ISNu7N6tc5k}p#ipmwk>B;mA`1jKv2MeHCb-Z> zOyR#D%(tn*?|Dvnx`iWUp%Z@J3%z#^UBq!1>Hi(xiAVyM`SXpEA0+56B@5bR(KUbC z)HV#KpF=ur)1`ryl9;ps($kaD3-6@tzes&gmxifCGa~!}e)qxOhGNz)#Qw+QQns-F z?XJjfVojieV;JyN<#gdp!2<>xPjtCQJGl zJvW|57v*31SJ#9gH0X>iUb#ys|9$Jp6st{>hXFJ}FV^EtpWpuWp2q=t^Z&6B;(vCq z|KTE5ksz{uSD0+vtOuFhWK;grK6CCn6TdPhoME5Cp@%}>n|lJC#0p6(C1S|mCwPHP z2H64yV%wljo@_&F>#iHD2>ClMU(5h-gk-N_npYaH@+%?Rb_VW8pP@4ABZ5H55a@&5 zNik|g+~$+9ETjnvLj3+Ji#bB~@5(oVA7W&Xb_(02{nV7u%hT!3UUoX+xT`S6D#iN* zWSGqDj%W-!WOEs7XoQ;0$jnh$BFN@gFwRzJlr*}yPPZYX{{x-1#$L?wuQ-g}HtH35e5C>Y9MG%EN|H2B1wW|WyF zb@ceeRlWiW!wdLO-u;oj`-}Q^M|bI_wSAWj|O}AK^NmS%r0B)?5#I@hOc0f(S9A z-}=ac3jDcF0kWrc@tx=T4S8|Ka`bSnpSkO z$-zYSTb_Lic++l#jFsH12Yo`PS);;3H|(MlMsMSBk|?^_j(9OUkCMlufu6Woo6R`` z^MeCtEzGI(v>A7TvL^vSC?t4N6w1k_zMp!eSF0kS4S=?j9_n+16MrJeOS0mC_5(?# z48v!FHhgD`v!(}6qnOf#PKn^ZJfMQvxLTCZHP!aj` zpAmpgC-b=<=R7ByF;16t=1|N%ca`$xi0f&=*VERiapHh$up)$7S-`J|tHI&$UqY=@ z6q8-!7t(Yc=gw!Gu}s!@m+EA~_jgpHpHaZ*UsC0c$=40LiYi~q_jHx){ctp{rbPJs zeqR~mF^c__)A#o>9EYOLE89oy;5gF{9FqmEC}g+`KKaK2O56Y2pxeo{bzaZ> z(~1vAWG0ONd{c8}kIRvn3aN(0`M$FM zM*3+z`Ab1TA%3)_n`dJ#bO8budtPw}X;x}X>%R#cJ(S0oP?^Y(~NLamR_&{mXD@CK!gX;tL;!d$jG6A6ho}-FheM`bLbDJJ)39$_TC}3|hM(`(7 zQ+sQBkZnvHb-fMB3k4AUGlQ22&h?OXX4Mbe@uCK$u9}rfTQnOV^^r(;{(2h?WTvV? zfHYX*vYdKthtF?V+1hhQFlC8SgFoOROWG z?*&~1zZpdUaT_bn+jPbt)CX45?%;9}JQLXJCaO&h6=6;JrGV}8sQ;%SRk#Yjqt>&^ z?3V$`dS$fSHTQ9C1kgM>Ma#aE=3o&3#~gO#JUdMt36RV03>LIxOaVC3wRa_HdsJj| zM*;>BTI} zO1>DB4bjZqkpPJk1RC(^=(XXbs;%wKO`FbB-EjZAtjNmsgQpNjO(?-eZ*lkL1WTnK ztFT10V2@D*Ad_8$hpQD)RS-WAw0`5ebAg&n=0j{(V7fsENE600%gXK~-BgKe0IS@F zW&J}p-}}eiktprqYClZ{8TA<pG)?BEYF)w$(??Dlfp{5enULU}; z=jY5oftl0J^Pn+5C&`s`^T=jB+|0CC?1janl(T#!OQ zQSXK|CQ$1%a9o-I#=Sa-Pd%(a^>e3C(N%>Jucj)u$?gWGs5*@pjrI%+U4{o=^aEp0 zzG!$&qG!P={B=&w zk&rn5ttKK1|ApFza#1OYP3dFGHB4!FD3cEIy{-3&iN1;B@8|Ad5wM6&&^D*D;aT>m*GU|L3#+7;bdt#8|dY70Jy;$T9*VF*! z$xP)O05UNt-4S45VDRTUV_{o4a()_|*1nM|ihe^AwZc#FqJwF_)a)PKbC#fRDHFca zYD8lPL53|jAoN{vbnib4;@b>5JeGG@eA?J4CAv&ATaiG9%a}z_NREF8pn<0Wdg%PG zs%>)&r|JpvT=)+&#un!+T#I@<3Vi0TNimg=x5z0XyO&@pqd4@>HYAi2v48@tJM#e8#6-hrk zJ+oL{Xb-XNQnqBjxHI>r%;7%EA@e)2h4+8djqTjkU2*Rj83_R)5{63I_MBN|w@dV| z>&?nax`3>ekUh*`!DQ|C{!Cx;00V=PTMUux@{-rr{`Ki0j#K-<+=p|Tgri@aem_U8 z%`Tb~wJIzS=$cf65!7_hCHlvR?wx$jd$z?nq;GV{;a%-K z1AUj$V`6{bz^NJO-{0MyeLu{Xj)o=Y_^6Lzkz?g31l z@0&%@pE#>isYZf+dy|%0i6X^kD{qsWt9Rfk#azbGl*K34e%@!sDKNMh-IXmq)f1Lb zqwyMjz~8RJw)jfiw$|hN`ugjl`~5xg?i4ol*HeZ;%P^h77y_fmWHhqTyqY>*A| z_3Ky0YJg%oN-0V7P3^)2VbF zVN&|BHOyW<%E07P&;N#=JEoT3Eyoq1{rrk>hP7O z6ZnmoRgJ>|B3;P0ug=c-NV?xZWQ z>dG&jI~L*nChGRQ1JLUrnuT*jma^Z{W0q`&5-j#gt*hBbNXq&pZR}2&N>DUx0)XUC zjz3f}EUNip=ooUsdK}RnU==%ivF;b#4MQf@gNR=X;a)6D$If)gC!**AQRE+IFM|;N z@@ff-pOO2IK`P}@0=|xIetWUndjTa&o!W!nM8WJQ2y(I1w*@Q-9g(h1MqDYA2IJXV z2ON*!r#~MU*nW=7G~Y{ii;FTmdy9_~r8kfy~_+Sn_*iWC{Cm`X@*TYr|Nbm2^hrod<0lFN_HLl)EoXnBlF6xBPQyykFRbb^aJ zw^LSMFyZ>qKxYA>EOWU1&aZ^+(Cav(LAGS$U?}3jm z+Jn3~xCXGT-aDIGGj_~*%o|yoHSmImfxe6V?jU$!T25RW&%DU{S+2IAZTUjMB9@)Ubwd6`}o$65L2oV#K@ zglbx_?m8FqaB4KIn_IC3^L;nB0iDP7 z1ioD*bZPKmP8_|#j){rM9$P=_u=@UBieJIfM9glqzqcL)xM9EprvSARY!MizfKJ8$ z2Fd1WR{N_UP^YEV-d`+t&o1uQgENSkO=<4?=!Mrr)TmdvZK^#BHME) z^la2Bpk3vna}x}{F}Kmjv^Y&hPHxWIAwnTeJ2c3)@z+TwI9(|6)qkPu_&u@oR2N4Sn$8ORCPeuhT$ghyLlN|^(gwJ&$6f$sB0 z3rKszeCka2EQKmpkxYaU=9Va3uFRT|+FAK?UnFS@*WYPm3@c)gE;jPzEekq}Cr>)J zZ{7d5VcH0W>6eTQrdkW`1(%T!dS0lxX>{e0T^aw~)8;Bbe6Q(p*&7&2CqPMr)YLv> z$#4xWB+^X+{e+t&z$~Z-`KD+hodrm^-z4qUd`^IOF-CzrLFOQl{RqEN!4mXN1=*mV z<^y=kO)6TjAnjrt-Zie%O?&SF%QNvV zWH*!H@6^v&2DDcaCYQissR>B7IxY>IuHR8Yv8#i7a`)UXWv>CCIc{-Y(|ogvfl|jG z^zov*_X?Q==H=M)L@T=Em_w_@61DGnd5y%p^80(H0|&C7 zE|#?#VzD;W2$~Q81gC8nO<#I9h8(PZ%=kBZj=YD@eHiey&|}StW_5}XTG#ZC_%~Ud zsYeOrm6Y&;N2~{U0OxlR5fS%XTn;R_lw0rot1rzWo}=$IbAt8=Fw;U&<2IAKcZJ>& zTQ)Y%NyDp6Hvq~Qv{5p|aQy7Ka|aF!2sG~C=GK5Op9V3{z&)VBJioHixUund@a{id zTuUm56T0RHs5OD_-W`(asqosA1So-LTuOKds%k3^B{11~Ek*c>+s?X8*X_tDPRNxX zj>Fr8D1Vx3+I>;{^;mg^lL1gjsVDAafq7Mk^R|}7)2BTvMrGGs898F5VDD}ocSW*i z7tKzWK+_{{jz<_v&g91b+uH;7>(4sP`0M?BG>JUgHR=@v@ZjC~cKBt7`JG?!D85nX zFqEK8*MyjC?3i6Xw(*0BRW+4;YCwLoRyFIyT`QxsmlPUKW zNsWuz$T#>5E z;6+v6KVtp@;Z5Eis3jPEr8+ACcbRk6g1^~W*5c*!M-B!D6o?xN^aGnKbddS6J~qfa zW-#LZxrf>nKtQYJXi&QxwNqQj5*Kk}%VCjGIGliez0A_?H9APuzJyRYcch3E{Il99 z2bm}6NZL*x#HjT4!>6!NPDJ%?YSLhWtZ|r*g~vRP&t7vy?0@D-Cb(kU11R>+y$ktQAH|Y$ZU-WYaPhj zoonC*1fIo3D0nAeZwbE9WIgoh(T@!dX-GKIjbBrIHDY*C@YZsWDf(Nbg6t};8@`zz zye#~_Hs;|*iR;yh)bEzs)6-5aPZqBpd9cK?ihHu$N)CFAPz=FG&E~)$ZA(Y%GJcTv z#Z!ap2-wy>WQ-O1C&B&6;&X(dT6x>pcIyO1!QD+&usdoZ;~T1+qKzJ+uGsewq(-QV zUR#GP?34(=BM1+D*{%SaWVMx@j*=vW`@OMyGtgw4tdpcAT&c87j7UD}gjW+KhV~;x zUphvpqSFZ?mdt(uc#knJ=|;gb3>G#B>&0Z<ov6l;JJAszmOSbRb&tsl4PNg zQ<&kGc=a*%rVJwZD1=<>NtoGLp~CF=X45dPkdseTthrpki#~OFlT8TQetXiL@u<0A zF(+kfXVnYGu8BsH93$#6BE#@JiedoWK;WRJso~x9zrokZ6jrMH?g{4Q_O_RI+=2bwhrFi%; z#Up?$!fb12hdUUi`mgWn}h)tu%{b^NYB zOTX}Eza#a(X@2Yf!2wfDm;w+)8V~&TGFh(kUsf&|i!dq?4r#Okz!p`R!>0&IF7mGy z79PM2|5h+S$S#5hLttj2(5jIg^Iwk3sQ?WjtMPJI<7ywz&h@o5r?BvF;Y972Fz!b$ z{u<>hWHr&uwNCKJ5q9wD6p--5)A)@mBj=ZB@;X4Q$qM+u4x{pa++`LB7l1E$6K4yl z(Yv`-@=vK;oJ?=Eg_lvhtZVg52=%}ln_~q zIJe8Abou`$bH8<&KI0#Y?{ENlEpheyO6fk%;`+3;O?-`I!uU5nR?sydC$C*-tX(L;K?0t}UVgOFUf@7QC?r5XY zlqmUZs(C!jQYxl>6Ful7q-R2wT6~UL8g(9#1sLT>nJnRTo{Mu;DJg;-OIXaHgVutB zD%BW$K6+)a_#r4d3?P+}CNWEx+##A}pjtK}u5Aut20ozkMMe%9OvCc7!1BI>k8()f z0u(b`1;vIzX0B5Z!py}vt4U5zL3_*CNsgmRDQB}ykg1b;o)q=kjCIm$M?xZt=^W=b zceKc4&Xgo zuBxLscZlP)&z^P6VRG*@SJgggp(HXbLY;`Yp_|yx7+_Z+%7Yz!@tlfwW#WFx?jj|m za@v~(;XWF@A5AF^cQJAk<5>y0t8iR`QZL_AaR4yov4+b*@9AzYVngn-SPqXOeJ+RJ zj~U)8`pU(5XH)(oHR@t&MVt%S`=`5r-=*8%A$hsA>H6kHm~KY;n(`yBHXQ;8a%E`e z+hRT6j`=0p`Bf9$CAV@5(7niX&c)=&IroXh6H3Qo%E`UhRl%1U%%@Mr+4Iv6LmRMu+hK zZiWINgnj}o1fSYlAZyXv+j{~I|7^tsYK{-FkBbnl`UIgb8We8>fW)ziO6zvldc zg3a^u;#UJ_K`@+zVkPtw<1aC&|B2ARYKO@pm0OtA_>)k)GA&$H+WE-?Y?Ku(*k*)m zr%*OkEN{@x=5W58n#Rx5}7K6H1##^R*#De!zjNUP0c&w@*fEaN}naEPUN zV4Y=yo<#aDo#RCVKBTP|2lTRuz-o;l5+BVQ&HY~(#CI!c*Z+o*754-BzD^Hsm|#9# zN~8}X*M!D*3@gsp?>XG0dvV#5IS^5VsA;dEv*kAC{O9Hu51vkCy+?7o$xxUCOTo+rMe z2B59q+xh>gfnf!_KG0F!$^y6TTw});>Gr<$M^f`80+{KRI7&GRE( z2?#bylrUxA%T1Um%MyB20iDZXTn61HPU?VpuFNsP zFBkzl&$YQs?ewUA}b>QDkZ`+>m_Bjw0f8)pZ9k$7%fiEkX?!aR6CTP6$zp!eig0 zQ^;9KbqR#^Hf+H~9vd?pHozK%vS=nwvjnV9}(Xvq@T_!vqQ%%l@ z>Kr|0L!n0F4F)j_*azzb?@1K?kFjpxH+8S0K{Qy87uEhw?_T}8@2}_|bjN=-ND)PG#hX@9b5DU#yU} zGW+?_M_qkj-s}9V@dm(8bphx3&MPnArLyi@K(TiK#{<9k~$9#Bv=4J=+7yRcc^z{zb2=~5B!lrlKG9;Cg}$rK-mAQDEQ>wzk{>_OA8pzn)|`Zd zfU4Drw&=OQ(`{B#_25(|tJ;^ZXL>eo(`k)b<(b$q!^;sl%kpb|FlWh>(<4@S&-i>6 zWS^3|6x}6-0t&K{MyxJxCs9W zq*d5pA1G}*HvFdkKV4XN(?*MYMtrdnlaX%U9x@lY)0fCy z8j-b_i4#`Djm8~a;rsMdE6RLlMJs#@Ox8^GE>iJHHE-rHt*HLA2XQpIR?GI#Gnqj? znSMLJT~8xP0(@wH@PZnc{hL$EREF+#x8ZLbRo9NU`FN=0PUO?l1%{K~LDk;sa9C=G z>4~`Op-gw8FI*c~hVHl4A31O*7i}DA@Zh#}2Ss?(deuNc7+>zP@Or7M;BHZ?m-#%d zfZ-F6{{|&Q&bAn6*BvD#rSR_VTbM4$ZXj=f2kVLk2*->1A>5K~_qG{O=UcSZHM$eY z?%2zc$9<{8^kDe43`H9$Z*g~XWas!{128(}6t*UprW!+yf%;?PZG|bEwkeav6vrp9 zEfHxoV7VFWw-5+!3WA3L7v|jn10I2>;i$ICKCrb>Ti&ypHeS;jL|CN{Jad4PIBQt@ zL7}k2v~#u~VE8?wpZXfMH>rn1P6a}KNN%KQ`A*3e>*+!>BY+VTiJL5g!5gAn`tX>U0AmvpzGm`lYkkK+5c^11G2Vg@ZnT{UkPm+RjlGWcze)^6 z={sj0Y33%WK1Qh(?cDJ8QqtWbmDs|rm~ZzDc*Uvgpb0o(ct zoUx3{!+dk<%Roi27FNA|j8cq*K_+Q(JB*ckm0NcJZju>dyt-V7FY*3$YnG*N0K-M~ z#-bw}Y?IVLv(~&Xcx{azJRWDA*mkqZ{CMYN+eAd$-kAVsO`|#pkfNx-&LcZb>{2?Fx0Yt8p07@yTv22JkO%56FRr0MZ;*Qt+gM?ZmYfN08T z?$-R|h3G_WZS5%s;`VfdY!^gk?vcRwIEd@CFXK2slhJyxlw!bfg|Dqvb`&FdbH&^ zzy@>vlwZVCotwKlLPvt*7J$Gg1j0q?h0V0fr6FqzyR4$pZWnV<1MHIX%P7}&1Sdem zXunAfg8Dv3ZmT$v39hHi%Fj96WqT2T%FfOnX`*vBH+y?I{wi>dkXgKf@+`;dQ_96l z=8w33P_bU|l(yOIufN#G@SgW%gd9Fs7^+{Oq!Zza2ock;TQGuG&k*2J6mClK|Z!HaRnn)3+@2FW?sDNau|fK+KC8N{c)DOs+zR@!ZPu-A(thO(fcEcDEotR1*W&{zXm|x*Xz<`PW)f3 zy&5`<2?kqQ2>^W)Z?|tRC5&s0^6PcS&I~2Wl5bOuC%g?&=7~5*JxM&hA1D$ZJb3a@ zC?6;#fjsR99s5H2H+Ksaam+WPuy0kBlxbT|kJ2YrQ9cO^wrgALxv2wJi$baSR18hrPG_M!2p% zKes0?lg~1uAYD5{@5D1`3RvANvtTH`WLrU26DkY3OL?g&Sw>cfAl*W#FLzyi+_Z^$ z+|T{$`WcV!?Mfh1xzVphOZulgbURT&ZC@fL*%6x)y#j;3U)uD8WBj{953nAwt#c#U?_@A!G%G zd?_6RyuUqj!FTx-FtXmyQdLJ&k`d^o6Q3|)#6HaxmS?9!&(*JVl(HRv>Uhu(VDg?1 z2JJcKLq~Pj+ZgmmtND`Y4xC~jYXMr%T#Wx=mgRarhiYtJ*fC{pU|?iagOU1UY`dF0 zJ@>fMSR%YzIXXU3^ZzcE0|DUwO|G5A`kDfL3c#+uXK&9z(+SHTJg+578e;uhKcY0Pg0T4k zuzl|C6{nqRvDvmWAGc^a;Lkm-T?5rCgtS@t&%0ow56LCZ^T{X{q(oCw(`BmmKg-k4 zWRNQIUUgoZx(0SIET762So19TxTUZFc0C&#JIaj2*9V}qG&TE{L3jNA7XK*xEF|{? zzRY7y7?5)y=WAnlDOSOqZc(zcK30X7Hd9}I)kFT|;C^XMVk_kMLb^>|(rP=cF6yVi zJku`-A)HmD50c&6dUg=0h)?{kgOuG7vHL2~EdHxr_t>|$%mdV|>hGuu}rZ&h&;!tD1vXO~N9!r1XgC>Nu<&KwGO z2-77~g`kk$a~<=Gi|gt2UPZMrH<2e~AZINhePibyLDC6~?Y|5JAlcVlXU%4mB7f~* zp~Ec8gv})YzkV?Bbw4{34Cu)fH2u(9fd+o-H1odNK1g_l>qW5>mKu`TE?OshfX-!j zR#VhY5_sL_*lbZUQ~a)_caB6guxAI7SGi9aYKqj#qs#o|N2s34-AWdND7c!M8cP8j z9sZ(O?-I_9CaaATzYaQT^-|mMdU!A(8CroM6(emXDX*2GS0w(=fI7L#;$qfyM<@<* zZBq8k8A~nRV;VmUb%t71^TAF)K#O$_2g*GtY;^o&RwUe`u`+pgQ#5Y0#4zJd7UfKe zm;#9+@N7I*`PW6>&b8u%zWpRt^N=ClZ<-OURC$oqch(w0SwhW_pjZ>p7kTEBCFud^>f`1$#9sYh`Gzu(Eb5TYL& zkof=*mY`Ze%BRUkz;!1b$TKJZUW87`Lm0j!jwgb_F{mHAGqt-m&1TyA&B=<=?4UFL z8OGZfi+n<}29Xc5bJ)Igo%wd9F7&m&ifC%57A^6pcN$;;29LF@JUUUa6g|J>y0UNQ z_xX2eHF`i42z&L47F1o!0v(3>BDuTAz;h23DLHfv zFmz0w&F_8RZ++)m>#VcRI)BW}Gf(Vi#~s&w-S>{r(Rz694BHt91aeMI_5NcBgiHy1 zcxb4=87JpaM+k&`$^VIg=Y1=W7w&eho^~$I5QuL^v4MK*{2fNcw$iuOCD5H`=Cwus zmFsOi=4DZ)oQ;2PY5%0cqA(%wP{xJlJ`@p3*maL&v>l?9h}}8rE?qxa={}|zX4@aB zHqx|N`15@z@sLMjU)bO)Odqu9M1W(r!0&SAf z2ipOb5T}U;3Gc$ZeycDQ=_XK)E!!H=Gxk9hjt!oTO3(@G3Pf6!pwuqV++8d}cN>?) zQAQ3*a~LyMXY-x?_2uP-3;dFvyf0&BI%;q4 zm0t2CWquaUkymNGXJl)9{-`{I{ai?tlKi$nvC?z-Kb13&R8)DB^>_@Ju5O1c zZ67P8khcreke?}cR15W3ob|r0q7qV-XZ5G*9ptjYz4O5=^p$E$j)4!2)uMQ_>At?q zxpP@dCi42W4ig zCsutqX2X#?Z)aaN_IYTE2KO_~eB-c^ShXtQD)na@j+Ae^nu4OOIT%Yo`#%*yKTts0 z)FuzNWL7oYc4NPg=@jtG?&oHDfB2C)lXqv_Qd1EI}G zo5H9+^bD-prs#lTXQm0uPnu&*Sy_FI&@*Z)MlDU(I9H$DW?PZdQVqJP(u3`y%-gAh zr$v`Tc3W(1FEPvZFl=>yoHI{&m^qgkP(Zok|xn0DLai};J#!JEYr>cYK) z>U$R}THaHZ+1;eEF4Rw` z8r=?dC9pH;QMJ+*yGBc#CzAK zR*GW2Prajv`N{RKbP23^8GtMMCN~XG55G$+Z?~ujnvQUIo5s06h@>;5*Ff^%-rYa z3s|9QYCM8!7ja(pp0X)Oq z&x;35BofEj%j4VkR4E&;=tNw3SEchv2~!nygpL*tGb-6V|5blT>b_E)(W)kHob7%Y zZp7)!mt%5rr?F9yb$#J1vztfh4f*slkxEI=M|j$E7~Lu3c~r^%_{(L%q{P!QGp92% zvl`_3J7ogAeY~x?Flk2{Jq~7=qaK2@*8Bc%7sL6T2 zl~4+LDkbojhL(da`1FPgcP>NDpFZL$3gHD8RAP}Qo+gSfg)_? zD>#BMp8f9!3g34@BK|a!Thwj6>62)Ks7Cia2$wm*#a$XOmmq3(KrjFMmBt4jx*)#` zdwRZc`#t4VSb9PwsE^bez?5cz&bviML3QqMT$)hlQ#Od7)Cgl%3W(qfZL>7i&3^iy zyHs7jt}|QJLF3q`(n!G?FcseOGSx+tyWj5XJw&XKZD%C2fv}wGYESE*_FP&Wa6`l%T;z@LR z&jN26>vb308>Nz8BU6%AtHGO%C`%zHm$n^F&}g(Kp??Z5V!z_F=+;)eMKVc8v>rlt zc_F`+r5kkX=f*x#;^wGl>&?%#qz^SH&_afet1xERD)iK*>@R6N{h`>L*Ersc1&$-| z7&FfDPY^PR#|wwwf7v1mNgEw-)p61qK?U8{HjuoqaY1b<yDsfLxJVa6TCxDUoePsL5*uVNBX@mRfv zq337TcP7tMNju*WCX`Ux)<63DkwJVdgU+1{%`DbJcz!m@963STaHWo^8U^P$>Bl@{ zdLoM?#$q0dzh}`bQ_&*Wlw#qZ_wsRD$*AswxKaY5@y461?yTbGCZj`7#Txu0s?|;^ zGlBJ%!KW7XB4`O|UU%G$GRJ>4%@!;fSw6ZjGGe`k50;i|@`S_an^k<*4sNV|0V=iE zS!zQ0EMR~W`GrnLYN`+7M@b-J_u{j+-r^5e*!IIMJyz}k1vWmEdw}51zGPr`rccG0 zmFKm3NVKak`OCq7M7{qZe&YOqHVrM?BdTA;CoA5}26e67kg*an@im__Si%7lFc8l1 zJC+5Hs4O&C%ZexQZM{IpcjFg=^;ok_2wKWWBplq+F07$&?&GNi`uzUaUka5|1M@iQ zKZeBuavz+CYiWhNJ-sF5_5Z77`fm*w@L!1d1y4P-cHha!d7h{JEx&|}R08cAyn-@* z?|Cmqn(9$Je^=GjZT>QkYQmzD?v(NrU)P^5+pg_X72fNJX4iwq{!9PuLilQpS|H~m z?k|FNBv;R;Lp{j^sTafB%dU2Y)Js;;ylE>bJ^E&*>nvhPxNujM5wxnK!W77&xJz76Hx)R2tNs%Lxbz zLbb2!=Ym@!qn+C|^3VP9(BJT%#j{T@bz$f(0_(|bf>2CqRY%sUX`Hjg8u27FlgF|3 zrrHHt`CZDOQ;d4WO%T1tPQge2&WthQ{!5YcfZbMZ`Zrcd%N_+q8^I>tM6DFS%SmW92%+dD27^RTDFEWs%FDYgy(308DoyExPNDb-tC0A9zP@hGPF!in*B)oDBc^1Z zkMAN{K1wY7@L7UVKQCs%N=9eg{E|qc5mFI{UUR=1!TS-0Zp8vTtz=6$4nBBACDvCId)#3FY)iihAp?>ai)Zg<4df9_t}HFN{Mt6 zN~&3uyEho^oirt&*Tk+AyUTO=C`^n{@z5d)i;l1EGOqxfmiHK z3|uf)qcaI{$0CL zGN$xI1XKFl#8ZoRM-#5XF&x^knfQekAf|UrseXz`+}m``Z#wfwII8iTF>XB8-Pf-? z-cF%*e9FnXZrX%ooiZ7T)qXSC=hJ?kM2YJ5Vked1ljeg+l>T<%2IUB#vC83_6N0DIc;5&LD~} z>;2OM==;-rxj|9J3qPVpMhta== zE}as4(ra{0xeuSg{0-3{7*GD>iz;^WO0hkB zl~4HLHNPj*%W4`n@J*O3h>mc1!$BDl57l#JT{GSB;FUW zJ(7KHbFlLF{M2w}_D{_mlYla*{JXMlFfu}BHgq8>mMA?#JK^UmU<<4^++y9j$9bBT zZ5y^LvA)5PB-FACouLL6T~$%f)92M;{buUr7vP18jm->kf23v)GqY*0gf2?g9YV#X zDN-DiGwjK__Zz0-0(rc1>G)tk39z!-m2wqpk&Jg=X_T-mEFKKaR?Hm@xklhFA3z6D z@00=@AXIk&IPK9HfX1P;UkIE6Rm;Z%|8gL2nN8}LBu+uDs$$#!hi_56Wc@CusPSfh z?l878G!Cz{K1r?0aM-ZW) zu{{mlq#gV9yrjD9@q}mNz-s{_t^NKcL zrtMO0ncB;i8PzyvE|5Z=AK07=27a~N+op6nBB1GBe}1{|1IAPtb5SGYB%hj6jrld+ zP>Qtm_4T5Ko2KdPTY4h>C8Vek_0Q&>lAUXiggV_#DrIjO|NVlid#non z5-PD=y*zI(@;yt>ffLZ?a@Co*P3h;@{WZhR@hS%v0&AHkvw=L9Hmi59s6x zQRB^|)$JdV%lR7UmRKuqcJYu>R(pGUjnYWR5bIl)HB;3MAr`yai3TKcwDLd>?%_gJ zVw?KON$1 z*xeFb)mz*H!}L`YqUkT;(d;J*Zis6^F8Q9lz3b{5&i6;$l6Us)sh5Snw(8S+&9*nP zd2*~P^)|9SdGaJXHF(gr?t8C>KsqsTs&JO7O z{y3G$cAFg)0qXUEj~2dP_qDXN|GIk0*=ORn>#XJW@0@?z{`~gv$Ou%FC8M4hzuNu$ z(lr{RI*-7Po%WzMH2>$7Oog6QY{&$uem z5hTa8Yu6ybhlk!nLrH<=_*d9=-Pw928c4NN0XHJt+Jd`mrd_jr&~4JGX09cK zJRDhU*2EU8aQJ@7kL8uQa=IX`kbX%LG`qa~!irC3EJJ_bdm6T9^~mTi$E2OWK$;c& z>Gi7apV7!W-Jt(3mo_|h7oTZ3XJ+^|Nwey$ z3%m&Os=}tr*D*i-U3&h5JnQ%05hySUjgM3B*4I;A^*KfBT+G@PRWudNr0!Avap6Dy zZ6)9BX>aED!y^@;xby%i^B&q2?^y$dT+p}MF}(kKdpYXxJ$_=b5=oe)hP4omP%iSB zQnP8$BKbSyuB!?DcN??YL$Xa%ip^Ei=S3d6Us|mqM#Zwj#eLnrJiU!egO(dyB6OcE zsasC3EDf~!!1wj&+WZSS_ZP?8b9UyC;aMASU?B5Cr3-UL{JHq!WzC{o3Fz9J2wc;6 z^Xsi6O3l%gA1fm5Vf_MRS;(gSrq8Kkj;nHWBB(fDRGFprplgk86FcDm-Tf)BKl}?s z@E2=#pc1>M-}zv}weH+36?PgKy>AwxaJ+BN``hGAO-*W9g@uK;1CLz;7uZp%Y}zLT z8}pNQD^{Bu8=eF%B{=RUA;*7YD2s%*@jC8G7NQinrFQhAG}DD2dANR4It5u%qfeN^ zOL`2gb}~_*9}Hr3OZ=9CIgzZF4mWXfEc`Ppw=xnWrktL*G$G+ZGD(>6vOwndug3Jv ztYrUEUpa;*qz-Lbm3;kr{?t4PDaZX`wt%Ay>jo|ZgUhG(O7LAApBkr`scGgg?Ngb{ z*K6LEmXvg~zNXe&7I^pJrJB*~aXrJ`ZE`+YD0u`q5p;2h0frwKB1${sDth%X+zS4c z=x+0;Pbn+O<&befQ{A`@{Z}jk>Dk}DeGAS^hguQ1kGO@@*=mY<{1E(I(vJ66e)v27 zEu%imqSYE6&HlZt*(}J1y-DAkYmCsfdt+&!$)@cYceW?cC+=4qu&&urW;5$;^y9<& zdfA80p{rFxT88Zgy!W0(w=)~d`E1=+Q;WdDw`W^FW5B;Boq7ZGV^`JAQV1yzyogl@ zpLA{z-gI%M=7!^N2P`3-LtQP_42ho0hT5aP zlvc0riPdMl{I6bNdlI)4*k!1d;2duq?CnEU`4U((1>lstKL_h3G!AX@1iQqc_&aP~ zi;w*)pc$Etsng|xA^rW&BQWT~kVFCP`e!jFzbgr0ZF4zC`EC7jw^=GkJDuDt&P@l; z>T+^;^8>a8={RLCzG2`FA88N;UN17i?T?LF62>|AXiZ$%>}1I5RrwX$q4m&O&1#4s z>O<$0VAf?OtFKxY%+P3VNy7w+C91btxl^v-#56DP zd^pft;On2vpiEuH?4~Ikm&PWy;onVPShfbdiQToC`>`xCezGV_(}K@MFo`bCcqvfx z;!?wU6e4lm{U~Cd-z&e^Y3unO%avu_*WBW%El1NrzlwQiR3)gP%g$u0Pne#3$Ff4= z8*}1b@hnv&E(L+df8V-^sJD2_n814bMwiSqDSv1hLbJ+1)-&q~d8`4aQsOHWOoFIJ z4q3r9eJWI?$$0O+mD#-w;q7ZtRN`|HJ;QfOd{l4YXVMCMYT;F-m_*IX+l+VL;sDLz zr+&rib+uYTurpF!nZ}KB^PWyc^use$QX%n;KZ=_rLm8hZ2iBg6x&x*MU}-?cs%yVK z1+z5QU!M8KFyJ+2YI9P(h{R1}9P_WOF;oMxQ*}p2RMTS2)F%^q6dcFP zDJN@OYP=Xf!~UK!FF(U3C{ntk!x}rbT1yKHBjH#8x*3x{^Ot>5PwiUUN?#qzIhc?=-Io}B&~t8 zSJ^=REdhEoe9a>s@s2xbgotlcknjnMDB-uJV$+@Bw?TW zClWO42TZo$_3PhrG;(TcSRyY8C$LhS7p~qSmuSLRB+&|KUiL5N3`}-A9M({0%gZ24 zZl1jhh^w%J7aeox2Jg9_ks=*GS^B6Kxwzix-y}j>Vd@#PH z{1%RVy$ti)eOZ!tS_LDg!Pgq2xCWtX7i^zjT5;k34{0OD3oqcuI{jj>GCbzKgEE2yY@@H}q zt;!#9ktJq|790KD1q!`+1R=HUBf3)iGkffe#EI_Qk|bm++dNsp8nEj1Up zX;i67Jgh;UgIpHnsc9S8o@;~hy(%y#?xq48?x{5-bmtGlZ>`Y?_z|A+K#;ERc=~(_ z+y);R!*M#h&VNY)dO9yVOQ%m@xQz-K&49LZ(z7naWtZ)_H{64O`H|U87wn3J6p@xh zgf&Z7R{!M6aKB{%$Tc-7Df{#1`@OsehlkI>GS~-yaot^1%aHdIvzr2DZNlC^7iEgz zA>(=c7eBebc5H91hmK$pNWhXH5zA%wI3M1wmOqlHGyE8IXqc3m`eNhn_w};2Hw=X~ zRVqjY(3{%1aQ4-F6ceeaPfJ1?^8QRx>8(x#=?Fm%>4T91J$-ywJ|lv>Brk1FzG+~? zQhAbL2;#1D`fQBR&%P~4N)cHh;3!Aeej}@OlnPJRYmoHe1!cTWQ>h%MOUgQb)#5MpFSU*s&PeUi&6eS>EnCw{YrP}(_6X3&zu#ZH zk##P~e9()9k#^}fX3lA3o(c3-D<>s#%84?!I77ZD9>Yp^5Ua0|S_`DF>O_qLaDW`Y zhLB);01y^%ePyn5cSlHziQ4nuP$rZoib{X!l2TImonrM(+`^Xl%QEn>nqdQtlhx)I zrGG1tmod~9e!{$4&{8s^EFxUk7MCE8ZZTE8uL8U0@jOEXVym;VCoZvYOJddrS4642 zM&E4R@l;3b(lc4lAxsG>9`cqD^p>TFTbw>}2F@;I!-_Yc*O(OVou#(XrHAX~lZmWF z>X>cSo4a9VGO?4mrKP_UM|H#0q-R-#LP<1A7?Fo1g;NtzCSJ_MH5iFW-}HdpHg-jy zuzbV9p7%I@g)9|6oVj_s5a}nq82+_(F<&8tkW;HxQZiaJor-;sIz^|nP`p(bc90%2 zlAdlDYu_@(X`G;g%@m~843cVn>$$M{!G5)$8@UM)*O&U)FqP(B_tr^$J+_*F^AXo&F2fV2^%U@tKghqQyt={5@}|qCg@9*B zz={DAlT%-B)O5Xog%!9!5izASyxGfOv6CjyCh+zDwS^X|Fp zck*n6RD}xC+(axqq2jken3JwrR#ed?@d+~~@!0;!NgY2VyvkOSX-E1bUyzTcLfqWG4XnJRdDkNLlr7=%_qv;JwRfK zWWOu%43DLYW7$HHD?r=m2ULQ30w({pcEyN)4xNvnT_$Di zR&zk5Dd8R?Pkp~m07ZwN9E@|c9KYkv-3ca=XODc?S*u`O!>cUF%p==Aqb%ef;^895 z$kXwiPY?mk2LRLhIlFT!NPqBT$m@qf;IZhV!o=?7D$+d$eA*~UTfu;ohL;YQ6VY5u z0jOWBtNVzblJ)eh6O&8?)8UtK%xB?fRCJlg_7`L=!5&iSJS}Uv zHuyybw$T?!7q@$V*ReMFdN%AYF;mWmOjR*=FRt`p@#(6XTWF%F-TH| zM;{czv3}>>l`pTwV$dp#62PGa?*DmsS=Lif5xaV|va<5?)SP}Dx)d&tUGwQgko7B0 z#z}mfi6uM45!$`6ujjPw$hswIZlG#!Z}wz5lQ|HL=9}h@V){m_^-rcFyUU^*PpTEC zR7iq!JO^6?TG{f{zgM&K5VsQkv|_^9om=`c8T@juUQ?=c3~EsCUdI~DszAZ4N&(AnfVHkU z`*4NZFI%Pn$3=|N~20)PM~X*3fc1(afuhz{(E^YfD%Wg5@~{rBgTs$EbqD8iOc zOtSP?OXqduNN{%v?1Qv1WO;a(UDD%Vzj9$U-rC}Z=%tR{@6QO2RYR z4vu!`RU<<%1g(EbCfN_j(m!bRp&7MOXAEbBeDQP-Ibk2<7q6Rzde$)XQ=cNsHlaT~ zv;P5%p%+E`IR7b82(4|EfwKgk<__B({%6&Ks|2KeH7D|>kI}U-1~lw%8S(Ww@N@Aw zL7e>ml6HLP5_+80AE-jiBAsOA)RLDr-y4&|H0oXKUg9qzS+rppq`;5f+k<|{FFpkY zg>`P;i)WaZ#3sTHxE&2ht>NJ3%y*)u0-YD226yAG+$)bcO3cDjph(0cE6AN7tOS?e z;`xWqRBm2MT1S! z)SMh0T~_5RBN~#5NN@vEM;S5ElCXjxd^i)#ubCcdH^{HE}pR@;!nEtS<6y?SP?3~%L!#fJxg#D@}m%;2aS7G9=CSKd&A&X zMa6@>F4wc0R75PgbYZt!#AhQmMd*>tMTFqRSBDx)U-Liy@aR`~L(S#e@;!+Uopq2! zJBsu<9nYh*Buo)$>i2cXBLQI{Au!^$^^wB!kw10x^;hnXKlWWtvl))oiKrji*=oSl zKc@Q0eI{&RcsQy23RYQD^BnNVehr2Qg{GA}t~_s1 z0w;KS8`QdfYP4*lQn&jRc9x|J1XYMZ(M_t+p`l!7yb6*$!m6x(>cotcMvN;WQT#L^ zK}e(`#3(`sjfx;3x}q6Bq^B=lxfgB$ywG)aB|}5Q3H`h0-M``O%s!GYLKPD~8^`2&T#hanW3kD4%6nf+@+ z`A?DFe(p>AYeRnAS6nV$LqF(P0J@`S&BebJK#jruXPVD6`#_sb6pvvZZ5YD^Xnddtf zVkgqvAbqr_i9O1KaMbp1Id~>Gj2$aQG#q51u}9^^bL2cu&`Rkm_4Dt9M4hMZaL9Vn z$a!z5vgKtHgfB(@R@&w6qMO)B_Jb(t>$8Al-k*_?u=uMFb3jlA8SbC(*{rN1LYbeH znh6U^dzZf(IW)JLC@HyROf;E9Ku3{eK)CzCtBuoZWA7Fr2&ZGND?x~$QQMXUHhmeo zXFoN4n6GtP(79dBYZuZP&Hl!!JLRj$rb}1lYifo*yKA>`*bN;31ieAyW^s5}@mwn?EOAK#X_?)3}$w+j8#>{U>tHJD#g? zvP3{?m09sWeSKKsbHcGC#`aqg0!&HaLBYTRjPyUEuwJr!xf(zpQLZ#`VtrTc zR2Q_f6f+aqS22_yBlTn5)nm!%vpgEW{Zh+#~;$F0EM_t=ki$DkulsX-(nq2TLRwe%yaRMYSfa%yW%MYs9; z>RO`+SP=qOMl5c_)&O@ajW;8iVJX!T9#h>isnwy{F#Ta;0|zu}Ue&v4tL-+-5%y@( zMWXoWsZo#{svtHUv1>Xok0Rh>NXvi9f*2q7T$TzstwapHDE@ycP5f^KK>xFXh`J7V zf5+*{cNe9K5CBea{7--&8ptLOC^2+pbv3`_n~nuHP%ilJqtkr^5vOL^LI;W@Yg>Tp zE(2B(xXX5Z(o9o8(4LUhHo4XKv=J#@mCqpyi3wbhD>*p(8PyDPf_VOU!18+{HJOYm z8tBl8DMhCRVTB%@wYs*pwlfV2!g`udHF$6S;3jTUn@>SR!3q5_grlMQ1ghG3`i2cw z3jseKk_u_s>yuMk`|@D{; zAK&}L=)F0y)YaIT1l^qOK=!6fs_W3#8`n4|+w`U{9V5cwIAT#yaLP?XUhQ;=>vn&E zv0O?>xX}Lmd(=?)-76qjH*U0TaFgFSdLEej?O#`8|C;Tnr`(M1{j7`FP0X6bp-9bi zkbLbd@Ah+iqpd)N-P5hRQ-rI>6k4#<1|;QD#O)jWuaLX@3#w;7^J&X->BA-!j#v zkC_sE{RrY-(d0e83-K?yjX<6)lv#DdHKaYn0B88-GP4z(DnU5Pb+mja3kH|7{a}*R z@BC7EwPvOND^sQS${qkbxivLoHBwtTf=Qlb=fds+O*sW7r?@QtqyHJOR&4-BUi~X` zYzN?(I*u&(MQ4o6r`tbw7COb7r-BbK=7a`Q)FY*Ag!UUA001 zs5!d}s#x0c!BZCl7Vr$f1AXuoZ zf9Yf3uA1Lyk>M-%mZyralf}doT$b3p1k zIAC*Yjb6ga%IfXU=LSvwlFz?i1`A@c0|OXo9jom#TD<))3^t0mVK$7s@bb&mRHwEZ zk2tAIh*hlAeDvQ6G$bl2qg<4`gD-(%H;N=aEMFzvs(QB%+0JWviJt?Q53p-zzZ`>% zBtrhnP004&!q~a*`rPVCmUnn=VO;X+*782A_FqMQg{Yz`Khb@VcKIlhxp8qtykGux zvXK5Mp-WBAp(J?mu}{16Mw~cj=sq=tG*Gox02==c4^!|EpyTI&vqfS1NAY0ydIe*q(q?`HU3>gOL`+&$)@Y8E(peq)O3&(-8x406a9rD5*+7iw zEtB|(vG%xWNM0Vv(BxLv;Om67C<($AR$M9sWcbIMJ)P!$gr%%lN)&rPoC26`3m*li zE)u?{r|s>`q@(Iy9A!gXdC z_}&GxG-7+(Sp0tdNi>^emn-NR6wuDMfcjBu*dW{w@?RfdTnILWnDTNlugS7`>2;Q& z;bA_+?r#Bz*qC3Qlf~}hZ`SV22*;uHuO!R1@YZ#yEce6lR5jZ*4Xxkkc(!Y&+(CEq zL9xr+M5z{W_blmfLLG@6DGjFFXGuVn(WMQ%{00h2hR^asX6sfywtes&(j!G9uuO`k zRbA3ZRJTh9Fb%Rn*vch2KUp{GfqwvIYYaC`F?R((Pk<6%YBk5gh?l#d3n1zN!s;$~ zvFqerN>jiQFMx2TAQ#w++`h?o$l~I2oSdAH;FG`I;ZX-*CeX;LB-yPzcyr@j{drWHur1r7`z3K1lWM zVWscdYiN#h%iQWxX=5HOHmK#%b3ZIsO8n)Vg*1rp)z}U^n8sqe5mS7ae zKSkh{c1DFYO8WGdAs{Fc@bvQfU1t_9Z_~#Cu=ZnHN5>>;1}?{L5=i0wZVNxB_r?xp zlLKTg!Tc;5rc2T{50Wf_!4=Bb-*U!YgFl)0;Byo$PZNhBSLBHMJ7)Bi1cDQ8z{J1@ zeIUoBB&o7GuffdU1+;Xk8P@#z(TZXD%ZNrF49aq*k-=^4OX~bgK#0x96Y-A$eP)C#pBcaK zZtJ5u9WMv_^M_mC?6G^lT$Z`+efjbQ5^T7V@mgCF)pR&E<6}PP1H)&L2~L-_dXR#d zh01RsIv}g%TpBa`=Q4uiim(M~h#n}oP6bj%HWx(9gq zhl8S&n=SyyQYA1HJi~Xb0IWVdHg=k0x%x2XKEU{pf~+cxH~vf!iHOB)Z6TKmrbLC<)gNTd8G`uY5Gw3z1)uOasFQG^6Jc3Mf z>MubR5J$w{o`ud;PZJDToTQdj=X1qMGO^ldgh;&Aj{ryqAJy+84b7wl1tr@Vr`7)C zrRRuxL*y-Uz(z!2ChR^sJGKL_wlg0o(ghrE@A^m#&hy2Kcc>_1ShTlchJQYcgwK;xcJL9@H&>u&VSStP_B8AWJPkWeN7Vq_*ZgJ; ziYm^QY`{90o>MlI-jh#Ze-{XVL4~#EpidaUI7i?nZ3H$^7A6kgJf5J_DG`K&2gJKXP)?tRAZ`F8bnvh@Ug>Bst{$#1Ubu-KDGc*}Azhtx?jcXi%kxd~JYQ`pgH_ zBzQe8*M*d^uZ~(}UqraLxI8NrbWU(^2${B35~lywR)wwxMK@r&)o>+C9kv&>rKRST z)h^t3OXP@tme-{2EnyVV(E+=cU`^ZoK)3leo952S{FeE(2rJ!`UUj_e@et+}s%L3` zg5QnYy^bOSenc=N&sKg-WvEy-_1}Y=M~@!e)C}0FTUnOx1=D+4IRa_R z(MezBr`~G&{w|=I%0R4PcpW(|Zqa0J7ydZCdLM)nhC66Wg1|bmvht$s7Poe7G4%Ze zOv!eO;nAa&0~-r>Q_>>@=QULw><&mq<-G8qUViq3ugT$SK`jF(r%xd&*)CbAPAgM3 zd9+Z%XJnKs^l;jlpq+6?mjLfqcu}sE%eex8SSypZyk!INpnLI&_+{El*p=unKYxr^ z@8cHw{kgM2VlXEshYSeCPY@To`J7>p~~G>Prg>f^T+Lqmkdfb(NDA ze<#KaBlPr`oEtW!dKzp$V#(t6P31PKC!J57_Ll>g?EuedNd*A$Kfy%19*pQ;y?AC0 z81!%cbv1{kxIubQZC8t3FT4%zG;wXEJWbe&+74t_&XlBFs;rE92zH3n8yPXuzoA@$ zz04} z$A2G<%+G)LQOb#pjh$2!!vsWAL)vLVq6*dJ2U+LxyYE_0OpVOJw~#Z?bTxR(>Q3>& zwp++wxnDoI8hcZ8$^6#4U1tfUgiAC)h~YZxup##xB6kv>Wu0KxduawtGw#;J#KhyS zY|g_z@%~w$0GDo=2+AFh^t*V}5_sOl9dxVF&~h2dDPur~0kAraLT@!}h|zJ}VFZ8I z1M=o3_G_N*!<$5gTnph&R4ud{FN5*h4rw6l4nN19H(Km%YQw(u1X6Uc8k81pe865z z0(zDE-R;g+oedouJMQ)RLT79)7-kRw79CxCo9*X=z2&c&E}NrBT>&%60@2g%CsZn( z3oSpX3JD(6e|WO>l7NEaHh%!4a%)v2ggO`$ecsoBkJ0kg7yl%eMSZLBm0PZ2x*5TF;6+{r(wA&?AOE{bi zTgnkcc<%g^Nq&GHv%V2kehF&{QlrnDr3wP2j7g7XbDIo5F`-e9svo3v{KiTfDS|C5 zzu6$?FL)+FR!=dHigwO-w_2=06d0U<>9p73hG9~2@-<2&@A7jhP@U>*K@|P|qr9#S z|6g8#|JogMw>>9sD3`)U&87cEj(sf7n@oY?^TaN=&BR+mcE2e|Q{E*IAk*g?aG z_)nN^xvqQpv^eF;Pm2H4tNi!PgMR&hI^61Jn%?`VP24@@LwWKg+Le}d=ebEXMZZ$WyQSi*~t3)^R$*W!6nDW}_X=__!s7~I+Z2-QOG*Fo> zF0d=@a?K~j9~NEUXnxkr^pH%uha$4bkB*wIr!~9yXqQ0p(}P@`A`+)aIh_@Om>N6$ z6)~Bji;pzN|A?P$b3uOmXM@oW#%>DiKa2$%h3;_Vp{)KH$q+fLRnU(DGP@ax z(!yhsH`M)h5zT+`|3rN_`AuReQ-N;<@1`e`cu>kIgaQ%b%xGp~W4!8p`mnnoObVHt z42?%@PE@%A1akKi<5uIIRzJZ^81b0kuv12aE_lsKf|6`8$nfy6!L3fn%Dcp<>fdT7 z8!DGNv`O#9vYRG<%M6;U5>L1FT-88QMkB@kRfn22#4dz!_7%fw*rCeOh^|_TV(|<%94efS`h`zZicMa8Hcfw*_76I%@uVqZTLvFgpLV`-LQp z80YD((lgRKZ%*Ttr4P>aYLH;S{AoGC2kHBnkp#6RRax?(mtO|=spHr(Ba_xZmis3L za#NLf6vp(ml_5^*>_#{@cDC~#((p8~01Es7m*?r}32GC&{+v7%%6-cnl}jnSPAXm* z;sV%iu04Y3^6lpoR191j1>zrIz+re~;W$1bh<+wsBTs3@H;!dlkk%q=5+^eGhAt}KZzK5dC#$T6wO8$B2ng-iul zQIytfK5XkHg*tFIcd)=9jWgBU{h9t#9;CB1o!>pQg&=>;NE0vu*yknc{7RFHUpOu_ z?MqJJ;vEa0wAWi>?t8Cf)>mqbQCpo`KZ7Sypp>lWbdDO zxJ>!n`xhJJ`dRqgnZ#88Eh70e;CxcmK|%yz+!YR_|=vNYZRiz+OB$x7B>aHRaRa+hOmF`c|LmhhMqWD5#s#3;F(GqyipHRZ8RF47PA_qOS! zr**x@{}seP167z08lcwm%>i3K(M~vM?EpS8j8)Hm_%)K7xGVraor-j}V82ad;Nblp zB6e)Rbq_Xvm_L2kbxVA>8R6GMJ+Neqz2z4xDJW<;7&DK> zz>gYgceD}ZcpJ|jARHK*oM3%F0l`gyS~3Z)>1{^h%Et9>ML8mdXd!cYyx~_h!a_23 zX%1H?t;Q}Rz%KLeD*uaanh~n=sUShr{*(k)OUl`H`YZWP=J&oIS7ivF&^$!R zN8lVth+l=-RGGpH#tG$F&U5*&RDVFsD}g$zJdLzhV8cUq(_ODageXh^4|uH z+w>YI2_B}49y=)Ch3MlRzqT^pInL&j{J^hNSu!r~MTl85B%Zv$uO0CRS+}>>hZ{X> zlS63J&AYQJt^|4yGUB_>j@>heSG??X7DiAxh$|-??EnVg6R=d@6_vtQ%d@~(K)Bcj z>g!I;>=8L*CO~`Cr>9P7(D^Q*QcoB}+~8C*Z!LAJ+!@Os#V#EiSZ z>YR^**s1xH=7LQZS->k?Rf%f(s+VtaR%!5Lti)6ZiQnz6UH?{SvKg9TcOsyf{@I(% zr=CIQ)&YjHi!>b@5GMo5j2}Zj=LL$JkWEZaN1tPt%5G?22h_qU2;Wo;Zd!djsjy1e zYFIIo0QLdmx^km{j(Dn9#E0mX6vb)Y{?={)TM-PW)us-`KOAQv`k!v@O*>FfM1QK~aG6nCI zl7DZ$pvWl_SBu!f z{tLG3^6vG%w^mqywU7e5plFbaFLh_!N#gxYC86xt@g?nPy?+%uV8Fveo>p2Hb| zSe0ew0A6XhY^-X6Hx#OweXYpyVlM9ew0!?_QNHJCk8d^o6m|p~4I)_WmB@Bgi(2&K zK>T`SyPhusToPSLUumQriXmsBjca*76lK4s(fp3z$72ldg#bppvG7~_n!_F^>7X?| zqzI>O(2UWo|EhQWq0IkpFyy%rusvOH`416(761&hw;V19i5R|f*^ilp3(WxnzH!cF z9oPy@PV>bV>yT`xA>PM;qu90eEbg8;pL}E^tVTofEYJG@9jl~YqFSVdP#umWGU35< z?qIbXYl;>5S{>ZPuj@`gG>8gn3u>@Kom-FJPEVo~GR(l?Q3ZmQ*RQ{!k0FgR_nLMZ zf!OFib3LLno+Wx5ygz^P?9(&kGTwEyQ(6Ok`}t=|^ak^Y5a8n1KlX)f1sr=2=4M^| z35{L%@E|!WKOJA3N5~d9i;f?n9>oEUILL!5e-ND;yp)7ezSJCj`pVq|Lxm~W?my)E z?9;LE;am4k`=ltdE(8@zOcU2o^IGfg9{{#N4#<`N3Owpx-C(`Tk+jGQIFsGH$P*n- zCoak_d=>*VQ~_-=$9)i4-?%8yoWxPEv}R^EcS1Sz)DYi94E*4!(3?L7eX6`ix=w&E z{QUhp+|?13ToBsAy#=o#d*&3_P2f|eNlw=UPS!u0tr zBjo`Nb<~EZRY2V(6h=wrUz)r2GPruveJMHY=ZZDp?}1JVvE0cX%Mc|49y!@Ta3 zUsA88Tpuj=xczPiEM!grM)4C-2Tm3`LjMB0D0fz=@ic^X&`^Vq>lxH-&H;5e7d0pqvV8;6L8+dIYgvQ96Hubg~e6fq@(MW5{UHalgO3tc#3LVJ++F?Jb>+H zG+DA9x`zJJ7wAe6v;+jP$$iFB*$1~hWX(My3uld;6z%=_bML+)#K~tS_=xu%Eo0th zIQ=1O>_QoHC^Dm+z*^xQLJN`z?g+UGn$x%`A{$UQJL=Uig+ZYqq3_>Pzp~~o@l1m< z1`KxN=X-t&J49;wfO-PJnqiy9t#Z=h#X)rvn<_lL#xIQ(4r1S!aYa zXmJn!%e!UA$}thWBrTf5<;)Ctw%HD+A*H#n;+`S+!I_qJrOLNqUZJx?1eeu85m0;1zm54S^B`Mx6h(pg#~Ifa{-%m(X932#nl`^ly@&u1Jx+zuolu*A(((j zMHt?L0(VS{kvA)vl<2-&k-QhEySSdp9yQON#K2T!enPIg@cO-Kc8Ku^=tv z%8O$oyWB4?QT&}NS>%g~_(ZlYBaQg1S7#1z zXYPq_s@Ir$G=@nDrG%X!Y<%;=ZVK$BXB<|t|+es3b8zlD6G~of8yCL4KFpZRx!mno2$B24=W$==~hP zmg;<}jwWqPFXFahC>zIpxb$2Sh_g8vA68=1jkIm0xM7WB-k`o3_P(LU=Z`QGn!@Dp z-y{a?>CGea?Hr;ofGf8%^NgA?t2K#RJkJM&V8pjeOIuxa!uHEz!$Rt73m)(Ro*4L8=Ki@Tg@Ew5kN7^m0#f;;{jKNKzbWgZh zbTOy9>LV^>$ys916uLI>U3zIg63>X`tfv!s2fG&VYq~0+rlw@&>EZDN3*=7}9^HF; zIA)yR;BzR~5P>Eo3R)C9BAA4s?x$5T2D73I1iRxg#GQlOt>S=;HO;l5m%>&}>6JC} zqc}FW-Z`Zrib9$xc=M*-Z@rwx#z=tj1AL*k+^oR+?!RtQO5!w0iUp~ZL zDTl$L1f{}lRH6W^P!b@mc?=2G4#c3b{w?t>RzU^W3MU|hQ$HM)g`t95L%2imLFk#t zG5h-9D*8x-NHtk-??(B84UD&`4Lm3tLbSRuT&rCrazC~!_Zv;Mj(7%;c4(6zxWDpF za&2*Ft_p2oiQqBaP!NMcpn~X}S#J#r2h7A)4j^#aP(C!Ab!KrK9TfW4ny{c$xF$mW z0o|JUHvU^ypWmka(HQI$UG48onP!I92c- z)f>>W(~cX-%1G1)mknt%!}*W@Khz-pXQ?8PaRjiD%)NYn<;no?+8T4oBBE$kd;$pl z6kp=|qmRaJohqYT9d)H`-pm8>&zt*ffDqdMGPR8p{_3g$pY;%bf#>DBcV9cl%X9E< zEQl+3oy`aYgTi2K+lMu;eXu(KEAO!_l*zePBtl`&Yh(o$jD6Mc1^flr`@rSPgWTEp zD6CaO3J!4Z*iRPBAnf3(BhSkO#&OXw&}f%GhfJ+`1<8H^%QX$od}J%eleIA&pb^G@ z_g-Ws$7L>aY{H*G$8ON!J@bO1J8y2xJBvRbRK(Q%*SAz}LjTQsSSK<^E`Wvq#~g{6 z4{)R*9Q{6mOxVw#w%{Icn0991zug3Tcs`HL*~>Qf9z(-=Tyg*O8b4H^1Voz_{&Q#l z*c3Y3M@iuXERDa9pyGakk{TOrmSEU;foDUIDo^we6zzW_{{BzC;b2FheT_5Jj=HyH zL+a{s8mKQ*?70kO!Zrj-dH^Tp3qe72lyBoOwscjoiCMJuTqD5`Jq;+Qd5(LCNQ8V7 z>c+)b{PCrX8?2C`z8L&meK&*c?nGd~zM`kG`iA$z4!U4c8iK%zzs^<}Q$#Z)58l}x z4D_TbQjEjv6l|iwa|SYefS)=-n3wTkDfVl9T%8^Hm~yC(mAMoT>e{WvuIUOSShD`U`J)1E z+ReB_KM;?{h~+3y=emS()n0<^SCERa6-cToU9z z08am=j?P#G^ybYzKgUpY)F}Euh?J1XSSmE)vT*b2$nd_$CvJIX(wFOzoUr;I=N}>; zn&o980qrEfIhBs4D=;Z7NQt*#CJ{l=;WDs1{;o~})R46z?AG+(S?n$W3$6s~UE!Nb zTi=B4Y&l-#dAgt=A`HjOdz)r(Hod-1=aR&M{xxri!PYvV+ivFWX6ebsKXVE8yeO(n zRaPYHOrwXZ5MP?YxdnQc`#_!pe|swPA(wpH;Uh21DunKgYq87Q<~ydph3WVBpAS;= zUU`m}80V9F>;8ztEj>5PXleD?9^69k(!j}LdepAZ&_b2w9yuS6%zL?SWr$Bk@&VX^ zwIsrlGfkv1ZYI)02=?~&6y9KiWS&J*mzUGJhdp;WFcdnE2bGqX$D8Wtzi-;Gy?n^h zW{?rJm1>GnHkY%NIv;R%)5lHOV0ks4#qYLyvgzd;rn}2lD=Gknxo(v;EXZPR;TYpSjRJ@KfS4CT_nTS=bmt=>EPIxWrX-y0?nRdO`>Y7O3 zYt;$X?5(r!H)FMGSx?G;39H|lwj_;+C<@b0o$v&pNXi(3HGORreS#%zL7A&4rk8VO zpG1W80*lIDiw*Hs#lFx#0@?&(@0|eeeHM^@L=t=~4}aVPsbd*IViU$czwVtoetTfo z99_tgYukUWi)0Sfa^ z4_@Kv)Fb~&@;MTTN#&5_F^D^})0XEwEHlQ@SXz{$GxMJFC}h3{ow@nW#4>1v9C3MB z1Mb{{9+#4Y7&Gc>n@o6r)R#InFa#5P5>9{QhDN)gHwWU*-nI@mtoaaKF1Tmabj;$C zgY<3#%Tr5ZUsvWd)IjP}jMrYs!4)Ln+zf**J8BK)ABVn3p;6bet%lM1fVJ2E(5w?y zRc5}m9zcw?%ThoZQV7;i;?gcd63<|*YE5Y(T|?(7vAXcF3gqB<8xvle4&kp08;xi~ zRgF}nSy`1J%y|r4C#P=l@J)Bo$G`P=%uIAerAWy=a}`(BK-mH*l?jv2X4*0OBa1I@KoAT$Gjy&MF*nF~AFkx_R9LXF*Ce}mC&C;_U5XPGDDwAOvK2RZl zePEWW4h&6nk)ds^`@w5kv}tnCdh9RU;@-D`x`m5&5B$|V(cF_y&s`&Y$-p9*%>9gW0TzG zX@QOy_1!xjeQFJPhF{~CA(T7RinSevw}Y!l4zoP(`t&qs2t41H ze&5r){~=dl-F~Zi#K$VXM4<%(yvY3~^bhN>s$lUm7XXwEJy^M<5q{; z-m6?H7X&?X;RYs1O3u}Bnye1bn_Jpm@F17TG5b)7dkve#$Yzz7!#uU^YkRL?r^o@&jV-S!Bk>dszY=*p5wKq{e_QU7Q^ ztQ{^E5G4pBe7Sz5 zzmP3@&-mzI)ffJB_5~=>nxmbp+%bl9qiacbf%CdZTkNeR8FYiPh;JH(yf|dC>hs#} zgnK&l%TC$$SDIHhu%2?z*$yIa3&E&m)NpM}qKKx7-R|g9ra77sduTANHEvJd1D?Mp zkIHu{0L9G!DG*(WUWOOx$Zv}PgnICYA!l@f+h35s!hedP{!M@Q-`CfdQ$d~0S0v^+ zUi?7yv;v6T@EgY^gNpW}XyF~RmqbNxfpWj>znyGUPQ&y#x|G9#q6!YVh`V!m`w55! z(!s6QcQJ_D;_&|LBxLZ=Z}vjC-s<+)-CQyRAow5ISZx)DTFHPRzikq#4sV5h?ai@b zh!EnV{!`Q$)$MFLI)E@JUuGYupKxGq^!(x0>kwWlA)88Cwdm*lTmY8l*mvt5yzFql zGYmr&NcR{@1VgJY4>`n!CxB>G*I@WMWL5qtUeK(Y4(b696FjCcY$k!{lL!nowgcI4 z&8hKph+7J%mv6y6=N_J4ngQ$VrvQks{qBvS>ho+!LjK%GFXTG3kZI*EeKC!|a&4A= z6cZlZu zs^6+~4?dL3pW3jfl;Zj{I?HVOoLf#o^zJ^-kN(f)!w$M?H4Ygl4wFY6|_tY(66O z6vrZU9n{lXDD0YA72+`VYt8}`BqaT}$QyPkmlqZ!=A*TGvlf%>2iy7t-v#K0(#}F6 zB5Wl+06zv~I8|BQz|fA44&yGa^JH4Py1F_iOmh47k3jkEZdN47{UIqjZLpbY2fw3w zQ|lm>X#oFi4n3Hj3hP!KfY!CX*Vt^CBoNQg0DoHJeaZOhdK9d&ecG85^oT!(gg>xA7pI<&$tQ##u*;bWij;WKJILd^=(ut?|S%t2X%(lOW!>zcfi$CgXCRSSDU3-5446UQ{AkhEkw45(*+rk6O_$#FRZers0`MC0 zSO7U3>+H-mmKIf3mKMm>@R2cQ5&N4XHnD4}|SV!PUC%LE?==PcH?{|!RN zH|Eax1!<;9H*Ee5UUpzhB9_%Dq_t(KnN^GqCUm4wn?-&|B_M|{Hi=-=IeIiBT^www zSj7QCFWOPNufKn}<@bIZ=cL>AV*rodRs*>k$ZPmhI^WtS%fTyMkIRfv*zIQB^&vW*3 zDoX=C5;$F*$=G8drT=JzB|hsL%0(GcmpRJyw!q2PcMB}x6n{?zF?Lf!+PZ0Yl-#BD z6%$7-^JgJ%m3^o7)X{mTYbqstI@#Iy9sGNw#?e zyJ>w#C=YAdgg!bf9#ALB8o>(x;x6w)Cqdttgk!99uX^pJP94HI^ql}P1pH?8n!m$I zAMPKva~0+7)hgR!e>>+XQcs>Zv4j|_7rf^yo}4Xc7J*NVC{_H7ThZkraSy8`y%$8q zuSdGQ`Tk}R29r)IagppZ${4>cb8Cr2xE+wkGjnB||kH#jT8EQ+2=W}4l&Ej%YibXfAb zal`TEP0@EYg6Zk$fxiPoMnbx>^e7+{*_!-XkM$;zL5Ly2*QA!(v35;8h}LxYx9gZk z$3i>kxl^b^tFgJ;kSx#X*$a~X+nIxv%Mo61%3*ybL_v23<+C`EGq0VAJ*uhYUW?RC zOL*Mece?{xBiP{%jB1K1TGpK;Ez^4YB?p(U_uPA~&gCAAwuJHz^7X^?bv&9)!g zL(5DTM`y5U6#methiYf038vUm70aU46jeA*>Jlz&atnAoSYTFRBTSy?2(0$rbL5~> z%ZICv$5i>+QD33&(DG|LmH^>13BhtEQ+1f~Mle!R?b~#xZ}=Mr%`0m2aQEjJf`Y1=`V9aEi|0;~8QJWsOAhY}Uo+LAO|FgxR+2C5nP zSx+Y)VlkL<(^o!8Hl$cxN`Ktp`lh`pw`N{wuPwKf6OU{OLm2cgkX~#4_D!sQHIq=; zm1{XfkeRQO%J1kn?R4xWu?KI#T#Rbqi+SoG#dFEdPG-sBc-bzsIbY}#s4%@NFON!1 zm7*^OK)yH}5^D~@GKi4xnm|LH_C9t~9$3QVoO~^&^U>-haE(+`2hs+pS0#kXt%)A42~`zvM`m--n&H9#j=` zGk%?!^AfWH#)oD{=#3lqs)SGYAszEsU~~)?tE}A5a9C1RQR!Cws!CfGY44I(Gd$WL zm6&*F>#lYPAhTaciCS5QyyxQbasH|(c{J2FfV7l zN4UGceywblt)qDLO2b}i9dAZ2!~oh-AUAk^d5f5YJxg@7)U9g?z(jXGDCx%YFioOC zXT4zyU=iPpC@Y$A3WcpJ(=h-j{{8oFr(pK$Lb-qdHC|ID_&?5bI1FSP;$?;Adn@As zTPFlyi4^x(fp&oFd?#)ZI~*3>P>T)^A}?0WW%^lZ{mo3WKT@(k9iEkz_WI$22aX{j z_HC*;8`thBdV%IiHFItGU1xV-+dzFb(hf=B0fElld6d%QSAf$B2%gD;};o z$lnhxKtQB~-B@OFYbOeZI-1!GbWMR!LRb{3y}f<+)=kAK*9TX=;x929ATB)+%K0ru z=^i;UU5Jp8xp60Dy!g-Y=+oHeXFdR|@+EyhDjZ!7yfhG=J?>K#W|$KSCekP%ECf=C zuV_CYEb`lo=H4f#e%MlX5_#KT+Css=34s8}Gq0?=`u^WACv4o{UnfS&X~C`fNY{8! zg_b}3Yk&^HNp-=KSPHX2N-lpH-T>y?^7<5RY&d{$<$Sk&*bIIaVx`%!vVdcTg5oi$ z%>Ko85(J%GAV7OD15$jj)?H$)PnEu$Rr<1XZR}aBlG*B3^%qjF(wR$)FnBfyM1kQy z0yK93BTd%k$9|$0DgTTQ<9VVT@U(8UxiUu4edz7n_Xk&VEq9NA67WaBJ2^{c%U9%D zwhJ0P3hO4l`M&xz>}uA>^;9Z#cCZ1e6|`#<>%5{=A{WYZr-vyU#Dix}@0NG;5CV1_ z)+igA_Sc(Ij7qS_a&Ze5g~%u2#XLX0slMbWVSFa(NQJIy!20I>Sfu!doD{d4n@z!e z8T7=PIeD~ zm{tvW2#9c$>&obN`%#|}(fs}Ri#*c=5srjFp2<}KBz$%KxFL3RO<5D(w0061kNvm? zeG$A{i1sT|+Ea)JeK_1Gez<=svjBKha<16N}^6>W1kBq1(Q@cjQNS5hDE3u zZmg8hMrSwXLv<9kMujZ+g|IDzrw{lf;>Jy)73)C5wv2iDPpT@wog|9{VJIIJepqX# zTh7%qhHhci90x7np2Dhya#&&u_H;2;g+DKtgcG0Voxc-AX5E@%pP6;=z~3`Zl2cB> z91^Cs@iRIGajk;qO4pQMu9L>uAwpLR(hF?gHM&em_Q===<+h@ZWENe@(m0wOS$GwX zR2~3MSe^!V3q5>z-pdvUm9Qtt{6NGQt~OLJXzi}`>rke();JX(WKhU@JVtCMde!dj zXMGIvVU$3u*EAY~GDYAzblMle)L`yb7sW_ylaS8J%#ms@>0PlfUa_Fe;t0R+%LQt+ z3RY*`{U#TfRz z$eXZnI#+c?j*yTLze&hfwvp>8Dn!5pKe<=y&k7n{*8J^XKRnU+GDONYDHG|4p6MOI zZJqZz&ocSUJTMDZ89qw&9bH{xfM`?cJ0&b3A#wLKACbl}0-&>J=rFbp;2tJ$U}HdR z2`1;lLIXz(%fm8D7_dPE_`&UF`BzlmQ>VmK`{tt`LeI2Oz{?5<2ne++6y3{4Mge2I zcOj*Yb)MYLq`S~u2v~83j!UX@z&B^|W^nmJ&ZUy7s+hPqA$c_C-_BdnsFb%->%OL2 zCVuwpSzxAr@1Miz1w{d{!^vUe4I?~b-D6?=luI}iMl%H-sbu+2wXx_0E}?jO_r`8W zd;=X^%w25V`@0E4!hc8*yZ`Q_^nd(%awI*+RXue-GGbA=O}hV2PqVu_U{2)Lz6WfZ z-NNRy?yq>aVUiOwQS4{2@jwt!;5ohTIShDu4{j*`0RXT+i2g02%av@N?+v_*%#oYf zPK=cm^-YnSD(ycH8_r4m=?u0N_hf`A8BG08b~gbl^-s}~sYVZrYG|u=;10D@_Y^smh2`s^{+Qw!60*F~PUK-o2V-*sK}BtZDeCaRGB)Iw19EJ+~#n zHF|LOw^>{BM{nB!!=(&cwHJ<*?dt7U7q5(&aA@hVJ<3+7t22z3{wh=^hoJr!E8 zszhIAWU9APnc5zx*Jyvn3_*bPki+uWEI$ft#(|i4qTaS%;x^dD`FYUk61M)q%6%i& zeMhW`5990#ka9dFMU@)D5FQ+$uUZe|RFB~vPm}wwg}iG}-WZMrBu8UcbnsOxr*8Mt z2HRj#&HIGLuBN>(=+ShZDn-5azSLgAxh?k!t4zf*aT?d5?N1KC=af5NcuJV3J7{ zm6rclZH4FUMH9>biA)os1tnx$cn?;D!ck5r>3+uscN+@`1?2=XXpIOJ*xrF-a>7j$ zxwNAP)9%%;>`Zw39g#{`ql+$DE#PcyhuZsnO9HvXccIP=`6s?{Hg zZ$f8TiO!H)D#jZ_Aa|j8sNzdORAfK0gBma^vK6*Vse;8n`*I&n@;TZCdOS=_{$!{( zvF8hN58L_^O;@#O!be@Q(Hz*v`cFxOUx;akKX?NMYQ&^_19?!h;|~YQ>hB(F|JPn0 z7V$D7fV~*Hnhus>-50(8n0)p$dPWwJjM{808{Yz)xUDD16oHURQ3vEA|4uceAa(@i zp6?+HNQMLE|Js)gY&!G_5y+>KX+8!-U4h^R>JxQh!e#3wZkyyXkGp;Q|Jos7bB3t! z)8U;HKJZ9G4iSWYBOq}u5ogYl-(gvpyq>G)_CAqgsf+&eeJ2WBDC~(}-6mL-QEtIU zp1u74F`*$j_Gt8t;ZlFWzna9qdXGVw&gJjXjeG#M8wd#d8-aqR6Z-J}JjVS+eadnj zDg#~DQ6!I%6y=4c)u$hhtH`Gq-<9R~6CrQd#0jtKV($yl1xjKSbNf8|&ssiv49jS` z$BFt^AK;j3jIct^)y~2LMM;ljOsm_IT{vJM-WgdQ8`(AB!3>uAeDyY_VVGAq=Ih-% z;7?-{Vo_3zBNC^431)Ov-#$KYQp|qz5p1M(G9F*Z^uk2D~@n z4yR~*%g_lMhdlsC7*x)9>)~DVo|vLYy}rXsTXmSwJFqevy3fJsSD!SdXTAnky90E;@&MJfC8Zg;?RvP##sfLU1FdNRwf4 z!<)Hdz{E?Lz^$&keSZy&k@W9UuP->H;g|2U$u|-9oCJF}L^segA=6hgKfABaSa4J- zeO2Xy@Rcs8^djs`nYR#_jz_?mejZ|jT2&!OiNo2Txftk?gsxhl@(i*UHhSL2vR8`98 zCq#N#XEy(Qn@d9{f`0ePT(fLP@hx|mthEOjA8etOd{RYY;1cGPeDA4gjIySZCh-7PP6Nnyv-qV9D!nZd9^MRSNC! z+oBx_&kA)JagT~1m9}+d@gi(I#iau4!gzeYA6Je8dmqiS)3$%toge~% zXJ?jc2QE1}{}=luUwrFm97wQ_f@+n}TuMrc)$Xm17yHUL+gAL0^dX|je>A0C2pBQl zV2Y?kmhOk1e2bwLK=FBGo^SQ)TsXZQ_0RV~D5c4Dp^vl|HZB%ZzDfF};y*SloF1kc z(e>Z14vBc~sQ)mo&?W4kl$1@(s#?`|j9D@g5JF5Hs;9 z0a|}`6-z!Vi}ko@%*X_$EV1Wv)Rizxq+$p&k-;ROZ$EzkCRS($0jrHZ;bWVNyh|lW z!VcwS!KU4A0lNWy2V{D;zx1G8931r@5N8S`G8E>J`JXBsQMfIH0O2DYvssd-jR?Rd z4p;Z<(;D+&z`B{PX;qGqT$~n=y9UrJ@AX>HH2qD>pR8F)Bf#>NG2}Z$mPzp~9`6Qu z8-F{jEA|qI93^!5@9YkWT5f|`B4MsmrQMoBX)mfCrGVt1pdGe8690H}OfOin9~-+o__GmkyORg03GeyRV07YFDuIO*#W%-RMjdOD1Oly4Eybj<)p-F+;r zMx_b4?*m$A=8MBzJu}QJk^|QHd=)GO-+On&H2{<4ul3`c0PDRR_EjVp17EK&O^>@r z1wt&?baozIi!RrQlrLg-X2iN8@n6Z9u8b5OtVsg$doFX20j76K*90WNnrL;$^nO*?F(yo_J4zIVZq1CoW>E-p}XNaftidm}S(uG|2eiAahMo;py z-v1;8{KR4B(f6R;jl=~!o#ZC}YjRw6B7 z<94$Z$L;o+^~PCLW6vyu;Xz0m&VwMv@S59)pWkGUV_45AF8z1{?i|opW+c1lT`Qc`;zv4#~#vl!z_+)m)O60R>4uSBWs|vSzvI^9u)uRXHc_+w*{47~FCM zb}GN;$Q|NtVVNV{#hBZ-r9gC+?BWp=^$UbJ~InEb6jMrj;d|$NTdPulqhXWbS;*+^kg;|Od z13lJJG-v%Lrg4FKf6%XGS`p^wEX!9Y}|j!oN4NUZk*>0 z1^8xA5&;Y7OR~ZUwP(jb!ujh39^*Bs-Qe?CvT#Vjc>CgNs`ieG1Cm)jirI6xNHoll zZ{{rL>F_n2Um7mWunQIRm5^j`pLL&q^}Z1>T>D0~9$53h9B&-uhdqUoBVSwvznds; zCkuJ!@$z896ByJ%xP`%B&k^53il4C`V5eYb z8bCOt#-W%`3t-Wz{5~{L-tsgwROUFXpLutf%e9I_6wCEU)X-n4TSl&-hvS1jys!BX zS#Psj_OP&V6o_SZ>froRo{;ht*Qahd7r6`_e%bN5lx4l*^5C?xef$=Bpax111KOj< z$q=@@{oIZa*nCJ*ZToOMRj@ZTK%t#5lCd77gQSYDSg3G5Zyqtdi@l}J5vZQoS;CN6 zu%G6a&%^V9rB_Sh?xLhi!rI4&))n&~@1ANmHg8{slR%Cx1O;(2f70_^J=9JiBc#E; z)hQ^B1ec2-nPuBq5kr;pxF{j^IFa#eZNR@&y}KwBdnOAIKa2yps<%nX=RqTEg8>Gd r*v9^Vt)6V!9**wCHtTUgdY;<qJZc_^L&``=%Sg#c$s)zhU-xwL_I37i_VmY4+J;d7^{Akx zmL=Fc1mJWu$LMC^NA+X5{L-X#vm8?NV~Zm>H1!_%v6+=AP2{*&wl*Ro5!_}b80sv1 zBHoS5F^Q5w7~q8cS(QZ}I3h0Mo{wj`-_>a1jbtL>4Kdwm_&7~CmsvcfCk?N!Nh|En zth~T$mZ&eL(URj=(U_6pc(=?yMSl_PWT>f!iAvF@EjBaO)RWH`$7A^X@c3&QOCU+j zCS)X2_?sjP%6oQV5!{dI0TTc~#N~6wK_jCpp@0kk!1BZrXT=hQlu{gV97k0^?jr!8 z)0+*K%=WSlZ7?cfFs5y4ap#?ag~e9D3}!kMh80VK#G zU9m0%)xWU^a1c`>iZm?T_DhU#QF0aUS@8Epy<5O}iZ3kW_`OyV&Gze6T+H!{^L3GS z1?%Pbu|~LH{z~O`FKD=zQ*gaXk0N|@Il+3Qh6Rml3gaM-qoG9U+UXuJh5EXHyMFo| zn0l=QRyhLYCm#8E8&g^?*jljh)I0&E)VLnq^3$Z?{-fSs>;e0$!Ko1K^9ZT;urQ2M zhv?Q{L_1yh0`1D^OJ8=burL|_4Vh-%i^DwltLJb45R7EQ>j_5v4Tyr#oDTh%M>*m2 z;$=kzaWVrE^@B36C}5?w{;wxbf}#4-Py3wzf5bjN)pKduI50LCzItnT zp55YI`sIt`&eL1hubc>+-VT`A4w##Wx?-K-{15T3u7f=xAT;5Bb)=ZnaZq|OFV#fz z-@1te33i(D_V}RB`J!K@NZ?ZC4C+;f##D`dYn!qejhX9Q@Yk7c(3wm#n(#N8^tZ5X zylmZceRBM|UB>m9?K}S|2JjtqQ4au?^b(8o;)?VV=M+=WkbJ=k0N|p`Cb76e#l$(i z6f`cQ2$%cSy1?aH$<^TUQs_|?ETsx1h>>P7C9{}$N#LXhXZ+uNJpUVH=;aaW|2zNyAccN` zmpJDqhf6azXf!u!G&f+kIB)Ua1$m<}IU|s`btfV6|yRBqn*dj(jHk^bJ-Y^0YXh=#4B_6Q@Ak4cF zMB>2sR~A6Jap%RN!1#CmfAj}Z$;CiPVt=b-3L)2WLMiF*MnNjbaukvz{y!q}_roA9 zkWlV_rd3KJh?W04EfJ6qvRveUgVz6V6D|003{a!5F9;N99am006F#EdOhw#U0$ zTfQ4fBo3i7ENgVLU@=R?(2ULKII+Nu9@L`V006JmFmv!BfXWRD2tojwb9EBuH&lm@ z>x`LOxRMrQ3&i3|+{(q}hBl6ry_^L*X(5P$EGsXkH`-7&Wuw%zh@#Xafi=rly8f-^ zy8yws0#_2H=1LnDTq)#0^?3ONNSjnr-c~I^Whw`*9u^bn&i15oFs!saW;8JZ>wp+S zc^jAq>zG@B#zwj`*Jn_*4?Onx2wa*7aGq=ewI{D4Xu5D}h;mtQTq&eG!B6P}3@`dq~c|IGyPuUKsyVxB8t-D zDJBPA|H!BS7jlYa0j}oo2jF9vVz7!R0F-t@0A#0b@(`VFI6ad!9Z&=XIC=XXgA7nT z&nAx>l^X_GDQ9H#7-TevF-lzw$`y+%069-7IO1{jNpK`6jB>JO(-{GI8F1x@x8K^N zj7-ff-UVFle@x;3fQ-jSIWX(YRa#y?0J3o6h@%kTGaWO4rBSH3)@Ni5qf)!laK7%HRy(X8KoRbcK0N);oE)F-=7tW{HC`X3M{|Kc1U$v6* z-_*waFTBzJPQU(Nw?YrRN$>{V+>y#>WaEC!3h03{5N{eM4KM4l6ztCQW3_Rw(j-bR zq8rj2hBN&T`fjJ1a;5u_X(={$pQXLV;i?)rZ;A62rr-^vw>}wQgp1!he1G;RNi*?O z@B3TB(#0GXE9$mw9rf$paXS8dw$15SQ8)hS)=%jsOZP--z+OQSz@p#RDtF;Vtn5KM z1VR9S!_q%<+Ypxn?3Mw)1f6*~8C)R{$r%aviwwzHj5hHPeB(9rF-}R+y+!FM znthx_ZygNsBiL>Yx2C@Z%_1ZmfJ;GOG;sQM1k`~Mz#>qx+L~9`C8We6XkvnZUjU0B z3xF088$EqG?-g*u-)ABW5srvNa?qM!q0GiDUt-UwexVUvVoO&BHzHu525tfXR*XO- zx>R?~LWQ&(BMM*4QE49)76G5B0DumHLXleO?=r+QCNL#3-#Z2l2bQuhfYOTvpwPd} zHA)@|{cB^4jX!!EplpmOrROA;Q9uA>QHPf0Zx`@yCSu zUw8Jp8R&QOP86R2AHM*f08%h4BqZpl8L*}K52R3Uzw1NlEpbz9KX1w<6K%4}c-n4t zT%5kx*XZRN{Bzs#C1AdKZ_lA(tM5)7Jsr_aBK-K8R157)&#zav7UU-qY<|YkDPx%5 z4c)$eO#4TlS=cW8ZH3}LBbI36^to_Cf$$gj0RWMj_gNc;O@ihv5ef=ZrC5ZCJSn`x zuDLNpT&!upAewPKXw2&AtLBMSqUt@d>#K*nFK9voP^WC{pZ#D$H|`0|cG7Fjequp$ zvzfpUj7Xpz(^RE?r$tbx`Qs0gUfIi%_f3btzeLARc|LJR6^m3;b1FnZu@b^4tTqyk zj2BUw6~jrZycwL*O_4kkihdAH%@^)(STDL?P~s8NJb$ueP%Bka$Nff(*lup>SjvUE z(>iDHy9uA@8$Nm&H&ZdxH&4@k^LwG>;d5Nf1Zc<6Y)STid$j*e{_90)?3@VK`wnEq z!}W@ZG_M{Yp}L{7ElmO{BdS5!pTn?*kR&!}n1^jNx2vuzY2jW9mD}-*=e(mOk~EEW zj`43~G7Q-d3Sw32m^sh{wk#9r>aBZiEd}heDO3KMNJu-KE=X;6_|NyYubr~?m)Xxe z??0rrCUZT!+{}BErm~`7Y*!O9YM_lmIQ><#f?^VxlNl6ie zpX+EqZ0RiD&eTq-GryV%4V&6DtAw5W=Jo!&K+M;l9oQecm|ZNZ!gCXj6u>E-NTkeL zZC2BGHY8i0K1|x%kmfEGpFUdbdY$Om-GY`%>6cme>$*}e#kR++a4E@2Zi(<$&ws07 z7GTOK09sq5lXnN8r)_t>uFfR=6!5BE46WC^(>oyPMUK8rzUgS=3!gj0o0g_T@C6%MhP+I(9g%1fhB77!ZFJ}Tcc(1^Pk`6yiHT?d|8 zNw|`_Cn4Rx_-;=M5*o5h{magLYht&EOs3rww+)8upGZGwR9hyKHJ-&8`w0pX(u7eI z2@LX;=kq2Yf>?0eK|A83MS>hLa=QMy9sG*RRlj?TJPczrN0T0Ib6x9jO1u(SP_nt{ z<;+!PzrN(W`IZ{RBX#*Xq70!S4}{>DTh)`Q?yo=jwg1z6(*7}X-2M5aJ*vrIOb5d- z**Kj^WF>E@K|TwOJbbUM%Um7Rjb6_32t4Qe@TuKo3q7N`8$PZ**iLD!_z zMC^bj)!hG`9elXVYC(Nw+}g*_gC&$2X(zdSW^;c`xSZazvcBM0X5hz$&F3ciy#NxY zccjypHN(0(<9hiN`I%?vI;0Ktp&zEmu7gd=PAy>Soytq#XTlfG#LQctjF_1lb!i?D=M7h2>f)Opt~BM#hjq{A-iJs( zQI2CKKD>7s@$i(FQm)>V;y-4Wa${YKiLBPTcuVQxGzbzC3!_3|kzYC^(Za$y4#_6H z8oFV5d17b$MBGHKlusCKe^Odz*}X6we0eitWbVzt9^$c2$gJOs-jC8arZu)Zy5#q~ zh}=Tzlyx-@R4{kKGBt{hwLSKASvJNkW`2fy#`jy==l4#>ADEpn8)bgkA>aP>E#`S$ ztbt9&6$}+NMbCsrj{qb`Y9wRDP^cYl5{n*f|H)XN0c^plx52ma<_cN6829*#H(YEo zNPNW=e(%0aOYnO}Pk4K)8>~o+=+f{~;Wp4^wjx483{HV!$Sc5M)@z^arUl6&+tudz z3|#84f8xgm`B1^lYaPPPhNKoq9`k6MTrrGL1OwL$fB?X?&_ISS&%8@ff&w3$icVXB zn#+o<4O!OO)xt%@L?yFZ+2$KW_T|c0IJ><(K6R7YHDsSE{#UJ96CnetovZZPI$LRy zmhSSNSCFE(pXVU&V&zcI_lU^qgJxCUbfq)ORrm2wq#~;@3WXhAcy)5ppU|H+uOKQ) zx}UwEFFXI$MN7LJkBfXMyxmP)ob$meUVS>GoI#ffxmcC)V#U$OcZqw7r$19UQxN>$xm)~DJIQ6ykCD9wK~-rw7*A6zZO>= zm`(UXwF?6Un4rgrqvtcwkE69}(o6MlQAl1`a8?-NTgd0@b;{|@U*Ed!*?+L`aUkTZ z%dvCgFH=QTHX0)W)}6LCRzEf~D-K@ZOZ+82(fZ;`f~fk*>eLI?ovVNnCqP5dctFGa zJ#CxybEu;XFg5#g_0g@n9nBA`9k!4r`Y8@D+}6*IAorT>Q$N=hRr{|3=&zEApN~L4 z13@hVzKVu#f8pAJ<0?aYis;&wgkRdJUfjWrx*srXh+qdE+xF;4;tppg2hOM1uGnRs zf#5SX#e=yFUx|Drh#>WniEz%liW+zcWW0`0R@u}bgfuTNnk_Q9PctaM-hfMS5fQz1 zbK%s(;N5|0DgW;6pF%}G{2h;HJ`gil2EP~!@OvBFVZIc4>~ZT(3~<2m+y-l(4{cu( zmgzvs3UuAu91ggCb6>(8bC=832(@bJBMfePMC6AaJ>(0B(zv?&i zP4$@95r?JgpDCUzG~63h2oYK7@o}_!F#hYL6TdFKDdKr>B;Td3M-sIiEYP zJKBwOs64&yZwQUfHm+i2sl@{AK^&83+Gllk3dy2{<_~=~Bp!R+?zy{uj(lFXOs(*k z>j<-bDr*K35=)s@pe2{XNt9yM{jSH^NC3PQu{6mp=x{V~jb&GH_D5*@bH@hHlObH; z3Y?whCV>rg>r@&22ipA?-(Q5ym!DQ6DQwX;_AzX4o+~kVIP3c1y}(<3$*Bo}EX_M{ zKUjG4Sb!;d;5e%%6pKY2S&X2o;R}-0!GST3K!t@%Abbd}NK1)zfrLAB8S@%t_wVVV zP7QX#MDoyj_9V-Trq1`(Lfk~wz48t+Th+U11SiebMh)j@uzS*ep+qLl$Bzn5aF&>G z5X7XBSc*fN&CDDXkFe0SG`98Z9~@#&9!hbMd9BRRadVnl&7r3KxI1yDW6bS4!z+uD zH$28BK8+!r?-O5-o@HZnKCwWL)&mY>7rKUE)?_`4o8%k2j74fa=jBd#iuCWEEAQIt z7`uwx!~`eXzjuNGX9bbq3a*&s;b2VP&n4wYnDX$u$du*QTPt-;h;Kl6PIu}L!^fB~ zu{jBJN^NLOhShLUfR>sVdx+V^KitgAE%$rA>T@Sr&u{sAXgp2ub3P*9$(GWS?dHrD$${k06?S_WC_%aed+&5Fq}LZSt9V0f z<1AZd;9E5-$6B^R*?0^_=(l;E9|jyiCJyg86poqXVyTGe*d#bmfb--r%9dMK#_B2v zc_Fzpvqgp+dh^GyeLk+aX>t!MoO=8%zpbX;*{1ujF>tN9FhDHaMhKtK`cC(cWM@|# zwnE*^=ebEI7Se9bTs0K;>%i}s`mO1-CO)uMd&Thn$+hT3dt<;cfSnuU79XQBV80w?l}JSr~l}XQOpP4 zcQ?OneLQ%lx`xXD64}0Q<&1D$yG#Q^i^1EMg(u13eNRu_`ns>E>}BLLX7HFyeJ|+Z z*1(RB|0hzxi9nVVTJ1E7lMURrgrkwDlSy(o+0iLEJK3>*)7%-39-orMNMbJ!81F;oJONz&W^^;PYqx<)_tO3VrW7t63aXna)1&jzs`XOVsPf z@JkUZ=g4%jmwXWcCr<~5?MJZfe%>7k?P9#ot34eTk|Zc@dY>!*Z0DOa89+OVh@b-i zbP*>nG*Lu1LJv)1({+f8gw&OuHosOK?-y;C!+j8}F<9!VTSFc>2oRO;zZ<^vdplry zdG3?tv$da150#>q`w13$5&}p9PZAc!IOlaEo|yv5c?#h`gne2e@hyJvFr%S_h~k~| zsu?^2uIa%d1O!4#8;V!GsfN+1v3q0=uzmHi3&N*$-1!OC1j`vOsGs5G+}mE0 zUw1XKRG;^&7xN511zdA(L;_Ud+WAXw>Y6dBm9I?!*jKNg70d%OpDtAC$O|EvSp{ii zG4GU&Vk{s0$Z^*B4K7upt35Lx&zBRUj8WWoPr^kWZSa@LUBnIe8`v6spOxH7`auEW zA`tz)2qbH)W{JS!P(X-rZQ^9|Yj*CPp@Pu(`frVi$JX{v47TFt&)hwfeqBDHtk(V0 zPHIu)FbPv(k!6wWY*A&Y4eK;f8ovq1|>e~o)F%EeIEC?2!r zyOB`Zs8d0Dx-)0hB~!tq{xOvLy2O@I&70KHTB|+ok#d`3NlFL64;{!|dUgnZdDHiq z-AHordEvAhy=d9iT%zRZ;yg|A>za#4|JtVn+nD*)O&LV_c%SP2v_ zlOV~dL}p`MEdaZRja|0Rw0ta|a{Z6ZVpECz$SIxA zt^3#QE3?}P27S1w(NB;IP}??<%9+9Tj`5u`^3LKlHEUiXayW`Y{ z;v1{Mi@mKlMZ+A?g|$siKL|ZfgKSk#o#?Wj#FvO3^=A9&NP63Wh3`Xyd#Yadp}P-5 zHL3)A-dO!BYDorSh@nMF!!;>887K={_+_0G{fHhc8T*=0Oci^DKih{J#dSS)=)QoP z#PTwuzMOK+%R{e@5bhr)7dxD6Hk9-pkz?{~qf~%2vXurr?{7B+f#a_wiQ=XJ{T#qf zM6QLAZxE6VB7j6j1>GVZ`6W07gd)Ok`2~2~2=@9n9|k898RqVN!!y9|#vML>B(DHJ z5`{zx3Gk!%1%>zpg!lx61yCTS{R7Q_%YyZuBc@}8e87;*$8+H$c5+bFJyhcBjf0L* z!N-n;Jc928Sx4or66m7~z?T4zNO_;L09s8NAz4K_i*JlwBh6X*wMmtT+yH*wsO@aa zrQab+f2L~wF!4!sJN2XWvpISne1!lHVuQM6fTj<+^OBIyPwj4hBOg*XGwIkUR5!8g z7yybtPdwc12z`ECD>)+}HyU6vp_NL*%K)repo1O&l87SO)+6+6fOkV{Y0nV-ETffE zwQ<87TIO3B3%=&!$T^~x8SDLwcPq{klXZW}B@qMXKKCB7%sE~qP>r#sQERVw)hxx1 z&)AL#sb9zH+2cQ>HP=)|>RxPC58Mbt1C{e$51#8Ej&m_WfxN9V&u;nDiUFXyv3lUR z&s0%(tx+*gkeflf&nI`WE?wosjr{M0fca0ay@9e%Gh69}r^S;2<|Ra-#v_RZTz_<| zlw0(B>Pu_)`m}5Q^f?wN6f$c<83lEzN|ZL<{*L46`sAz;s<#`<{8BxqRqexU8=1Nv zLb_d`wSMes^}VK+AE6Lmg2*A3&FQ#yMEtc8Bv5Ja5}JfWx}s1hYpapC5kVRvy&^Y~ zlq8x^!iwh7_G#_?>d#lVnK5&DQuK#k&e=MN`WL4Tdd@t4TGqHAym&p1dXB8uc#B>_ zOl)ec^c1`dO3fY-*G;Wf&W~2$*}S^V`R?0Cf}~OtT+?AzCkCKNwjx+PWBLdw z4g!0oiI$^JPIy!qA4>F;8^2Ai0Dj=Oo?j+vBSg-J)jz9Zh!FbaI8!oGxO>UFLHj>-8r}7LR=hjqy5b zE8k=I6R~$rGw?R%!T6!d?Ul81Oxp*#_ov~6qB0~43m%(PYs$&V(ksX9=3?tdjuo=twg`-BM0Sn@`RET-DkV3H1_qydDFHnZQ|lU+4i@I&V>Zn@^;7 zuAUPCy#mwdwNM!0Ewg^G4c_5asp3B)mI8~sf!bVl7=f5nf`Krjn2+P~*$iMh^gwM^ z;_DxlT0YpfY)f!MwhJn;M9Cm zQ$1CV*{42hYC#GYuwfr)S@@TS9+MLo>n<)_<2r9U#QBferH0cl!U2TQabc)9>ZP8H zFD)n1&Qn*{pp8PTkB?5iF%_he6E5Q0!j&t?#cMhmL3cc{{(s ziy#xW?rgum?@X?gT`P-S0i+B#>>c7o060M^UySo4F&YLNm0KdT?vR{LoS-F9r{v#E zaGqMmWC)91Hn!0!KO`RnFWt`$T)Jr=zYnaqd@Fz2TV(>dFDaRhp^Fe!{c??&Xa(@M zS^nwB{MHv>IdNd?Yl=5xynJ%s&Tw;1xndec(F?*7?}oh(2v(CNGvL!e)0&IU$54rE-;V4Lj8?KukFP(q9@!FjRWkLnM1g8N-j*|XtkwkP zcC=a%uq=0rlCaXTpbxViCp2`QxkP91Il|YuDy2N*?c4K;Uhh<*8ZZ8)YBa$!g9TNByacpO9^Ija>aO?VwR!%RTPFH%QB5(bmsh+@#$_ z*@luOj2>Ku+xkqJH!vD`WWK_LXjuwW`y%VgPM4&pq7ig140J;H%$qe=FpLg3_m=@q zx_H>Pwvp0J8aEcd^Z=cQJl>aBE>Kgc#WgLfe_mBnGj?f@7`BjYDpC9w%o60gm1Gn& zspN=MqW1Tjd9I~MkHrzi*Hj$Q%sAacG>VBEmt~th8f|!Ol_U9?TK4Z6kvny(#Us1K z(aUFw%r9HRuf)%NL?o!(HJ1Vp14A&(o1t*K=9w*2M`%tnrlsWOzhIW48n5U-hha4g zV*w-zh_aO6Fh!t8Je-P>rR`HhV$*z<-ughLnb&msuPYw(M307u7U%ByX;n|RHz`fc zl?|Ehk(47%e<*#v84pF&$DYK_`}#m^mjVvX{R#D+5SYE0EmU1%^-uXFxhUqpPCLLE z?FQ8*NK7AnF}C9 zYNts-yon%$~r#;&gIvB4}}r zu4d}frH?PW6HevzVG8r(A=(^br3V){X;v-+pTu6L4^a~W_rjeSsWt?^`@R2X1UPs_ zXbLT4eio3I;twd{TX%%ki@2y>z8V@#6+}IXaPmy%4v;Zh4`yHEsoOqx+R|N}|3ZTq zaW~+Z6<-9Ljm1K`*lpC(Bp1b&%gIk9-v!<<)83t7ujfjcj_m%0-M51g0u`1LBDKH0@%qi-u2yMGDXU5kIv;Zu!UT zl3X!{V!Z-}+CZtkjI6B6XDlsA)ULfhEma{s*-7EN6SsNhxx)EWWs8wH`HhAJXaXU*wq{w9gt%jp2gWB#vS^t3Iw5=6dxs9w~uQfl6y?fE}958+GyZ=q+M3$ zgncB{z=@O+^0*QZl2JKYr(kyZ=I_baV!J3mSY6TgPLqSve&@lGL+y z{ll;F$ww6K+aeF6_Mh_Zl0(JDE0!80#;j2kS}aNbp@{ zMP?9s^|UE^HUrg#>XqU@W`cm}B_k8BSa}r3({TxzxvV<$7q3d(es|4NtZI&wuI3;7 z&0P6MThg}{egCNM^Kgqh=wX)5IF=JM(BJctO`lS$E*B5(@heDF0_ zHAf~lnl70F`?FqWbwk&h`3r5dSXiKnuE$Sl26kUssu4V?Be!_(hHv&ppGxccDiBEv z2`5M&T$Z2k3a)lY&l3YAK-WV0X$rVzDwzW7A_O9sudHVh-=&VRQ$yzGC0}Fx)=yl` zv(eH*5!o11kiE9;gW;b%IkL?}^p&(%C96{sKGTs4wY`2Du^&(!h_Mv>+K9?3;Ti1tsf4Tr+* z=Ab%-Z;)s$Mpn&7r_(x~pT&8H=FiCk5_4W=qt5%+^~+xeqtS3qDB;rL$-U%i}W(ToojK)O!}uBt2O}zu!5P?j>6h zp-U|d5YWN3{qEGj%#Vtb0;h$)bj+^W~!xB>-~!?ayd$!H0ujQp+3wF6nZwKD8hAO5}^k^3KB z2Z~(hZg~p|$NPuf3ik5#^7ZicAjI&YP_e-`0)pJ{#0CZh`1sulAcP0p4j_^E-(;sB z|M^4Es`uWRXYb{E-u@~|Cw>~`vXRZ^`{Fos<{On)0Ra!ao{2r1FxF9!WpZPvI{%oy zx@F+hNyCtux62}3KgG9uFLZ}2$ROPaI6Sz~;6!oLu&@+Zacb+O=G=A@ zN_UcV_zuOD3cj_D`0=fHD^pGFzDd;Z!rOqZ*Ly}@M&GhoL!*h)f3ByF6v^|Tq9S(F zi|exmP;H_0o*5X6+9C+6S}^n5A^ob2w%$i82gkV24TrT^mj&2P{PBNA)+n_2Ad%@z zmjT|{Kmn*LIY~&tFP&jBujguAJ!OX*=DJEr$>v_wS}|hH36pBQfgHZuydNycux}Hp zQDp&Iv3gXE^}^)|8}W(WS`ipJ7SB7<+BX_bdYZIK!NmZ6(rdBosP?Uix!YDVEyS02XH27h!@6V;9y=En?x?;g)fT3mm{2yh88A zY2iyZq@t}KNiNA(e{0(QaHno%@6wrS>6$B2u*e^Jf?P~l9Rj`f&|kNs5SK3Dd#Ksz zsoS$&&nr;f3|ZRLy0l_8Wq8#$8=|WIdsnb}6Qg|HnNCbc7rbW=tZT|@72)3O@A%5# zsfJt?WK5mVO7ix$x+o$2@@H;m&KbT+9-NkR5l&e9^-`L~FXzS?7JX$)Nc^A0GK3bS z@2Q0+#6;T!2pJHOnK2Af8?4zsp{I2x?vV#-V<>I$#r{BOnB3b(OEMgl^@eam#^V$z zifrPu0CbbC6$O2e>tDDlr=?==#-V>x=Dc9qxbK4+KK^+0ZC)(*Lvmea zJY@N@nl55OsEC%3$y2CnZbhN^I9p?5QEM-s{5)~fOx5}LAit>U6p3kEVgLkX2hx`^=;D(Pm;q~D{Dy2ppUX8Z{m z2oSE>Bafb6w< zV!yjAB(6FGP{3rtV$t9wNswd;d+&?VB+Xf7ZWb=O9p955iDJ;#e{3fbhpgn)t@r= zgg3RXXeH}E<~*`0a90y`R9UuV)vB^OO&Eetn}8vhVfEJ0+pp*dZ>nQz~dvdzz6Qb%Mq|tz^s*W zMfXrX`emwPRF(UtCt}&~ER#ikzM02uf_bwen*m`;&DR!eaREX6#6YhXtAW-R>g-yjj zjhAAUmW=OpOWvK!S~hNS-)yQVT9^CrAgZ=xMeHL<`l){ozb1eWPwOS@>2ZAu70h|! zxO`8Vp;#h=v%WOX60jtRym8rxAO2DIaQEk#KP|!Tam8-X>k8n-D*nAPa!ACzisq7~ zWBG`8aCuYnZ)Fm~dc3l9V%`+Q>z(@s&LU6`t#Oq3tE7pI&PE_1k9z zib)0ZbgXc=bhp?9)!6B{;l*UA+?6ob0&CM%)?dYUs1CW-8T06Ef8?w(d&u@ zy-X)s7JgU@fRth2DbSN!@^2CZBwZ{^xz0^Qd_HsM&W#$HwzavQL3;T@ z_XY_=K}$rETqlg843)%{Fo~?uoK8s%>!Mln)V)brS2($pKCutf6jb%O7zj7uZ0mWF z;%-9qj_c_xCdbALYYai@{xH4y?sOXX!&nrq0@${Jj;5?q^4Rc<#OnEv>L=wemydN0 z8NMYiFM4HcJz9OpPWpqa{m?0A4Mn3B=~zIz)OiRtRz#{G5EYAL)%HQg=L@++o}>|a zU;-O5wph`BdV3{W?`6ZqB>JL)48p~!4SFjV7WzthMcZ~*;zOM<2!9+ukewd#X=3q4 zV`2y4^_VB?zhGv$89a&+5OH{z919Y91(8HB2{VPUiVF=583=QgrClOL>S~U+1hltD zWeyj$rQLb!qb}DII1@=rU3z0^LTODUSx-(ZX<741JN*EIK5G$CLZ{ zlZI{zFEpdw^l4;D=R6cHx{s+u>9w|&r8zPh+*BGtV#?KfovqxPEa@Ds3vYkQj*a^m zC|KOh**C|E5Qe7F^Xv1Y6tWe`j%Ot{hJD@R^5+E|>SH(5$6v^hC7MfI)1^Dv2B7+5 z+5{r2vDF%pT`}#2{k0MwpZtwX9jyhqF{_0u#IU+W=k~%H-p#CdF+cyiPoh6Ewyx&x zxi%KcZMoFR)9hFxznu14Fg%$rKVpZytzOn~ zYW(sUXfh0>+DXQ)Y_CaYH{QOVe?c|`{J2H^&F-DsgD$6LoR{9kt4TB@MA6-c=pAPU zSP=apCWFaErF{3Oe6*qG!jtME;$_D=->Xh|ZC?~hGuCF;7oSYg|F9&#pC}-xsplY; zbsGg)Nv12yv*;~lz_}THE2YZd#NvTZLHyC=h~311^T*B~m+yJKA+;~?_D1Ec;G3jU zOq*$hHnR40krQDwk_rox@MaU_J_k4VM>=iD93Nu9IpGRM^ZXks5}$}RFR_h|sFhi# zm?*2LtyJq77E^mlU}jE95xeu8-iSM%Ih`pdS~lJHRRoa?UhU;CAQN(i=eR3Z`<7}j zo+&X)>d3{778>_G>0S3YW1dt^7?vaj!NL&2vUWn*lF5=P_6qC1JZ{W5eO+ClAtv^s zB1^6^?!>+VI$^;KsoSV?w{3V{h!wv3ae+o#P#eQ>&6El1J9+!GhP;$H@CnCXL@roq zJ*#kUUH*=IkMTP4;Kb$O)w-axn&k>i8>{^T90wps@&<@lxoFnjZe%=A#E3Qm?}9eC z*`i0EMy9!*Rkm_`TRx4FtIPMeYI-{L0QJ~ZOu|1H}p zy&>%wel{|EeB0{A;|77g9rw8GS&g-O_IK_Dh#Ktq7M-$cW9UaWnr_m4|;SFd=apyXx9!n>X1m@4Xg1 z1TXDTbIM?-I$bqU&`4m;3ef1HmvWWA+F7)Wl|{dhGvHVzCbPQn-be7*P0JPiz7Q9N zUv6twz*>or%P28&{*h1EfR-=PMkJ zqb?O8)qcc;Qwou_aot6p$NW8t8J)v@&DJhi+P?kxv3Zx;o;T{3-sOgm*QhlXQ%Aio zQ){!?F7t_yrJZgGOc?HNE%t}MB=ZV-9 zUES0{kKCsaS%=PjuARqj;8m>B64TaL^pGhXZjb59dhLAR2|j$|A^KfgtBRyZy{D?A zG-l-FvyoG^@W|VPhT>KEwunvL*6A-cbWWvJ;CG??qh$E;nK@;xnUKm3l0(T&J+hGD z?RzVXclPQ)uB+(@0@2`h7m=`}K5kFQ!|2#$#v;oB{vEzFa%8Z;y^;AH z@M{+Lxa1j)o%5yJYn(>8>f)Hjk|ljYfQU1IzJkKRhyW~EidC4XERJAxo9_XJlGH^D zhm88mknE;Q)1`9)- zTV*X$!`?h(nNNzW*s#&k`*v&i(q;w5Hkfu$oq1KYTDtK-_QC0)uYh8E4M zx@nMd=c@b1kgFNgL!RYSH0(zX3fN-nk->QM^#=Iq4=^vbe~H#7;6~6j2*h@ID3cu4 zG{a%t+F?vB3!awzGh!*C8}K-f#pBp0FBPK**9_NYB}7Qk`?B#C1da5gboO?J#diuiO|4i-Lbz8oEoS-hFymSbzJ> zFW81E!}rvy`!SgNz$+0XSh62nq|pPl*aUA^J0uj7HqKs6><5cY!h?>-Ww2rW9Q=A1vVzN1g$ zlZ;qp@XNDFaV1q-a{MdGvUjCFJ|*AWZ|q)DJG9nRnXsJrL!5HAgSoP+-Jlz|I7m?Xh99dKP5_PivQdF|+&LA{Ojmj-B8l19qc$?Zu_zko_Tx|XoFqs^%oPal~d$Tg^^=0L;(8?$e zXyT9ErtEu<0+O5LlF-tWIVOm=3?teKUyW@gQrHM23ia>W#Y0{;rZ zgntq_+9Qz=UdS~ce@FL#<18q?=3gj#|9rPX43BI6&v0B50z%Ufah3?BqkjwCRR1(2 z3YJ^C`?`r6`d>kLx;t9@Z5~BLNl8dbNk~aZql68;yxo2MT>@OZ1F^?#Lume~%BQYj z0X7c-IGoI|TDc|@I*FVCS&~}0j%1z0iWoL^!rcHC(<+6T0*{)u7E}y^%hU)Wfu)E;rioX9iL!}evFB&owVO_Q!6q z6xX>;Q+0&ZS_=XmwA{Y!bgL?mth0e})>9{7W63&n6{ZI2g!8wjO|U!xCMH+a-h(97 zAE9DSM7>NmKmMIvI0RQCJzxX?h@=vZBxp=r4HS?90P14l)VIQ^{0d|zBHLdSQ2Gb} z=<;PDX0Qx2V00(MbSLq~=3%d7&CP!W*~}bAl#Da$ajQ7Oz1#{eR1c#w2ke9u4S)hg zq$S*gp!yH-0FJ^634+b*Hv>|mT@~C!p05Y`qF=2Oy+zj73j#(Jgz^LWJRm!o6reEe;SbuX$bVs_ZnF$JSh_a8>*{m_o0u6TQS= zfvHgi5asWqn*CmYufcK4rN7oMd8@O7DHYCpHv-g;^Zpm!KjH!TRpXG2^Sg&46qQAC zXePK*%IOx%dNFQ{{`6JaWn~#AA5d9l{Y32De>jH$0ACD?34t&6UylU7I1Wb&_Fh30 zy+~DgX_C~SSkti7(D7rdzG+nPqeLG|gnj!0v%@I;X2?9k-moS6Sdch`nD7{VPte@OWY<4+P+~1OHci5umJ{g(rfsS#M}c z&ydypRkqFLX_v)cUJmTn7I%V{c7j%CVjZk*yZl@Hhjow>5<(sJ4A;rzy}Cw2c_ z6#qNG(*fXR2KPV)H#oqFU;^@2y5L-Z0=|qd(!oIwj`)A^X!rvZsLeRdf9?PPkihhs zh-nAN5VOp5Tg>!Z%ye1J4bA_%a9)2>MjsTc0DzzY07c!i)2~HISy2|zZU|>Yz;?Q+ zfg_^Saae6wEeN6R-u_}(lD2l;QZgo|&r&*`C3*rBgD5rWB_j}xfsiYY<6m(Aq<8Kl z!6Y#L0|F>_uHr;A82<(TAANyT3bD{U;eV;*V?u7#r2BdQY80e`sz#&oME;M6{HroZ z3nWzdpK0CCBMDdkPg;T?Ayl>C{|#FIuZ{mFf&aY(NT6l}=)ey{$;)(B2(ADib^D1i z001{}LJRAonFz}W%Ldm1KC8_K%rh%p(tQFH(lJa%ua|D*3hJ4%=$}d`b*Bfls4oD(>eWmg{Yap4g93aIfL6Of%<#MN z*eT6PGjq4Rjl@#nq)PW{5t)(if0ezAIcwf}$Z=*>bv3>IcV%OiV@&hdW6V4dvwExN zKQLbf@gcpswWx&4;PS zKs^;5_&M%pQ0%;*F_2)AEZJX>WrFQ52r$s8VsQd3l?vx%$&G?c6RG~3fKei7XMt8k zc~Z*I;XIVvnGH5e?1CQ5oMqwP;zXe{54emj~tl`9rv@33MF5lvdEWiwP%eIiM1^pH$-^K$R@gyzuxF#1uAA8KepdX zS5H0LKYL?LvV!gMgN7YjC!K~@98TNqI~-0A8m8ae*p_@`;gL!M*vrZTILvIlVh?fL z(jK%!ASBR=>ftyx7>_4_fzAL&z^EFGF9xB5LC9 zpyF=|p+l%B2Z!x3Ay`FLmI=K;7FeyMoD7ar@MpkE%FRqfs0tN7KfK z0AB!RK4t(TC_Eu9UOWV_2l~xKBBBs6C^kAH9F)nRbtO?wd4*Q!JxjJCxDf$W7!7b8 z0C2*jgap^Rp0`kb4X5a`-c>66aUoC-EK>mh9D+vYwb9>VNM=kqk;;^I66_A#@xlPk zUK{|0{$s8k!%*ly8{@9{<3a#9-WVU33Ui0QI|~7W0QyFd*VV|#(3^e%ohev-SCw6_@1K5Hgmnbc}5#EaO_m{3L zJB8@*&8#1_Z7vsw7e%J6VGnV}187m>JB{u-E^G+Pj2cD>edgok)hcPc2boH*MlVUr zU$vQhjecPEJ`11Sgj>Iow_bAo-krR|V%>wq;gc*J&1~!#GnmHfis?@a<>I%odb^@9 zB6Sto5fV-@&yHXiS&%ySr&DNmnD3(b;aQo0p=Upi3g1bKi*c}#X}X2fL0Kngt}^j3 zz?dEM64uvGDW-eM@C3RA=9s#B9&FSG@lK?i6;jhucsQK}&z`Lh%HP=5wz;8QYR}(E zv-5f0M-bK8VM2|O6@MRK%nY%mm`_FY)2-fo-${2S)>`w=m75Zy@rO6QtWafQ>@DwO z(%sN_(2f9*4G1hF@FF_FPg$@GmBFHTCuic(nhW`-XgDA7j9+x~x&5b}6fu2C`k?oh z#r^sg)caU7K2RFoy|=9s4ANBb7Z;~3q?|~Ict&npd-iVolq#|f@-^+E)Z>CX2VrmH zbuUQ_>p%%InjnKHEG?djQwa%qw~idZeS@_K=a_Oz?O&%@S7tZ%Y+bLbvpMNNu;rupDKHxRu|@ZZ_)|IF>%VwWpXmG%x{C z#1w7kf&BPpb^ELw@_fmAiQg@P-JdTUzVYWbUPY6F9wkqv!2lx+BNBPLtfU5GMrPlQ zNrngzzjKip=MWh=FD&Di#6R9@*O?ZdChi5Rru+_O|J7!rwDZlgzAYoWgxU8yCkH07 zedD7*&0L2WAt70to8I!$B_kLD&XEq-CXLSJyPuC*Y%BEPyr8Nxu5d%TR;ylV=KI;Q zjrbvl6O5esT`ZdkfU%D7Z5aIR*Bm@TUB=FK;wslVjmBj6%cPZu(U&f_H-xNeNmbVe z558xePSCI(|8OA7!TQxdmR?6g$v#(wsy!{rZXx_Nd?Me^xeobUghrAnG}uq;Lk(9ly<6zMecWkp^c0G??h$xQ|}S-yG+i-Zgn+*W?$N*EH=K z+8iI$k+n19$zA6HjjM4++D8{7j+HF_tv@1&j8G$>$OrCjt}02f#j7#Hn|!@lcEY>{ zSF6QBf~&tKWD69cus9+h0xxB>r{x>hUT^I3-{1!r!mUPMcUoL^;OrzWJrw9%ZY*et zsGaJO3eW7Y(+!XGFr{U*!m^N}7+KIDFI<8Q?ut^c|=RCl3>U_l`OoTGD&QcPGmc{=r)eJ!)iThiN9(F z__GtQTvh*X&~n^W)<(cGjsYr?BaFrYKoZKChP$?Ow~^KTdxct_UtJ)5vYKL=6!M&6 z9eeEL%Ffz6#}2nsm`q}uF@!56&?QcsAOii;I@+4HeP+;rjX~2{_0xzFV=)3Kv|8^S z@z;4aoaNx32HSMhs^+h>GoD4FzinqBoQg#eBdiz5Mm0vqOeFA6Kd zE!b0t{L9Xf7!^Cz7QWsZA>;U^<5%&G4(z}u#+sOim*ukiDB+W~Ws}@z zwXyNSsbFU;vVGoK=*AU?hg(n9I&MF!UM~FltB<5@qq6_m_5Q-@jEd!~ni`HqWlnQp zUEiiH=%DiSW64uF1LALGeLf7)4Q9mgS*hVn&J-+E)VNI9yOflpkf=i-fe#&9{~DH)bV(dCawU* z8`ofzn0zpoER(OApP{8?kbZ8Uk~qnzPk6mS`SSDd?WgGpGT-B5q0;Eh`Mt+a&+a=9 zZrzMZ7q6S>@^YZjsh*94W?jA{5TMRzWCRJ%X-Pb)&5iaS+BFK6tano8arJr|;jv!4 z;IA@e!}yWIP^BJ2H7zX*0R+)~c;KT1%!@8kolcE0$}RmJE<>1FAveUmJQqpU3S4Io z`c1hs|8Zlz-Y)gi$Yw-kql->^y?ef$;UcTJh*|1*6|Y4h!HAtYKw#$0(~B4{30WUe zD&9GPsHOZiotcrno2!D2y40O=0oir=KX?06JTB2P3W!1gl0ia33=scSxS<@6LBi1) zC<=W@+phoVU9wwCazG1DzIXnN^{@{fIrnnA`9}F##9FXG%lN%*$;L_ViidlbR@LkGfEXr)E9oh&%__2l7qnh?RJWZE~J`i-k+4mKFR zC2x^P8n?-X85j&Wy;FrnV*T;z*Sx7RR8?g%6c9ws(~%N#DO|7BF()tenQ=Yzs+><^ zNfTX_kbU~TDLF{nE1P~=;XGc&z4rimr?oWofnNN1B5DP$IP2iR=?m#_*V;`BSaq1| z-r6X7Top1WQ+Dv8?Q8wV<)7cj=BJ*u&QfnR>Y*H*V_*O@N$V}x@m&@i)O^Lew8NEZ zF&T|0Q}0>p#v$t{Mb zC>ZANaF~SDbO~=u)9j_$c2P{~3!vWQALmq;>4ESk>mNt1_XWNUn>lLxn8zCMU*OeV zdn(A*9Xwt*h7puI=tRMZ`Ld8KWsn@t`PDGcVh&RzCU=zPDldy=g%HXK_r1*7_qedl*lN_eSwD>HQf;TI%Z#F;3JSM8U>0chW!k zcl=oT(e$5zRUKFj`yebCNksx({pj`U_c6~)Wz*y0J_4L`X0K%oZMoVSCp@LgW)*&< z&TWU=D&3Z{GLzjrdtvp%)tjp|&pP6J=Hd+VS(xu+ph~l6JTip8{BJ%XQ&zjZf*;>8Dj)b-LPN~}Zubb`feg@X>>u=3q-v&jrTALkh%xSqj zKVzBlv1R0h6h}=&xuG-(LSqq1>(&$=aB=H!WjEE=nb!2bz^f0L&5ziE_qS3e)o84>8h6b;cZa|BbcvA zR1H)x1T{d4!s%(&Tyu|Y4>PXu+@f;c@Og-y+ns-q;27Ek0TKjyVorVit$dMbk;9OC zaSCb;mZN5N=S34LE%d1&)S#LL91C77&aZzu+$6@(AJ<2L^+gj7xTnGT)J$l&fUwly zlNFcGIU|n&=e4wG0nrFnySI$* zqnSv;^w0!tF*VQ0{5^$x&zVzlc%&t#A3{T`c?D%NV>V>J-MgMzd1Ig|G-p;1SvXHA zdaIE4S-^ryLZ$)>A*UCkm`{U4l?5)`t*)VX;;fCmUw|~g`XK+3W<{_3#oqc>*t(<^ zJdjpVzs~&a8<`e~@-FTgbV;${0nPnGscsryrMGZWpZ3?p`_n)0?U4pdfH5?@n)hwE z*N*paeE6Am@oNG94mxGSF>xk3e571^^a>KRCi@cUkixt~!bB9Nw^`z>o<^KQkGfLo zc}8i)H&Y0Cfj_3$&65IY#=RFk1oPWwvgxE%aFSi2=V?CPZD)neYNpo+Lpxx^b>Pb~ z6?5UG(caDrc_9l^AqkcyLm|H(YfGo)E1qP&<-uM*+DMITFcTyVL_+5wOhzc7MA>gw zWJdI*$&VEH?6kDXy-p=kSOzm>3IcybyNiY`F0*}ldCKbcM?U_zH-#~An+XrtkAj(e zB)5%FaRGP5hcxp z=-AlkxOlH)PXvSwgSmAhEXp%ZP$*;WX7j9k#@qL`Q``92d;lY zL}sXNvEO?01#Yjv?0~1XpU<#lTrIaO#c+-c=wHsr%ok9+sw6EqU$K?@bW8r))%Srl zH?BVX!{}sqyzXN0NllllcZANQC(aVeDciO2{%BZq$#y<6+unY)v z0pXOjgrhQKy>r`{Jx)qdd%Sh(Z&eY9?(O}OqR4}}EgC0APEj}jaFiub5&+?=EGZ(e zGBu8|+DO3^Wq0zVVAXT6X>}wIW3Gx)R_?hs5qfo4PYIV0|BVJ4pWsDF(bpH8|a8PiVLhzU0r&nidodW{$p zrs0!MuYjAXb-IpKr)eIsqllZ{Dg#4Os$Y1{G<~+;Jz5R;PJALI)m<+JuXn|$VekL} z-Mmd=9jdD)PDf8AkF z-mob$gyYkW({P=*)8lq{@6P*Al4yqzGXK6}DDR@l+pX6*G%9bRH`|lMWfyQX-uCue z&Ii8)f73w70F=3q!eey!wNzs0&}Mfh%bGozR_`5?@X>YS9G9cIgBv<^3|dr*CtR>_ zF?j*JI`ERhiAph(eVj|>>N*+u&Y3YMcVtS2Sk|jNJgI!XOz_R#bKmrbkLUPrBnuh3 zy11v!hSgH`yF=Q~hnCHSpR+$4C-2Z@f84PDoS4x`dHv(F{k|rLOIWC9vfZ%V$%s#MEk(UFw8u>~&&Gay z41TC+LB&%aGPrXk0JO~(rng(dZ(Q!2*{eMe#HZsF*mNm`Dc zm>w$#@!q;Js$8vs!jKsIxzj{(wSHvOE&Y3J6~dH-t2e7IQ5JI!J24f>uvkZ(QEvX4 z^rw=4B8WPi%=FK*3KX<*ZZtdT&&`(S8M`JB7wtsPoR$hV%~Ga zX3M||*0=Z<{y^>0eOc*49bjhk!WdZdF* zBN>oFW9}z_hXy2W5h(qdB}XGsJR>FY-EA5FvJ6@2=p@WX-@*i@>h`7nA=8fAqb`$m zzf=n)ah;rd0#oM2*g|^vBSw8ohb#3xOq#=G^yC8x$$IrD`a-MG*nD?=!Gtpeq zK<=7#Ywq-qzUmv{7w$_^Eo;`-Fmy}tp@~RmW(YtT8ER`a8mH=~|2F>c*#*2%X_eTO-lA5)uNo0=cuP->x7vT=8Z<%j#h{Gi5~u-U zQmhFF9L+4m%^34iMkul7S#l)GxW4R~ZOJ=jx3^y#!Emuu zu;Qg8o!o=IZ^efbOFn-tw<6DDch%T_>bRDthdsRe+FkexNLfpr8U~=axt)#D%QQ@u zQDj^O%BV+8?7K{5<(x$2SCJ)}f=v&VpI(aLKheQAgMWK`$^QBN9;(eB70=mmMZ&3XTm z3AJ{GZvBYQud&)y_J}c@*B!LH$SxJ9W;;dL<7ZT3!d11nnBIC8G>JwiF(v^(L?=X| zm{SCl`t0dWshd#-Mzr`x2#JCLaq9H$ZgI~Onez53f7KI@?(DnG^UgJee-2QQ(h42v zr=|YVfa~0FqT=CBi)Fa^L$m7~HJdNdhyWB)+865VQb`L;D#*4w^FN1})91VCJVTDR z82<#V*BsI*t69&*lD}tZGOQ}QjLW2IxN5xMD=X38dpEaT*!t=BTGM2={-@xv&y`do z>=7ruUmq>rG7$34KW75`RZO4?vU2v>+7W9^vJgc;pfs!F63Ienwe`-hh=8Ruk*j|q z-r&V+X15R8uRIUm*uF49MZ?0lP8~wblH;9sPyQc@|I0tuz?s2mnOl!$q6tb?Pv zxWgCx`*%b~5292X3pruEs8adr>PYithhR=y7%4HK9)T82M~|bD`(ci$ugA+Js$sXI z-1Jstf+!LvZ>^VX`i|~=k_mh>`~K(8rR;-zA7A0c#+8Ij37XoS_Ch>*i?i><>8?Cl z29e$$q{Tult*B>ul~;&Uw~{nzi~(CX?;E+H_D1}6XzH?Lk%z$b>q}xggUI$Rg{T)d z>*{_1aq8c)KpDE=G4$_Rp{Gu&#SjGsrq;w%=Zz+}erCS=%5y4Xfa$gZue@9)KA)!X zMOeYxSnTck zC=^x=kvKSbS|Xow93oZWF7k8X=O_8+pI^PZ(@xOLPc+Fb4(zR@U{iin&1ghL(eoU} z(2NGph+nUG$G~4d9JvZx);YVdyj|x0>hwXFOsz-+4w2pkI+0-N((Q{ko-TOk{Zcy% z{CKiV8&q_P9gCGI^m)}r)=KNY>7`TY?p1W ztSU#=`kkYVq6_85RyEN9z z7fxh+x4gY2O^)t-IF|4MD2{@l!80io8*TI5xaSj{xXP}JZ-S^6-flY$zCU}YQkgsm zj$Vqr_u(++GQqLSI&XwmHQnmXju^ar_MvSx_Sb_u)dU=bisPQ2TYQIntK^Y^?~>-m z?@$R32p61J@lZ1H+JpOb10`fpbw#9d;DHnJlZCNOriQ@9nC6pudcNuMdRQy)a1*d9 zfT3iP;^6oN2ZS++zwZ>DFS+Cl zF8$o2%_}XXnb=$uPhVDPG;G6BR9E_easZiG-LV8YguS60j1>`M#8O?wO8Iw~pJnV8 zsb<2gxJNAU+I5qmrtgPI;GPV@oQTTHSEY3`;Gp2vJiMLP#|GTE;QHURC)~97FO46@ z_Y3~&?I|$g6bKr6a<`yo{Hdw#H7AAZH!*cIGz;8a(?>E|j*MMVvH5@WwYx6PnJkF% zr94Gx*-}P^j~>K$XKC!u{nELQedoGG~Z@^L!6{38)qO zVX*f#PrJ%`vdq-F$|iTPe}3L_v_qjWTk|n(G2fjxt6lg6;iHE1A&JHefutIlGU=A! zgRFC($L5~`dsd^}BR`l&#;qnMi_Dv%wyr49$xUj@XkQ^3Mp%r{*Qp44AWAwX5kP##Nl3Lp9TRqNpPY(v(H z3iYRUe@)n?R%=62xnc9ISdq4-`c)%jSFEj-{jptSB0E`m!FOPPYvM+@=k55ck!JUk z*53}F{3twQkUxyXVbqY$h!|k`rhxzVYQB43*Sds>u1o_ssQ@W7@!QMhv&2S+T(R?? zxg$JoTeg3+(;vUK{&*u>P2|F43iQ#1)dDWBS@nkQG!vz@r2Aw%A9nROfO~2XB||cvczx8??+7N7TSFFyqKE z{5Wa=aS5lac`Qo75ZA zr5_11{F0|i<pR6rgq2&I$kS^XKEyV53KJyrGA%j5>GfBux94UCO+lFBS0h|Hi=Tn4P?5~Q$nc0(>7281e-*7rS@^5kHlgV+ncjhc z-W|URpE;Q*#{Xzr+M`q4F66n8`x;03B}`RwVbJu<*7v8`EDZavN(lyF_Xe=U)(l_k!6_cWD z>#P$WQji?ccavzhd1Ng`YtT-)D<)x*Qt$h$d;6MTRBTd$4t4lI#YZ27fHLK&2%k&h zZCQWLUh&R~-`m!|#ZFymod8rOrz1f3#B#Y&q$cyDh;@yG8ATBiG`D)|ik_mFVTw4z$^j9f&Aao#N7{ zbX+zNJ|Hlx%A27OeQ-ov-yrMeL@1*JXm^h?htsaW%0o#(B?6I&0+{2T?c?Bqp_lbc z<`%TTNvM#qzJ|}^bVm}AUi|&-zE8jDUub)3-sh$C-n}(*F~uW#sr-x%ernPE@x)-E zcv~L6wPDaSAfjd%PyOD+*G}3#(cZ7h5(wYq(K@>IMDonH@9wJSIF=`rk`LK~oK)Uz zOorP^kS1kMvlp1)F$m_2^>S_3yF4XahfIE@f&#H)co@$wCxzyhQil<>Ix~hl z0uI)E4mxK7XMJ6+&IZ3R^=W&0;CHbzYj@u~t%YPWOXC~t5P$U4_aWqM=f2e7+PY9U zYt3*ct<;g@c@Z>(ElK(C_=GzoaOEfCx3PJ5;VRDU_xC+pobQSrPa2tIl21aM zFAc9Zvm|FBm?1Dymjg11>?>ABAUVN>939XJidQKM4PIo2?s}gie5z?-Yu876>NU=i$w;5#n+xjd5XfN&c!}a# z8Ye4hBaL4Ip)#g$WAd|P8T8A6A2n^%Ndh_2VX_D4ih>Z;!IcoadF$BqsKE)2N{*uz ztTJ}EPwN2i^(^_>m#b0l=)^*H>piTdZOr_5Lo z{H6Ee7eg;6-haX|y~Hd!L4BLvwtBr)fBSaUZM$zfMURcv`E_1#Ki*s~8!5-gv@r|dI+aZ>5)r>1i^*`ET=n|i|o1KDd9vdyE#*G_k?1djpJSTd&^(^EUbw_+h5!!TnLdtK8mx48 zsz!)@`Sx$n+b9&{T4H(zbrd563J4P#yOQWKP*~XA@t2Ui`KahsZTunn3PEdwusJb38-xc`?u;o*ms;I&@5qG&_r zkDD7^D^2-ZV_d7Z_=9JkoU`+6;(Y;=!$BTVM*NNznz@s=c?_ssGxApt+uRj6mXr!$ z$!E%i`9HK&mokPe^`bFzK*h2QxJ;$y81F4wnGyNnN#POs=1Dh> z6HXH{wmwT8Vf)wK1k-7KZs>f^?Du=Cd-U$UQs~W|i+7dE^}iENvz&g&NeR0ZKH}6R z6#r37QKglqgJybQw1}xV;4}yDacb#wkHMdIK4Hghx>F71mJ1WkMTG}G(^cDJ({Il2 zexH-~wozX6`Ce+cGym-VO(lRU3P7eNlInNHllfhOFT55R_^C0Sl zJ*-SjuRF=q8|c;tYzJCaA}X>sLzTXt#iduhd;O(zVlc4%?k*dO(t4XlBbSwWQX5ar z(nrQ~oJ7;Yi+BAKF?I&&&Xqhu&RiO8g&$8T+~e3Ox~saMb?}RN4AC1dewyX*;Y*&I z_p{z14@}m>ndQQ48hAv#2I*6!FlNkW=Ac!U-OS=>VK_+qtExyjAua#&QhuaPUCNO$ zpJwPn;L#h#--tNAt|u&x>M;WP+TeN>lN99%*G!=AK~Zx@tqY_x5Op^hc&_dx=)Tw3 zqo_{~8X}(53#_b^uUB}MNO4?@izi{&Ald%WqJ~Ua0$oX(g!@o9x^SSSFT&=kr6KE4 zd!$~Sz~PojZ)o-J?Gvq17|T2Av9O^c1VEjEf*Xl}zS@arkn|brn46Ip6Fk%9z1f!w zerr#`TcRuU*rv?Kp6ACY{KJ?#G@tXnv}|I7r4Z*U_m8lDgqK2uqYHRiAW!H9f`7X z{vglT+boaS%t>8wYSH%1x{&nz#mbkg8u_-83-a_44vDeNjuGsqQXSjG!v@zlN>7u@ zs6~HiI<7$rDQi6=WzpZ0pBx#E2Zm^)?=Z-vF^x)pI8@b~T;r*O$Tw1zpW*|DE(>*x zgNz7G46%fdHpZHY%$zYpmZ?S6>S?^zDP6o_`o6PuC4gyu&nC=s$+z|Lkg(HSvzFgy zLFNyATcS=o5q3tgclETB-qSm;Gg=ZX5r8dat)|m_-PJ4OXsqigwH}-|)_QdBvWxdL z+wKwLGu^JN<(1}e&I~Oy=&l3On{&sXLB4SjE#jKncKOL>t`>M(S9m1B$!;^>HKliu ziD&S{rx3H0E0qP+aD_!Xv&E;@@Yb82P`Wh6y|Ts1v${8fd$k=MK{VirN1bhI#BJU#jJ(94fYr&PZ7ia=x_8Uqfb^mEL#WLFI>TU(g{UFp-H*&!&^ z6rx{2MCQ3=|9N#igg;dE&-!P_?@x~8%B1!DH1=p>&NhWy3^A6AtFW&z;jBI9tn|cs zv-i8!#Xy&@_9PtS4W(s8^+B_@!nvQ@M2pG{kKPCi_eFo(4@;Rf$tM{nq8u!cxKiw~ zvH%*Wg<-3xx6G)dWFEZHEqenO4%aj1CR{FIMW3b4yfVL#HODO4TlnC8!5ar!DaS%8 z55^dLkBKls1zpo!kp!}8-eU*9tQ>K%Q?-MY3iwF)$5fX<$1xVA?3Df$aBNz#|^)xmFttH$wa$`u(00)2bF@) z9F-Qk(?s%Wv~E3MwG`{EqiJ25gI+{pgR=P`ROd0k8={3&=jTP&J6DX3-gLO}mS)yC zhc7-I5g#i)Y!4e(jv0!KaTvfblOY;vi3u=36PbY`v*;(`ql9C|6J$)Nw4B$R31sKt zET&D%roMm*;#UZ)SxUFnXs&a`WjT#qcv7x{X z<=%NK=EnW|1Q-kO#>ygkB+w!A&(q&KKU-#*$Nvkw(kz~<2l$m|AOM~8T<3gD28KvS zE(@U=D9Ypn?_15mb~9u(@-cWMkISD26)i-)1{V+CSCH=z{Bm|PYkjXh`KEm?`&nxrlci2cOyXV82MfG)a6=}=WndDG z#%0}`LWubzFPjHu#m(qmRbAznB(bi&W_#G4bRsNzbw+Yn{51E-dYkp;FKziU8#cE` zhWJ|YCvm0Qzdp0j*RS(kOnu=2=aUo0L3jsZuYXUDZdm*Z8$H1L^Sx1Cwf78Gj*?cj zO(*|3P4!C%K_aq10KPog^ zrM#1R93nfQFco1~?RUMzMPZiQCG__-G9x#I)P^#(0BI9wQ$W(w9@xNVO%up38O_U2QISrEC!!3oa>I0$-LE_bCfsHma< z8kR!J$lQ@|jy>`y%&RFE?>%~`-A$eOd)p&_ZFr_igXH~LYY zeonxymOzj9>2P7^3F$Ph``zL(!{?%&&Sx_wGo#S|`nLmJ=Z_WGKW|sifZq-|oPH`v zq{zs4)bV8nHWWq>#V3GHJ%i#CLdOL8Ub6smInZZfgChcOCh+m`f`0;n5IzCETj3G&mCD%s><)Q`4RN;oo;IlL<5`4f)Pu=2(y5T zWQ?Q$x&alqVC*Ess!nE-DV=+^;3sjduz!^2wZil1_Xx=k7oX^vRIe&X4kQ!5Er{;y zeDIn2gyDM&%zkJxk zc&v4!6ZJ|-rgN{)3{}i)$&lQU(qgpL z)1^!ov-zg!{5mcWbmKAgjQo(vuwha@@TiE<^}HSJD}6!V`3}{|qf6KoWSyj-gp7bF z!BT?kKmuQY(Wj3&`#e*f*<5`>%UkPER`vDsNQbL&78|prMDlpcTEw>w)e zB#?fdWb^$Q!N&T6JHP+zNhagD#hH+71A-*IbUsNu9*?-Sih?B3q7>As2XI7bbdR2X zqfvicVzWqj{^unB5pPDnC&||{HQPQ|1~uMDwF*0EP!q32p_qaGcPViiXv)247LQv0LqspRhxy3|wxDYZN{ z-koPycb?PIB;PCts?MzNwujuM)&T0}SWzShem+glv-uCDZ_wu?3{IV19~Hy%jOTQG z#n{y5r#S|j;~4-Rx-Wx=?#sO>5C{~yxOnBkoHc-d_1uZwoIUOCGqz<2{!}Whp#0;y z&YzD@e;Zl%34DweoA()i?XrLN(t{+bEGUfimLOx}Y-vYZ=YZRyg?B;Edj1s%er@bt zoAK^<_qvokJs4LhHOf+wnu9h+H~*dMkGlL8f5|(9LI(U=Jlex7T)45?bP`H(ghA`Q z>epunx0iFhY<|_Io>5-$k!~^kJ+D_Q-UtUIsi<*%NW5*-HG#csgB7A8E1G+L`!0p| z_)*R9lbVZq8KI8bs~g$ct9!P1?h%vso8_Y^2EC0jJD+>sHy%DtQb2K(Li!3|V$v>j zt71F1rMxW!6F$+HaDwkhgg(qlJ~^|``8(vfuFI^2+*Z4Zl#2ECmE{fAbB8#yTbHV_ z9xXLm`dQhGd@-7hi3oMXDGiJ|2GWO1mKWBs$Kr?Z^K4R<92)Z>GIu01)R2kSc9NOT zL~vi!uX^IcN1ev&F;-Xk`f3HPL>=h%ynV59>~cjhi_aB_(C>}9r)ygHX<)441i0Rs zkIih=K`n!arUn!Sfl}inq%LtwB-_}I8t9@wuG+ZqMsMsf8#+1#nDemL7b)%k?X~&dxWWZgEF}d(Q6Sr;I;AuS6xqI<%jQQ$x9DxiB(zX zgnIF3EPwTGN&=h&FMX6Ch-KrKr^WUmSk#QkuJ2?ACI#KgHb%CR>J;9#?S*^g4`-3I zW(K$U%UH4Bycu^7OSMbrht%73#JqV2TE4tk>pxdo3LL^lE9RGM4Uj*V=F<~p_R^NE zpZxi>hA}>BKaoo)+in)0BY}e(0KQNoGDhU=waU@zT3P{0_O7x`;}lBf`p^(z9#$%B zd-1`IyP-pOQl}*M&pTT?`G|hMZk=1NTjgn|yu_ADfazVCR4`xu$w2sYk?K(R(QESv zhWh6Ct)C2PB`=8sdeaF2xd41sJ#fB321vYlKF8)a4t;0gXrsvHB3Fo~)3p^UgDo;#62L(Llp`LBm(kDEqt%l_ z4-5>=EEI5Oh(45(3YZui(UQe@$z*)pnkkUEus**+8^892E7^H-CP*=Y?&j#W4IsC? z^%zI$8=BLORQWxK0N=g~v)Pd|#ob}58oz7Z9_GDs_5oyJ`ka>NHf}txhU<5 zR_W2xfxX|+EZL=8S2fR{=Er9XV=N_I*p^T69rJ)_h;j;Kk<>wU<2C6{$4eOW77s`~ zN_@oWZra94RJ>@`jc8cCwavOWq!o~P+wVokx~J6KpYkY5))fe+>_z83V&!s9kN4Gd z$CBq?tsIQN&N8n#D$Q-$JX9UvNwj{xcP>vM|MOAi!b&efm)E3s5;I`T|VMW2R)K8Np^wA7*^^W$u zmI{}%Q~yU7=NZ&Q`?c{v0!B&*K?Ou=LPttKsz?ig(4>hJLAsz=D1so8fRq3M6N>a+ zM35?iScuYlk)jxi4^>2s0)hx6|J85rJF~Mh_op+v_s*Vku5_;`{Y8g8AX%>5}75Z~vGnH`xpA{D8N7oOI^&vp;nj3B9^k zI8_=7|D7C8kK77-vOvtv42^aVb_LW*1? z$Be60(F3K9?*UKb>q78CiRXL#Jw(vu?^bCI zPL{2O>DBj)jtFm_JKd_$D=eQK#hs;Hr_l;c^u7iDd^D<^k3L!Mp@LMHp3G7x-db<52>Q*@`(p?;%F6y^}rL3sjK2b_qD5W9iDw0z~s&j z1N7{@RRV?~Bo%!wA|Zy=HstHsP?a%W>aDC>N*xLeNJ z%;~#5JLRcCdCe>e*K9P7xgf={P2RSifD@6lpb1ua!*=TZ%`MZ^jn;6~m(oHuG#9Hi zk=NYru-h$UJMNDw)0%B^l5Sjc?aOZIRMH2w5V$@Z$8jpzm>LjzKL28>HqHmsJXx>) z;NPw4nvWP1CO{Aa1?Jigc622rJ%gYo7Ve??x5GpMiWn*aAs^#jgvESn)hG>?FQ4Z4 zPf-5s%uU{J>4zuAtJOgq0uXp2!oX_Cy;?oX*=OzNk>zQ+k6+NnE?UhQJOvfkgs?br zq^jKbKAwHD!p`|zgu=3wR;F*8omEB73%BFZYETu;VvA8t-Raj3Osl!;0*rzev@y_- zg_BZIPLrGB!Vw-RUMZZ1@(zCik6!zVRVd@n^-%QwFPio`E9l8P6yu^lg1P;vIseil zp_`2PkNBVn`eQwpJZkF>vryvf`I|fk;SqN~ZBE3%5OV#HS&5Au{2h@1s^$kq)5~>N z{KQMhu_=0id-9iEtA@=P@G(PHzC=xg!3>OA^Jk|0dw+2V{~ssVSkX>&AgiqEt;Ylo*t9Mpmj@%LBr)`1IQ-~fFq)t7|f zdqi5&w6yyu&=Z(13GOF{qQ1$1mt-c&mplbo`)Z7YHFnGFoK{YLdp;m{eTGli9`0ds zu8KNW|IGbR3iIjAXwZlk(H(RycjO1PPIm6u-HqK^H~-A>ka*^8%k{cB7wXMlW;M@y zU;-WH1U{paKywxQbF3uY(*P*B)x0a&Ez+@a7M<<_Cp?vj8d@~RG8@;Af~GO#t5HGo zYy7)61|Zs-^OKf%Y@dCDVIO8-;f0IAe_3ImqHu!zmyTQgJn%pkkqFrR;q7x$r^D8M zMh#N-vd4l20xEY^{M&RM?7E~5^*(=h(y>XwisFeOWWyhNMK9XuKr0eSuTawI4myfz zQa!O;*B^-`H3YVwW?JBN+oyMK?{e^Yk}BZm66!DW=4_t)sBf=qYOmq*^vxswH-9t; zl)?uRJw$X5A$lN&tzA}xBkEhN^il<$iQ8=YKdVI!E-py`=f$N$fhiqe)8$-DLgxF$ zqi8IMAfz_83P!s8m5xX4VAjUhRz{P{wG#_TBy-87%xLJ zl9_Ey;k$($KZt0Q=U#Dv8JNmg1Ee@$83usj4OIcrcMA`YS?>M5T32pX){eSIn&S0R zFU3f@L3_k2oZyY_5`sX|gos6xBvj=62~RAXa@xT0k(e|Sb;-Om_N7=ch;&&-Q}Lsu zb34_?;TE1A;l#xyj!H*s_G#ya<#cWe+1P-}=BLE@kd0&B2^LdS^URweb#NdHbR2E#H zBaV6NB*7Pl=D&BB(yAcbArDojeYL&fZ!i&z!{;bD1F##Hrp1H>kuAOWuS5yg2gMo? z7eh72{2b!*Nzs0}{UE=G0cLz?UYR&|L$Vy3FUj7t+LDK@u?}YV?;JI~AtW zaCW?0tWp8-A_G*t&nj;Xijr+n%?mFApy@1p<*UAm4KU=07t0TgukD*ry*}M z`n!YBk*klrb~}mHi)~jZXXLG2g?uo@uv=O6uacyo8uw$VRrj4$Ge6#+ z(9NNi7m23O5_pp1VvYO+2{9BD3$QEtXbCX`(;<~^giZ1o4BS_VIvVbj=AO@+5j)B! z*817;*W~_n;W9>iV7okf^P?x1xXie!-UJQQ_`x|4f54YSCZPNXhQNq-lyL+)ijT?Y zQ@X=-1x=OE6{IHO@yqclbgGEElCE)w%G}p5A-6VfHecq@|o|YX6U2#i{+DA_}_~4RGmZb=hpw6>xJ< z@!Ml!`XB<*n8LUBBASZKZu4*jI|*tW3AEYX-@vJv#aKYB8m2@9sFsvud8X( z_rmr%O16?JW^tUs?Ha+aH$?KLf@|tHX)442U4e`7e6%N|_E_L}?j?f?udcQYM{s!k z*`=Q?@(_)6E@iKUG~J9Tciy-i!=MJ-vUvG4JyxcAY6Cs(92f>j|oZJsm>; z#;NkMP$Y&=0+FJnDujNghBWa;%?w4(^bPtwG&OGS#}I|(eJ3b_k!|b7IydI81bs{W z3ZDq*x}>))%e?5Ct~~HU?m6+6JIQLPYMk)0w8GCUYll_v`$ZjFcb0R`J72;M-hH_t zLSITG`!;`_qW`X#nmaq+%O{?~bAJvJ@Ry4}X@LN=asq{vW^vYD0s)u9f=ZB58SGVR zG5KU0|48Psf>uqP(7OK~*G}9C-OY+GZ>XFN-U_8Tx@%9#;*OFXUKMGR^)4I5J+#Sy zAb8saD+lU(T0gE}H}+eSKXv+M%TZ4*T+I@yrPCB+c8A^OviMx^xE!Wsr4VuxFW09Csb%c|V#bQ5_PmvZv!2@_wuH*H$G_&MFTs zj{)IsB>^LvKELuzZ)^|961|BIQe__+vc$Og$kQ;sH&oN?pN>oUujxKx4$fVAJ-+9$ zcf9*`a@3l~(fXO|n5|`;?b|+=s-rKL)X@UAMBfYOn!ria=7SM7R#p_mZ6;M&JUjWd2+vpk}YRFR=x&IbbRB8}RmkQR4gHh|gHufFe zW&C66Lokq7Xcr%-I}ml$1YslDvAVhp1sK5=-fzl&(yph5&~7d7xA~v!A(=Vz&(*eq zr(Rt9Ci42DOzWAPk99d-PAg|(WU%IDwH7!tp>8cNeJ!(MnPJGruF%t@<1QrxnZL}~ z+~oq6uI-onqtM&3fieuKw(|WNRYG>u?xJ9cq9m-lXyQ-Y-}Dt5OM!|>yHKzrAPO%S zt6tXR-;PqH`4amqCln~g8Kv3FnP)8NG=YueApz$53$%DKeN2p}yErKCSvytX)0P$(h~CRQ45&NS)%6BD@TfyUk3qi@ zTp=dKu5Noy>+}qe>;UAL09;Zzd+ZiS3FPJ`J8{+9+q*K{KX=s|Gt^UJ^t5jb`|(Rv zfq42$yrZmDkM(Z;Xx3LxRWsV*jrqu^eP_6MaRV@do?6e+*97rm8yMFcZE9`*-+EC^ zVFvW?JQF}e8LKiyHnr_-t&9%Gt0AQ|lr)r7g+j6)h35iR?%cvKdga=w%lAiwVR-HB ghPAnupIj1_`u&U^Xoa2F+o=Vg(z!1m{m*awKdq+P?f?J) literal 0 HcmV?d00001 diff --git a/sound/voice/medbot/mcoming.ogg b/sound/voice/medbot/mcoming.ogg new file mode 100644 index 0000000000000000000000000000000000000000..d3eb9e467f4b3adbc1f794431644e921d84d5b46 GIT binary patch literal 13341 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 V;NH1N^QoGgT$ttm#mK?&e*g;~SE~R3 literal 0 HcmV?d00001 diff --git a/sound/voice/medbot/mdelicious.ogg b/sound/voice/medbot/mdelicious.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5158538580edf901d8d46631e319d3492a266754 GIT binary patch literal 7843 zcmeHLcU;rG*8jDvGH<~uLxi>zYylOdG6c1hg0$>16clC4UIi6VEV73PrSL%62*?l> z9zc;tKtYDGK~MofrizNV5Ji1ceD3<^-p~8F_xXlXH@9l9Q8IoH$_(!J$7x zzR54*X$qqmCI>qi5bWZ`;1*Zp%As$Ud?^aXat+rcD1C6)v^Y;o2c4xTzhY+~3VSK-uV#o$| zKs*eRa2?Zifxk7S1wKqC9jwmG3Wv1Y#d8Q2mt`7IGPVI@@y?9ombzjKp9Mbx**T%aDlj zApD~8+ZXhGD!FAHI#;5CjHCb`r*1*tTXPhYZK*5M@!okKP}unes^88>fa=o$EE`Fs z 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 literal 0 HcmV?d00001 diff --git a/sound/voice/medbot/mfeelbetter.ogg b/sound/voice/medbot/mfeelbetter.ogg new file mode 100644 index 0000000000000000000000000000000000000000..fdbe57fd2e94a295d26a3ff88e49a790ecc48ae2 GIT binary patch literal 11877 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 bMN@q3=MnK+GgE!RZTst|G%V-X0lxnOIKS^! literal 0 HcmV?d00001 diff --git a/sound/voice/medbot/mflies.ogg b/sound/voice/medbot/mflies.ogg new file mode 100644 index 0000000000000000000000000000000000000000..831281ebbee0f59e5c8733c36be9a0502b695d8b GIT binary patch literal 29036 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 literal 0 HcmV?d00001 diff --git a/sound/voice/medbot/mhelp.ogg b/sound/voice/medbot/mhelp.ogg new file mode 100644 index 0000000000000000000000000000000000000000..516d5db068d223e952ab1de422d2698794e14e38 GIT binary patch literal 10968 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 LR2U@;2n+uklF}e4 literal 0 HcmV?d00001 diff --git a/sound/voice/medbot/minjured.ogg b/sound/voice/medbot/minjured.ogg new file mode 100644 index 0000000000000000000000000000000000000000..0e968b3980c7607798eabe10e00bc0d87a9c8f1e GIT binary patch literal 14977 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 literal 0 HcmV?d00001 diff --git a/sound/voice/medbot/minsult.ogg b/sound/voice/medbot/minsult.ogg new file mode 100644 index 0000000000000000000000000000000000000000..017292977a137a08167b2af1f7ab0c16178dfd7f GIT binary patch literal 90336 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 BsR;l8 literal 0 HcmV?d00001 diff --git a/sound/voice/medbot/mlost.ogg b/sound/voice/medbot/mlost.ogg new file mode 100644 index 0000000000000000000000000000000000000000..7b332ac346af990aa5ca3c61b4b71640a008cd36 GIT binary patch literal 26355 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 X6;w1OYkgm)Kd-16IGUEHVq^P1qmSF& literal 0 HcmV?d00001 diff --git a/sound/voice/medbot/mno.ogg b/sound/voice/medbot/mno.ogg new file mode 100644 index 0000000000000000000000000000000000000000..030e43a0109372d247e140cf742515a656096354 GIT binary patch literal 10894 zcmeHsc|4SF*Z4hSFof?IldLr}1~Z~;2}xtJ%-9VT_03L*ETcsWgHdCRF^aLo*oh)3 zN@ORJJr$BHrKnVj;=QN7&+|Utf8OWw`#kUOzxVoFbKTc+?sM*Qu5-?H&NVj2j@biH z;IE=#_q$Uwc+3~F6>=&t#NC(1n}Ql&{|jXG_wz2qhWF+_3-3(`IO;E7KqB^R{H;9X z`;BNjxbEm1#jBSzkTJ3M|^20%X|*!X-OgzVp!&ah4$7Y@~$f*RDwK>O7%0E2T77@ z(G1b3C&>qR-`PY&$W#jhwg7;L%ae+OGA>?+0-68-%f%gpPxc~i)K5tQwZ6=IfnxPhJm7zF)@ENOw2_o_fA4_R+O+xX#qD* zvs?96kLDv@vvBj)WBqsPt%&_16*Wi;tJ}kl9u;+SS;xf&4*OQz9x*2rg1b!kB|kd2 zJ#cByWFu1^W+tX6E2NuHk_-JMPH>TD7zSN5W3$lzt{pT3Gqy1WtTmR8hAeG19~e$M zdSt|F{A+;QmQ&*^Cnr}Gn~l+JLc< z0GBHPlPeegrJj`k#UdF1=E+F~f1AsJ7oA7b@x=GVy7LIbIfRZ!g z#P#+oI(D|K1o{hv$OGXOJm(dm=oNwcN{_2x&hk=w@02IS^82yO|5RHSdig@*xH~{)3Ev$vi?nW%LrxUr0eJ=rSytqw*gS`Riqn7Dy=PUul(a==idK z(ozBmq05y1H)#DIj{lRu|11GI=otY)@V6=NN%Ce0F$LO}Ti`!RH8qPR5Q=V zT!xaRJ<3Xg$@LWmy=V{sz;7Day9d)j=LQ8Z5J14JO4VlBpijbN(BXg&XD*hDk1O&m zQ_=2S{^jho4{YYlhVdp#%gThUmJRGsJjeqvJV*`*S+>yp56Iz@m^iKvhX=V(PXtd2 zZO}a)-2&3)6qVIis`A-sgQv%V(KIhtP8nDh>Z?U;tw0!XhF(?=jzJiQ17NU`<|X|S zbnV^M{?CCwM^Ac<)q>trP8SSaq>PlM4@kP@3vJoT;{gVMF&|ySl2F8Uvn1g$+Hn*( zfnjNGUYh1$L{==Ms=!MN9L!A%!Sl8o&8AXSHZvT|RSE&%CZ8bq}IAKuWHo8Wezm4QdxbE8x-N_FNs2cmqKCykzeO}QV>;J((#wh@Bwr*3{!|AnG+anDx6S=K!Qix zOE3g+B}wD8Jxu@v`1NR9VU)GGVjeF>`4y=AM@{Pg6BgFLfu{T~e9`|7U;n?c2m?i({wIGL2B*8cQdpGKkNk@Bh)XAkqLVJVNL zh7~D~@~V-Eb4wbv2ahN51Fkx{01@}}rhYS}-_aF}Lm+f8ifWeP1&llcur}|KqCGZ( zV;Bf?f;2eC>yZeGpxp>!7`7yQp=XaCn3M2&pp6L1gR4S?Y?j6xFHZq`RQ+E)d?9F& zgzRVpXub@pIfVeO!t)rmR01J}7o~y-%oPiN^$_Od!U9ljd4%AFY&KO`kqy3D=B>uFj=VL4 z{4O|jcu2s>Gt7Wf0f9lM{Askv6URdSTKnfi3WL3HKJXMR6atY^z->dL6)+0Qit!QA zVdsA#1c08WffcFJYZWKCm4_srKoD{PM=scZ$?Q_K93S3`boOjZ*nMWM^&m`P8J)!N1^BtHyCReR4+kQ$W-!zYqQPA=2 zOW=ba+}o$Q393#XPpAxs%uVQAd80ALVZh$T<(~h{AN9xi!w#-+2f(n))BcY}p(-0_%k{$XcRUq0_os7a|Suw#x4QQ2+gxFcm-)%~P6Adc6n?-2J zs9BP$aBAU`XW!r5Vg1Rzuk5<588L=*$h{6kZFVJa>B@eeW95zNU6avFz`2WmezNoR zi-N|v9}H1%l{(<3Y(`e*=asB$HysjAg6!qqg{}>GtqO%x@qG_bCqkop3hVS5~e$eLgQ2=wfDYE$yZe= zsboO6ICm*N+-KoNieT=u`DChi6}F)oBlHuqZqOy`%y?+4Nr+9xTl`|r8W)K&P1G95 zGW8=;WX1{xL{h!CGL4d+cP4Q=UoiEZU+BL&{$?-NHTFejz3lw1*7iN)dvzx!_iSzz zC;c&~!L?eGl562Zs^A<1u)qUprJ-JnNT*vQ>W{PK5yeG3H#~I3{Spf=1d* zf_8sNbo!MZ2rD`5>L^YVIdc~ed`;p-i<0rED~#vK|>zI&c5q?mU+8!cjrDc z^iyNnSMT?|heu^!UsFKb)d3cY5E58G*qWzR=!6bWMH4I$aXIRIU2^JX6P?}B9Q!7_-wt zAxdX=1$lrNUq1G-_=X?;(ak}|Lw3gHZz)H0L4^gL}(7O*)B$8$U|N-%^% zN;0-`&?oNqG*(RC5*;i|omUK?K4XWOyHe>huY|62cfh4h^V)?{Hw{ZTmN&xogsC!G z@2WfL&H&zsm+za{p@Ri>-pd|wV!DV=Yv;Z6zhl0PtU>E7L7ACKC zknSi=HHL^prSaO)Z{5_@-8-fv;5PmB|y8-jPrs)rVvEc0{=qCeA z_?kXk(eiOzREyY1P;}Do#eWMI5Pj4zvvjQr7ypM_GERSdb(HhGF6b zUIj~IDPkBIVgBzN6Vqd%B25PydQdOmK+!7?`b&?TXdR%b1yAvx)GV;$KPU3 zowPD)>s4!d^RsFZWx%J~?G89QwP*Al_vop=G&#A?U*(bRa#%ou)5?dnwM&T>97dkD zwqhh8CPf5u9RvmE#_vYQ$Urq|LVQ99h4vW!P<-fNorIviav|!x+>2&(?vrNA!{N9X z#XI?Nd_ypR|5go2IrLA~woQ>3sI#6@_2f#=;Bo85iG6(A(mb$h7y1kuW`HMBMpw2K3YQvf0CU^qWmz8-{N1mv{wW29l z6-ray?8$CxFAR7%vZ$<`H&-oltdk(K;m8!i5&8S+pEs;3KK@I8ibZ#GLNHt9A(T=pEh;LLq=t0dn+OaT}bR;>e=2G>SrgCda9eV(jN~q>zf_br9L>-1xw(b zH6x_az=O`TZ+*U%urFKwFgdLnqPR}uY&ZJZw!dHAS^a%Y&StFT@BaYk>gXK!bRH!+ zCE$d!>1)qU?;@*#ge+Xwqu#hU?fj@8{LXR@rls!mYs~J{8F;c@u-$Q9(^-h|MTiWQ zbhrj|Pd(ju9rRI%0u%d35dakuEHzJ$QXAVAS*r*z3rwR>N@q#cr5$n{d#+~ zknbKU%(c2iGpwt4kXx|5p~mHV2quuz*?VOYiXpOUg>8(>`UNHG#y%ZE!^i^%r((&w zR&y;*xQfhNHZ z<6W=da&~QNc;lIpqal3;4i0|lmIcPJnd>zAVYi^hZT3*Flfp*czy$p9=-R%cdvZ7Q zX31Z6MJ<0>w;2_ik4Vy^Ua(#uWq>xxD@?o)!YV{lkh9aOx-Nj`DM7g<&8ME5z%(U$ zY0-8utP~IRR)+1cU-J@ZStg#JID7uy?4$H2`cK1@kw(pHg8?mr7v$6{g||wJt(uU| z?FxRg(V*ex5icV66Pwq-x%+uzBK>BSo|-18t-PYHL^sz8LH3&F{P;fTJ$w1Q@2zTz zC#^VmUR}1Rm0lX^gM0Sm&GQNS!oag{$F*uRzVCg|{xTw4UB9v;)DmrihfdErd*T|m zXkCAE7dZj1T|MAl{~+P&!jeTnd!4xdm-5!o3({bCa+RETYf$|W?{oyyIw87_!gd8; zmPmTP_pC*xhO4)VLZck_u>!i{yv=A>Uo2@lVs{CNh!$d0`I?h zA&4;vpxYWrCGrbN2&uWZCOyPQSvkqMJFA<`z9}EO^~0!G58YebQguuHonE6vw!WO< zMBrplV_1WH(`GtT+z8A|Yo1O%+8_V3!GI_Na@4d&4IJ6fY8c;b2oV`ws$j`iP99M# zf65R;YrCli-CYVb+ei(zK3cKVw{Kzv`gvr@r0*-Q>0XH>tEZz(qaB%=IjwAn;sZy! z@vr(@)gVIyOA8K_g_EPDsu6G)A0R@E6vDbaxf6!YZnoMcJ~R~3_nfo36jrV;5@kfp z1>D`V2{>2eMQ((xCSE*N3_y+cZ9g9T z^L};rwjcyOR0(d6qD@8yfIV*7a{tb+3(j}N{@8x{1Se4p%q9d3R|B$^mgQiTeGOne z+2PhfQ&Y*bPHsZGCeGN=QV-(Uirf!wI1xrM5<93KS4|3n8z~|8_*{w!_DfAF^~_2v z$mizkXzujOeuQ&&b8+{Tnwoa1moIL8alW?BZ7DI=znkw&xZp&~%pVS}o|2tjHfnxx zfOFizXqPr*`#TpOD^{PIv0W1;cdz{>j<+bJ45behgOA&GE~6ch%~o3IoL z1?xb>5lAK?4zWGB-hiBhk^)~7ov}ypgCUo#PdDrgJ7p&REb7OCLEF@-|^mAlp3 zkLOxP=g2>5N{+8du5=Mho9QfPD54<~hn2eao!sfM{wiGHt%N_i<_hJL&G@7A#=F-d zS7EYn>t!ThnJ$He0yle^HQ)D>))TT`;6iR`Jb^6F{ej7>?J`i6=^(2_?A~g=@P5ZF zjdu^;S1m2Jw;yp?7-H`m7n}BdyE#QTw(4WR9%I?hrdj6?`Z~0na2QH!A3TQ@u{Cjp zgvTAM=&e}~`C9yK{Vm^aTkHO^+ZiJ+kJnL?E*D-3#2rJI(d)km0)r@C0!vpg$}LG3 zCu^}Hy$4wZe6s~6tSd^ramyA-_a+*A`;K3?zjI^8;PJG<^hZ*TnE_l8p*+Bi&@j`Mt} zBh)F;go||q4-L~-RX*@$J3hP&8L9xV;J7hJjc38!c(0!PxwkW@L!#bpE$W**K4o_2 zjoeRLCs(bR?Ns8^foG_HSbu%%56v@Jq#?}z+0SAANS9!{Na0_X3@~8p@BgHDmkhk) z(dpqex<*_W&G$lVRBTXW#2E})VJjBBO#!Ef#h@_|tfC?-DgnK18%9atpBD`f=fe}p zCr(veak^&Z-|@;GuNFw&eb4dH^**IqkB@}AI*|BePZlxNoHQklPT>k|moc8fnecT$ zNe|BJakP6{vSRwvgVT*$Et3m6o$Z!l%1?WiOjmm-3A=P!)joZuZ+hb5`R?Ug?JCUq zz>Gnh)g`KuqMbU{ut^g8dTLnOL&=;^{W`x8l>uM(eT zBg=n0KVxv#CF5D`s<3bE1g6U9>JFyx-SOd8oe>w+5?1kFulw@{HEe{07VsCRWeuE6Hc^%TC*Id@c|m7&M-H9G0@jD7L*jkEFau zBDTa9co3$P)?1&b;@nq!W>QIu-K$mVKN8^Z@vLFnnodUE-AjC2rAU|#K~#bm#r(a^ z=vIxXrnpmR;|%(Bsp{_%d45d}Uhg@oNs&Q8qu2{0Vc?^Pi`D#4kfz0owRuh!(1NHycGVPRB+-4btAl4 z2_B|fVW9)@j51b0LI5l!q}pn5Rwra;=8=V#U=R5gWjTa~%fPzibeozgU>~Wi-ff4^ zUSCYV%~j}d7yl%e=B-aa^ouF6BXZZ(z06IS@j{t3j-ixfj01} zrb&#ccd;cM8^99h^Y)}Iv$Akl5veh_l_J-&+mZii;J!ms#B!xtmB35mizW#&*x>f< zo;Q%{u4>65d}Z;pDB~2oqjTrX%m!H(=k|GZW0EpGNXTC^0`SgRmITp zFecKfngnODo8pL|4BpSG!Lky15)yFX!2$SGeIZfV zoVmp2IEmZnKMDtK$}~JX-nCKjj!A^>a((E$alCM=XUW~q#5Oe4x$E}FeSFsW>ju4J zmWre88zQ=itIOKQw4Boq-rQmHO_^uesLocdTRN(BI19qfkRIqvDb-8qz4{u>Vr!o@ zxO`~cy3?&#wqW9@-FVKScYT+yj4NnuENj`6Klhywm2!WG9=<dvSQL(|I||%^6V_ zATwE#^W$e>AERJjJ8zF&D{Q!a>BmL~x@y?0vUgqez1QB?8~X%eD^~fa9)nQ`m0?XS zMImd!R1z$Sgyxxhtvm+bZG1!nNeT)|=-22@-I77VV)Kau28fi*Q5C>V6T07w$vNZ3 zw=G9f%n;895&u(@1(6qZ9S2ST+1Plv>hr+9l z0Jzc1mO6Fep4GKgJwUDy3?W|y-DPpSt|I;C3zfnEh}>A<9!0aS&#hw(=_UxG9kkL< zgP8a{LZOG+vLJ62b?gRIdo1wCQ>C?lP1`5MnqW{Scw0Qrc|B9=xp;oQ6RJ8EcqdsA zGzM%V#0UzYk(U`EC7+y4KBrd(>0B5< zbU-1*8scBPS@sp{*$|QijKLcgv;3u{Yxyc_L{c=xJf!tv@Yd}crx!1cDBHbxVJ~qA zYB?Tw^tS!VkwX>cm&wtwXH+9A%zKR5yPhB#7SB6tr_c4B4&%3+UfRHBw@+@E_~jSD za$!aY2Gc>ZgW#ExQ^-7@I*jCzlFjd5S!pj(Nrf2!M%s(&HP4f1NA3}A?rvJqor73T zO}f|=eOS7o{ON*hE(-QCeOm1LnbE@H*J%lz`$)1cMwXlsCwNWwLJJ=gdB|YvlN)(I zcg-!U6~E8?20G}^BYpkPCsy^&mg~x$0gP}+i@1wZjo&X!7O(bdu`jH+@EgwrhP9jW znz9-+Df%Pb$F;@Lo;zvG-nbOdyT4xdN~|JaIThGnW&iC+=ygB76kCJ{iXu!*(<>^o z_K?ZQftL$$EEA*QtAq(4@XAl)yr7)C?c&=%{(U%QmW+{E5EV{Ig-CWOk+|eeJeJy& zgh#**TDHC`C{c)Il9DgAwY448ve}$(z03}l%fy&$IaF|_bt(JK^mu&sNYbMM_jLcu+ZjwY67_(Q`f6Zkr(*;~bx z{ND`@e9Ex+WZKoMd2R1Wwa&RxR^J&hpc*Mvtr{7HiXtPS#v#U1s2Rj&^g!~?otZ@e z4*DWA`{}-9oWwsq8$bH}*^~P>`tmY0Z(wa!iob5leiom`s*3A>|7Cf2Yoa-p zHO>Dlx9OAq#_ak{E9tk0&-dU5VT~dEi}`=~7JG!DC7NQ=QwS1=_oI9{E@SQFIsm zz{aA+CN~UrR5xyfU4I6{!J}TPzqMtFD7pEyGfILYK1sqxC$|PhF9cq`^GPQ%8gNh1 zg<$$pcYPL@ZvX%Q literal 0 HcmV?d00001 diff --git a/sound/voice/medbot/mpatchedup.ogg b/sound/voice/medbot/mpatchedup.ogg new file mode 100644 index 0000000000000000000000000000000000000000..1314f6ee471889572291bf6a10d49055fd033d84 GIT binary patch literal 8670 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 literal 0 HcmV?d00001 diff --git a/sound/voice/medbot/mradar.ogg b/sound/voice/medbot/mradar.ogg new file mode 100644 index 0000000000000000000000000000000000000000..ad347a6d891c00d5975141b8efc76563eb4ed48e GIT binary patch literal 11177 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 z zvtUo?eh9f3Ye;4Y3(9I{u4?!y3dQ;7@NoU)QEOAK{VuCj4zd+p*zhuLyz^~KG3`yj z-=M_(}i?hDR$jUO$Pvd8@H}~c!Jyz4+FWmhd zbMk&yIB8i%q9BE~BUSmBF+JV3Pu`iD8GnP`G|4Dp@RTT=F#`o4Lr`UKHMQGH_9($T zOgg)&R>urlZ>r(1-`BmzVb9FwdxrOqMm=(JTBj43N)iO3w z)9K2=GsbZTn<+k;*WJ@?G`dA&v3f_Hy8_sLafJ7=%j#j!J=9W-38 zGD@{Q%o6H7Y7PJ{bB8DIxEWK`J9CFDaph zg}k4>eW7SIc*3qC>u~Lf(f%)$dX>(E+ME6bO5nciq%ViOG%X$~zM7IhrGk z!S?J|?jzMPVaUt3!&8;GfS{-GbKWUlzNISmH@Jo; zwZ+5lsWrBLyzq8PnPd6v*sdD#`&QOf-*<#71kSse(P!;%7)LI0Fag&6v1=>8&eHMdue9};I|e_JSn3K2xFQpoAhP-TO_f}m z!~Ldj5VkW=Knnse04NA}Pif>&L>F==_LVTWXABSDkd;+DhOgh-Dx` z#and&S%IuSp@Lh(zaotMpEL`)Z}xhU`+cA9IcHeZPHN?=*wO#g#@WVW(`}RQp2R;d z2hRo4c%YsF{-LDtFgG+3_U3U{2$3rz6NOxIL05YS!WF(=I`uWvM78sx^AFE%o7W=T z?AsnF#iOWF?Km<$hsw1W7E1D+P&VBfG;r!{nl_T4N3LoTy!k&LQgV{Nye6}a&@KRNMS;owcD=~ey z-Qv(YCvAV1>+6E)4@~qCJTbqQ_b4{>CkZ2r`IssE>1TV}Zr>ID2EAcaWH-dHjH{x+ zbyeqTFhc0Els4rFBtym@6jUfQHr!X0mI-uF5*H}^D7>v3($Y{cNwBzvI%D+Xy#(tG z`0-?euM+t>k`Iq8^YWiK6&B>Nb0=@@opu@DrEfFrN;7FsyVuCGJ=uV80%yGO8q<6v zDKz4?A(1DhM8|2o6%vB5owZ-fuw*o0I}XE346Cph&dh%fC^Fg29nnE1xdE2+CJPHV9HTky z$`XhIph%ol40%YYF7}B4zNyHYNsHf1Tl0HsEvqFT@!`uh$Cck3?hJsDuH~I@_Opx3 zwK#p1#5yc`{>WDh={^^5Qh@Wr+<=I{gO8e0v9(5VI@=e&;F;>SM-7UlOsgP9mnMG zEGbJrROn|ZLdyK_;6k)_v@p9Y%V&%I;38zopnVpIF)z`k6ETuD5$)za-0S!4RFSW) zU{CwGJL>^=2BtJmqYfOdlX}vtewIB+uR#r3v!E-eW_@2~`z4h*tvbgdvbIGFYOBKqmgV76qt}YE!>&H)Y zzOdPtf9RI&?`mcTcKfX!MqCnmz53y_{d{^2dGEVX>*%ZI4)PIlqnH-3CQJDO!|w|# zhh%`e7$O~&{3s-5H2fvIS_}5VjPq|)z>7<5rmDeyxdl`8yN<@}Z#8Vg==l1iJK26d z2`}bvd)oIw$FkkwaNJ3E5lBb>a(u)`TUTNGQ^MP+x-zD}14b1#f3|*k5%JT3m&qoF zh^KsFucV!2{FSI#W&8+2u!bN92j_sNo*t}Nz@sMglzg=J)ynnY>W|HyJ?-)wmMuBV z9a2Bu#Ja2z)egcZCnIJO?Xp?qQMLG0mB z+a=0bwYiLM1oMwOa{0V`y+z%s z4iOf;1FsgA2E4BB%FlB4b{tPq?U*%ww)OQ@lF9YgzW(aIVL6<4?S;HL-};74%}s<~ zsNZ=rUvY8Ac%zW{l`J^*Ri%B+_x#BNckPotwCz@0eCM#;^XLnRo#Xl~v|d9mG{^PW d@XJ(lVQ1^{TY}5-ay9km>EIX*fOejwt{D literal 0 HcmV?d00001 diff --git a/sound/voice/medbot/msurgeon.ogg b/sound/voice/medbot/msurgeon.ogg new file mode 100644 index 0000000000000000000000000000000000000000..a300ee57ef6db62606fb7e8d8b90949dc02ff352 GIT binary patch literal 23357 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 Date: Wed, 2 May 2018 17:44:10 -0500 Subject: [PATCH 9/9] Last Stage --- .../integrated_electronics/_defines.dm | 18 + .../integrated_electronics/core/assemblies.dm | 182 +++++++- .../integrated_electronics/core/detailer.dm | 46 ++ .../integrated_electronics/core/pins.dm | 2 + .../integrated_electronics/core/printer.dm | 36 +- .../core/special_pins/color_pin.dm | 7 - .../core/special_pins/list_pin.dm | 1 - .../core/special_pins/string_pin.dm | 5 +- .../integrated_electronics/core/tools.dm | 3 +- .../integrated_electronics/passive/power.dm | 71 ++- .../subtypes/converters.dm | 88 +++- .../subtypes/data_transfer.dm | 58 ++- .../integrated_electronics/subtypes/input.dm | 431 +++++++++++++++++- .../integrated_electronics/subtypes/lists.dm | 111 +++++ .../integrated_electronics/subtypes/logic.dm | 92 ++++ .../subtypes/manipulation.dm | 4 +- .../integrated_electronics/subtypes/memory.dm | 11 +- .../integrated_electronics/subtypes/power.dm | 12 +- .../subtypes/reagents.dm | 268 +++++++++-- .../integrated_electronics/subtypes/smart.dm | 6 +- config/admins.txt | 3 +- icons/obj/assemblies/electronic_setups.dmi | Bin 0 -> 16484 bytes icons/obj/assemblies/electronic_tools.dmi | Bin 0 -> 2390 bytes icons/obj/electronic_assemblies.dmi | Bin 35959 -> 39706 bytes tgstation.dme | 1 + 25 files changed, 1369 insertions(+), 87 deletions(-) create mode 100644 code/modules/integrated_electronics/core/detailer.dm create mode 100644 icons/obj/assemblies/electronic_setups.dmi create mode 100644 icons/obj/assemblies/electronic_tools.dmi diff --git a/code/modules/integrated_electronics/_defines.dm b/code/modules/integrated_electronics/_defines.dm index 52aeed3558c55..219cac711e467 100644 --- a/code/modules/integrated_electronics/_defines.dm +++ b/code/modules/integrated_electronics/_defines.dm @@ -45,6 +45,7 @@ #define COLOR_WHITE "#ffffff" #define COLOR_SILVER "#c0c0c0" #define COLOR_GRAY "#808080" +#define COLOR_FLOORTILE_GRAY "#8D8B8B" #define COLOR_BLACK "#000000" #define COLOR_RED "#ff0000" #define COLOR_RED_LIGHT "#b00000" @@ -77,6 +78,23 @@ #define COLOR_PURPLE_GRAY "#a2819e" #define COLOR_SUN "#ec8b2f" +//Color defines used by the assembly detailer. +#define COLOR_ASSEMBLY_BLACK "#545454" +#define COLOR_ASSEMBLY_BGRAY "#9497AB" +#define COLOR_ASSEMBLY_WHITE "#E2E2E2" +#define COLOR_ASSEMBLY_RED "#CC4242" +#define COLOR_ASSEMBLY_ORANGE "#E39751" +#define COLOR_ASSEMBLY_BEIGE "#AF9366" +#define COLOR_ASSEMBLY_BROWN "#97670E" +#define COLOR_ASSEMBLY_GOLD "#AA9100" +#define COLOR_ASSEMBLY_YELLOW "#CECA2B" +#define COLOR_ASSEMBLY_GURKHA "#999875" +#define COLOR_ASSEMBLY_LGREEN "#789876" +#define COLOR_ASSEMBLY_GREEN "#44843C" +#define COLOR_ASSEMBLY_LBLUE "#5D99BE" +#define COLOR_ASSEMBLY_BLUE "#38559E" +#define COLOR_ASSEMBLY_PURPLE "#6F6192" + var/global/list/alphabet_uppercase = list("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z") var/list/all_integrated_circuits = list() diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index 8f41daec1fa30..2e6bfa53f5314 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -5,14 +5,61 @@ name = "electronic assembly" desc = "It's a case, for building electronics with." w_class = 2 - icon = 'icons/obj/electronic_assemblies.dmi' + icon = 'icons/obj/assemblies/electronic_setups.dmi' icon_state = "setup_small" var/show_messages = TRUE var/max_components = IC_COMPONENTS_BASE var/max_complexity = IC_COMPLEXITY_BASE var/opened = 0 + var/detail_color = COLOR_ASSEMBLY_BLACK + var/list/color_whitelist = list( //This is just for checking that hacked colors aren't in the save data. + COLOR_ASSEMBLY_BLACK, + COLOR_FLOORTILE_GRAY, + COLOR_ASSEMBLY_BGRAY, + COLOR_ASSEMBLY_WHITE, + COLOR_ASSEMBLY_RED, + COLOR_ASSEMBLY_ORANGE, + COLOR_ASSEMBLY_BEIGE, + COLOR_ASSEMBLY_BROWN, + COLOR_ASSEMBLY_GOLD, + COLOR_ASSEMBLY_YELLOW, + COLOR_ASSEMBLY_GURKHA, + COLOR_ASSEMBLY_LGREEN, + COLOR_ASSEMBLY_GREEN, + COLOR_ASSEMBLY_LBLUE, + COLOR_ASSEMBLY_BLUE, + COLOR_ASSEMBLY_PURPLE + ) var/obj/item/weapon/stock_parts/cell/battery = null // Internal cell which most circuits need to work. +/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" + desc = "It's a case, for building small electronics with. This one resembles a pocket calculator." + +/obj/item/device/electronic_assembly/clam + name = "type-c electronic assembly" + icon_state = "setup_small_clam" + desc = "It's a case, for building small electronics with. This one has a clamshell design." + +/obj/item/device/electronic_assembly/simple + name = "type-d electronic assembly" + icon_state = "setup_small_simple" + desc = "It's a case, for building small electronics with. This one has a simple design." + +/obj/item/device/electronic_assembly/hook + name = "type-e electronic assembly" + icon_state = "setup_small_hook" + desc = "It's a case, for building small electronics with. This one looks like it has a belt clip, but it's purely decorative." + +/obj/item/device/electronic_assembly/pda + name = "type-f electronic assembly" + icon_state = "setup_small_pda" + desc = "It's a case, for building small electronics with. This one resembles a PDA." + /obj/item/device/electronic_assembly/medium name = "electronic mechanism" icon_state = "setup_medium" @@ -21,21 +68,132 @@ max_components = IC_COMPONENTS_BASE * 2 max_complexity = IC_COMPLEXITY_BASE * 2 +/obj/item/device/electronic_assembly/medium/default + name = "type-a electronic mechanism" + +/obj/item/device/electronic_assembly/medium/box + name = "type-b electronic mechanism" + icon_state = "setup_medium_box" + desc = "It's a case, for building medium-sized electronics with. This one has a boxy design." + +/obj/item/device/electronic_assembly/medium/clam + name = "type-c electronic mechanism" + icon_state = "setup_medium_clam" + desc = "It's a case, for building medium-sized electronics with. This one has a clamshell design." + +/obj/item/device/electronic_assembly/medium/medical + name = "type-d electronic mechanism" + icon_state = "setup_medium_med" + desc = "It's a case, for building medium-sized electronics with. This one resembles some type of medical apparatus." + +/obj/item/device/electronic_assembly/medium/gun + name = "type-e electronic mechanism" + icon_state = "setup_medium_gun" + desc = "It's a case, for building medium-sized electronics with. This one resembles a gun, or some type of tool, if you're feeling optimistic." + +/obj/item/device/electronic_assembly/medium/radio + name = "type-f electronic mechanism" + icon_state = "setup_medium_radio" + desc = "It's a case, for building medium-sized electronics with. This one resembles an old radio." + /obj/item/device/electronic_assembly/large name = "electronic machine" icon_state = "setup_large" desc = "It's a case, for building large electronics with." - w_class = 4 + w_class = 5 max_components = IC_COMPONENTS_BASE * 4 max_complexity = IC_COMPLEXITY_BASE * 4 +/obj/item/device/electronic_assembly/large/default + name = "type-a electronic machine" + +/obj/item/device/electronic_assembly/large/scope + name = "type-b electronic machine" + icon_state = "setup_large_scope" + desc = "It's a case, for building large electronics with. This one resembles an oscilloscope." + +/obj/item/device/electronic_assembly/large/terminal + name = "type-c electronic machine" + icon_state = "setup_large_terminal" + desc = "It's a case, for building large electronics with. This one resembles a computer terminal." + +/obj/item/device/electronic_assembly/large/arm + name = "type-d electronic machine" + icon_state = "setup_large_arm" + desc = "It's a case, for building large electronics with. This one resembles a robotic arm." + +/obj/item/device/electronic_assembly/large/tall + name = "type-e electronic machine" + icon_state = "setup_large_tall" + desc = "It's a case, for building large electronics with. This one has a tall design." + +/obj/item/device/electronic_assembly/large/industrial + name = "type-f electronic machine" + icon_state = "setup_large_industrial" + desc = "It's a case, for building large electronics with. This one resembles some kind of industrial machinery." + /obj/item/device/electronic_assembly/drone name = "electronic drone" icon_state = "setup_drone" desc = "It's a case, for building mobile electronics with." + w_class = 4 + max_components = IC_COMPONENTS_BASE * 3 + max_complexity = IC_COMPLEXITY_BASE * 3 + +/obj/item/device/electronic_assembly/drone/can_move() + return TRUE + +/obj/item/device/electronic_assembly/drone/default + name = "type-a electronic drone" + +/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." + +/obj/item/device/electronic_assembly/drone/secbot + name = "type-c electronic drone" + icon_state = "setup_drone_secbot" + desc = "It's a case, for building mobile electronics with. This one resembles a Securitron." + +/obj/item/device/electronic_assembly/drone/medbot + name = "type-d electronic drone" + icon_state = "setup_drone_medbot" + desc = "It's a case, for building mobile electronics with. This one resembles a Medibot." + +/obj/item/device/electronic_assembly/drone/genbot + name = "type-e electronic drone" + icon_state = "setup_drone_genbot" + desc = "It's a case, for building mobile electronics with. This one has a generic bot design." + +/obj/item/device/electronic_assembly/drone/android + name = "type-f electronic drone" + icon_state = "setup_drone_android" + desc = "It's a case, for building mobile electronics with. This one has a hominoid design." + +/obj/item/device/electronic_assembly/wallmount + name = "wall-mounted electronic assembly" + icon_state = "setup_wallmount_medium" + desc = "It's a case, for building medium-sized electronics with. It has a magnetized backing to allow it to stick to walls, but you'll still need to wrench the anchoring bolts in place to keep it on." w_class = 3 - max_components = IC_COMPONENTS_BASE * 1.5 - max_complexity = IC_COMPLEXITY_BASE * 1.5 + max_components = IC_COMPONENTS_BASE * 2 + max_complexity = IC_COMPLEXITY_BASE * 2 + +/obj/item/device/electronic_assembly/wallmount/heavy + name = "heavy wall-mounted electronic assembly" + icon_state = "setup_wallmount_large" + desc = "It's a case, for building large electronics with. It has a magnetized backing to allow it to stick to walls, but you'll still need to wrench the anchoring bolts in place to keep it on." + w_class = 5 + max_components = IC_COMPONENTS_BASE * 4 + max_complexity = IC_COMPLEXITY_BASE * 4 + +/obj/item/device/electronic_assembly/wallmount/light + name = "light wall-mounted electronic assembly" + icon_state = "setup_wallmount_small" + desc = "It's a case, for building small electronics with. It has a magnetized backing to allow it to stick to walls, but you'll still need to wrench the anchoring bolts in place to keep it on." + w_class = 2 + max_components = IC_COMPONENTS_BASE + max_complexity = IC_COMPLEXITY_BASE /obj/item/device/electronic_assembly/implant name = "electronic implant" @@ -75,6 +233,12 @@ /obj/item/device/electronic_assembly/implant/update_icon() ..() implant.icon_state = icon_state + overlays.Cut() + if(detail_color == COLOR_ASSEMBLY_BLACK) //Black colored overlay looks almost but not exactly like the base sprite, so just cut the overlay and avoid it looking kinda off. + return + var/image/detail_overlay = image('icons/obj/assemblies/electronic_setups.dmi', "[icon_state]-color") + detail_overlay.color = detail_color + overlays.Add(detail_overlay) /obj/item/device/electronic_assembly/implant/proc/nano_host() @@ -184,6 +348,12 @@ icon_state = initial(icon_state) + "-open" else icon_state = initial(icon_state) + overlays.Cut() + if(detail_color == COLOR_ASSEMBLY_BLACK) //Black colored overlay looks almost but not exactly like the base sprite, so just cut the overlay and avoid it looking kinda off. + return + var/image/detail_overlay = image('icons/obj/assemblies/electronic_setups.dmi', "[icon_state]-color") + detail_overlay.color = detail_color + overlays.Add(detail_overlay) /obj/item/device/electronic_assembly/examine(mob/user) . = ..(user, 1) @@ -280,6 +450,10 @@ to_chat(user, "You slot \the [cell] inside \the [src]'s power supplier.") interact(user) return TRUE + else if(istype(I, /obj/item/device/integrated_electronics/detailer)) + var/obj/item/device/integrated_electronics/detailer/D = I + detail_color = D.detail_color + update_icon() else return ..() diff --git a/code/modules/integrated_electronics/core/detailer.dm b/code/modules/integrated_electronics/core/detailer.dm new file mode 100644 index 0000000000000..a63c174c2846d --- /dev/null +++ b/code/modules/integrated_electronics/core/detailer.dm @@ -0,0 +1,46 @@ +/obj/item/device/integrated_electronics/detailer + name = "assembly detailer" + desc = "A combination autopainter and flash anodizer designed to give electronic assemblies a colorful, wear-resistant finish." + icon = 'icons/obj/assemblies/electronic_tools.dmi' + icon_state = "detailer" + w_class = 2 + var/data_to_write = null + var/accepting_refs = FALSE + var/detail_color = COLOR_ASSEMBLY_WHITE + var/list/color_list = list( + "black" = COLOR_ASSEMBLY_BLACK, + "gray" = COLOR_FLOORTILE_GRAY, + "machine gray" = COLOR_ASSEMBLY_BGRAY, + "white" = COLOR_ASSEMBLY_WHITE, + "red" = COLOR_ASSEMBLY_RED, + "orange" = COLOR_ASSEMBLY_ORANGE, + "beige" = COLOR_ASSEMBLY_BEIGE, + "brown" = COLOR_ASSEMBLY_BROWN, + "gold" = COLOR_ASSEMBLY_GOLD, + "yellow" = COLOR_ASSEMBLY_YELLOW, + "gurkha" = COLOR_ASSEMBLY_GURKHA, + "light green" = COLOR_ASSEMBLY_LGREEN, + "green" = COLOR_ASSEMBLY_GREEN, + "light blue" = COLOR_ASSEMBLY_LBLUE, + "blue" = COLOR_ASSEMBLY_BLUE, + "purple" = COLOR_ASSEMBLY_PURPLE + ) + +/obj/item/device/integrated_electronics/detailer/New() + .=..() + update_icon() + +/obj/item/device/integrated_electronics/detailer/update_icon() + overlays.Cut() + var/image/detail_overlay = image('icons/obj/assemblies/electronic_tools.dmi', "detailer-color") + detail_overlay.color = detail_color + overlays.Add(detail_overlay) + +/obj/item/device/integrated_electronics/detailer/attack_self(mob/user) + var/color_choice = input(user, "Select color.", "Assembly Detailer") as null|anything in color_list + if(!color_list[color_choice]) + return + if(!in_range(src, user)) + return + detail_color = color_list[color_choice] + update_icon() \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/pins.dm b/code/modules/integrated_electronics/core/pins.dm index 98b013eddd19d..6789834df2d73 100644 --- a/code/modules/integrated_electronics/core/pins.dm +++ b/code/modules/integrated_electronics/core/pins.dm @@ -112,6 +112,8 @@ list[]( /datum/integrated_io/proc/write_data_to_pin(var/new_data) if(isnull(new_data) || isnum(new_data) || istext(new_data) || isweakref(new_data)) // Anything else is a type we don't want. + if(istext(new_data)) + new_data = sanitize_text(new_data, MAX_MESSAGE_LEN, 0, 0) data = new_data holder.on_data_written() diff --git a/code/modules/integrated_electronics/core/printer.dm b/code/modules/integrated_electronics/core/printer.dm index f850955259a16..75809dbf1867b 100644 --- a/code/modules/integrated_electronics/core/printer.dm +++ b/code/modules/integrated_electronics/core/printer.dm @@ -52,10 +52,33 @@ // Now for non-circuit things. var/list/assembly_list = list() assembly_list.Add( - new /obj/item/device/electronic_assembly(null), - new /obj/item/device/electronic_assembly/medium(null), - new /obj/item/device/electronic_assembly/large(null), - new /obj/item/device/electronic_assembly/drone(null), + new /obj/item/device/electronic_assembly/default(null), + new /obj/item/device/electronic_assembly/calc(null), + new /obj/item/device/electronic_assembly/clam(null), + new /obj/item/device/electronic_assembly/simple(null), + new /obj/item/device/electronic_assembly/hook(null), + new /obj/item/device/electronic_assembly/pda(null), + new /obj/item/device/electronic_assembly/medium/default(null), + new /obj/item/device/electronic_assembly/medium/box(null), + new /obj/item/device/electronic_assembly/medium/clam(null), + new /obj/item/device/electronic_assembly/medium/medical(null), + new /obj/item/device/electronic_assembly/medium/gun(null), + new /obj/item/device/electronic_assembly/medium/radio(null), + new /obj/item/device/electronic_assembly/large/default(null), + new /obj/item/device/electronic_assembly/large/scope(null), + new /obj/item/device/electronic_assembly/large/terminal(null), + new /obj/item/device/electronic_assembly/large/arm(null), + new /obj/item/device/electronic_assembly/large/tall(null), + new /obj/item/device/electronic_assembly/large/industrial(null), + new /obj/item/device/electronic_assembly/drone/default(null), + new /obj/item/device/electronic_assembly/drone/arms(null), + new /obj/item/device/electronic_assembly/drone/secbot(null), + new /obj/item/device/electronic_assembly/drone/medbot(null), + new /obj/item/device/electronic_assembly/drone/genbot(null), + new /obj/item/device/electronic_assembly/drone/android(null), + new /obj/item/device/electronic_assembly/wallmount/light(null), + new /obj/item/device/electronic_assembly/wallmount(null), + new /obj/item/device/electronic_assembly/wallmount/heavy(null), new /obj/item/weapon/implant/integrated_circuit(null), new /obj/item/device/assembly/electronic_assembly(null) ) @@ -64,7 +87,8 @@ var/list/tools_list = list() tools_list.Add( new /obj/item/device/integrated_electronics/wirer(null), - new /obj/item/device/integrated_electronics/debugger(null) + new /obj/item/device/integrated_electronics/debugger(null), + new /obj/item/device/integrated_electronics/detailer(null) ) recipe_list["Tools"] = tools_list @@ -77,7 +101,7 @@ to_chat(user, "\The [src] is too full to add more metal.") return if(stack.amount >= num) - stack.amount -= num + stack.use(num) to_chat(user, "You add [num] sheet\s to \the [src].") metal += num * metal_per_sheet interact(user) diff --git a/code/modules/integrated_electronics/core/special_pins/color_pin.dm b/code/modules/integrated_electronics/core/special_pins/color_pin.dm index 0fa82b45069a9..2d20560fb6e7d 100644 --- a/code/modules/integrated_electronics/core/special_pins/color_pin.dm +++ b/code/modules/integrated_electronics/core/special_pins/color_pin.dm @@ -6,7 +6,6 @@ var/new_data = input("Please select a color.","[src] color writing") as null|color if(holder.check_interactivity(user) ) to_chat(user, "You input a new color into the pin.") - world << "new_data equals [new_data]." write_data_to_pin(new_data) /datum/integrated_io/color/write_data_to_pin(var/new_data) @@ -15,24 +14,18 @@ if(istext(new_data)) new_data = uppertext(new_data) if(length(new_data) != 7) // We can hex if we want to, we can leave your strings behind - world << "Wrong length." return // Cause your strings don't hex and if they don't hex var/friends = copytext(new_data, 2, 8) // Well they're are no strings of mine - world << "friends equal [friends]." // I say, we can go where we want to, a place where they will never find var/safety_dance = 1 while(safety_dance >= 7) // And we can act like we come from out of this world.log var/hex = copytext(friends, safety_dance, safety_dance+1) - world << "Checking [hex]." if(!(hex in list("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"))) - world << "Hex [hex] failed" return // Leave the fake one far behind, safety_dance++ data = new_data // And we can hex holder.on_data_written() - world << "Done." - world << "Rip." // This randomizes the color. /datum/integrated_io/color/scramble() diff --git a/code/modules/integrated_electronics/core/special_pins/list_pin.dm b/code/modules/integrated_electronics/core/special_pins/list_pin.dm index a40557679dfb3..e3c10b25df4c3 100644 --- a/code/modules/integrated_electronics/core/special_pins/list_pin.dm +++ b/code/modules/integrated_electronics/core/special_pins/list_pin.dm @@ -133,7 +133,6 @@ clear_list(usr) if(href_list["remove"]) - world << "Removing [href_list["pos"]]" if(href_list["pos"]) remove_from_list_by_position(usr, text2num(href_list["pos"])) else diff --git a/code/modules/integrated_electronics/core/special_pins/string_pin.dm b/code/modules/integrated_electronics/core/special_pins/string_pin.dm index 6128418c1f320..8f297fa340fcc 100644 --- a/code/modules/integrated_electronics/core/special_pins/string_pin.dm +++ b/code/modules/integrated_electronics/core/special_pins/string_pin.dm @@ -4,11 +4,14 @@ /datum/integrated_io/string/ask_for_pin_data(mob/user) var/new_data = input("Please type in a string.","[src] string writing") as null|text - if(holder.check_interactivity(user) ) + new_data = sanitize_text(new_data, MAX_MESSAGE_LEN, 0, 0) + + if(new_data && holder.check_interactivity(user) ) to_chat(user, "You input [new_data ? "new_data" : "NULL"] into the pin.") write_data_to_pin(new_data) /datum/integrated_io/string/write_data_to_pin(var/new_data) + new_data = sanitize_text(new_data, MAX_MESSAGE_LEN, 0, 0) if(isnull(new_data) || istext(new_data)) data = new_data holder.on_data_written() diff --git a/code/modules/integrated_electronics/core/tools.dm b/code/modules/integrated_electronics/core/tools.dm index 7cb2ba3df5b30..a77c933befe83 100644 --- a/code/modules/integrated_electronics/core/tools.dm +++ b/code/modules/integrated_electronics/core/tools.dm @@ -122,7 +122,8 @@ if("string") accepting_refs = 0 new_data = input("Now type in a string.","[src] string writing") as null|text - if(istext(new_data)) + new_data = sanitize_text(new_data, MAX_MESSAGE_LEN, 0, 0) + if(istext(new_data) && CanInteract(user,src)) data_to_write = new_data user << "You set \the [src]'s memory to \"[new_data]\"." if("number") diff --git a/code/modules/integrated_electronics/passive/power.dm b/code/modules/integrated_electronics/passive/power.dm index 1b8128175fc3b..788003b0f13f1 100644 --- a/code/modules/integrated_electronics/passive/power.dm +++ b/code/modules/integrated_electronics/passive/power.dm @@ -21,17 +21,36 @@ var/max_power = 1 /obj/item/integrated_circuit/passive/power/solar_cell/make_energy() - var/atom/movable/lighting_overlay/light = locate(/atom/movable/lighting_overlay) in get_turf(src) - var/light_amount = 1 // Unsimulated tiles are pretend-lit, so we need to be pretend too if that somehow happens. - if(light) - light_amount = (light.lum_r + light.lum_g + light.lum_b) / 3 - + var/turf/T = get_turf(src) + var/light_amount = T ? T.get_lumcount() : 0 var/adjusted_power = max(max_power * light_amount, 0) adjusted_power = round(adjusted_power, 0.1) if(adjusted_power) if(assembly) assembly.give_power(adjusted_power) +/obj/item/integrated_circuit/passive/power/starter + name = "starter" + desc = "This tiny circuit will send a pulse right after device is turned on, or when power is restored." + icon_state = "led" + complexity = 1 + activators = list("pulse out" = IC_PINTYPE_PULSE_OUT) + origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_DATA = 2) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + var/is_charge=0 + +/obj/item/integrated_circuit/passive/power/starter/make_energy() + if(assembly.battery) + if(assembly.battery.charge) + if(!is_charge) + activate_pin(1) + is_charge=1 + else + is_charge=0 + else + is_charge=0 + return FALSE + // For implants. /obj/item/integrated_circuit/passive/power/metabolic_siphon name = "metabolic siphon" @@ -85,6 +104,44 @@ origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_DATA = 2) spawn_flags = IC_SPAWN_RESEARCH var/power_amount = 250 +//fuel cell + +/obj/item/integrated_circuit/passive/power/chemical_cell + name = "fuel cell" + desc = "Produces electricity from chemicals." + icon_state = "chemical_cell" + extended_desc = "This is effectively an internal beaker. It will consume and produce power from plasma, slime jelly, welding fuel, carbon,\ + ethanol, nutriments and blood, in order of decreasing efficiency. It will consume fuel only if the battery can take more energy." + flags = OPENCONTAINER + complexity = 4 + inputs = list() + outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF) + activators = list() + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) + var/volume = 60 + var/list/fuel = list("plasma" = 50000, "slimejelly" = 25000, "fuel" = 15000, "carbon" = 10000, "ethanol"= 10000, "nutriment" =8000, "blood" = 5000) + +/obj/item/integrated_circuit/passive/power/chemical_cell/New() + ..() + create_reagents(volume) + +/obj/item/integrated_circuit/passive/power/chemical_cell/interact(mob/user) + 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() + +/obj/item/integrated_circuit/passive/power/chemical_cell/make_energy() + if(assembly) + for(var/I in fuel) + if((assembly.battery.maxcharge-assembly.battery.charge) / CELLRATE > fuel[I]) + if(reagents.remove_reagent(I, 1)) + assembly.give_power(fuel[I]) + // For really fat machines. /obj/item/integrated_circuit/passive/power/relay/large @@ -104,6 +161,6 @@ return var/area/A = get_area(src) if(A) - if(A.powered(EQUIP)) + if(A.powered(EQUIP) && assembly.give_power(power_amount)) A.use_power(power_amount, EQUIP) - assembly.give_power(power_amount) // give_power() handles CELLRATE on its own. + // give_power() handles CELLRATE on its own. diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm index b0cd8cb4594ac..b9f5c912d4c14 100644 --- a/code/modules/integrated_electronics/subtypes/converters.dm +++ b/code/modules/integrated_electronics/subtypes/converters.dm @@ -7,10 +7,6 @@ category_text = "Converter" power_draw_per_use = 10 -/obj/item/integrated_circuit/converter/on_data_written() -// if(autopulse == 1) - check_then_do_work() - /obj/item/integrated_circuit/converter/num2text name = "number to string" desc = "This circuit can convert a number variable into a string." @@ -71,6 +67,40 @@ push_data() activate_pin(2) +/obj/item/integrated_circuit/converter/refcode + name = "reference encoder" + desc = "This circuit can encode a reference into a string, which can then be read by an EPV2 circuit." + icon_state = "ref-string" + inputs = list("input" = IC_PINTYPE_REF) + outputs = list("output" = IC_PINTYPE_STRING) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/converter/refcode/do_work() + var/result = null + pull_data() + var/atom/A = get_pin_data(IC_INPUT, 1) + if(A && istype(A)) + result = "\ref[A]" + + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/converter/refdecode + name = "reference decoder" + desc = "This circuit can convert an encoded reference to actual reference." + icon_state = "ref-string" + inputs = list("input" = IC_PINTYPE_STRING) + outputs = list("output" = IC_PINTYPE_REF) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + + +/obj/item/integrated_circuit/converter/refdecode/do_work() + pull_data() + set_pin_data(IC_OUTPUT, 1, weakref(locate(get_pin_data(IC_INPUT, 1)))) + push_data() + activate_pin(2) + /obj/item/integrated_circuit/converter/lowercase name = "lowercase string converter" desc = "this will cause a string to come out in all lowercase." @@ -172,6 +202,56 @@ activate_pin(2) +/obj/item/integrated_circuit/converter/findstring + name = "find text" + desc = "This gives position of sample in the string. Or returns 0." + extended_desc = "The first pin is the string to be examined. The second pin is the sample to be found. \ + For example, 'eat this burger',' ' will give you position 4. This circuit isn't case sensitive." + complexity = 4 + inputs = list( + "string" = IC_PINTYPE_STRING, + "sample" = IC_PINTYPE_STRING, + ) + outputs = list( + "position" = IC_PINTYPE_NUMBER + ) + activators = list("search" = IC_PINTYPE_PULSE_IN, "after search" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + + + +/obj/item/integrated_circuit/converter/findstring/do_work() + + set_pin_data(IC_OUTPUT, 1, findtext(get_pin_data(IC_INPUT, 1),get_pin_data(IC_INPUT, 2)) ) + push_data() + + activate_pin(2) + +/obj/item/integrated_circuit/converter/exploders + name = "string exploder" + desc = "This splits a single string into a list of strings." + extended_desc = "This circuit splits a given string into a list of strings based on the string and given delimiter. \ + For example, 'eat this burger',' ' will be converted to list('eat','this','burger')." + complexity = 4 + inputs = list( + "string to split" = IC_PINTYPE_STRING, + "delimiter" = IC_PINTYPE_STRING, + ) + outputs = list( + "list" = IC_PINTYPE_LIST + ) + activators = list("separate" = IC_PINTYPE_PULSE_IN, "on separated" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + + + +/obj/item/integrated_circuit/converter/exploders/do_work() + var/strin = get_pin_data(IC_INPUT, 1) + var/sample = get_pin_data(IC_INPUT, 2) + set_pin_data(IC_OUTPUT, 1, splittext( strin ,sample )) + push_data() + + activate_pin(2) /obj/item/integrated_circuit/converter/radians2degrees name = "radians to degrees converter" diff --git a/code/modules/integrated_electronics/subtypes/data_transfer.dm b/code/modules/integrated_electronics/subtypes/data_transfer.dm index 7d23929f5ecd3..697a2be2593e3 100644 --- a/code/modules/integrated_electronics/subtypes/data_transfer.dm +++ b/code/modules/integrated_electronics/subtypes/data_transfer.dm @@ -27,13 +27,10 @@ /obj/item/integrated_circuit/transfer/multiplexer/do_work() var/input_index = get_pin_data(IC_INPUT, 1) - var/output = null if(!isnull(input_index) && (input_index >= 1 && input_index < inputs.len)) - output = get_pin_data(IC_INPUT, input_index + 1) - - set_pin_data(IC_OUTPUT, 1, output) - push_data() + set_pin_data(IC_OUTPUT, 1,get_pin_data(IC_INPUT, input_index + 1)) + push_data() activate_pin(2) /obj/item/integrated_circuit/transfer/multiplexer/medium @@ -79,10 +76,8 @@ /obj/item/integrated_circuit/transfer/demultiplexer/do_work() var/output_index = get_pin_data(IC_INPUT, 1) - var/output = get_pin_data(IC_INPUT, 2) - for(var/i = 1 to outputs.len) - set_pin_data(IC_OUTPUT, i, i == output_index ? output : null) + set_pin_data(IC_OUTPUT, i, i == output_index ? get_pin_data(IC_INPUT, 2) : null) activate_pin(2) @@ -101,4 +96,51 @@ name = "sixteen demultiplexer" icon_state = "dmux16" w_class = 2 + number_of_outputs = 16 + +/obj/item/integrated_circuit/transfer/pulsedemultiplexer + name = "two pulse demultiplexer" + desc = "Selector switch to choose the pin to be activated by number." + extended_desc = "The first input pin is used to select which of the pulse out pins will be activated after activation of the circuit. \ + If the output selection is outside the valid range then no output is given." + complexity = 2 + icon_state = "dmux2" + inputs = list("output selection" = IC_PINTYPE_NUMBER) + outputs = list() + activators = list("select" = IC_PINTYPE_PULSE_IN) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + power_draw_per_use = 4 + var/number_of_outputs = 2 + +/obj/item/integrated_circuit/transfer/pulsedemultiplexer/New() + for(var/i = 1 to number_of_outputs) + // outputs += "output [i]" + activators["output [i]"] = IC_PINTYPE_PULSE_OUT + complexity = number_of_outputs + + ..() + desc += " It has [number_of_outputs] output pins." + extended_desc += " This pulse demultiplexer has a range from 1 to [activators.len - 1]." + +/obj/item/integrated_circuit/transfer/pulsedemultiplexer/do_work() + var/output_index = get_pin_data(IC_INPUT, 1) + + if(output_index == Clamp(output_index, 1, number_of_outputs)) + activate_pin(round(output_index + 1 ,1)) + +/obj/item/integrated_circuit/transfer/pulsedemultiplexer/medium + name = "four pulse demultiplexer" + icon_state = "dmux4" + number_of_outputs = 4 + +/obj/item/integrated_circuit/transfer/pulsedemultiplexer/large + name = "eight pulse demultiplexer" + icon_state = "dmux8" + w_class = 2 + number_of_outputs = 8 + +/obj/item/integrated_circuit/transfer/pulsedemultiplexer/huge + name = "sixteen pulse demultiplexer" + icon_state = "dmux16" + w_class = 2 number_of_outputs = 16 \ No newline at end of file diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index 093d4c0af50d8..583c50c4a3a60 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -17,6 +17,8 @@ activators = list("on pressed" = IC_PINTYPE_PULSE_IN) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + + /obj/item/integrated_circuit/input/button/ask_for_input(mob/user) //Bit misleading name for this specific use. to_chat(user, "You press the button labeled '[src.name]'.") activate_pin(1) @@ -105,9 +107,13 @@ push_data() activate_pin(2) + + /obj/item/integrated_circuit/input/adv_med_scanner - name = "integrated advanced medical analyser" - desc = "A very small version of the common medical analyser. This allows the machine to know how healthy someone is. \ + + name = "integrated advanced medical analyzer" + desc = "A very small version of the medibot's medical analyzer. This allows the machine to know how healthy someone is. \ + This type is much more precise, allowing the machine to know much more about the target than a normal analyzer." icon_state = "medscan_adv" complexity = 12 @@ -130,7 +136,9 @@ 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.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range. + + if(H in view(get_turf(H))) // 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 @@ -145,6 +153,53 @@ push_data() activate_pin(2) +/obj/item/integrated_circuit/input/examiner + name = "examiner" + desc = "It's a little machine vision system. It can return the name, description, distance,\ + relative coordinates, total amount of reagents, and maximum amount of reagents of the referenced object." + icon_state = "video_camera" + complexity = 6 + inputs = list("\ target" = IC_PINTYPE_REF) + outputs = list( + "name" = IC_PINTYPE_STRING, + "description" = IC_PINTYPE_STRING, + "X" = IC_PINTYPE_NUMBER, + "Y" = IC_PINTYPE_NUMBER, + "distance" = IC_PINTYPE_NUMBER, + "max reagents" = IC_PINTYPE_NUMBER, + "amount of reagents" = IC_PINTYPE_NUMBER, + ) + activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT, "not scanned" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4) + power_draw_per_use = 80 + +/obj/item/integrated_circuit/input/examiner/do_work() + var/atom/movable/H = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) + var/turf/T = get_turf(src) + if(!istype(H)) //Invalid input + return + + if(H in view(T)) // This is a camera. It can't examine thngs,that it can't see. + + + set_pin_data(IC_OUTPUT, 1, H.name) + set_pin_data(IC_OUTPUT, 2, H.desc) + set_pin_data(IC_OUTPUT, 3, H.x-T.x) + set_pin_data(IC_OUTPUT, 4, H.y-T.y) + set_pin_data(IC_OUTPUT, 5, sqrt((H.x-T.x)*(H.x-T.x)+ (H.y-T.y)*(H.y-T.y))) + var/mr = 0 + var/tr = 0 + if(H.reagents) + mr = H.reagents.maximum_volume + tr = H.reagents.total_volume + set_pin_data(IC_OUTPUT, 6, mr) + set_pin_data(IC_OUTPUT, 7, tr) + push_data() + activate_pin(2) + else + activate_pin(3) + /obj/item/integrated_circuit/input/local_locator name = "local locator" desc = "This is needed for certain devices that demand a reference for a target to act upon. This type only locates something \ @@ -173,7 +228,8 @@ random." inputs = list("desired type ref") outputs = list("located ref") - activators = list("locate" = IC_PINTYPE_PULSE_IN) + activators = list("locate" = 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 = 30 @@ -197,8 +253,64 @@ valid_things.Add(thing) if(valid_things.len) O.data = weakref(pick(valid_things)) + activate_pin(2) + else + activate_pin(3) O.push_data() +/obj/item/integrated_circuit/input/advanced_locator + complexity = 6 + name = "advanced locator" + desc = "This is needed for certain devices that demand a reference for a target to act upon. This type locates something \ + that is standing in given radius of up to 8 meters" + extended_desc = "The first pin requires a ref to a kind of object that you want the locator to acquire. This means that it will \ + give refs to nearby objects that are similar to given sample. If this pin is a string, the locator will search for\ + item by matching desired text in name + description. If more than one valid object is found nearby, it will choose one of them at \ + random. The second pin is a radius." + inputs = list("desired type" = IC_PINTYPE_ANY, "radius" = IC_PINTYPE_NUMBER) + outputs = list("located ref") + activators = list("locate" = 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 = 30 + var/radius = 1 + +/obj/item/integrated_circuit/input/advanced_locator/on_data_written() + var/rad = get_pin_data(IC_INPUT, 2) + if(isnum(rad)) + rad = Clamp(rad, 0, 8) + radius = rad + +/obj/item/integrated_circuit/input/advanced_locator/do_work() + var/datum/integrated_io/I = inputs[1] + var/datum/integrated_io/O = outputs[1] + O.data = null + var/turf/T = get_turf(src) + var/list/nearby_things = range(radius, T) & view(T) + var/list/valid_things = list() + if(isweakref(I.data)) + var/atom/A = I.data.resolve() + var/desired_type = A.type + if(desired_type) + for(var/atom/thing in nearby_things) + if(thing.type == desired_type) + valid_things.Add(thing) + else if(istext(I.data)) + var/DT = I.data + for(var/atom/thing in nearby_things) + if(findtext(addtext(thing.name," ",thing.desc), DT, 1, 0) ) + valid_things.Add(thing) + if(valid_things.len) + O.data = weakref(pick(valid_things)) + O.push_data() + activate_pin(2) + else + O.push_data() + activate_pin(3) + + + + + /obj/item/integrated_circuit/input/signaler name = "integrated signaler" desc = "Signals from a signaler can be received with this, allowing for remote control. Additionally, it can send signals as well." @@ -432,3 +544,314 @@ 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." + icon_state = "internalbm" + extended_desc = "This circuit will give you values of charge, max charge and percentage of the internal battery on demand." + w_class = 1 + complexity = 1 + inputs = list() + outputs = list( + "cell charge" = IC_PINTYPE_NUMBER, + "max charge" = IC_PINTYPE_NUMBER, + "percentage" = IC_PINTYPE_NUMBER, + "refference to assembly" = IC_PINTYPE_REF + ) + activators = list("read" = IC_PINTYPE_PULSE_IN, "on read" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3) + power_draw_per_use = 1 + +/obj/item/integrated_circuit/input/internalbm/do_work() + set_pin_data(IC_OUTPUT, 1, null) + set_pin_data(IC_OUTPUT, 2, null) + set_pin_data(IC_OUTPUT, 3, null) + set_pin_data(IC_OUTPUT, 4, weakref(assembly)) + if(assembly) + if(assembly.battery) + + set_pin_data(IC_OUTPUT, 1, assembly.battery.charge) + set_pin_data(IC_OUTPUT, 2, assembly.battery.maxcharge) + set_pin_data(IC_OUTPUT, 3, 100*assembly.battery.charge/assembly.battery.maxcharge) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/input/externalbm + name = "external battery monitor" + desc = "This can help watch the battery level of any device in range." + icon_state = "externalbm" + extended_desc = "This circuit will give you values of charge, max charge and percentage of any device or battery in view" + w_class = 1 + complexity = 2 + inputs = list("target" = IC_PINTYPE_REF) + outputs = list( + "cell charge" = IC_PINTYPE_NUMBER, + "max charge" = IC_PINTYPE_NUMBER, + "percentage" = IC_PINTYPE_NUMBER + ) + activators = list("read" = IC_PINTYPE_PULSE_IN, "on read" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3) + power_draw_per_use = 1 + +/obj/item/integrated_circuit/input/externalbm/do_work() + + var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) + set_pin_data(IC_OUTPUT, 1, null) + set_pin_data(IC_OUTPUT, 2, null) + set_pin_data(IC_OUTPUT, 3, null) + if(AM) + + + var/obj/item/weapon/stock_parts/cell/cell = null + if(istype(AM, /obj/item/weapon/stock_parts/cell)) // Is this already a cell? + cell = AM + else // If not, maybe there's a cell inside it? + for(var/obj/item/weapon/stock_parts/cell/C in AM.contents) + if(C) // Find one cell to charge. + cell = C + break + if(cell) + + var/turf/A = get_turf(src) + if(AM in view(A)) + push_data() + set_pin_data(IC_OUTPUT, 1, cell.charge) + set_pin_data(IC_OUTPUT, 2, cell.maxcharge) + set_pin_data(IC_OUTPUT, 3, cell.percent()) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/input/atmo_scanner + name = "integrated atmospheric analyser" + desc = "The same atmospheric analysis module that is integrated into every PDA. \ + This allows the machine to know the composition, temperature and pressure of the surrounding atmosphere." + icon_state = "medscan_adv" + complexity = 9 + inputs = list() + outputs = list( + "pressure" = IC_PINTYPE_NUMBER, + "temperature" = IC_PINTYPE_NUMBER, + "oxygen" = IC_PINTYPE_NUMBER, + "nitrogen" = IC_PINTYPE_NUMBER, + "carbon dioxide" = IC_PINTYPE_NUMBER, + "plasma" = IC_PINTYPE_NUMBER, + "other" = IC_PINTYPE_NUMBER + ) + activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) + power_draw_per_use = 60 + +/obj/item/integrated_circuit/input/atmo_scanner/do_work() + var/turf/T = get_turf(src) + if(!istype(T)) //Invalid input + return + var/datum/gas_mixture/environment = T.return_air() + + var/pressure = environment.return_pressure() + var/total_moles = environment.total_moles() + + if (total_moles) + var/o2_level = environment.oxygen/total_moles + var/n2_level = environment.nitrogen/total_moles + var/co2_level = environment.carbon_dioxide/total_moles + var/plasma_level = environment.toxins/total_moles + var/unknown_level = 1-(o2_level+n2_level+co2_level+plasma_level) + set_pin_data(IC_OUTPUT, 1, pressure) + set_pin_data(IC_OUTPUT, 2, round(environment.temperature-T0C,0.1)) + set_pin_data(IC_OUTPUT, 3, round(o2_level*100,0.1)) + set_pin_data(IC_OUTPUT, 4, round(n2_level*100,0.1)) + set_pin_data(IC_OUTPUT, 5, round(co2_level*100,0.1)) + set_pin_data(IC_OUTPUT, 6, round(plasma_level*100,0.01)) + set_pin_data(IC_OUTPUT, 7, round(unknown_level, 0.01)) + else + set_pin_data(IC_OUTPUT, 1, 0) + set_pin_data(IC_OUTPUT, 2, -273.15) + set_pin_data(IC_OUTPUT, 3, 0) + set_pin_data(IC_OUTPUT, 4, 0) + set_pin_data(IC_OUTPUT, 5, 0) + set_pin_data(IC_OUTPUT, 6, 0) + set_pin_data(IC_OUTPUT, 7, 0) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/input/pressure_sensor + name = "integrated pressure sensor" + desc = "A tiny pressure sensor module similar to that found in a PDA atmosphere analyser." + icon_state = "medscan_adv" + complexity = 3 + inputs = list() + outputs = list( + "pressure" = IC_PINTYPE_NUMBER + ) + activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) + power_draw_per_use = 20 + +/obj/item/integrated_circuit/input/pressure_sensor/do_work() + var/turf/T = get_turf(src) + if(!istype(T)) //Invalid input + return + var/datum/gas_mixture/environment = T.return_air() + + var/pressure = environment.return_pressure() + var/total_moles = environment.total_moles() + + if (total_moles) + set_pin_data(IC_OUTPUT, 1, pressure) + else + set_pin_data(IC_OUTPUT, 1, 0) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/input/temperature_sensor + name = "integrated temperature sensor" + desc = "A tiny temperature sensor module similar to that found in a PDA atmosphere analyser." + icon_state = "medscan_adv" + complexity = 3 + inputs = list() + outputs = list( + "temperature" = IC_PINTYPE_NUMBER + ) + activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) + power_draw_per_use = 20 + +/obj/item/integrated_circuit/input/temperature_sensor/do_work() + var/turf/T = get_turf(src) + if(!istype(T)) //Invalid input + return + var/datum/gas_mixture/environment = T.return_air() + + var/total_moles = environment.total_moles() + + if (total_moles) + set_pin_data(IC_OUTPUT, 1, round(environment.temperature-T0C,0.1)) + else + set_pin_data(IC_OUTPUT, 1, -273.15) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/input/oxygen_sensor + name = "integrated oxygen sensor" + desc = "A tiny oxygen sensor module similar to that found in a PDA atmosphere analyser." + icon_state = "medscan_adv" + complexity = 3 + inputs = list() + outputs = list( + "oxygen" = IC_PINTYPE_NUMBER + ) + activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) + power_draw_per_use = 20 + +/obj/item/integrated_circuit/input/oxygen_sensor/do_work() + var/turf/T = get_turf(src) + if(!istype(T)) //Invalid input + return + var/datum/gas_mixture/environment = T.return_air() + + var/total_moles = environment.total_moles() + + if (total_moles) + var/o2_level = environment.oxygen/total_moles + set_pin_data(IC_OUTPUT, 1, round(o2_level*100,0.1)) + else + set_pin_data(IC_OUTPUT, 1, 0) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/input/co2_sensor + name = "integrated co2 sensor" + desc = "A tiny carbon dioxide sensor module similar to that found in a PDA atmosphere analyser." + icon_state = "medscan_adv" + complexity = 3 + inputs = list() + outputs = list( + "co2" = IC_PINTYPE_NUMBER + ) + activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) + power_draw_per_use = 20 + +/obj/item/integrated_circuit/input/co2_sensor/do_work() + var/turf/T = get_turf(src) + if(!istype(T)) //Invalid input + return + var/datum/gas_mixture/environment = T.return_air() + + var/total_moles = environment.total_moles() + + if (total_moles) + var/co2_level = environment.carbon_dioxide/total_moles + set_pin_data(IC_OUTPUT, 1, round(co2_level*100,0.1)) + else + set_pin_data(IC_OUTPUT, 1, 0) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/input/nitrogen_sensor + name = "integrated nitrogen sensor" + desc = "A tiny nitrogen sensor module similar to that found in a PDA atmosphere analyser." + icon_state = "medscan_adv" + complexity = 3 + inputs = list() + outputs = list( + "nitrogen" = IC_PINTYPE_NUMBER + ) + activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) + power_draw_per_use = 20 + +/obj/item/integrated_circuit/input/nitrogen_sensor/do_work() + var/turf/T = get_turf(src) + if(!istype(T)) //Invalid input + return + var/datum/gas_mixture/environment = T.return_air() + + var/total_moles = environment.total_moles() + + if (total_moles) + var/n2_level = environment.nitrogen/total_moles + set_pin_data(IC_OUTPUT, 1, round(n2_level*100,0.1)) + else + set_pin_data(IC_OUTPUT, 1, 0) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/input/plasma_sensor + name = "integrated plasma sensor" + desc = "A tiny plasma gas sensor module similar to that found in a PDA atmosphere analyser." + icon_state = "medscan_adv" + complexity = 3 + inputs = list() + outputs = list( + "plasma" = IC_PINTYPE_NUMBER + ) + activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) + power_draw_per_use = 20 + +/obj/item/integrated_circuit/input/plasma_sensor/do_work() + var/turf/T = get_turf(src) + if(!istype(T)) //Invalid input + return + var/datum/gas_mixture/environment = T.return_air() + + var/total_moles = environment.total_moles() + + if (total_moles) + var/plasma_level = environment.toxins/total_moles + set_pin_data(IC_OUTPUT, 1, round(plasma_level*100,0.1)) + else + set_pin_data(IC_OUTPUT, 1, 0) + push_data() + activate_pin(2) diff --git a/code/modules/integrated_electronics/subtypes/lists.dm b/code/modules/integrated_electronics/subtypes/lists.dm index 84e0724bb933b..f2c9e52ccc1d9 100644 --- a/code/modules/integrated_electronics/subtypes/lists.dm +++ b/code/modules/integrated_electronics/subtypes/lists.dm @@ -52,6 +52,117 @@ push_data() activate_pin(2) +/obj/item/integrated_circuit/list/search + name = "search circuit" + desc = "This circuit will give index of desired element in the list." + extended_desc = "Search will start at 1 position and will return first matching position." + inputs = list( + "list" = IC_PINTYPE_LIST, + "item" = IC_PINTYPE_ANY + ) + outputs = list( + "index" = IC_PINTYPE_NUMBER + ) + icon_state = "addition" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/list/search/do_work() + var/list/input_list = get_pin_data(IC_INPUT, 1) + var/item = get_pin_data(IC_INPUT, 2) + set_pin_data(IC_OUTPUT, 1, input_list.Find(item)) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/list/at + name = "at circuit" + desc = "This circuit will pick an element from a list by index." + extended_desc = "If there is no element with such index, result will be null." + inputs = list( + "list" = IC_PINTYPE_LIST, + "index" = IC_PINTYPE_NUMBER + ) + outputs = list("item" = IC_PINTYPE_ANY) + icon_state = "addition" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/list/at/do_work() + var/list/input_list = get_pin_data(IC_INPUT, 1) + var/index = get_pin_data(IC_INPUT, 2) + var/item = input_list[index] + set_pin_data(IC_OUTPUT, 1, item) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/list/delete + name = "delete circuit" + desc = "This circuit will delete the element from a list by index." + extended_desc = "If there is no element with such index, result list will be unchanged." + inputs = list( + "list" = IC_PINTYPE_LIST, + "index" = IC_PINTYPE_NUMBER + ) + outputs = list( + "item" = IC_PINTYPE_LIST + ) + icon_state = "addition" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/list/delete/do_work() + var/list/input_list = get_pin_data(IC_INPUT, 1) + var/list/red_list = list() + var/index = get_pin_data(IC_INPUT, 2) + var/j = 0 + for(var/I in input_list) + j = j + 1 + if(j != index) + red_list.Add(I) + set_pin_data(IC_OUTPUT, 1, red_list) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/list/write + name = "write circuit" + desc = "This circuit will write element in list with given index." + extended_desc = "If there is no element with such index, it will give the same list, as before." + inputs = list( + "list" = IC_PINTYPE_LIST, + "index" = IC_PINTYPE_NUMBER, + "item" = IC_PINTYPE_ANY + ) + outputs = list( + "redacted list" = IC_PINTYPE_LIST + ) + icon_state = "addition" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/list/write/do_work() + var/list/input_list = get_pin_data(IC_INPUT, 1) + var/index = get_pin_data(IC_INPUT, 2) + var/item = get_pin_data(IC_INPUT, 3) + input_list[index] = item + set_pin_data(IC_OUTPUT, 1, input_list) + push_data() + activate_pin(2) + +obj/item/integrated_circuit/list/len + name = "len circuit" + desc = "This circuit will give length of the list." + inputs = list( + "list" = IC_PINTYPE_LIST, + ) + outputs = list( + "item" = IC_PINTYPE_NUMBER + ) + icon_state = "addition" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/list/len/do_work() + var/list/input_list = get_pin_data(IC_INPUT, 1) + set_pin_data(IC_OUTPUT, 1, input_list.len) + push_data() + activate_pin(2) + + /obj/item/integrated_circuit/list/jointext name = "join text circuit" desc = "This circuit will add all elements of a list into one string, seperated by a character." diff --git a/code/modules/integrated_electronics/subtypes/logic.dm b/code/modules/integrated_electronics/subtypes/logic.dm index 4bbffede35f0a..82667634a1c0c 100644 --- a/code/modules/integrated_electronics/subtypes/logic.dm +++ b/code/modules/integrated_electronics/subtypes/logic.dm @@ -55,6 +55,98 @@ /obj/item/integrated_circuit/logic/binary/equals/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) return A.data == B.data +/obj/item/integrated_circuit/logic/binary/jklatch + name = "JK latch" + desc = "This gate is a synchronysed JK latch." + icon_state = "jklatch" + inputs = list("J","K") + outputs = list("Q","!Q") + activators = list("pulse in C" = IC_PINTYPE_PULSE_IN, "pulse out Q" = IC_PINTYPE_PULSE_OUT, "pulse out !Q" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + var/lstate=FALSE + +/obj/item/integrated_circuit/logic/binary/jklatch/do_work() + pull_data() + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/Q = outputs[2] + if(A.data) + if(B.data) + lstate=!lstate + else + lstate = TRUE + else + if(B.data) + lstate=FALSE + O.data = lstate ? TRUE : FALSE + Q.data = !lstate ? TRUE : FALSE + if(get_pin_data(IC_OUTPUT, 1)) + activate_pin(2) + else + activate_pin(3) + push_data() + +/obj/item/integrated_circuit/logic/binary/rslatch + name = "RS latch" + desc = "This gate is synchronysed a RS latch. If both R and S are true, the state will not change." + icon_state = "sr_nor" + inputs = list("S","R") + outputs = list("Q","!Q") + activators = list("pulse in C" = IC_PINTYPE_PULSE_IN, "pulse out Q" = IC_PINTYPE_PULSE_OUT, "pulse out !Q" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + var/lstate=FALSE + +/obj/item/integrated_circuit/logic/binary/rslatch/do_work() + pull_data() + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/Q = outputs[2] + if(A.data) + if(!B.data) + lstate=TRUE + else + if(B.data) + lstate=FALSE + O.data = lstate ? TRUE : FALSE + Q.data = !lstate ? TRUE : FALSE + if(get_pin_data(IC_OUTPUT, 1)) + activate_pin(2) + else + activate_pin(3) + push_data() + +/obj/item/integrated_circuit/logic/binary/gdlatch + name = "gated D latch" + desc = "This gate is a synchronysed gated D latch." + icon_state = "gated_d" + inputs = list("D","E") + outputs = list("Q","!Q") + activators = list("pulse in C" = IC_PINTYPE_PULSE_IN, "pulse out Q" = IC_PINTYPE_PULSE_OUT, "pulse out !Q" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + var/lstate=FALSE + +/obj/item/integrated_circuit/logic/binary/gdlatch/do_work() + pull_data() + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/Q = outputs[2] + if(B.data) + if(A.data) + lstate=TRUE + else + lstate=FALSE + + O.data = lstate ? TRUE : FALSE + Q.data = !lstate ? TRUE : FALSE + if(get_pin_data(IC_OUTPUT, 1)) + activate_pin(2) + else + activate_pin(3) + push_data() + /obj/item/integrated_circuit/logic/binary/not_equals name = "not equal gate" desc = "This gate compares two values, and outputs the number one if both are different." diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm index 3cd5ad5b839fa..1b28c8f4a5c5e 100644 --- a/code/modules/integrated_electronics/subtypes/manipulation.dm +++ b/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -122,7 +122,7 @@ var/turf/T = get_turf(src) if(istype(loc, /obj/item/device/electronic_assembly)) var/obj/item/device/electronic_assembly/machine = loc - if(machine.anchored || machine.w_class >= 4) + if(!machine.can_move()) return if(machine.loc == T) // Check if we're held by someone. If the loc is the floor, we're not held. var/datum/integrated_io/wanted_dir = inputs[1] @@ -162,7 +162,7 @@ if(istype(G)) if(attached_grenade) to_chat(user, "There is already a grenade attached!") - else if(user.unEquip(G, force=1)) + else if(user.unEquip(G, 1)) user.visible_message("\The [user] attaches \a [G] to \the [src]!", "You attach \the [G] to \the [src].") attach_grenade(G) G.forceMove(src) diff --git a/code/modules/integrated_electronics/subtypes/memory.dm b/code/modules/integrated_electronics/subtypes/memory.dm index b2b94a358831e..0d9e2962453e2 100644 --- a/code/modules/integrated_electronics/subtypes/memory.dm +++ b/code/modules/integrated_electronics/subtypes/memory.dm @@ -1,7 +1,7 @@ /obj/item/integrated_circuit/memory name = "memory chip" desc = "This tiny chip can store one piece of data." - icon_state = "memory" + icon_state = "memory1" complexity = 1 inputs = list() outputs = list() @@ -40,8 +40,15 @@ O.push_data() activate_pin(2) +/obj/item/integrated_circuit/memory/tiny + name = "small memory circuit" + desc = "This circuit can store two pieces of data." + icon_state = "memory2" + power_draw_per_use = 2 + number_of_pins = 2 + /obj/item/integrated_circuit/memory/medium - name = "memory circuit" + name = "medium memory circuit" desc = "This circuit can store four pieces of data." icon_state = "memory4" power_draw_per_use = 2 diff --git a/code/modules/integrated_electronics/subtypes/power.dm b/code/modules/integrated_electronics/subtypes/power.dm index 15e3cebf0d045..339448a12b9a7 100644 --- a/code/modules/integrated_electronics/subtypes/power.dm +++ b/code/modules/integrated_electronics/subtypes/power.dm @@ -37,9 +37,7 @@ amount_to_move = 20000 /obj/item/integrated_circuit/power/transmitter/do_work() - set_pin_data(IC_OUTPUT, 1, null) - set_pin_data(IC_OUTPUT, 2, null) - set_pin_data(IC_OUTPUT, 3, null) + var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) if(AM) if(!assembly) @@ -72,7 +70,15 @@ set_pin_data(IC_OUTPUT, 2, cell.maxcharge) set_pin_data(IC_OUTPUT, 3, cell.percent()) activate_pin(2) + push_data() return TRUE + else + set_pin_data(IC_OUTPUT, 1, null) + set_pin_data(IC_OUTPUT, 2, null) + set_pin_data(IC_OUTPUT, 3, null) + activate_pin(2) + push_data() + return FALSE return FALSE /obj/item/integrated_circuit/power/transmitter/large/do_work() diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm index 960eb5d8747fd..aa12f7dcceea0 100644 --- a/code/modules/integrated_electronics/subtypes/reagents.dm +++ b/code/modules/integrated_electronics/subtypes/reagents.dm @@ -1,6 +1,7 @@ /obj/item/integrated_circuit/reagent category_text = "Reagent" var/volume = 0 + unacidable = 1 origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) /obj/item/integrated_circuit/reagent/New() @@ -18,13 +19,23 @@ complexity = 20 cooldown_per_use = 30 SECONDS inputs = list() - outputs = list() - activators = list("create smoke" = IC_PINTYPE_PULSE_IN) + outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF) + activators = list("create smoke" = IC_PINTYPE_PULSE_IN,"on smoked" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 3) volume = 100 power_draw_per_use = 20 +/obj/item/integrated_circuit/reagent/smoke/on_reagent_change() + set_pin_data(IC_OUTPUT, 1, reagents.total_volume) + push_data() + + +/obj/item/integrated_circuit/reagent/smoke/interact(mob/user) + set_pin_data(IC_OUTPUT, 2, weakref(src)) + push_data() + ..() + /obj/item/integrated_circuit/reagent/smoke/do_work() playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3) var/datum/effect/effect/system/smoke_spread/chem/smoke_system = new() @@ -33,6 +44,7 @@ for(var/i = 1 to 8) smoke_system.start() reagents.clear_reagents() + activate_pin(2) /obj/item/integrated_circuit/reagent/injector name = "integrated hypo-injector" @@ -45,40 +57,121 @@ cooldown_per_use = 6 SECONDS inputs = list("target" = IC_PINTYPE_REF, "injection amount" = IC_PINTYPE_NUMBER) inputs_default = list("2" = 5) - outputs = list() - activators = list("inject" = IC_PINTYPE_PULSE_IN) + outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF) + activators = list("inject" = IC_PINTYPE_PULSE_IN, "on injected" = IC_PINTYPE_PULSE_OUT, "on fail" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH volume = 30 power_draw_per_use = 15 + var/direc = 1 + var/transfer_amount = 10 + +/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() + set_pin_data(IC_OUTPUT, 1, reagents.total_volume) + push_data() + +/obj/item/integrated_circuit/reagent/injector/on_data_written() + var/new_amount = get_pin_data(IC_INPUT, 2) + if(new_amount < 0) + new_amount = -new_amount + direc = 0 + else + direc = 1 + if(isnum(new_amount)) + new_amount = Clamp(new_amount, 0, volume) + transfer_amount = new_amount -/obj/item/integrated_circuit/reagent/injector/proc/inject_amount() - var/amount = get_pin_data(IC_INPUT, 2) - if(isnum(amount)) - return Clamp(amount, 0, 30) /obj/item/integrated_circuit/reagent/injector/do_work() set waitfor = 0 // Don't sleep in a proc that is called by a processor without this set, otherwise it'll delay the entire thing - var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) if(!istype(AM)) //Invalid input + activate_pin(3) return - if(!reagents.total_volume) // Empty - return - if(AM.can_be_injected_by(src)) - if(isliving(AM)) - var/mob/living/L = AM - var/turf/T = get_turf(AM) - T.visible_message("[src] is trying to inject [L]!") - sleep(3 SECONDS) - if(!L.can_be_injected_by(src)) + + if(direc == 1) + + if(!istype(AM)) //Invalid input + activate_pin(3) + return + if(!reagents.total_volume) // Empty + activate_pin(3) + return + if(AM.can_be_injected_by(src)) + if(isliving(AM)) + var/mob/living/L = AM + var/turf/T = get_turf(AM) + T.visible_message("[src] is trying to inject [L]!") + sleep(3 SECONDS) + if(!L.can_be_injected_by(src)) + activate_pin(3) + return + var/contained = reagents.get_reagents() + var/trans = reagents.trans_to(L, transfer_amount) + message_admins("[src] injected \the [L] with [trans]u of [contained].") + to_chat(AM, "You feel a tiny prick!") + visible_message("[src] injects [L]!") + else + reagents.trans_to(AM, transfer_amount) + else + + if(reagents.total_volume >= volume) // Full + activate_pin(3) + return + var/obj/target = AM + if(!target.reagents) + activate_pin(3) + return + var/turf/TS = get_turf(src) + var/turf/TT = get_turf(AM) + if(!TS.Adjacent(TT)) + activate_pin(3) + return + var/tramount = Clamp(min(transfer_amount, reagents.maximum_volume - reagents.total_volume), 0, reagents.maximum_volume) + if(ismob(target))//Blood! + if(istype(target, /mob/living/carbon)) + var/mob/living/carbon/T = target + if(!T.dna) + if(T.reagents.trans_to(src, tramount)) + activate_pin(2) + else + activate_pin(3) + return + if(NOCLONE in T.mutations) //target done been et, no more blood in him + if(T.reagents.trans_to(src, tramount)) + activate_pin(2) + else + activate_pin(3) + return + return + var/datum/reagent/B + B = T.take_blood(src,tramount) + if (B) + reagents.reagent_list |= B + reagents.update_total() + on_reagent_change() + reagents.handle_reactions() + B = null + visible_message( "Machine takes a blood sample from [target].") + else + activate_pin(3) return - var/contained = reagents.get_reagents() - var/trans = reagents.trans_to(L, inject_amount()) - message_admins("[src] injected \the [L] with [trans]u of [contained].") - to_chat(AM, "You feel a tiny prick!") - visible_message("[src] injects [L]!") - else - reagents.trans_to(AM, inject_amount()) + + else //if not mob + if(!target.reagents.total_volume) + visible_message( "[target] is empty.") + activate_pin(3) + return + target.reagents.trans_to(src, tramount) + activate_pin(2) + + + /obj/item/integrated_circuit/reagent/pump name = "reagent pump" @@ -96,11 +189,17 @@ spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) var/transfer_amount = 10 + var/direc = 1 power_draw_per_use = 10 /obj/item/integrated_circuit/reagent/pump/on_data_written() var/new_amount = get_pin_data(IC_INPUT, 3) - if(!isnull(new_amount)) + if(new_amount < 0) + new_amount = -new_amount + direc = 0 + else + direc = 1 + if(isnum(new_amount)) new_amount = Clamp(new_amount, 0, 50) transfer_amount = new_amount @@ -111,17 +210,23 @@ if(!istype(source) || !istype(target)) //Invalid input return var/turf/T = get_turf(src) - if(source.Adjacent(T) && target.Adjacent(T)) + var/turf/TS = get_turf(source) + var/turf/TT = get_turf(target) + if(TS.Adjacent(T) && TT.Adjacent(T)) if(!source.reagents || !target.reagents) return if(ismob(source) || ismob(target)) return if(!source.is_open_container() || !target.is_open_container()) return - if(!target.reagents.get_free_space()) - return - - source.reagents.trans_to(target, transfer_amount) + if(direc) + if(!target.reagents.get_free_space()) + return + source.reagents.trans_to(target, transfer_amount) + else + if(!source.reagents.get_free_space()) + return + target.reagents.trans_to(source, transfer_amount) activate_pin(2) /obj/item/integrated_circuit/reagent/storage @@ -132,12 +237,18 @@ flags = OPENCONTAINER complexity = 4 inputs = list() - outputs = list("volume used" = IC_PINTYPE_NUMBER) + outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF) activators = list() 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/interact(mob/user) + set_pin_data(IC_OUTPUT, 2, weakref(src)) + push_data() + ..() + /obj/item/integrated_circuit/reagent/storage/on_reagent_change() set_pin_data(IC_OUTPUT, 1, reagents.total_volume) push_data() @@ -150,4 +261,95 @@ flags = OPENCONTAINER | NOREACT complexity = 8 spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_MATERIALS = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) \ No newline at end of file + origin_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) + +/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." + icon_state = "reagent_storage_big" + extended_desc = "This is effectively an internal beaker." + flags = OPENCONTAINER + complexity = 16 + volume = 180 + spawn_flags = IC_SPAWN_RESEARCH + origin_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) + +/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." + icon_state = "reagent_scan" + extended_desc = "Mostly useful for reagent filter." + flags = OPENCONTAINER + complexity = 8 + outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF,"list of reagents" = IC_PINTYPE_LIST) + activators = list("scan" = IC_PINTYPE_PULSE_IN) + spawn_flags = IC_SPAWN_RESEARCH + origin_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) + +/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/filter + name = "reagent filter" + desc = "Filtering liquids by list of desired or unwanted reagents." + icon_state = "reagent_filter" + extended_desc = "This is a filter which will move liquids from the source ref to the target ref. \ + It will move all reagents, except list, given in fourth pin if amount value is positive.\ + Or it will move only desired reagents if amount is negative, The third pin determines \ + how much reagent is moved per pulse, between 0 and 50. Amount is given for each separate reagent." + flags = OPENCONTAINER + complexity = 8 + inputs = list("source" = IC_PINTYPE_REF, "target" = IC_PINTYPE_REF, "injection amount" = IC_PINTYPE_NUMBER, "list of reagents" = IC_PINTYPE_LIST) + inputs_default = list("3" = 5) + outputs = list() + activators = list("transfer reagents" = IC_PINTYPE_PULSE_IN, "on transfer" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) + var/transfer_amount = 10 + var/direc = 1 + power_draw_per_use = 10 + +/obj/item/integrated_circuit/reagent/filter/on_data_written() + var/new_amount = get_pin_data(IC_INPUT, 3) + if(new_amount < 0) + new_amount = -new_amount + direc = 0 + else + direc = 1 + if(isnum(new_amount)) + new_amount = Clamp(new_amount, 0, 50) + transfer_amount = new_amount + +/obj/item/integrated_circuit/reagent/filter/do_work() + var/atom/movable/source = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) + var/atom/movable/target = get_pin_data_as_type(IC_INPUT, 2, /atom/movable) + var/list/demand = get_pin_data(IC_INPUT, 4) + if(!istype(source) || !istype(target)) //Invalid input + return + var/turf/T = get_turf(src) + if(source.Adjacent(T) && target.Adjacent(T)) + if(!source.reagents || !target.reagents) + return + if(ismob(source) || ismob(target)) + return + if(!source.is_open_container() || !target.is_open_container()) + return + if(!target.reagents.get_free_space()) + return + for(var/datum/reagent/G in source.reagents.reagent_list) + if (!direc) + if(G.id in demand) + source.reagents.trans_id_to(target, G.id, transfer_amount) + else + if(!(G.id in demand)) + source.reagents.trans_id_to(target, G.id, transfer_amount) + activate_pin(2) + push_data() + + + diff --git a/code/modules/integrated_electronics/subtypes/smart.dm b/code/modules/integrated_electronics/subtypes/smart.dm index 14aa9b6eab49e..0e16cd40794ba 100644 --- a/code/modules/integrated_electronics/subtypes/smart.dm +++ b/code/modules/integrated_electronics/subtypes/smart.dm @@ -25,8 +25,10 @@ if(!A) return if(!(A in view(get_turf(src)))) + push_data() return // Can't see the target. - var/desired_dir = get_dir(get_turf(src), A) + var/desired_dir = get_dir(get_turf(src), get_turf(A)) set_pin_data(IC_OUTPUT, 1, desired_dir) - push_data() \ No newline at end of file + push_data() + activate_pin(2) \ No newline at end of file diff --git a/config/admins.txt b/config/admins.txt index 6059a09aa5b80..a6c13e1cbf2c6 100644 --- a/config/admins.txt +++ b/config/admins.txt @@ -13,5 +13,4 @@ Kubbrz6 = Midimin M00nm4nhere = Midimin Roleplay Rascal = Admin SpaghettiScience = Midimin -Memeoo = Trial Admin -Stakks = Host \ No newline at end of file +Memeoo = Trial Admin \ No newline at end of file diff --git a/icons/obj/assemblies/electronic_setups.dmi b/icons/obj/assemblies/electronic_setups.dmi new file mode 100644 index 0000000000000000000000000000000000000000..f18018c0aec049c54e4dc8fdf8079be0f9a26508 GIT binary patch literal 16484 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%0Aa3;Pa&IU(?slP5lOlIF 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 UK{)d!Egqn+ZLC$P;Sl+M03(fh>;M1& literal 0 HcmV?d00001 diff --git a/icons/obj/assemblies/electronic_tools.dmi b/icons/obj/assemblies/electronic_tools.dmi new file mode 100644 index 0000000000000000000000000000000000000000..975f2fc9a812829918c18a4602e109bfd00a69f0 GIT binary patch literal 2390 zcmZ8jdoE6!nsEH~VL2&e9JQ#m}% zv!KKP-#`E>7>&{#7E^;l579;G~AH!sKKqhO>@E`A(SZ*_M$wGLV-y@sbl`l>^&cSpPmz1nle zb>A(AULZ+O;`6>-3y~a9UhkRD(5u!G$3M)0&~_yxTaYsx;mR-elB;`N2#imH&W${f zUj1V5UU`P+sRRR(0MGE#C*2w5?|D&wZe2^Emv`cxq*|0v_iay6Sp@#Ps?nL*4AFax zSAO7s{lv+7F*j&@Erj=A#D-U?eGhCo^tH(R+`^;g?gJAopYp2VQ!_^Ui+G3osn10K zp!0)|r&~}8Ls}dYJmFw+O&aBMy`rmDKktv&ChJN4__8$il3E>VbvU}na2{5gHFq0J z@MX*OYQNrZmFIom>vrxx1a&wQ$|4@_J=C1msYY2JvCIv|FZ`Ou{5;pvyR83b;_qFu>Ny4cbY^BlI4R3_Z<s#gravKUGq;1{k5=uBlXLQ5nd}6Lgja1k{ zW#{a%Ag1?=<32s#;-%`e_sEX%!}fGr6Sz;~R07dP0&a5fJM=eUTsR!o$O4B@DJlF} zF*UsB2G4gQHy26(&BOS<@Dm}~C&b%``18K~5Cm+~Y1)Q=+7yr^_<-i~L_lA#HYc@Z zKRq}lBWp@WsB;1~&F+F>oUf(P*KDT6b(K?y-?V;PQ+!yTZ-suKeQ?t$KkLQc&=attgCuvhqvwDk>6WPMk*xHq>8W+LDW^lOc=dc<0G5txX3YS zypBDB(W-F;!faP1B2ppVub8Pq|4}*0RIJDt&9}qVTQj>>ekL8UH+{CN`J43Z)%rFT zi}!00r0w*H`J180fx*(RV8k9=XdGcYol|`rg`Crg_U=3H=DxrU6h^X3 z9L%cXd{+z9apk%?F75{bP@7 zDe3+|b_;ZO{yVru*!|bA7fHZ01Jh`e5gehL?N}bUR(4ZUfMm97kL^Gb(C97Yfm-qQ zHj$|>r;s;DJZ6zmt<4G!y~LH;2f$jr?g(1(_(|lp{=tE?(UHXk!Nbd22C@TpOHWZR zH=m=l;t4qI=h}Y?C_0`sjUB12UC^1g6Ok?h7$mXH=I!iQY35)Y-?_fH?H5KS_szIf z)g-9n&b~`_#*!%lf$%_Jhg2!!__&F|7*aZh*}tl4wL5aNX?0Z>mkw+?N769hTN6{6 z!rMyaCn@}G*Q5C@4dKo_nRW~<``x(7N7RZzlxx*Xzg(az)^}VTW_wdvWoLDcIUUsK zTvU$YoSWzeP{js#V_#ADqxu;aeA%L~q4}9+5^37Ds8UIegSWAbU0jni;YU7(AO438 z9+pe3V+aY0KjCYZgk+jA>7peQ%QqJ;hU0)Z%;08PL5of(s9xnPS*nPzTTaU=Jf|dQ zo3)NZy(R_~>lE53__31Ao6@nRKPx?}N}mUR2!1`c@JKmF7HPj;lU-M=ukKv&Tv&>W za}3-eml&20DP;7M4bgh{!IUO7aL6nUbE|n|e=KMbac~N96GKDDDVKgMiUq-`DL~%O z>oSGgpjp;iP=Nj3-#x0v4Olt`@6{f~N8%%UV{<|3+4)n8?;~LD#oxUG>uQ|WDWIV{ z)beN!LXu579xIe-4?itV-?2b%Qn?KI$x$k>y<4c}JMG=ov;)b|tg$Jm>NtC73F%~U zf#&y%gicpqOx4VxdE?F8ZO9lXL8)AAp{sN99mc68?>%X6FmeLN$X_AT6zu{2(AwX! fB+Z>cST}w)W$f+pr=d!-QUE?)zMeJi5gC6061u)b literal 0 HcmV?d00001 diff --git a/icons/obj/electronic_assemblies.dmi b/icons/obj/electronic_assemblies.dmi index 6ad2b65b2f92eb46c37a5abc9da34d2c515f70dd..5799d85866fd843f54fa5fe141db13785819581f 100644 GIT binary patch literal 39706 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

1t4|ochsc``Ej3^(* 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