diff --git a/code/__DEFINES/integrated_electronics.dm b/code/__DEFINES/integrated_electronics.dm index 8e9e1b7cea..77ee69892e 100644 --- a/code/__DEFINES/integrated_electronics.dm +++ b/code/__DEFINES/integrated_electronics.dm @@ -20,6 +20,7 @@ #define IC_FORMAT_BOOLEAN "\" #define IC_FORMAT_REF "\" #define IC_FORMAT_LIST "\" +#define IC_FORMAT_INDEX "\" #define IC_FORMAT_PULSE "\" @@ -33,6 +34,7 @@ #define IC_PINTYPE_BOOLEAN /datum/integrated_io/boolean #define IC_PINTYPE_REF /datum/integrated_io/ref #define IC_PINTYPE_LIST /datum/integrated_io/lists +#define IC_PINTYPE_INDEX /datum/integrated_io/index #define IC_PINTYPE_PULSE_IN /datum/integrated_io/activate #define IC_PINTYPE_PULSE_OUT /datum/integrated_io/activate/out diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index 40963c3b08..b38e872ba3 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -59,8 +59,7 @@ if(io.holder.assembly && io.holder.assembly != selected_io.holder.assembly) to_chat(user, "Both \the [io.holder] and \the [selected_io.holder] need to be inside the same assembly.") return - selected_io.linked |= io - io.linked |= selected_io + io.connect_pin(selected_io) to_chat(user, "You connect \the [selected_io.holder]'s [selected_io.name] to \the [io.holder]'s [io.name].") selected_io.holder.interact(user) // This is to update the UI. @@ -82,8 +81,7 @@ to_chat(user, "These data pins aren't connected!") return else - io1.linked.Remove(io2) - io2.linked.Remove(io1) + io1.disconnect_pin(io2) to_chat(user, "You clip the data connection between the [io1.holder.displayed_name]'s \ [io1.name] and the [io2.holder.displayed_name]'s [io2.name].") io1.holder.interact(user) // This is to update the UI. @@ -162,5 +160,9 @@ desc = "An omni-technological interface." icon = 'icons/obj/abductor.dmi' icon_state = "multitool" +<<<<<<< HEAD toolspeed = 0.1 origin_tech = "magnets=5;engineering=5;abductor=3" +======= + toolspeed = 0.1 +>>>>>>> 0d2955e... More integrated circuit fixes and code improvements (#33034) diff --git a/code/modules/integrated_electronics/core/analyzer.dm b/code/modules/integrated_electronics/core/analyzer.dm index 02b8c88acc..0166f9bce7 100644 --- a/code/modules/integrated_electronics/core/analyzer.dm +++ b/code/modules/integrated_electronics/core/analyzer.dm @@ -1,7 +1,7 @@ /obj/item/device/integrated_electronics/analyzer name = "circuit analyzer" desc = "This tool can scan an assembly and generate code necessary to recreate it in a circuit printer." - icon = 'icons/obj/electronic_assemblies.dmi' + icon = 'icons/obj/assemblies/electronic_tools.dmi' icon_state = "analyzer" flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_SMALL diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index 6f552e1df4..5d457dfeed 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -5,10 +5,11 @@ name = "electronic assembly" desc = "It's a case, for building small electronics with." w_class = WEIGHT_CLASS_SMALL - icon = 'icons/obj/electronic_assemblies.dmi' + icon = 'icons/obj/assemblies/electronic_setups.dmi' icon_state = "setup_small" flags_1 = NOBLUDGEON_1 materials = list() // To be filled later + var/list/assembly_components = list() var/max_components = IC_MAX_SIZE_BASE var/max_complexity = IC_COMPLEXITY_BASE var/opened = FALSE @@ -40,11 +41,12 @@ /obj/item/device/electronic_assembly/proc/handle_idle_power() // First we generate power. - for(var/obj/item/integrated_circuit/passive/power/P in contents) + for(var/obj/item/integrated_circuit/passive/power/P in assembly_components) P.make_energy() // Now spend it. - for(var/obj/item/integrated_circuit/IC in contents) + for(var/I in assembly_components) + var/obj/item/integrated_circuit/IC = I if(IC.power_draw_idle) if(!draw_power(IC.power_draw_idle)) IC.power_fail() @@ -59,8 +61,8 @@ var/HTML = "" HTML += "[name]" - HTML += "
\[Refresh\] | " - HTML += "\[Rename\]
" + + HTML += "\[Refresh\] | \[Rename\]
" HTML += "[total_part_size]/[max_components] ([round((total_part_size / max_components) * 100, 0.1)]%) space taken up in the assembly.
" HTML += "[total_complexity]/[max_complexity] ([round((total_complexity / max_complexity) * 100, 0.1)]%) maximum complexity.
" if(battery) @@ -73,16 +75,14 @@ HTML += "Components:" - var/list/components = return_all_components() var/builtin_components = "" - for(var/c in components) + for(var/c in assembly_components) var/obj/item/integrated_circuit/circuit = c if(!circuit.removable) - builtin_components += "[circuit.displayed_name] | " - builtin_components += "\[Rename\] | " - builtin_components += "\[Scan with Debugger\] | " - builtin_components += "\[Move to Bottom\]" + builtin_components += "[circuit.displayed_name] | " + builtin_components += "\[Rename\] | " + builtin_components += "\[Scan with Debugger\]" builtin_components += "
" // Put removable circuits (if any) in separate categories from non-removable @@ -95,14 +95,17 @@ HTML += "
" - for(var/c in components) + for(var/c in assembly_components) var/obj/item/integrated_circuit/circuit = c if(circuit.removable) - HTML += "[circuit.displayed_name] | " - HTML += "\[Rename\] | " - HTML += "\[Scan with Debugger\] | " - HTML += "\[Remove\] | " - HTML += "\[Move to Bottom\]" + HTML += "[circuit.displayed_name] | " + HTML += "\[Rename\] | " + HTML += "\[Scan with Debugger\] | " + HTML += "\[Remove\] | " + HTML += " " + HTML += " " + HTML += " " + HTML += "" HTML += "
" HTML += "" @@ -125,6 +128,46 @@ to_chat(usr, "You pull \the [battery] out of \the [src]'s power supplier.") battery = null + if(href_list["component"]) + var/obj/item/integrated_circuit/component = locate(href_list["component"]) in assembly_components + if(component) + // Builtin components are not supposed to be removed or rearranged + if(!component.removable) + return + + var/current_pos = assembly_components.Find(component) + + // Find the position of a first removable component + var/first_removable_pos + for(var/i in 1 to assembly_components.len) + var/obj/item/integrated_circuit/temp_component = assembly_components[i] + if(temp_component.removable) + first_removable_pos = i + break + + if(href_list["remove"]) + try_remove_component(component, usr) + + else + // Adjust the position + if(href_list["up"]) + current_pos-- + else if(href_list["down"]) + current_pos++ + else if(href_list["top"]) + current_pos = first_removable_pos + else if(href_list["bottom"]) + current_pos = assembly_components.len + + // Wrap around nicely + if(current_pos < first_removable_pos) + current_pos = assembly_components.len + else if(current_pos > assembly_components.len) + current_pos = first_removable_pos + + assembly_components.Remove(component) + assembly_components.Insert(current_pos, component) + interact(usr) // To refresh the UI. /obj/item/device/electronic_assembly/proc/rename() @@ -142,9 +185,6 @@ /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" @@ -153,9 +193,10 @@ /obj/item/device/electronic_assembly/examine(mob/user) ..() - for(var/obj/item/integrated_circuit/IC in contents) + for(var/I in assembly_components) + var/obj/item/integrated_circuit/IC = I IC.external_examine(user) - if(istype(IC,/obj/item/integrated_circuit/output/screen)) + if(istype(IC, /obj/item/integrated_circuit/output/screen)) var/obj/item/integrated_circuit/output/screen/S if(S.stuff_to_display) to_chat(user, "There's a little screen labeled '[S]', which displays '[S.stuff_to_display]'.") @@ -164,21 +205,20 @@ /obj/item/device/electronic_assembly/proc/return_total_complexity() . = 0 - for(var/obj/item/integrated_circuit/part in contents) + var/obj/item/integrated_circuit/part + for(var/p in assembly_components) + part = p . += part.complexity /obj/item/device/electronic_assembly/proc/return_total_size() . = 0 - for(var/obj/item/integrated_circuit/part in contents) + var/obj/item/integrated_circuit/part + for(var/p in assembly_components) + part = p . += part.size -/obj/item/device/electronic_assembly/proc/return_all_components() - . = list() - for(var/obj/item/integrated_circuit/part in contents) - . += part - // Returns true if the circuit made it inside. -/obj/item/device/electronic_assembly/proc/add_circuit(var/obj/item/integrated_circuit/IC, var/mob/user) +/obj/item/device/electronic_assembly/proc/try_add_component(obj/item/integrated_circuit/IC, mob/user) if(!opened) to_chat(user, "\The [src]'s hatch is closed, you can't put anything inside.") return FALSE @@ -200,12 +240,45 @@ if(!user.transferItemToLoc(IC, src)) return FALSE - IC.assembly = src + to_chat(user, "You slide [IC] inside [src].") + playsound(src, 'sound/items/Deconstruct.ogg', 50, 1) + add_component(IC) return TRUE + +// Actually puts the circuit inside, doesn't perform any checks. +/obj/item/device/electronic_assembly/proc/add_component(obj/item/integrated_circuit/component) + component.forceMove(get_object()) + component.assembly = src + assembly_components |= component + + +/obj/item/device/electronic_assembly/proc/try_remove_component(obj/item/integrated_circuit/IC, mob/user) + if(!opened) + to_chat(user, "[src]'s hatch is closed, so you can't fiddle with the internal components.") + return FALSE + + if(!IC.removable) + to_chat(user, "[src] is permanently attached to the case.") + return FALSE + + to_chat(user, "You pop \the [src] out of the case, and slide it out.") + playsound(src, 'sound/items/Crowbar.ogg', 50, 1) + + remove_component(IC) + return TRUE + +// Actually removes the component, doesn't perform any checks. +/obj/item/device/electronic_assembly/proc/remove_component(obj/item/integrated_circuit/component) + component.disconnect_all() + component.forceMove(drop_location()) + component.assembly = null + assembly_components.Remove(component) + + /obj/item/device/electronic_assembly/afterattack(atom/target, mob/user, proximity) - for(var/obj/item/integrated_circuit/input/sensor/S in contents) + for(var/obj/item/integrated_circuit/input/sensor/S in assembly_components) if(!proximity) if(istype(S,/obj/item/integrated_circuit/input/sensor/ranged)||(!user)) if(user.client) @@ -234,12 +307,10 @@ if(istype(I, /obj/item/integrated_circuit)) if(!user.canUnEquip(I)) return FALSE - if(add_circuit(I, user)) - to_chat(user, "You slide [I] inside [src].") - playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) + if(try_add_component(I, user)) interact(user) return TRUE - else if(istype(I, /obj/item/device/integrated_electronics/wirer) || istype(I, /obj/item/device/integrated_electronics/debugger)) + else if(istype(I, /obj/item/device/multitool) || istype(I, /obj/item/device/integrated_electronics/wirer) || istype(I, /obj/item/device/integrated_electronics/debugger)) if(opened) interact(user) else @@ -270,7 +341,7 @@ var/list/input_selection = list() var/list/available_inputs = list() - for(var/obj/item/integrated_circuit/input/input in contents) + for(var/obj/item/integrated_circuit/input/input in assembly_components) if(input.can_be_asked_input) available_inputs.Add(input) var/i = 0 @@ -316,9 +387,14 @@ return FALSE /obj/item/device/electronic_assembly/Moved(oldLoc, dir) - for(var/obj/item/integrated_circuit/IC in contents) + for(var/I in assembly_components) + var/obj/item/integrated_circuit/IC = I IC.ext_moved(oldLoc, dir) +// Returns the object that is supposed to be used in attack messages, location checks, etc. +// Override in children for special behavior. +/obj/item/device/electronic_assembly/proc/get_object() + return src @@ -363,3 +439,6 @@ w_class = WEIGHT_CLASS_SMALL max_components = IC_MAX_SIZE_BASE * 3 max_complexity = IC_COMPLEXITY_BASE * 3 + +/obj/item/device/electronic_assembly/drone/can_move() + return TRUE diff --git a/code/modules/integrated_electronics/core/debugger.dm b/code/modules/integrated_electronics/core/debugger.dm index 7dc89178d2..ac6f5c1a1e 100644 --- a/code/modules/integrated_electronics/core/debugger.dm +++ b/code/modules/integrated_electronics/core/debugger.dm @@ -1,10 +1,8 @@ - - /obj/item/device/integrated_electronics/debugger name = "circuit debugger" desc = "This small tool allows one working with custom machinery to directly set data to a specific pin, useful for writing \ settings to specific circuits, or for debugging purposes. It can also pulse activation pins." - icon = 'icons/obj/electronic_assemblies.dmi' + icon = 'icons/obj/assemblies/electronic_tools.dmi' icon_state = "debugger" flags_1 = CONDUCT_1 | NOBLUDGEON_1 w_class = WEIGHT_CLASS_SMALL @@ -20,7 +18,7 @@ switch(type_to_use) if("string") accepting_refs = FALSE - new_data = stripped_input(user, "Now type in a string.","[src] string writing") + new_data = stripped_input(user, "Now type in a string.","[src] string writing", no_trim = TRUE) if(istext(new_data) && user.IsAdvancedToolUser()) data_to_write = new_data to_chat(user, "You set \the [src]'s memory to \"[new_data]\".") diff --git a/code/modules/integrated_electronics/core/helpers.dm b/code/modules/integrated_electronics/core/helpers.dm index 04137a4d05..e84823f201 100644 --- a/code/modules/integrated_electronics/core/helpers.dm +++ b/code/modules/integrated_electronics/core/helpers.dm @@ -54,21 +54,6 @@ return activators[pin_number] return -/obj/item/integrated_circuit/proc/handle_wire(var/datum/integrated_io/pin, var/obj/item/device/integrated_electronics/tool) - if(istype(tool, /obj/item/device/integrated_electronics/wirer)) - var/obj/item/device/integrated_electronics/wirer/wirer = tool - if(pin) - wirer.wire(pin, usr) - return TRUE - - else if(istype(tool, /obj/item/device/integrated_electronics/debugger)) - var/obj/item/device/integrated_electronics/debugger/debugger = tool - if(pin) - debugger.write_data(pin, usr) - return TRUE - return FALSE - - /datum/integrated_io/proc/get_data() if(isweakref(data)) return data.resolve() @@ -76,7 +61,7 @@ // Returns a list of parameters necessary to locate a pin in the assembly: component number, pin type and pin number -// Components list can be supplied from the outside, for use in savefiles or for extra performance if you are calling this multiple times +// Components list can be supplied from the outside, for use in savefiles /datum/integrated_io/proc/get_pin_parameters(list/components) if(!holder) return @@ -84,7 +69,7 @@ if(!components) if(!holder.assembly) return - components = holder.assembly.return_all_components() + components = holder.assembly.assembly_components var/component_number = components.Find(holder) @@ -105,10 +90,10 @@ // Locates a pin in the assembly when given component number, pin type and pin number -// Components list can be supplied from the outside, for use in savefiles or for extra performance if you are calling this multiple times +// Components list can be supplied from the outside, for use in savefiles /obj/item/device/electronic_assembly/proc/get_pin_ref(component_number, pin_type, pin_number, list/components) if(!components) - components = return_all_components() + components = assembly_components if(component_number > components.len) return @@ -120,6 +105,9 @@ // Same as get_pin_ref, but takes in a list of 3 parameters (same format as get_pin_parameters) // and performs extra sanity checks on parameters list and index numbers /obj/item/device/electronic_assembly/proc/get_pin_ref_list(list/parameters, list/components) + if(!components) + components = assembly_components + if(!islist(parameters) || parameters.len != 3) return diff --git a/code/modules/integrated_electronics/core/integrated_circuit.dm b/code/modules/integrated_electronics/core/integrated_circuit.dm index 042e93a2aa..748acfa5e4 100644 --- a/code/modules/integrated_electronics/core/integrated_circuit.dm +++ b/code/modules/integrated_electronics/core/integrated_circuit.dm @@ -1,7 +1,7 @@ /obj/item/integrated_circuit name = "integrated circuit" desc = "It's a tiny chip! This one doesn't seem to do much, however." - icon = 'icons/obj/electronic_assemblies.dmi' + icon = 'icons/obj/assemblies/electronic_components.dmi' icon_state = "template" w_class = WEIGHT_CLASS_TINY materials = list() // To be filled later @@ -22,8 +22,6 @@ var/category_text = "NO CATEGORY THIS IS A BUG" // To show up on circuit printer, and perhaps other places. var/removable = TRUE // Determines if a circuit is removable from the assembly. var/displayed_name = "" - var/allow_multitool = TRUE // Allows additional multitool functionality - // Used as a global var, (Do not set manually in children). /* Integrated circuits are essentially modular machines. Each circuit has a specific function, and combining them inside Electronic Assemblies allows @@ -104,9 +102,11 @@ a creative player the means to solve many problems. Circuits are held inside an if(!check_interactivity(M)) return - var/input = reject_bad_name(stripped_input(M, "What do you want to name this?", "Rename", src.name),1) - if(src && input && check_interactivity(M)) - to_chat(M, "The circuit '[src.name]' is now labeled '[input]'.") + var/input = reject_bad_name(stripped_input(M, "What do you want to name this?", "Rename", name), TRUE) + if(check_interactivity(M)) + if(!input) + input = name + to_chat(M, "The circuit '[name]' is now labeled '[input]'.") displayed_name = input /obj/item/integrated_circuit/interact(mob/user) @@ -124,13 +124,15 @@ a creative player the means to solve many problems. Circuits are held inside an HTML += "
" HTML += "" - HTML += "
\[Return to Assembly\]" + if(assembly) + HTML += "\[Return to Assembly\]
" - HTML += "
\[Refresh\] | " + HTML += "\[Refresh\] | " HTML += "\[Rename\] | " - HTML += "\[Scan with Device\] | " - if(removable) - HTML += "\[Remove\]
" + HTML += "\[Scan with Device\]" + if(assembly && removable) + HTML += " | \[Remove\]" + HTML += "
" HTML += "" HTML += "" @@ -151,12 +153,13 @@ a creative player the means to solve many problems. Circuits are held inside an if(1) io = get_pin_ref(IC_INPUT, i) if(io) - words += "[io.display_pin_type()] [io.name] [io.display_data(io.data)]
" + words += "[io.display_pin_type()] [io.name] \ + [io.display_data(io.data)]
" if(io.linked.len) for(var/k in 1 to io.linked.len) var/datum/integrated_io/linked = io.linked[k] - words += "[linked] \ - @ [linked.holder.displayed_name]
" + words += "[linked] \ + @ [linked.holder.displayed_name]
" if(outputs.len > inputs.len) height = 1 @@ -169,12 +172,13 @@ a creative player the means to solve many problems. Circuits are held inside an if(3) io = get_pin_ref(IC_OUTPUT, i) if(io) - words += "[io.display_pin_type()] [io.name] [io.display_data(io.data)]
" + words += "[io.display_pin_type()] [io.name] \ + [io.display_data(io.data)]
" if(io.linked.len) for(var/k in 1 to io.linked.len) var/datum/integrated_io/linked = io.linked[k] - words += "[linked] \ - @ [linked.holder.displayed_name]
" + words += "[linked] \ + @ [linked.holder.displayed_name]
" if(inputs.len > outputs.len) height = 1 @@ -185,12 +189,13 @@ a creative player the means to solve many problems. Circuits are held inside an var/datum/integrated_io/io = activator var/words = list() - words += "[io] [io.data?"\":"\"]
" + words += "[io] " + words += "[io.data?"\":"\"]
" if(io.linked.len) for(var/k in 1 to io.linked.len) var/datum/integrated_io/linked = io.linked[k] - words += "[linked] \ - @ [linked.holder.displayed_name]
" + words += "[linked] \ + @ [linked.holder.displayed_name]
" HTML += "" HTML += "" @@ -221,80 +226,24 @@ a creative player the means to solve many problems. Circuits are held inside an return TRUE var/update = TRUE - var/obj/item/device/electronic_assembly/A = src.assembly var/update_to_assembly = FALSE - var/datum/integrated_io/pin = locate(href_list["pin"]) in inputs + outputs + activators - var/datum/integrated_io/linked = null - if(href_list["link"]) - linked = locate(href_list["link"]) in pin.linked var/obj/held_item = usr.get_active_held_item() if(href_list["rename"]) rename_component(usr) - if(href_list["from_assembly"]) - update = FALSE - var/obj/item/device/electronic_assembly/ea = loc - if(istype(ea)) - ea.interact(usr) - if(href_list["pin_name"]) - if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool) - href_list["wire"] = TRUE - else - var/obj/item/device/multitool/M = held_item - M.wire(pin,usr) + if(href_list["pin"]) + var/datum/integrated_io/pin = locate(href_list["pin"]) in inputs + outputs + activators + if(pin) + var/datum/integrated_io/linked + if(href_list["link"]) + linked = locate(href_list["link"]) in pin.linked - - - if(href_list["pin_data"]) - if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool) - href_list["wire"] = TRUE - - else - var/datum/integrated_io/io = pin - io.ask_for_pin_data(usr) // The pins themselves will determine how to ask for data, and will validate the data. - - if(href_list["pin_unwire"]) - if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool) - href_list["wire"] = TRUE - else - var/obj/item/device/multitool/M = held_item - M.unwire(pin, linked, usr) - - if(href_list["wire"]) - if(istype(held_item, /obj/item/device/integrated_electronics/wirer)) - var/obj/item/device/integrated_electronics/wirer/wirer = held_item - if(linked) - wirer.wire(linked, usr) - else if(pin) - wirer.wire(pin, usr) - - else if(istype(held_item, /obj/item/device/integrated_electronics/debugger)) - var/obj/item/device/integrated_electronics/debugger/debugger = held_item - if(pin) - debugger.write_data(pin, usr) - else - to_chat(usr, "You can't do a whole lot without the proper tools.") - - if(href_list["examine"]) - var/obj/item/integrated_circuit/examined - if(href_list["examined"]) - examined = href_list["examined"] - else - examined = src - examined.interact(usr) - update = FALSE - - if(href_list["bottom"]) - var/obj/item/integrated_circuit/circuit = locate(href_list["bottom"]) in src.assembly.contents - var/assy = circuit.assembly - if(!circuit) - return - circuit.loc = null - circuit.loc = assy - . = TRUE - update_to_assembly = TRUE + if(istype(held_item, /obj/item/device/integrated_electronics) || istype(held_item, /obj/item/device/multitool)) + pin.handle_wire(linked, held_item, href_list["act"], usr) + else + to_chat(usr, "You can't do a whole lot without the proper tools.") if(href_list["scan"]) if(istype(held_item, /obj/item/device/integrated_electronics/debugger)) @@ -304,39 +253,15 @@ a creative player the means to solve many problems. Circuits are held inside an else to_chat(usr, "The debugger's 'ref scanner' needs to be on.") else - to_chat(usr, "You need a multitool/debugger set to 'ref' mode to do that.") + to_chat(usr, "You need a debugger set to 'ref' mode to do that.") if(href_list["return"]) - if(A) - update_to_assembly = TRUE - usr << browse(null, "window=circuit-[REF(src)];border=1;can_resize=1;can_close=1;can_minimize=1") - else - to_chat(usr, "This circuit is not in an assembly!") + update_to_assembly = TRUE - if(href_list["remove"]) - if(!A) - to_chat(usr, "This circuit is not in an assembly!") - return - if(!removable) - to_chat(usr, "\The [src] seems to be permanently attached to the case.") - return - var/obj/item/device/electronic_assembly/ea = loc - disconnect_all() - var/turf/T = get_turf(src) - forceMove(T) - assembly = null - playsound(T, 'sound/items/Crowbar.ogg', 50, 1) - to_chat(usr, "You pop \the [src] out of the case, and slide it out.") - - if(istype(ea)) - ea.interact(usr) - update = FALSE - return - if(update) - if(A && istype(A) && update_to_assembly) - A.interact(usr) + if(assembly && update_to_assembly) + assembly.interact(usr) else interact(usr) // To refresh the UI. @@ -384,18 +309,24 @@ a creative player the means to solve many problems. Circuits are held inside an for(var/i in inputs) I = i - I.disconnect() + I.disconnect_all() for(var/i in outputs) I = i - I.disconnect() + I.disconnect_all() for(var/i in activators) I = i - I.disconnect() + I.disconnect_all() /obj/item/integrated_circuit/proc/ext_moved(oldLoc, dir) return - +// Returns the object that is supposed to be used in attack messages, location checks, etc. +/obj/item/integrated_circuit/proc/get_object() + // If the component is located in an assembly, let assembly determine it. + if(assembly) + return assembly.get_object() + else + return src // If not, the component is acting on its own. diff --git a/code/modules/integrated_electronics/core/pins.dm b/code/modules/integrated_electronics/core/pins.dm index 25ef3b80b8..bff96b713c 100644 --- a/code/modules/integrated_electronics/core/pins.dm +++ b/code/modules/integrated_electronics/core/pins.dm @@ -40,7 +40,7 @@ D [1]/ || message_admins("ERROR: An integrated_io ([name]) spawned without a valid holder! This is a bug.") /datum/integrated_io/Destroy() - disconnect() + disconnect_all() data = null holder = null return ..() @@ -102,7 +102,36 @@ D [1]/ || /datum/integrated_io/activate/scramble() push_data() -/datum/integrated_io/proc/write_data_to_pin(var/new_data) +/datum/integrated_io/proc/handle_wire(datum/integrated_io/linked_pin, obj/item/tool, action, mob/living/user) + if(istype(tool, /obj/item/device/multitool)) + var/obj/item/device/multitool/multitool = tool + switch(action) + if("wire") + multitool.wire(src, user) + return TRUE + if("unwire") + if(linked_pin) + multitool.unwire(src, linked_pin, user) + return TRUE + if("data") + ask_for_pin_data(user) + return TRUE + + else if(istype(tool, /obj/item/device/integrated_electronics/wirer)) + var/obj/item/device/integrated_electronics/wirer/wirer = tool + if(linked_pin) + wirer.wire(linked_pin, user) + else + wirer.wire(src, user) + + else if(istype(tool, /obj/item/device/integrated_electronics/debugger)) + var/obj/item/device/integrated_electronics/debugger/debugger = tool + debugger.write_data(src, user) + return TRUE + + return FALSE + +/datum/integrated_io/proc/write_data_to_pin(new_data) if(isnull(new_data) || isnum(new_data) || istext(new_data) || isweakref(new_data)) data = new_data holder.on_data_written() @@ -131,21 +160,20 @@ D [1]/ || return "the [english_list(linked)]" return "nothing" -/datum/integrated_io/proc/disconnect() - //First we iterate over everything we are linked to. - if(linked && linked.len) - for(var/i in 1 to linked.len) - var/datum/integrated_io/their_io = linked[i] - //While doing that, we iterate them as well, and disconnect ourselves from them. - if(their_io.linked.len && their_io.linked) - for(var/j in 1 to their_io.linked.len) - var/datum/integrated_io/their_linked_io = their_io.linked[j] - if(their_linked_io == src) - their_io.linked.Remove(src) - else - continue - //Now that we're removed from them, we gotta remove them from us. - linked.Remove(their_io) + +/datum/integrated_io/proc/connect_pin(datum/integrated_io/pin) + pin.linked |= src + linked |= pin + +// Iterates over every linked pin and disconnects them. +/datum/integrated_io/proc/disconnect_all() + for(var/pin in linked) + disconnect_pin(pin) + +/datum/integrated_io/proc/disconnect_pin(datum/integrated_io/pin) + pin.linked.Remove(src) + linked.Remove(pin) + /datum/integrated_io/proc/ask_for_data_type(mob/user, var/default, var/list/allowed_data_types = list("string","number","null")) var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in allowed_data_types @@ -155,7 +183,7 @@ D [1]/ || var/new_data = null switch(type_to_use) if("string") - new_data = stripped_input(user, "Now type in a string.","[src] string writing", istext(default) ? default : null) + new_data = stripped_input(user, "Now type in a string.","[src] string writing", istext(default) ? default : null, no_trim = TRUE) if(istext(new_data) && holder.check_interactivity(user) ) to_chat(user, "You input "+new_data+" into the pin.") return new_data diff --git a/code/modules/integrated_electronics/core/printer.dm b/code/modules/integrated_electronics/core/printer.dm index 89a0e2b213..6951d1dd09 100644 --- a/code/modules/integrated_electronics/core/printer.dm +++ b/code/modules/integrated_electronics/core/printer.dm @@ -1,7 +1,7 @@ /obj/item/device/integrated_circuit_printer name = "integrated circuit printer" desc = "A portable(ish) machine made to print tiny modular circuitry out of metal." - icon = 'icons/obj/electronic_assemblies.dmi' + icon = 'icons/obj/assemblies/electronic_tools.dmi' icon_state = "circuit_printer" w_class = WEIGHT_CLASS_BULKY var/upgraded = TRUE // When hit with an upgrade disk, will turn true, allowing it to print the higher tier circuits. @@ -108,16 +108,13 @@ if(!build_type || !ispath(build_type)) return TRUE - var/cost = 1 + var/cost = 400 if(ispath(build_type, /obj/item/device/electronic_assembly)) - var/obj/item/device/electronic_assembly/E = build_type - cost = round( (initial(E.max_complexity) + initial(E.max_components) ) / 4) + var/obj/item/device/electronic_assembly/E = SScircuit.cached_assemblies[build_type] + cost = E.materials[MAT_METAL] else if(ispath(build_type, /obj/item/integrated_circuit)) - var/obj/item/integrated_circuit/IC = build_type - cost = initial(IC.w_class) - - - cost *= SScircuit.cost_multiplier + var/obj/item/integrated_circuit/IC = SScircuit.cached_components[build_type] + cost = IC.materials[MAT_METAL] var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) @@ -125,7 +122,12 @@ to_chat(usr, "You need [cost] metal to build that!") return TRUE - new build_type(get_turf(loc)) + var/obj/item/built = new build_type(drop_location()) + + if(istype(built, /obj/item/device/electronic_assembly)) + var/obj/item/device/electronic_assembly/E = built + E.opened = TRUE + E.update_icon() if(href_list["print"]) if(!CONFIG_GET(flag/ic_printing)) @@ -179,7 +181,7 @@ /obj/item/disk/integrated_circuit/upgrade name = "integrated circuit printer upgrade disk" desc = "Install this into your integrated circuit printer to enhance it." - icon = 'icons/obj/electronic_assemblies.dmi' + icon = 'icons/obj/assemblies/electronic_tools.dmi' icon_state = "upgrade_disk" item_state = "card-id" w_class = WEIGHT_CLASS_SMALL diff --git a/code/modules/integrated_electronics/core/saved_circuits.dm b/code/modules/integrated_electronics/core/saved_circuits.dm index cbbe58f16d..34abff9a1f 100644 --- a/code/modules/integrated_electronics/core/saved_circuits.dm +++ b/code/modules/integrated_electronics/core/saved_circuits.dm @@ -23,6 +23,8 @@ // Don't waste space saving the default values if(input.data == inputs_default["[index]"]) continue + if(input.data == initial(input.data)) + continue var/list/input_value = list(index, FALSE, input.data) // Index, Type, Value @@ -91,15 +93,13 @@ //var/input_type = input[2] var/input_value = input[3] - var/datum/integrated_io/IO = inputs[index] - IO.write_data_to_pin(input_value) - // write_data_to_pin includes all the value sanity checks you'll ever need + var/datum/integrated_io/pin = inputs[index] + // The pins themselves validate the data. + pin.write_data_to_pin(input_value) // TODO: support for special input types, such as internal refs and maybe typepaths - - // Saves type and modified name (if any) to a list // The list is converted to JSON down the line. /obj/item/device/electronic_assembly/proc/save() @@ -144,10 +144,8 @@ // Attempts to save an assembly into a save file format. // Returns null if assembly is not complete enough to be saved. /datum/controller/subsystem/processing/circuit/proc/save_electronic_assembly(obj/item/device/electronic_assembly/assembly) - var/list/assembly_components = assembly.return_all_components() - // No components? Don't even try to save it. - if(!length(assembly_components)) + if(!length(assembly.assembly_components)) return @@ -160,7 +158,7 @@ // Block 2. Components. var/list/components = list() - for(var/c in assembly_components) + for(var/c in assembly.assembly_components) var/obj/item/integrated_circuit/component = c components.Add(list(component.save())) blocks["components"] = components @@ -170,18 +168,18 @@ var/list/wires = list() var/list/saved_wires = list() - for(var/c in assembly_components) + for(var/c in assembly.assembly_components) var/obj/item/integrated_circuit/component = c var/list/all_pins = component.inputs + component.outputs + component.activators for(var/p in all_pins) var/datum/integrated_io/pin = p - var/list/params = pin.get_pin_parameters(assembly_components) + var/list/params = pin.get_pin_parameters() var/text_params = params.Join() for(var/p2 in pin.linked) var/datum/integrated_io/pin2 = p2 - var/list/params2 = pin2.get_pin_parameters(assembly_components) + var/list/params2 = pin2.get_pin_parameters() var/text_params2 = params2.Join() // Check if we already saved an opposite version of this wire @@ -318,23 +316,20 @@ // Block 2. Components. - var/list/assembly_components = list() for(var/component_params in blocks["components"]) var/obj/item/integrated_circuit/component_path = all_components[component_params["type"]] var/obj/item/integrated_circuit/component = new component_path(assembly) - component.assembly = assembly + assembly.add_component(component) component.load(component_params) - assembly_components.Add(component) // Block 3. Wires. if(blocks["wires"]) for(var/w in blocks["wires"]) var/list/wire = w - var/datum/integrated_io/IO = assembly.get_pin_ref_list(wire[1], assembly_components) - var/datum/integrated_io/IO2 = assembly.get_pin_ref_list(wire[2], assembly_components) - IO.linked |= IO2 - IO2.linked |= IO + var/datum/integrated_io/IO = assembly.get_pin_ref_list(wire[1]) + var/datum/integrated_io/IO2 = assembly.get_pin_ref_list(wire[2]) + IO.connect_pin(IO2) assembly.forceMove(loc) return assembly diff --git a/code/modules/integrated_electronics/core/special_pins/char_pin.dm b/code/modules/integrated_electronics/core/special_pins/char_pin.dm index 1d859f86b5..3e466891eb 100644 --- a/code/modules/integrated_electronics/core/special_pins/char_pin.dm +++ b/code/modules/integrated_electronics/core/special_pins/char_pin.dm @@ -3,7 +3,7 @@ name = "char pin" /datum/integrated_io/char/ask_for_pin_data(mob/user) - var/new_data = stripped_input(user, "Please type in one character.","[src] char writing") + var/new_data = stripped_input(user, "Please type in one character.","[src] char writing", no_trim = TRUE) if(holder.check_interactivity(user) ) to_chat(user, "You input [new_data ? "new_data" : "NULL"] into the pin.") write_data_to_pin(new_data) diff --git a/code/modules/integrated_electronics/core/special_pins/index_pin.dm b/code/modules/integrated_electronics/core/special_pins/index_pin.dm new file mode 100644 index 0000000000..802a2612d3 --- /dev/null +++ b/code/modules/integrated_electronics/core/special_pins/index_pin.dm @@ -0,0 +1,21 @@ +// These pins can only contain integer numbers between 1 and IC_MAX_LIST_LENGTH. Null is not allowed. +/datum/integrated_io/index + name = "index pin" + data = 1 + +/datum/integrated_io/index/ask_for_pin_data(mob/user) + var/new_data = input("Please type in an index.","[src] index writing") as num + if(isnum(new_data) && holder.check_interactivity(user)) + to_chat(user, "You input [new_data] into the pin.") + write_data_to_pin(new_data) + +/datum/integrated_io/index/write_data_to_pin(new_data) + if(isnull(new_data)) + new_data = 1 + + if(isnum(new_data)) + data = Clamp(round(new_data), 1, IC_MAX_LIST_LENGTH) + holder.on_data_written() + +/datum/integrated_io/index/display_pin_type() + return IC_FORMAT_INDEX diff --git a/code/modules/integrated_electronics/core/special_pins/list_pin.dm b/code/modules/integrated_electronics/core/special_pins/list_pin.dm index ddf3a48362..8a6f80ea63 100644 --- a/code/modules/integrated_electronics/core/special_pins/list_pin.dm +++ b/code/modules/integrated_electronics/core/special_pins/list_pin.dm @@ -112,6 +112,10 @@ var/list/new_list = new_data data = new_list.Copy(max(1,new_list.len - IC_MAX_LIST_LENGTH+1),0) holder.on_data_written() + else if(isnull(new_data)) // Clear the list + var/list/my_list = data + my_list.Cut() + holder.on_data_written() /datum/integrated_io/lists/display_pin_type() return IC_FORMAT_LIST diff --git a/code/modules/integrated_electronics/core/special_pins/string_pin.dm b/code/modules/integrated_electronics/core/special_pins/string_pin.dm index a619e7450f..49d6aa9554 100644 --- a/code/modules/integrated_electronics/core/special_pins/string_pin.dm +++ b/code/modules/integrated_electronics/core/special_pins/string_pin.dm @@ -3,7 +3,7 @@ name = "string pin" /datum/integrated_io/string/ask_for_pin_data(mob/user) - var/new_data = stripped_input(user, "Please type in a string.","[src] string writing") + var/new_data = stripped_input(user, "Please type in a string.","[src] string writing", no_trim = TRUE) if(holder.check_interactivity(user) ) to_chat(user, "You input [new_data ? "[new_data]" : "NULL"] into the pin.") write_data_to_pin(new_data) diff --git a/code/modules/integrated_electronics/core/wirer.dm b/code/modules/integrated_electronics/core/wirer.dm index c1caba00cd..bfbbfa4864 100644 --- a/code/modules/integrated_electronics/core/wirer.dm +++ b/code/modules/integrated_electronics/core/wirer.dm @@ -8,7 +8,7 @@ desc = "It's a small wiring tool, with a wire roll, electric soldering iron, wire cutter, and more in one package. \ The wires used are generally useful for small electronics, such as circuitboards and breadboards, as opposed to larger wires \ used for power or data transmission." - icon = 'icons/obj/electronic_assemblies.dmi' + icon = 'icons/obj/assemblies/electronic_tools.dmi' icon_state = "wirer-wire" flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_SMALL @@ -38,8 +38,7 @@ if(io.holder.assembly && io.holder.assembly != selected_io.holder.assembly) to_chat(user, "Both \the [io.holder] and \the [selected_io.holder] need to be inside the same assembly.") return - selected_io.linked |= io - io.linked |= selected_io + selected_io.connect_pin(io) to_chat(user, "You connect \the [selected_io.holder]'s [selected_io.name] to \the [io.holder]'s [io.name].") mode = WIRE @@ -64,8 +63,7 @@ the same pin is rather moot.") return if(selected_io in io.linked) - io.linked.Remove(selected_io) - selected_io.linked.Remove(io) + selected_io.disconnect_pin(io) to_chat(user, "You disconnect \the [selected_io.holder]'s [selected_io.name] from \ \the [io.holder]'s [io.name].") selected_io.holder.interact(user) // This is to update the UI. diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm index 373a059f45..272dbef071 100644 --- a/code/modules/integrated_electronics/subtypes/converters.dm +++ b/code/modules/integrated_electronics/subtypes/converters.dm @@ -175,6 +175,7 @@ extended_desc = "This circuits splits a given string into two, based on the string, and the index value. \ The index splits the string after the given index, including spaces. So 'a person' with an index of '3' \ will split into 'a p' and 'erson'." + icon_state = "split" complexity = 4 inputs = list( "string to split" = IC_PINTYPE_STRING, @@ -232,6 +233,7 @@ desc = "This splits a single string into a list of strings." extended_desc = "This circuit splits a given string into a list of strings based on the string and given delimiter. \ For example, 'eat this burger',' ' will be converted to list('eat','this','burger')." + icon_state = "split" complexity = 4 inputs = list( "string to split" = IC_PINTYPE_STRING, @@ -245,8 +247,8 @@ /obj/item/integrated_circuit/converter/exploders/do_work() var/strin = get_pin_data(IC_INPUT, 1) - var/sample = get_pin_data(IC_INPUT, 2) - set_pin_data(IC_OUTPUT, 1, splittext( strin ,sample )) + var/delimiter = get_pin_data(IC_INPUT, 2) + set_pin_data(IC_OUTPUT, 1, splittext(strin, delimiter)) push_data() activate_pin(2) diff --git a/code/modules/integrated_electronics/subtypes/data_transfer.dm b/code/modules/integrated_electronics/subtypes/data_transfer.dm index d28bb72e33..20b80926c8 100644 --- a/code/modules/integrated_electronics/subtypes/data_transfer.dm +++ b/code/modules/integrated_electronics/subtypes/data_transfer.dm @@ -14,15 +14,15 @@ activators = list("select" = IC_PINTYPE_PULSE_IN, "on select" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 4 - var/number_of_inputs = 2 + var/number_of_pins = 2 -/obj/item/integrated_circuit/transfer/multiplexer/New() - for(var/i = 1 to number_of_inputs) +/obj/item/integrated_circuit/transfer/multiplexer/Initialize() + for(var/i = 1 to number_of_pins) inputs["input [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called. - complexity = number_of_inputs - ..() - desc += " It has [number_of_inputs] input pins." + complexity = number_of_pins + . = ..() + desc += " It has [number_of_pins] input pins." extended_desc += " This multiplexer has a range from 1 to [inputs.len - 1]." /obj/item/integrated_circuit/transfer/multiplexer/do_work() @@ -35,20 +35,20 @@ /obj/item/integrated_circuit/transfer/multiplexer/medium name = "four multiplexer" - number_of_inputs = 4 icon_state = "mux4" + number_of_pins = 4 /obj/item/integrated_circuit/transfer/multiplexer/large name = "eight multiplexer" - number_of_inputs = 8 w_class = WEIGHT_CLASS_SMALL icon_state = "mux8" + number_of_pins = 8 /obj/item/integrated_circuit/transfer/multiplexer/huge name = "sixteen multiplexer" icon_state = "mux16" w_class = WEIGHT_CLASS_SMALL - number_of_inputs = 16 + number_of_pins = 16 /obj/item/integrated_circuit/transfer/demultiplexer name = "two demultiplexer" @@ -62,16 +62,15 @@ activators = list("select" = IC_PINTYPE_PULSE_IN, "on select" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 4 - var/number_of_outputs = 2 + var/number_of_pins = 2 -/obj/item/integrated_circuit/transfer/demultiplexer/New() - for(var/i = 1 to number_of_outputs) - // outputs += "output [i]" +/obj/item/integrated_circuit/transfer/demultiplexer/Initialize() + for(var/i = 1 to number_of_pins) outputs["output [i]"] = IC_PINTYPE_ANY - complexity = number_of_outputs + complexity = number_of_pins - ..() - desc += " It has [number_of_outputs] output pins." + . = ..() + desc += " It has [number_of_pins] output pins." extended_desc += " This demultiplexer has a range from 1 to [outputs.len]." /obj/item/integrated_circuit/transfer/demultiplexer/do_work() @@ -84,19 +83,19 @@ /obj/item/integrated_circuit/transfer/demultiplexer/medium name = "four demultiplexer" icon_state = "dmux4" - number_of_outputs = 4 + number_of_pins = 4 /obj/item/integrated_circuit/transfer/demultiplexer/large name = "eight demultiplexer" icon_state = "dmux8" w_class = WEIGHT_CLASS_SMALL - number_of_outputs = 8 + number_of_pins = 8 /obj/item/integrated_circuit/transfer/demultiplexer/huge name = "sixteen demultiplexer" icon_state = "dmux16" w_class = WEIGHT_CLASS_SMALL - number_of_outputs = 16 + number_of_pins = 16 /obj/item/integrated_circuit/transfer/pulsedemultiplexer name = "two pulse demultiplexer" @@ -110,37 +109,36 @@ activators = list("select" = IC_PINTYPE_PULSE_IN) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 4 - var/number_of_outputs = 2 + var/number_of_pins = 2 -/obj/item/integrated_circuit/transfer/pulsedemultiplexer/New() - for(var/i = 1 to number_of_outputs) - // outputs += "output [i]" +/obj/item/integrated_circuit/transfer/pulsedemultiplexer/Initialize() + for(var/i = 1 to number_of_pins) activators["output [i]"] = IC_PINTYPE_PULSE_OUT - complexity = number_of_outputs + complexity = number_of_pins - ..() - desc += " It has [number_of_outputs] output pins." + . = ..() + desc += " It has [number_of_pins] output pins." extended_desc += " This pulse demultiplexer has a range from 1 to [activators.len - 1]." /obj/item/integrated_circuit/transfer/pulsedemultiplexer/do_work() var/output_index = get_pin_data(IC_INPUT, 1) - if(output_index == Clamp(output_index, 1, number_of_outputs)) + if(output_index == Clamp(output_index, 1, number_of_pins)) activate_pin(round(output_index + 1 ,1)) /obj/item/integrated_circuit/transfer/pulsedemultiplexer/medium name = "four pulse demultiplexer" icon_state = "dmux4" - number_of_outputs = 4 + number_of_pins = 4 /obj/item/integrated_circuit/transfer/pulsedemultiplexer/large name = "eight pulse demultiplexer" icon_state = "dmux8" w_class = WEIGHT_CLASS_SMALL - number_of_outputs = 8 + number_of_pins = 8 /obj/item/integrated_circuit/transfer/pulsedemultiplexer/huge name = "sixteen pulse demultiplexer" icon_state = "dmux16" w_class = WEIGHT_CLASS_SMALL - number_of_outputs = 16 \ No newline at end of file + number_of_pins = 16 \ No newline at end of file diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index b579901a2d..aa486f8f98 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -248,10 +248,12 @@ /obj/item/integrated_circuit/input/examiner name = "examiner" desc = "It' s a little machine vision system. It can return the name, description, distance, \ - relative coordinates, total amount of reagents, and maximum amount of reagents of the referenced object." + relative coordinates, total amount of reagents, maximum amount of reagents, density and opacity of the referenced object." icon_state = "video_camera" complexity = 6 - inputs = list("\ target" = IC_PINTYPE_REF) + inputs = list( + "target" = IC_PINTYPE_REF + ) outputs = list( "name" = IC_PINTYPE_STRING, "description" = IC_PINTYPE_STRING, @@ -260,8 +262,14 @@ "distance" = IC_PINTYPE_NUMBER, "max reagents" = IC_PINTYPE_NUMBER, "amount of reagents" = IC_PINTYPE_NUMBER, - ) - activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT, "not scanned" = IC_PINTYPE_PULSE_OUT) + "density" = IC_PINTYPE_BOOLEAN, + "opacity" = IC_PINTYPE_BOOLEAN, + ) + activators = list( + "scan" = IC_PINTYPE_PULSE_IN, + "on scanned" = IC_PINTYPE_PULSE_OUT, + "not scanned" = IC_PINTYPE_PULSE_OUT + ) spawn_flags = IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4) power_draw_per_use = 80 @@ -273,8 +281,6 @@ return if(H in view(T)) // This is a camera. It can't examine thngs,that it can't see. - - set_pin_data(IC_OUTPUT, 1, H.name) set_pin_data(IC_OUTPUT, 2, H.desc) set_pin_data(IC_OUTPUT, 3, H.x-T.x) @@ -287,6 +293,8 @@ tr = H.reagents.total_volume set_pin_data(IC_OUTPUT, 6, mr) set_pin_data(IC_OUTPUT, 7, tr) + set_pin_data(IC_OUTPUT, 8, H.density) + set_pin_data(IC_OUTPUT, 9, H.opacity) push_data() activate_pin(2) else diff --git a/code/modules/integrated_electronics/subtypes/lists.dm b/code/modules/integrated_electronics/subtypes/lists.dm index 0d622f58e2..aa373c9940 100644 --- a/code/modules/integrated_electronics/subtypes/lists.dm +++ b/code/modules/integrated_electronics/subtypes/lists.dm @@ -2,29 +2,41 @@ /obj/item/integrated_circuit/lists complexity = 1 inputs = list( - "input" = IC_PINTYPE_LIST - ) - outputs = list("result" = IC_PINTYPE_STRING) - activators = list("compute" = IC_PINTYPE_PULSE_IN, "on computed" = IC_PINTYPE_PULSE_OUT) + "input" = IC_PINTYPE_LIST + ) + outputs = list( + "result" = IC_PINTYPE_STRING + ) + activators = list( + "compute" = IC_PINTYPE_PULSE_IN, + "on computed" = IC_PINTYPE_PULSE_OUT + ) category_text = "Lists" power_draw_per_use = 20 /obj/item/integrated_circuit/lists/pick name = "pick circuit" desc = "This circuit will pick a random element from the input list, and output said element." - extended_desc = "Will output null if the list is empty. Input list is unmodified." + extended_desc = "Input list is unmodified." icon_state = "addition" + outputs = list( + "result" = IC_PINTYPE_ANY + ) + activators = list( + "compute" = IC_PINTYPE_PULSE_IN, + "on success" = IC_PINTYPE_PULSE_OUT, + "on failure" = IC_PINTYPE_PULSE_OUT, + ) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/lists/pick/do_work() - var/result = null var/list/input_list = get_pin_data(IC_INPUT, 1) // List pins guarantee that there is a list inside, even if just an empty one. if(input_list.len) - result = pick(input_list) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) + set_pin_data(IC_OUTPUT, 1, pick(input_list)) + push_data() + activate_pin(2) + else + activate_pin(3) /obj/item/integrated_circuit/lists/append @@ -34,10 +46,10 @@ inputs = list( "list to append" = IC_PINTYPE_LIST, "input" = IC_PINTYPE_ANY - ) + ) outputs = list( "appended list" = IC_PINTYPE_LIST - ) + ) icon_state = "addition" spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH @@ -52,6 +64,7 @@ push_data() activate_pin(2) + /obj/item/integrated_circuit/lists/search name = "search circuit" desc = "This circuit will get the index location of the desired element in a list." @@ -59,19 +72,30 @@ inputs = list( "list" = IC_PINTYPE_LIST, "item" = IC_PINTYPE_ANY - ) + ) outputs = list( "index" = IC_PINTYPE_NUMBER - ) + ) + activators = list( + "compute" = IC_PINTYPE_PULSE_IN, + "on success" = IC_PINTYPE_PULSE_OUT, + "on failure" = IC_PINTYPE_PULSE_OUT, + ) icon_state = "addition" spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/lists/search/do_work() var/list/input_list = get_pin_data(IC_INPUT, 1) - var/item = get_pin_data(IC_INPUT, 2) - set_pin_data(IC_OUTPUT, 1, input_list.Find(item)) + var/output = input_list.Find(get_pin_data(IC_INPUT, 2)) + + set_pin_data(IC_OUTPUT, 1, output) push_data() - activate_pin(2) + + if(output) + activate_pin(2) + else + activate_pin(3) + /obj/item/integrated_circuit/lists/at name = "at circuit" @@ -79,31 +103,46 @@ extended_desc = "If there is no element with such index, result will be null." inputs = list( "list" = IC_PINTYPE_LIST, - "index" = IC_PINTYPE_NUMBER - ) - outputs = list("item" = IC_PINTYPE_ANY) + "index" = IC_PINTYPE_INDEX + ) + outputs = list( + "item" = IC_PINTYPE_ANY + ) + activators = list( + "compute" = IC_PINTYPE_PULSE_IN, + "on success" = IC_PINTYPE_PULSE_OUT, + "on failure" = IC_PINTYPE_PULSE_OUT, + ) icon_state = "addition" spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/lists/at/do_work() var/list/input_list = get_pin_data(IC_INPUT, 1) var/index = get_pin_data(IC_INPUT, 2) - var/item = input_list[index] - set_pin_data(IC_OUTPUT, 1, item) + + // Check if index is valid + if(index > input_list.len) + set_pin_data(IC_OUTPUT, 1, null) + push_data() + activate_pin(3) + return + + set_pin_data(IC_OUTPUT, 1, input_list[index]) push_data() activate_pin(2) + /obj/item/integrated_circuit/lists/delete name = "delete circuit" desc = "This circuit will remove an element from a list by the index." extended_desc = "If there is no element with such index, result list will be unchanged." inputs = list( "list" = IC_PINTYPE_LIST, - "index" = IC_PINTYPE_NUMBER - ) + "index" = IC_PINTYPE_INDEX + ) outputs = list( "item" = IC_PINTYPE_LIST - ) + ) icon_state = "addition" spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH @@ -111,26 +150,34 @@ var/list/input_list = get_pin_data(IC_INPUT, 1) var/list/red_list = list() var/index = get_pin_data(IC_INPUT, 2) - for(var/j in 1 to input_list.len) - var/I = input_list[j] - if(j != index) - red_list.Add(I) + + if(length(input_list)) + for(var/j in 1 to input_list.len) + var/I = input_list[j] + if(j != index) + red_list.Add(I) set_pin_data(IC_OUTPUT, 1, red_list) push_data() activate_pin(2) + /obj/item/integrated_circuit/lists/write name = "write circuit" desc = "This circuit will write an element to a list at the given index location." - extended_desc = "If there is no element with such index, it will give the same list, as before." + extended_desc = "If there is no element with such index, it will give the same list as before." inputs = list( "list" = IC_PINTYPE_LIST, - "index" = IC_PINTYPE_NUMBER, + "index" = IC_PINTYPE_INDEX, "item" = IC_PINTYPE_ANY - ) + ) outputs = list( "redacted list" = IC_PINTYPE_LIST - ) + ) + activators = list( + "compute" = IC_PINTYPE_PULSE_IN, + "on success" = IC_PINTYPE_PULSE_OUT, + "on failure" = IC_PINTYPE_PULSE_OUT, + ) icon_state = "addition" spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH @@ -138,7 +185,15 @@ var/list/input_list = get_pin_data(IC_INPUT, 1) var/index = get_pin_data(IC_INPUT, 2) var/item = get_pin_data(IC_INPUT, 3) - if(!islist(item)) + + // Check if index is valid + if(index > input_list.len) + set_pin_data(IC_OUTPUT, 1, input_list) + push_data() + activate_pin(3) + return + + if(!islist(item)) var/list/red_list = input_list.Copy() //crash proof red_list[index] = item set_pin_data(IC_OUTPUT, 1, red_list) @@ -146,7 +201,7 @@ activate_pin(2) -obj/item/integrated_circuit/lists/len +/obj/item/integrated_circuit/lists/len name = "len circuit" desc = "This circuit will return the length of the list." inputs = list( @@ -154,7 +209,7 @@ obj/item/integrated_circuit/lists/len ) outputs = list( "item" = IC_PINTYPE_NUMBER - ) + ) icon_state = "addition" spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH @@ -169,20 +224,20 @@ obj/item/integrated_circuit/lists/len name = "join text circuit" desc = "This circuit will combine two lists into one and output it as a string." extended_desc = "Default settings will encode the entire list into a string." + icon_state = "join" inputs = list( "list to join" = IC_PINTYPE_LIST,// - "delimiter" = IC_PINTYPE_CHAR, - "start" = IC_PINTYPE_NUMBER, + "delimiter" = IC_PINTYPE_STRING, + "start" = IC_PINTYPE_INDEX, "end" = IC_PINTYPE_NUMBER - ) + ) inputs_default = list( - "2" = ",", - "3" = 1, + "2" = ", ", "4" = 0 - ) + ) outputs = list( "joined text" = IC_PINTYPE_STRING - ) + ) icon_state = "addition" spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH @@ -200,3 +255,92 @@ obj/item/integrated_circuit/lists/len set_pin_data(IC_OUTPUT, 1, result) push_data() activate_pin(2) + + +/obj/item/integrated_circuit/lists/constructor + name = "large list constructor" + desc = "This circuit will build a list out of sixteen input values." + icon_state = "constr8" + inputs = list() + outputs = list( + "result" = IC_PINTYPE_LIST + ) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + var/number_of_pins = 16 + +/obj/item/integrated_circuit/lists/constructor/Initialize() + for(var/i = 1 to number_of_pins) + inputs["input [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called. + complexity = number_of_pins / 2 + . = ..() + +/obj/item/integrated_circuit/lists/constructor/do_work() + var/list/output_list = list() + for(var/i = 1 to number_of_pins) + var/data = get_pin_data(IC_INPUT, i) + + // No nested lists + if(!islist(data)) + output_list += data + else + output_list += null + + set_pin_data(IC_OUTPUT, 1, output_list) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/lists/constructor/small + name = "list constructor" + desc = "This circuit will build a list out of four input values." + icon_state = "constr" + number_of_pins = 4 + +/obj/item/integrated_circuit/lists/constructor/medium + name = "medium list constructor" + desc = "This circuit will build a list out of eight input values." + icon_state = "constr8" + number_of_pins = 8 + + +/obj/item/integrated_circuit/lists/deconstructor + name = "large list deconstructor" + desc = "This circuit will write first sixteen entries of input list, starting with index, into the output values." + icon_state = "deconstr8" + inputs = list( + "input" = IC_PINTYPE_LIST, + "index" = IC_PINTYPE_INDEX + ) + outputs = list() + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + var/number_of_pins = 4 + +/obj/item/integrated_circuit/lists/deconstructor/Initialize() + for(var/i = 1 to number_of_pins) + outputs["output [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called. + complexity = number_of_pins / 2 + . = ..() + +/obj/item/integrated_circuit/lists/deconstructor/do_work() + var/list/input_list = get_pin_data(IC_INPUT, 1) + var/start_index = get_pin_data(IC_INPUT, 2) + + for(var/i = 1 to number_of_pins) + var/list_index = i + start_index - 1 + if(list_index > input_list.len) + set_pin_data(IC_OUTPUT, i, null) + else + set_pin_data(IC_OUTPUT, i, input_list[list_index]) + + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/lists/deconstructor/small + name = "list deconstructor" + desc = "This circuit will write first four entries of input list, starting with index, into the output values." + icon_state = "deconstr" + number_of_pins = 4 + +/obj/item/integrated_circuit/lists/deconstructor/medium + name = "medium list deconstructor" + desc = "This circuit will write first eight entries of input list, starting with index, into the output values." + number_of_pins = 8 diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm index fb78915f11..bc22204a2d 100644 --- a/code/modules/integrated_electronics/subtypes/manipulation.dm +++ b/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -346,9 +346,9 @@ /obj/item/integrated_circuit/manipulation/thrower name = "thrower" - desc = "A compact launcher to throw things from inside or nearby tiles" - extended_desc = "The first and second inputs need to be numbers. They are coordinates to throw thing at, relative to the machine itself. \ - The 'fire' activator will cause the mechanism to attempt to throw thing at the coordinates, if possible. Note that the \ + desc = "A compact launcher to throw things from inside or nearby tiles." + extended_desc = "The first and second inputs need to be numbers. They are coordinates to throw thing at, relative to the machine itself. \ + The 'fire' activator will cause the mechanism to attempt to throw thing at the coordinates, if possible. Note that the \ projectile need to be inside the machine, or to be on an adjacent tile, and to be up to medium size." complexity = 15 w_class = WEIGHT_CLASS_SMALL @@ -365,26 +365,39 @@ spawn_flags = IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4) power_draw_per_use = 50 + var/max_w_class = WEIGHT_CLASS_NORMAL /obj/item/integrated_circuit/manipulation/thrower/do_work() - var/datum/integrated_io/target_x = inputs[1] - var/datum/integrated_io/target_y = inputs[2] - var/datum/integrated_io/projectile = inputs[3] - if(!isweakref(projectile.data)) - return - var/obj/item/A = projectile.data.resolve() - if(A.anchored || (A.w_class > WEIGHT_CLASS_NORMAL)) - return - var/turf/T = get_turf(assembly) - if(!(A.Adjacent(T) || (A in assembly.GetAllContents()))) - return - if(assembly) - if(isnum(target_x.data)) - target_x.data = round(target_x.data, 1) - if(isnum(target_y.data)) - target_y.data = round(target_y.data, 1) - var/_x = Clamp(T.x + target_x.data, 0, world.maxx) - var/_y = Clamp(T.y + target_y.data, 0, world.maxy) + var/target_x_rel = round(get_pin_data(IC_INPUT, 1)) + var/target_y_rel = round(get_pin_data(IC_INPUT, 2)) + var/obj/item/A = get_pin_data_as_type(IC_INPUT, 3, /obj/item) - A.forceMove(drop_location()) - A.throw_at(locate(_x, _y, T.z), round(Clamp(sqrt(target_x.data*target_x.data+target_y.data*target_y.data),0,8),1), 3) + if(!A || A.anchored || (A.w_class > max_w_class)) + return + + var/atom/movable/acting_object = get_object() + if(!A.Adjacent(acting_object) && !(A in acting_object.GetAllContents())) + return + + var/turf/T = get_turf(acting_object) + if(!T) + return + + // No ejecting assembly components or power cells + if(assembly) + if((A in assembly.assembly_components) || A == assembly.battery) + return + + // If the item is in mob's inventory, try to remove it from there. + if(ismob(A.loc)) + var/mob/living/M = A.loc + if(!M.temporarilyRemoveItemFromInventory(A)) + return + + + var/x_abs = Clamp(T.x + target_x_rel, 0, world.maxx) + var/y_abs = Clamp(T.y + target_y_rel, 0, world.maxy) + var/range = round(Clamp(sqrt(target_x_rel*target_x_rel+target_y_rel*target_y_rel),0,8),1) + + A.forceMove(drop_location()) + A.throw_at(locate(x_abs, y_abs, T.z), range, 3) diff --git a/code/modules/integrated_electronics/subtypes/memory.dm b/code/modules/integrated_electronics/subtypes/memory.dm index 548ea3fa1d..c7fed41847 100644 --- a/code/modules/integrated_electronics/subtypes/memory.dm +++ b/code/modules/integrated_electronics/subtypes/memory.dm @@ -11,12 +11,12 @@ power_draw_per_use = 1 var/number_of_pins = 1 -/obj/item/integrated_circuit/memory/New() +/obj/item/integrated_circuit/memory/Initialize() for(var/i = 1 to number_of_pins) inputs["input [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called. outputs["output [i]"] = IC_PINTYPE_ANY complexity = number_of_pins - ..() + . = ..() /obj/item/integrated_circuit/memory/examine(mob/user) ..() diff --git a/code/modules/integrated_electronics/subtypes/output.dm b/code/modules/integrated_electronics/subtypes/output.dm index 16839cc509..7cb2479ec9 100644 --- a/code/modules/integrated_electronics/subtypes/output.dm +++ b/code/modules/integrated_electronics/subtypes/output.dm @@ -126,24 +126,6 @@ power_draw_per_use = 10 var/list/sounds = list() -/obj/item/integrated_circuit/output/text_to_speech - name = "text-to-speech circuit" - desc = "Takes any string as an input and will make the device say the string when pulsed." - 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 - inputs = list("text" = IC_PINTYPE_STRING) - outputs = list() - activators = list("to speech" = IC_PINTYPE_PULSE_IN) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 60 - -/obj/item/integrated_circuit/output/text_to_speech/do_work() - text = get_pin_data(IC_INPUT, 1) - if(!isnull(text)) - var/obj/O = assembly ? loc : assembly - O.say(sanitize(text)) - /obj/item/integrated_circuit/output/sound/Initialize() .= ..() extended_desc = list() @@ -221,6 +203,26 @@ spawn_flags = IC_SPAWN_RESEARCH origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 1) + +/obj/item/integrated_circuit/output/text_to_speech + name = "text-to-speech circuit" + desc = "Takes any string as an input and will make the device say the string when pulsed." + 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 + inputs = list("text" = IC_PINTYPE_STRING) + outputs = list() + activators = list("to speech" = IC_PINTYPE_PULSE_IN) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + power_draw_per_use = 60 + +/obj/item/integrated_circuit/output/text_to_speech/do_work() + text = get_pin_data(IC_INPUT, 1) + if(!isnull(text)) + var/atom/movable/A = get_object() + A.say(sanitize(text)) + + /obj/item/integrated_circuit/output/video_camera name = "video camera circuit" desc = "Takes a string as a name and a boolean to determine whether it is on, and uses this to be a camera linked to the research network." @@ -291,19 +293,26 @@ /obj/item/integrated_circuit/output/led name = "light-emitting diode" - desc = "Takes a boolean value in, and if the boolean value is 'true-equivalent', the LED will be marked as lit on examine." + desc = "RGB LED. Takes a boolean value in, and if the boolean value is 'true-equivalent', the LED will be marked as lit on examine." extended_desc = "TRUE-equivalent values are: Non-empty strings, non-zero numbers, and valid refs." complexity = 0.1 icon_state = "led" - inputs = list("lit" = IC_PINTYPE_BOOLEAN) + inputs = list( + "lit" = IC_PINTYPE_BOOLEAN, + "color" = IC_PINTYPE_COLOR + ) outputs = list() activators = list() + inputs_default = list( + "2" = "#FF0000" + ) power_draw_idle = 0 // Raises to 1 when lit. spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - var/led_color + var/led_color = "#FF0000" /obj/item/integrated_circuit/output/led/on_data_written() power_draw_idle = get_pin_data(IC_INPUT, 1) ? 1 : 0 + led_color = get_pin_data(IC_INPUT, 2) /obj/item/integrated_circuit/output/led/power_fail() set_pin_data(IC_INPUT, 1, FALSE) @@ -317,39 +326,3 @@ text_output += "\an ["\improper[name]"] labeled '[displayed_name]'" text_output += " which is currently [get_pin_data(IC_INPUT, 1) ? "lit *" : "unlit"]." to_chat(user, text_output) - -/obj/item/integrated_circuit/output/led/red - name = "red LED" - led_color = "#FF0000" - -/obj/item/integrated_circuit/output/led/orange - name = "orange LED" - led_color = "#FF9900" - -/obj/item/integrated_circuit/output/led/yellow - name = "yellow LED" - led_color = "#FFFF00" - -/obj/item/integrated_circuit/output/led/green - name = "green LED" - led_color = "#008000" - -/obj/item/integrated_circuit/output/led/blue - name = "blue LED" - led_color = "#0000FF" - -/obj/item/integrated_circuit/output/led/purple - name = "purple LED" - led_color = "#800080" - -/obj/item/integrated_circuit/output/led/cyan - name = "cyan LED" - led_color = "#00FFFF" - -/obj/item/integrated_circuit/output/led/white - name = "white LED" - led_color = "#FFFFFF" - -/obj/item/integrated_circuit/output/led/pink - name = "pink LED" - led_color = "#FF00FF" diff --git a/icons/obj/assemblies/electronic_components.dmi b/icons/obj/assemblies/electronic_components.dmi new file mode 100644 index 0000000000..cdfa386233 Binary files /dev/null and b/icons/obj/assemblies/electronic_components.dmi differ diff --git a/icons/obj/assemblies/electronic_misc.dmi b/icons/obj/assemblies/electronic_misc.dmi new file mode 100644 index 0000000000..226b82e499 Binary files /dev/null and b/icons/obj/assemblies/electronic_misc.dmi differ diff --git a/icons/obj/assemblies/electronic_setups.dmi b/icons/obj/assemblies/electronic_setups.dmi new file mode 100644 index 0000000000..7074d08328 Binary files /dev/null and b/icons/obj/assemblies/electronic_setups.dmi differ diff --git a/icons/obj/assemblies/electronic_tools.dmi b/icons/obj/assemblies/electronic_tools.dmi new file mode 100644 index 0000000000..5c0b2faaa9 Binary files /dev/null and b/icons/obj/assemblies/electronic_tools.dmi differ diff --git a/icons/obj/electronic_assemblies.dmi b/icons/obj/electronic_assemblies.dmi deleted file mode 100644 index 8faa77ad02..0000000000 Binary files a/icons/obj/electronic_assemblies.dmi and /dev/null differ diff --git a/icons/obj/electronic_assemblies2.dmi b/icons/obj/electronic_assemblies2.dmi deleted file mode 100644 index 6cfb51affc..0000000000 Binary files a/icons/obj/electronic_assemblies2.dmi and /dev/null differ diff --git a/tgstation.dme b/tgstation.dme index e5d267b667..0cdc60eb29 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -1558,6 +1558,7 @@ #include "code\modules\integrated_electronics\core\special_pins\char_pin.dm" #include "code\modules\integrated_electronics\core\special_pins\color_pin.dm" #include "code\modules\integrated_electronics\core\special_pins\dir_pin.dm" +#include "code\modules\integrated_electronics\core\special_pins\index_pin.dm" #include "code\modules\integrated_electronics\core\special_pins\list_pin.dm" #include "code\modules\integrated_electronics\core\special_pins\number_pin.dm" #include "code\modules\integrated_electronics\core\special_pins\ref_pin.dm"
[jointext(words, null)]