From 97ebf0924d157a78196a9994c7ca69dfb50873ab Mon Sep 17 00:00:00 2001 From: Neerti Date: Mon, 2 Jan 2017 08:03:30 -0500 Subject: [PATCH] Permanent Revolution Update --- code/__defines/unit_tests.dm | 1 + .../objects/items/weapons/implants/implant.dm | 12 ++ .../items/weapons/implants/implantcircuits.dm | 44 +++++ .../integrated_electronics/_defines.dm | 41 +++- .../integrated_electronics/arithmetic.dm | 52 ++++- .../integrated_electronics/assemblies.dm | 56 ++++-- .../integrated_electronics/converters.dm | 70 ++++++- .../integrated_electronics/coordinate.dm | 54 ----- .../integrated_electronics/data_transfer.dm | 5 + .../integrated_electronics/input_output.dm | 105 +++++++++- code/modules/integrated_electronics/logic.dm | 5 + .../integrated_electronics/manipulation.dm | 4 +- code/modules/integrated_electronics/memory.dm | 2 +- code/modules/integrated_electronics/time.dm | 4 +- code/modules/integrated_electronics/tools.dm | 177 ++++++++++++++++- code/modules/integrated_electronics/trig.dm | 135 +++++++++++++ code/modules/research/designs.dm | 12 ++ .../integrated_circuits/arithmetic.dm | 174 ++++++++++++++++ .../integrated_circuits/circuits.dm | 73 +++++++ .../integrated_circuits/converter.dm | 52 +++++ .../integrated_circuits/data_transfer.dm | 17 ++ code/unit_tests/integrated_circuits/logic.dm | 186 ++++++++++++++++++ .../unit_tests/integrated_circuits/prefabs.dm | 55 ++++++ code/unit_tests/integrated_circuits/trig.dm | 33 ++++ code/unit_tests/unit_test.dm | 11 +- icons/obj/electronic_assemblies.dmi | Bin 25382 -> 30877 bytes icons/obj/library.dmi | Bin 28564 -> 28832 bytes polaris.dme | 9 +- 28 files changed, 1296 insertions(+), 93 deletions(-) create mode 100644 code/game/objects/items/weapons/implants/implantcircuits.dm delete mode 100644 code/modules/integrated_electronics/coordinate.dm create mode 100644 code/modules/integrated_electronics/trig.dm create mode 100644 code/unit_tests/integrated_circuits/arithmetic.dm create mode 100644 code/unit_tests/integrated_circuits/circuits.dm create mode 100644 code/unit_tests/integrated_circuits/converter.dm create mode 100644 code/unit_tests/integrated_circuits/data_transfer.dm create mode 100644 code/unit_tests/integrated_circuits/logic.dm create mode 100644 code/unit_tests/integrated_circuits/prefabs.dm create mode 100644 code/unit_tests/integrated_circuits/trig.dm diff --git a/code/__defines/unit_tests.dm b/code/__defines/unit_tests.dm index 478c75fdb25..840673221ce 100644 --- a/code/__defines/unit_tests.dm +++ b/code/__defines/unit_tests.dm @@ -1,4 +1,5 @@ #define ASCII_ESC ascii2text(27) #define ASCII_RED "[ASCII_ESC]\[31m" #define ASCII_GREEN "[ASCII_ESC]\[32m" +#define ASCII_YELLOW "[ASCII_ESC]\[33m" #define ASCII_RESET "[ASCII_ESC]\[0m" \ No newline at end of file diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index 17d3e32f92c..eec5638523b 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -54,6 +54,18 @@ part.implants.Remove(src) ..() +/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.drop_from_inventory(src) + forceMove(implanter) + implanter.imp = src + implanter.update() + else + ..() + /obj/item/weapon/implant/tracking name = "tracking implant" desc = "Track with this." 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 00000000000..cf55cbd7067 --- /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/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 de8f00dddbc..d9daa035d54 100644 --- a/code/modules/integrated_electronics/_defines.dm +++ b/code/modules/integrated_electronics/_defines.dm @@ -29,6 +29,7 @@ var/list/all_integrated_circuits = list() var/cooldown_per_use = 1 SECOND 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) ..() @@ -71,7 +72,8 @@ var/list/all_integrated_circuits = list() /obj/item/integrated_circuit/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) @@ -112,6 +114,14 @@ var/list/all_integrated_circuits = list() if(!CanInteract(user, physical_state)) 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 += "
" @@ -122,9 +132,12 @@ var/list/all_integrated_circuits = list() HTML += "\[Remove\]
" HTML += "" - HTML += "" - HTML += "" - HTML += "" + //HTML += "" + //HTML += "" + //HTML += "" + HTML += "" + HTML += "" + HTML += "" HTML += "" var/column_width = 3 @@ -196,11 +209,16 @@ var/list/all_integrated_circuits = list() 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]") @@ -229,6 +247,10 @@ var/list/all_integrated_circuits = list() 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() @@ -267,7 +289,7 @@ var/list/all_integrated_circuits = list() . = ..() /datum/integrated_io/nano_host() - return holder + return holder.nano_host() /datum/integrated_io/proc/data_as_type(var/as_type) @@ -285,7 +307,8 @@ var/list/all_integrated_circuits = list() 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 00676e778a9..37eabf20270 100644 --- a/code/modules/integrated_electronics/arithmetic.dm +++ b/code/modules/integrated_electronics/arithmetic.dm @@ -5,6 +5,11 @@ outputs = list("result") activators = list("compute") category_text = "Arithmetic" + autopulse = 1 + +/obj/item/integrated_circuit/arithmetic/on_data_written() + if(autopulse == 1) + check_then_do_work() // +Adding+ // @@ -195,8 +200,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 @@ -260,4 +265,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 3b9e7aab069..ff994aa43c4 100644 --- a/code/modules/integrated_electronics/assemblies.dm +++ b/code/modules/integrated_electronics/assemblies.dm @@ -1,33 +1,59 @@ +#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 + w_class = ITEMSIZE_SMALL icon = 'icons/obj/electronic_assemblies.dmi' icon_state = "setup_small" - var/max_components = 10 - var/max_complexity = 40 + 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 = 80 + w_class = ITEMSIZE_NORMAL + max_components = IC_COMPONENTS_BASE * 2 + max_complexity = IC_COMPLEXITY_BASE * 2 /obj/item/device/electronic_assembly/large name = "electronic machine" icon_state = "setup_large" - w_class = 4 - max_components = 30 - max_complexity = 120 + w_class = ITEMSIZE_LARGE + 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 + w_class = ITEMSIZE_NORMAL + 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 = ITEMSIZE_TINY + 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/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, physical_state)) @@ -79,6 +105,12 @@ to_chat(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" diff --git a/code/modules/integrated_electronics/converters.dm b/code/modules/integrated_electronics/converters.dm index b039299a553..96494ba469f 100644 --- a/code/modules/integrated_electronics/converters.dm +++ b/code/modules/integrated_electronics/converters.dm @@ -5,6 +5,11 @@ outputs = list("output") activators = list("convert") 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" @@ -104,4 +109,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/coordinate.dm b/code/modules/integrated_electronics/coordinate.dm deleted file mode 100644 index 0941c290f4e..00000000000 --- a/code/modules/integrated_electronics/coordinate.dm +++ /dev/null @@ -1,54 +0,0 @@ -//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." - 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 - category_text = "Coords" - -/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 = 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 - 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 - category_text = "Coords" - -/obj/item/integrated_circuit/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 bf4ddf4b6f5..7e37995df5b 100644 --- a/code/modules/integrated_electronics/data_transfer.dm +++ b/code/modules/integrated_electronics/data_transfer.dm @@ -1,5 +1,10 @@ /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" diff --git a/code/modules/integrated_electronics/input_output.dm b/code/modules/integrated_electronics/input_output.dm index 5bb3ea6aec0..296104d9383 100644 --- a/code/modules/integrated_electronics/input_output.dm +++ b/code/modules/integrated_electronics/input_output.dm @@ -321,11 +321,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" + 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_talk(mob/living/M, msg, var/verb="says", datum/language/speaking=null) + var/datum/integrated_io/V = outputs[1] + var/datum/integrated_io/O = outputs[2] + var/datum/integrated_io/A = activators[1] + if(M && msg) + if(speaking) + if(!speaking.machine_understands) + msg = speaking.scramble(msg) + V.data = M.GetVoice() + O.data = msg + 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") @@ -343,6 +406,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." @@ -415,6 +500,24 @@ activators = list("play sound") 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") + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/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() ..() extended_desc = list() diff --git a/code/modules/integrated_electronics/logic.dm b/code/modules/integrated_electronics/logic.dm index 6d53f6aae7c..d477be3cbe1 100644 --- a/code/modules/integrated_electronics/logic.dm +++ b/code/modules/integrated_electronics/logic.dm @@ -6,6 +6,11 @@ outputs = list("result") activators = list("compare", "on true result") category_text = "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] diff --git a/code/modules/integrated_electronics/manipulation.dm b/code/modules/integrated_electronics/manipulation.dm index 524c060d2da..f49b96d16c6 100644 --- a/code/modules/integrated_electronics/manipulation.dm +++ b/code/modules/integrated_electronics/manipulation.dm @@ -105,7 +105,7 @@ 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. It should be noted that heavy machines will be unable to move." + 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." complexity = 20 inputs = list("dir num") outputs = list() @@ -117,7 +117,7 @@ var/turf/T = get_turf(src) if(T && istype(loc, /obj/item/device/electronic_assembly)) var/obj/item/device/electronic_assembly/machine = loc - if(machine.anchored || machine.w_class >= ITEMSIZE_LARGE) + if(machine.anchored || !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] diff --git a/code/modules/integrated_electronics/memory.dm b/code/modules/integrated_electronics/memory.dm index edf263dd964..f9cd109dce5 100644 --- a/code/modules/integrated_electronics/memory.dm +++ b/code/modules/integrated_electronics/memory.dm @@ -61,7 +61,7 @@ "output pin 6", "output pin 7", "output pin 8") - spawn_flags = IC_SPAWN_RESEARCH + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) /obj/item/integrated_circuit/memory/huge diff --git a/code/modules/integrated_electronics/time.dm b/code/modules/integrated_electronics/time.dm index 8a6a0c9c04b..50bcc5e3867 100644 --- a/code/modules/integrated_electronics/time.dm +++ b/code/modules/integrated_electronics/time.dm @@ -44,7 +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_RESEARCH + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/time/delay/tenth_sec name = "tenth-sec delay circuit" @@ -52,7 +52,7 @@ 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_RESEARCH + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/time/delay/custom name = "custom delay circuit" diff --git a/code/modules/integrated_electronics/tools.dm b/code/modules/integrated_electronics/tools.dm index 1d3b2cf4a9b..6c76b9b4ffe 100644 --- a/code/modules/integrated_electronics/tools.dm +++ b/code/modules/integrated_electronics/tools.dm @@ -164,15 +164,33 @@ icon = 'icons/obj/electronic_assemblies.dmi' icon_state = "circuit_kit" w_class = 3 - display_contents_with_number = 1 + 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() ..() 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) +// 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) new /obj/item/device/electronic_assembly(src) new /obj/item/device/integrated_electronics/wirer(src) @@ -193,4 +211,151 @@ new /obj/item/device/integrated_electronics/debugger(src) new /obj/item/weapon/crowbar(src) new /obj/item/weapon/screwdriver(src) - make_exact_fit() \ No newline at end of file + 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) + +/obj/item/weapon/storage/bag/circuits/mini/arithmetic + name = "arithmetic circuit box" + desc = "Warning: Contains math." + icon_state = "box_arithmetic" + +/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" + +/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/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/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 00000000000..e8e2e09ca9e --- /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/research/designs.dm b/code/modules/research/designs.dm index b2f6a9c4474..8e91f3f06af 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -1557,6 +1557,7 @@ CIRCUITS BELOW 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 + sort_string = "VCAAB" /datum/design/item/custom_circuit_assembly/drone name = "Drone custom assembly" @@ -1565,6 +1566,7 @@ CIRCUITS BELOW req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 4, TECH_POWER = 4) materials = list(DEFAULT_WALL_MATERIAL = 30000) build_path = /obj/item/device/electronic_assembly/drone + sort_string = "VCAAC" /datum/design/item/custom_circuit_assembly/large name = "Large custom assembly" @@ -1573,6 +1575,16 @@ CIRCUITS BELOW 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 + sort_string = "VCAAD" + +/datum/design/item/custom_circuit_assembly/implant + name = "Implant custom assembly" + desc = "An customizable assembly for very small devices, implanted into living entities." + id = "assembly-implant" + req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_POWER = 3, TECH_BIO = 5) + materials = list(DEFAULT_WALL_MATERIAL = 2000) + build_path = /obj/item/weapon/implant/integrated_circuit + sort_string = "VCAAE" /* Uncomment if someone makes these buildable /datum/design/circuit/general_alert diff --git a/code/unit_tests/integrated_circuits/arithmetic.dm b/code/unit_tests/integrated_circuits/arithmetic.dm new file mode 100644 index 00000000000..1e62f6e7b71 --- /dev/null +++ b/code/unit_tests/integrated_circuits/arithmetic.dm @@ -0,0 +1,174 @@ +/datum/unit_test/integrated_circuits/additon_1 + name = "Arithmetic Circuits: Addition - Basic" + circuit_type = /obj/item/integrated_circuit/arithmetic/addition + inputs_to_give = list(25, 75) + expected_outputs = list(100) + +/datum/unit_test/integrated_circuits/additon_2 + name = "Arithmetic Circuits: Addition - Multiple" + circuit_type = /obj/item/integrated_circuit/arithmetic/addition + inputs_to_give = list(7, 5, 3, 26, 974, -51, 77, 0) + expected_outputs = list(1041) + + + +/datum/unit_test/integrated_circuits/subtraction_1 + name = "Arithmetic Circuits: Subtraction - Basic" + circuit_type = /obj/item/integrated_circuit/arithmetic/subtraction + inputs_to_give = list(20, 15) + expected_outputs = list(5) + +/datum/unit_test/integrated_circuits/subtraction_2 + name = "Arithmetic Circuits: Subtraction - Multiple" + circuit_type = /obj/item/integrated_circuit/arithmetic/subtraction + inputs_to_give = list(5, 50, 30) + expected_outputs = list(-75) + + + +/datum/unit_test/integrated_circuits/multiplication_1 + name = "Arithmetic Circuits: Multiplication - Basic" + circuit_type = /obj/item/integrated_circuit/arithmetic/multiplication + inputs_to_give = list(5, 20) + expected_outputs = list(100) + +/datum/unit_test/integrated_circuits/multiplication_2 + name = "Arithmetic Circuits: Multiplication - Multiple" + circuit_type = /obj/item/integrated_circuit/arithmetic/multiplication + inputs_to_give = list(2, 10, 20) + expected_outputs = list(400) + +/datum/unit_test/integrated_circuits/multiplication_3 + name = "Arithmetic Circuits: Multiplication - Decimal" + circuit_type = /obj/item/integrated_circuit/arithmetic/multiplication + inputs_to_give = list(100, 0.5) + expected_outputs = list(50) + + +/datum/unit_test/integrated_circuits/division_1 + name = "Arithmetic Circuits: Division - Basic" + circuit_type = /obj/item/integrated_circuit/arithmetic/division + inputs_to_give = list(100, 5) + expected_outputs = list(20) + +/datum/unit_test/integrated_circuits/division_2 + name = "Arithmetic Circuits: Division - Multiple" + circuit_type = /obj/item/integrated_circuit/arithmetic/division + inputs_to_give = list(500, 100, 10) + expected_outputs = list(0.5) + +/datum/unit_test/integrated_circuits/division_3 + name = "Arithmetic Circuits: Division - Decimal" + circuit_type = /obj/item/integrated_circuit/arithmetic/division + inputs_to_give = list(100, 0.5) + expected_outputs = list(200) + + + +/datum/unit_test/integrated_circuits/exponent_1 + name = "Arithmetic Circuits: Exponent - Basic" + circuit_type = /obj/item/integrated_circuit/arithmetic/exponent + inputs_to_give = list(20, 2) + expected_outputs = list(400) + +/datum/unit_test/integrated_circuits/exponent_2 + name = "Arithmetic Circuits: Exponent - Powers" + circuit_type = /obj/item/integrated_circuit/arithmetic/exponent + inputs_to_give = list(5, 4) + expected_outputs = list(625) + + + +/datum/unit_test/integrated_circuits/sign_1 + name = "Arithmetic Circuits: Sign - Positive" + circuit_type = /obj/item/integrated_circuit/arithmetic/sign + inputs_to_give = list(5) + expected_outputs = list(1) + +/datum/unit_test/integrated_circuits/sign_2 + name = "Arithmetic Circuits: Sign - Negative" + circuit_type = /obj/item/integrated_circuit/arithmetic/sign + inputs_to_give = list(-500) + expected_outputs = list(-1) + +/datum/unit_test/integrated_circuits/sign_3 + name = "Arithmetic Circuits: Sign - Zero" + circuit_type = /obj/item/integrated_circuit/arithmetic/sign + inputs_to_give = list(0) + expected_outputs = list(0) + + + +/datum/unit_test/integrated_circuits/round_1 + name = "Arithmetic Circuits: Round - Basic" + circuit_type = /obj/item/integrated_circuit/arithmetic/round + inputs_to_give = list(4.25) + expected_outputs = list(4) + +/datum/unit_test/integrated_circuits/round_2 + name = "Arithmetic Circuits: Round - Floor" + circuit_type = /obj/item/integrated_circuit/arithmetic/round + inputs_to_give = list(8.95) + expected_outputs = list(8) + +/datum/unit_test/integrated_circuits/round_3 + name = "Arithmetic Circuits: Round - Round to X" + circuit_type = /obj/item/integrated_circuit/arithmetic/round + inputs_to_give = list(45.68, 0.1) + expected_outputs = list(45.7) + + + +/datum/unit_test/integrated_circuits/absolute_1 + name = "Arithmetic Circuits: Absolute - Positive" + circuit_type = /obj/item/integrated_circuit/arithmetic/absolute + inputs_to_give = list(50) + expected_outputs = list(50) + +/datum/unit_test/integrated_circuits/absolute_2 + name = "Arithmetic Circuits: Absolute - Negative" + circuit_type = /obj/item/integrated_circuit/arithmetic/absolute + inputs_to_give = list(-20) + expected_outputs = list(20) + +/datum/unit_test/integrated_circuits/absolute_3 + name = "Arithmetic Circuits: Absolute - Zero" + circuit_type = /obj/item/integrated_circuit/arithmetic/absolute + inputs_to_give = list(0) + expected_outputs = list(0) + + + +/datum/unit_test/integrated_circuits/average_1 + name = "Arithmetic Circuits: Average - Basic" + circuit_type = /obj/item/integrated_circuit/arithmetic/average + inputs_to_give = list(8, 20, 14, 6) + expected_outputs = list(12) + +/datum/unit_test/integrated_circuits/average_2 + name = "Arithmetic Circuits: Average - Negatives" + circuit_type = /obj/item/integrated_circuit/arithmetic/average + inputs_to_give = list(30, -5, 8, -50, 4) + expected_outputs = list(-2.6) + + + +/datum/unit_test/integrated_circuits/square_root_1 + name = "Arithmetic Circuits: Square Root" + circuit_type = /obj/item/integrated_circuit/arithmetic/square_root + inputs_to_give = list(64) + expected_outputs = list(8) + + + +/datum/unit_test/integrated_circuits/modulo_1 + name = "Arithmetic Circuits: Modulo - 1" + circuit_type = /obj/item/integrated_circuit/arithmetic/modulo + inputs_to_give = list(8, 5) + expected_outputs = list(3) + +/datum/unit_test/integrated_circuits/modulo_2 + name = "Arithmetic Circuits: Modulo - 2" + circuit_type = /obj/item/integrated_circuit/arithmetic/modulo + inputs_to_give = list(20, 5) + expected_outputs = list(0) \ No newline at end of file diff --git a/code/unit_tests/integrated_circuits/circuits.dm b/code/unit_tests/integrated_circuits/circuits.dm new file mode 100644 index 00000000000..16fb2728de0 --- /dev/null +++ b/code/unit_tests/integrated_circuits/circuits.dm @@ -0,0 +1,73 @@ + +/datum/unit_test/integrated_circuits + name = "circuit template" + var/circuit_type = null + var/obj/item/integrated_circuit/IC = null + var/list/inputs_to_give = list() + var/list/expected_outputs = list() + +// Use this to set up. +/datum/unit_test/integrated_circuits/proc/arrange() + IC = new circuit_type(get_standard_turf()) // Make the circuit + IC.cooldown_per_use = 0 + +// Use this when finished to remove clutter for the next test. +/datum/unit_test/integrated_circuits/proc/clean_up() + qdel(IC) + +// Override this if needing special output (e.g. rounding to avoid floating point fun). +/datum/unit_test/integrated_circuits/proc/assess() + var/output_wrong = FALSE + var/i = 1 + for(var/datum/integrated_io/io in IC.outputs) + if(io.data != expected_outputs[i]) + log_bad("[io.name] did not match expected output of [expected_outputs[i]]. Output was [isnull(io.data) ? "NULL" : io.data].") + output_wrong = TRUE + i++ + return output_wrong + +// Useful when doing floating point fun. +/datum/unit_test/integrated_circuits/floor/assess() + var/output_wrong = FALSE + var/i = 1 + for(var/datum/integrated_io/io in IC.outputs) + if(round(io.data) != expected_outputs[i]) + log_bad("[io.name] did not match expected output of [expected_outputs[i]]. Output was [isnull(io.data) ? "NULL" : round(io.data)].") + output_wrong = TRUE + i++ + return output_wrong + +/datum/unit_test/integrated_circuits/start_test() + var/output_wrong = FALSE + if(!circuit_type) + fail("[name] did not supply a circuit_type path.") + return TRUE + try + // Arrange + arrange() + + var/i = 1 + for(var/input in inputs_to_give) + var/datum/integrated_io/io = IC.inputs[i] + io.write_data_to_pin(input) + i++ + + // Act + IC.do_work() + + output_wrong = assess() + + clean_up() + + catch(var/exception/e) + log_bad("[name] caught an exception: [e] on [e.file]:[e.line]") + output_wrong = TRUE + + // Assert + if(output_wrong) + fail("[name] failed.") + return TRUE + else + pass("[name] matched all expected outputs.") + return TRUE + diff --git a/code/unit_tests/integrated_circuits/converter.dm b/code/unit_tests/integrated_circuits/converter.dm new file mode 100644 index 00000000000..b2a414f4d80 --- /dev/null +++ b/code/unit_tests/integrated_circuits/converter.dm @@ -0,0 +1,52 @@ +/datum/unit_test/integrated_circuits/num2text + name = "Converter Circuits: Num2Text" + circuit_type = /obj/item/integrated_circuit/converter/num2text + inputs_to_give = list(10250) + expected_outputs = list("10250") + + + +/datum/unit_test/integrated_circuits/text2num + name = "Converter Circuits: Text2Num" + circuit_type = /obj/item/integrated_circuit/converter/text2num + inputs_to_give = list("2005") + expected_outputs = list(2005) + + + +/datum/unit_test/integrated_circuits/lowercase + name = "Converter Circuits: Lowercase" + circuit_type = /obj/item/integrated_circuit/converter/lowercase + inputs_to_give = list("Lorem ipsum...") + expected_outputs = list("lorem ipsum...") + + + +/datum/unit_test/integrated_circuits/uppercase + name = "Converter Circuits: Uppercase" + circuit_type = /obj/item/integrated_circuit/converter/uppercase + inputs_to_give = list("Lorem ipsum...") + expected_outputs = list("LOREM IPSUM...") + + + +/datum/unit_test/integrated_circuits/concatenatior + name = "Converter Circuits: Concatenatior" + circuit_type = /obj/item/integrated_circuit/converter/concatenatior + inputs_to_give = list("Lorem", " ", "ipsum", "...") + expected_outputs = list("Lorem ipsum...") + + + +/datum/unit_test/integrated_circuits/floor/radians2degrees + name = "Converter Circuits: Radians2Degrees" + circuit_type = /obj/item/integrated_circuit/converter/radians2degrees + inputs_to_give = list(1.57) + expected_outputs = list(89) // 89.95437 + + +/datum/unit_test/integrated_circuits/floor/degrees2radians + name = "Converter Circuits: Degrees2Radians" + circuit_type = /obj/item/integrated_circuit/converter/degrees2radians + inputs_to_give = list(90) + expected_outputs = list(1) // 1.570796 \ No newline at end of file diff --git a/code/unit_tests/integrated_circuits/data_transfer.dm b/code/unit_tests/integrated_circuits/data_transfer.dm new file mode 100644 index 00000000000..1d02e8f837e --- /dev/null +++ b/code/unit_tests/integrated_circuits/data_transfer.dm @@ -0,0 +1,17 @@ +/datum/unit_test/integrated_circuits/splitter + name = "Data Transfer Circuits: Splitter" + circuit_type = /obj/item/integrated_circuit/transfer/splitter + inputs_to_give = list("Test") + expected_outputs = list("Test", "Test") + +/datum/unit_test/integrated_circuits/splitter4 + name = "Data Transfer Circuits: Splitter 4" + circuit_type = /obj/item/integrated_circuit/transfer/splitter/medium + inputs_to_give = list("Test") + expected_outputs = list("Test", "Test", "Test", "Test") + +/datum/unit_test/integrated_circuits/splitter8 + name = "Data Transfer Circuits: Splitter 8" + circuit_type = /obj/item/integrated_circuit/transfer/splitter/large + inputs_to_give = list("Test") + expected_outputs = list("Test", "Test", "Test", "Test", "Test", "Test", "Test", "Test") \ No newline at end of file diff --git a/code/unit_tests/integrated_circuits/logic.dm b/code/unit_tests/integrated_circuits/logic.dm new file mode 100644 index 00000000000..314150f3b4d --- /dev/null +++ b/code/unit_tests/integrated_circuits/logic.dm @@ -0,0 +1,186 @@ +/datum/unit_test/integrated_circuits/equals_1 + name = "Logic Circuits: Equals - String True" + circuit_type = /obj/item/integrated_circuit/logic/binary/equals + inputs_to_give = list("Test", "Test") + expected_outputs = list(TRUE) + +/datum/unit_test/integrated_circuits/equals_2 + name = "Logic Circuits: Equals - String False" + circuit_type = /obj/item/integrated_circuit/logic/binary/equals + inputs_to_give = list("Test", "Nope") + expected_outputs = list(FALSE) + +/datum/unit_test/integrated_circuits/equals_3 + name = "Logic Circuits: Equals - Number True" + circuit_type = /obj/item/integrated_circuit/logic/binary/equals + inputs_to_give = list(525, 525) + expected_outputs = list(TRUE) + +/datum/unit_test/integrated_circuits/equals_4 + name = "Logic Circuits: Equals - Number False" + circuit_type = /obj/item/integrated_circuit/logic/binary/equals + inputs_to_give = list(1020, -580) + expected_outputs = list(FALSE) + +/datum/unit_test/integrated_circuits/equals_5 + name = "Logic Circuits: Equals - Null True" + circuit_type = /obj/item/integrated_circuit/logic/binary/equals + inputs_to_give = list(null, null) + expected_outputs = list(TRUE) + +/datum/unit_test/integrated_circuits/equals_6 + name = "Logic Circuits: Equals - Ref True" + circuit_type = /obj/item/integrated_circuit/logic/binary/equals + inputs_to_give = list() + expected_outputs = list(TRUE) + var/obj/A = null + +/datum/unit_test/integrated_circuits/equals_6/arrange() + A = new(get_standard_turf()) + inputs_to_give = list(weakref(A), weakref(A)) + ..() + +/datum/unit_test/integrated_circuits/equals_6/clean_up() + qdel(A) + ..() + +/datum/unit_test/integrated_circuits/equals_7 + name = "Logic Circuits: Equals - Ref False" + circuit_type = /obj/item/integrated_circuit/logic/binary/equals + inputs_to_give = list() + expected_outputs = list(FALSE) + var/obj/A = null + var/obj/B = null + +/datum/unit_test/integrated_circuits/equals_7/arrange() + A = new(get_standard_turf()) + B = new(get_standard_turf()) + inputs_to_give = list(weakref(A), weakref(B)) + ..() + +/datum/unit_test/integrated_circuits/equals_7/clean_up() + qdel(A) + qdel(B) + ..() + + + +/datum/unit_test/integrated_circuits/and_1 + name = "Logic Circuits: And - True" + circuit_type = /obj/item/integrated_circuit/logic/binary/and + inputs_to_give = list("One", "Two") + expected_outputs = list(TRUE) + +/datum/unit_test/integrated_circuits/and_2 + name = "Logic Circuits: And - False" + circuit_type = /obj/item/integrated_circuit/logic/binary/and + inputs_to_give = list("One", null) + expected_outputs = list(FALSE) + + + +/datum/unit_test/integrated_circuits/or_1 + name = "Logic Circuits: Or - True First" + circuit_type = /obj/item/integrated_circuit/logic/binary/or + inputs_to_give = list("One", null) + expected_outputs = list(TRUE) + +/datum/unit_test/integrated_circuits/or_2 + name = "Logic Circuits: Or - True Second" + circuit_type = /obj/item/integrated_circuit/logic/binary/or + inputs_to_give = list(null, "Two") + expected_outputs = list(TRUE) + +/datum/unit_test/integrated_circuits/or_3 + name = "Logic Circuits: Or - True Both" + circuit_type = /obj/item/integrated_circuit/logic/binary/or + inputs_to_give = list("One", "Two") + expected_outputs = list(TRUE) + +/datum/unit_test/integrated_circuits/or_4 + name = "Logic Circuits: Or - False" + circuit_type = /obj/item/integrated_circuit/logic/binary/or + inputs_to_give = list(null, null) + expected_outputs = list(FALSE) + + + +/datum/unit_test/integrated_circuits/less_than_1 + name = "Logic Circuits: Less Than - True" + circuit_type = /obj/item/integrated_circuit/logic/binary/less_than + inputs_to_give = list(50, 100) + expected_outputs = list(TRUE) + +/datum/unit_test/integrated_circuits/less_than_2 + name = "Logic Circuits: Less Than - False" + circuit_type = /obj/item/integrated_circuit/logic/binary/less_than + inputs_to_give = list(500, 50) + expected_outputs = list(FALSE) + + + +/datum/unit_test/integrated_circuits/less_than_or_equal_1 + name = "Logic Circuits: Less Than Or Equal - True 1" + circuit_type = /obj/item/integrated_circuit/logic/binary/less_than_or_equal + inputs_to_give = list(40, 50) + expected_outputs = list(TRUE) + +/datum/unit_test/integrated_circuits/less_than_or_equal_2 + name = "Logic Circuits: Less Than Or Equal - True 2" + circuit_type = /obj/item/integrated_circuit/logic/binary/less_than_or_equal + inputs_to_give = list(40, 40) + expected_outputs = list(TRUE) + +/datum/unit_test/integrated_circuits/less_than_or_equal_3 + name = "Logic Circuits: Less Than Or Equal - False" + circuit_type = /obj/item/integrated_circuit/logic/binary/less_than_or_equal + inputs_to_give = list(40, 30) + expected_outputs = list(FALSE) + + + +/datum/unit_test/integrated_circuits/greater_than_1 + name = "Logic Circuits: Greater Than - True" + circuit_type = /obj/item/integrated_circuit/logic/binary/greater_than + inputs_to_give = list(100, 50) + expected_outputs = list(TRUE) + +/datum/unit_test/integrated_circuits/greater_than_2 + name = "Logic Circuits: Greater Than - False" + circuit_type = /obj/item/integrated_circuit/logic/binary/greater_than + inputs_to_give = list(25, 800) + expected_outputs = list(FALSE) + + + +/datum/unit_test/integrated_circuits/greater_than_or_equal_1 + name = "Logic Circuits: Greater Than Or Equal - True 1" + circuit_type = /obj/item/integrated_circuit/logic/binary/greater_than_or_equal + inputs_to_give = list(250, 30) + expected_outputs = list(TRUE) + +/datum/unit_test/integrated_circuits/greater_than_or_equal_2 + name = "Logic Circuits: Greater Than Or Equal - True 2" + circuit_type = /obj/item/integrated_circuit/logic/binary/greater_than_or_equal + inputs_to_give = list(30, 30) + expected_outputs = list(TRUE) + +/datum/unit_test/integrated_circuits/greater_than_or_equal_3 + name = "Logic Circuits: Greater Than Or Equal - False" + circuit_type = /obj/item/integrated_circuit/logic/binary/greater_than_or_equal + inputs_to_give = list(-40, 100) + expected_outputs = list(FALSE) + + + +/datum/unit_test/integrated_circuits/not_1 + name = "Logic Circuits: Not - Invert to False" + circuit_type = /obj/item/integrated_circuit/logic/unary/not + inputs_to_give = list(1) + expected_outputs = list(0) + +/datum/unit_test/integrated_circuits/not_2 + name = "Logic Circuits: Not - Invert to True" + circuit_type = /obj/item/integrated_circuit/logic/unary/not + inputs_to_give = list(0) + expected_outputs = list(1) \ No newline at end of file diff --git a/code/unit_tests/integrated_circuits/prefabs.dm b/code/unit_tests/integrated_circuits/prefabs.dm new file mode 100644 index 00000000000..056c0d15684 --- /dev/null +++ b/code/unit_tests/integrated_circuits/prefabs.dm @@ -0,0 +1,55 @@ +/datum/unit_test/integrated_circuit_prefabs_shall_respect_complexity_and_size_contraints + name = "Integrated Circuit Prefabs Shall Respect Complexity and Size Constraints" + +/datum/unit_test/integrated_circuit_prefabs_shall_respect_complexity_and_size_contraints/start_test() + var/list/failed_prefabs = list() + for(var/prefab_type in subtypesof(/decl/prefab/ic_assembly)) + var/decl/prefab/ic_assembly/prefab = decls_repository.get_decl(prefab_type) + var/obj/item/device/electronic_assembly/assembly = prefab.assembly_type + + var/available_size = initial(assembly.max_components) + var/available_complexity = initial(assembly.max_complexity) + for(var/ic in prefab.integrated_circuits) + var/datum/ic_assembly_integrated_circuits/iaic = ic + var/obj/item/integrated_circuit/circuit = iaic.circuit_type + available_size -= initial(circuit.size) + available_complexity -= initial(circuit.complexity) + if(available_size < 0) + log_bad("[prefab_type] has an excess component size of [abs(available_size)]") + failed_prefabs |= prefab_type + if(available_complexity < 0) + log_bad("[prefab_type] has an excess component complexity of [abs(available_complexity)]") + failed_prefabs |= prefab_type + + if(failed_prefabs.len) + fail("The following integrated prefab types are out of bounds: [english_list(failed_prefabs)]") + else + pass("All integrated circuit prefabs are within complexity and size limits.") + + return 1 + +/datum/unit_test/integrated_circuit_prefabs_shall_not_fail_to_create + name = "Integrated Circuit Prefabs Shall Not Fail To Create" + +/datum/unit_test/integrated_circuit_prefabs_shall_not_fail_to_create/start_test() + var/list/failed_prefabs = list() + for(var/prefab_type in subtypesof(/decl/prefab/ic_assembly)) + var/decl/prefab/ic_assembly/prefab = decls_repository.get_decl(prefab_type) + + try + var/built_item = prefab.create(get_standard_turf()) + if(built_item) + qdel(built_item) + else + log_bad("[prefab_type] failed to create or return its item.") + failed_prefabs |= prefab_type + catch(var/exception/e) + log_bad("[prefab_type] caused an exception: [e] on [e.file]:[e.line]") + failed_prefabs |= prefab_type + + if(failed_prefabs.len) + fail("The following integrated prefab types failed to create their assemblies: [english_list(failed_prefabs)]") + else + pass("All integrated circuit prefabs are within complexity and size limits.") + + return 1 \ No newline at end of file diff --git a/code/unit_tests/integrated_circuits/trig.dm b/code/unit_tests/integrated_circuits/trig.dm new file mode 100644 index 00000000000..5ba351e2dfd --- /dev/null +++ b/code/unit_tests/integrated_circuits/trig.dm @@ -0,0 +1,33 @@ +/datum/unit_test/integrated_circuits/floor/sine_1 + name = "Trig Circuits: Sine - 1" + circuit_type = /obj/item/integrated_circuit/trig/sine + inputs_to_give = list(90) + expected_outputs = list(1) + +/datum/unit_test/integrated_circuits/floor/sine_2 + name = "Trig Circuits: Sine - 2" + circuit_type = /obj/item/integrated_circuit/trig/sine + inputs_to_give = list(0) + expected_outputs = list(0) + + + +/datum/unit_test/integrated_circuits/floor/cosine_1 + name = "Trig Circuits: Cosine - 1" + circuit_type = /obj/item/integrated_circuit/trig/cosine + inputs_to_give = list(90) + expected_outputs = list(0) + +/datum/unit_test/integrated_circuits/floor/cosine_2 + name = "Trig Circuits: Cosine - 2" + circuit_type = /obj/item/integrated_circuit/trig/cosine + inputs_to_give = list(0) + expected_outputs = list(1) + + + +/datum/unit_test/integrated_circuits/floor/tangent_1 + name = "Trig Circuits: Tangent - 1" + circuit_type = /obj/item/integrated_circuit/trig/tangent + inputs_to_give = list(45) + expected_outputs = list(1) \ No newline at end of file diff --git a/code/unit_tests/unit_test.dm b/code/unit_tests/unit_test.dm index a090548623c..f05514ce74e 100644 --- a/code/unit_tests/unit_test.dm +++ b/code/unit_tests/unit_test.dm @@ -96,4 +96,13 @@ var/total_unit_tests = 0 world.Del() else log_unit_test("[ASCII_RED]!!! \[[failed_unit_tests]\\[total_unit_tests]\] Unit Tests Failed !!![ASCII_RESET]") - world.Del() \ No newline at end of file + world.Del() + +/datum/unit_test/proc/get_standard_turf() + return locate(20,20,1) + +/datum/unit_test/proc/log_bad(var/message) + log_unit_test("[ASCII_RED]\[[name]\]: [message][ASCII_RESET]") + +/datum/unit_test/proc/log_debug(var/message) + log_unit_test("[ASCII_YELLOW]--- DEBUG --- \[[name]\]: [message][ASCII_RESET]") \ No newline at end of file diff --git a/icons/obj/electronic_assemblies.dmi b/icons/obj/electronic_assemblies.dmi index bd5263b7f36af4609e441a732d2deccbf0fdba6d..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 25382 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 diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index 9a32f79a4c4d6f9f8804d778412f6e7a3ac8be18..a725b4cc8607ffe329647389995ec1ff40344353 100644 GIT binary patch delta 10390 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 diff --git a/polaris.dme b/polaris.dme index db14ac1bd1c..413a2fd1cac 100644 --- a/polaris.dme +++ b/polaris.dme @@ -879,6 +879,7 @@ #include "code\game\objects\items\weapons\implants\implant.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\implantfreedom.dm" #include "code\game\objects\items\weapons\implants\implantlanguage.dm" @@ -1391,7 +1392,6 @@ #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" @@ -1400,6 +1400,7 @@ #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\library\lib_items.dm" #include "code\modules\library\lib_machines.dm" @@ -2117,6 +2118,12 @@ #include "code\unit_tests\research_tests.dm" #include "code\unit_tests\unit_test.dm" #include "code\unit_tests\zas_tests.dm" +#include "code\unit_tests\integrated_circuits\arithmetic.dm" +#include "code\unit_tests\integrated_circuits\circuits.dm" +#include "code\unit_tests\integrated_circuits\converter.dm" +#include "code\unit_tests\integrated_circuits\data_transfer.dm" +#include "code\unit_tests\integrated_circuits\logic.dm" +#include "code\unit_tests\integrated_circuits\trig.dm" #include "code\ZAS\_docs.dm" #include "code\ZAS\Airflow.dm" #include "code\ZAS\Atom.dm"