diff --git a/code/__defines/unit_tests.dm b/code/__defines/unit_tests.dm index 478c75fdb2..840673221c 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 17d3e32f92..eec5638523 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 0000000000..cf55cbd706 --- /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 de8f00dddb..d9daa035d5 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 00676e778a..37eabf2027 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 3b9e7aab06..ff994aa43c 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 b039299a55..96494ba469 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 0941c290f4..0000000000 --- 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 bf4ddf4b6f..7e37995df5 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 5bb3ea6aec..296104d938 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 6d53f6aae7..d477be3cbe 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 524c060d2d..f49b96d16c 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 edf263dd96..f9cd109dce 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 8a6a0c9c04..50bcc5e386 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 1d3b2cf4a9..6c76b9b4ff 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 0000000000..e8e2e09ca9 --- /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 b2f6a9c447..8e91f3f06a 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 0000000000..1e62f6e7b7 --- /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 0000000000..16fb2728de --- /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 0000000000..b2a414f4d8 --- /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 0000000000..1d02e8f837 --- /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 0000000000..314150f3b4 --- /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 0000000000..056c0d1568 --- /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 0000000000..5ba351e2df --- /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 a090548623..f05514ce74 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 bd5263b7f3..8fd1c4f5e1 100644 Binary files a/icons/obj/electronic_assemblies.dmi and b/icons/obj/electronic_assemblies.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index 9a32f79a4c..a725b4cc86 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/polaris.dme b/polaris.dme index db14ac1bd1..413a2fd1ca 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"