More integrated circuit fixes and code improvements

This commit is contained in:
ACCount
2017-11-26 13:56:47 +03:00
committed by CitadelStationBot
parent d3b3c54e70
commit 0be326633d
29 changed files with 590 additions and 403 deletions
@@ -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
@@ -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 += "<html><head><title>[name]</title></head><body>"
HTML += "<br><a href='?src=[REF(src)]'>\[Refresh\]</a> | "
HTML += "<a href='?src=[REF(src)];rename=1'>\[Rename\]</a><br>"
HTML += "<a href='?src=[REF(src)]'>\[Refresh\]</a> | <a href='?src=[REF(src)];rename=1'>\[Rename\]</a><br>"
HTML += "[total_part_size]/[max_components] ([round((total_part_size / max_components) * 100, 0.1)]%) space taken up in the assembly.<br>"
HTML += "[total_complexity]/[max_complexity] ([round((total_complexity / max_complexity) * 100, 0.1)]%) maximum complexity.<br>"
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 += "<a href=?src=[REF(circuit)];examine=1;from_assembly=1>[circuit.displayed_name]</a> | "
builtin_components += "<a href=?src=[REF(circuit)];rename=1;from_assembly=1>\[Rename\]</a> | "
builtin_components += "<a href=?src=[REF(circuit)];scan=1;from_assembly=1>\[Scan with Debugger\]</a> | "
builtin_components += "<a href=?src=[REF(circuit)];bottom=[REF(circuit)];from_assembly=1>\[Move to Bottom\]</a>"
builtin_components += "<a href='?src=[REF(circuit)]'>[circuit.displayed_name]</a> | "
builtin_components += "<a href='?src=[REF(circuit)];rename=1;return=1'>\[Rename\]</a> | "
builtin_components += "<a href='?src=[REF(circuit)];scan=1'>\[Scan with Debugger\]</a>"
builtin_components += "<br>"
// Put removable circuits (if any) in separate categories from non-removable
@@ -95,14 +95,17 @@
HTML += "<br>"
for(var/c in components)
for(var/c in assembly_components)
var/obj/item/integrated_circuit/circuit = c
if(circuit.removable)
HTML += "<a href=?src=[REF(circuit)];examine=1;from_assembly=1>[circuit.displayed_name]</a> | "
HTML += "<a href=?src=[REF(circuit)];rename=1;from_assembly=1>\[Rename\]</a> | "
HTML += "<a href=?src=[REF(circuit)];scan=1;from_assembly=1>\[Scan with Debugger\]</a> | "
HTML += "<a href=?src=[REF(circuit)];remove=1;from_assembly=1>\[Remove\]</a> | "
HTML += "<a href=?src=[REF(circuit)];bottom=[REF(circuit)];from_assembly=1>\[Move to Bottom\]</a>"
HTML += "<a href='?src=[REF(circuit)]'>[circuit.displayed_name]</a> | "
HTML += "<a href='?src=[REF(circuit)];rename=1;return=1'>\[Rename\]</a> | "
HTML += "<a href='?src=[REF(circuit)];scan=1'>\[Scan with Debugger\]</a> | "
HTML += "<a href='?src=[REF(src)];component=[REF(circuit)];remove=1'>\[Remove\]</a> | "
HTML += "<a href='?src=[REF(src)];component=[REF(circuit)];up=1' style='text-decoration:none;'>&#8593;</a> "
HTML += "<a href='?src=[REF(src)];component=[REF(circuit)];down=1' style='text-decoration:none;'>&#8595;</a> "
HTML += "<a href='?src=[REF(src)];component=[REF(circuit)];top=1' style='text-decoration:none;'>&#10514;</a> "
HTML += "<a href='?src=[REF(src)];component=[REF(circuit)];bottom=1' style='text-decoration:none;'>&#10515;</a>"
HTML += "<br>"
HTML += "</body></html>"
@@ -125,6 +128,46 @@
to_chat(usr, "<span class='notice'>You pull \the [battery] out of \the [src]'s power supplier.</span>")
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, "<span class='warning'>\The [src]'s hatch is closed, you can't put anything inside.</span>")
return FALSE
@@ -200,12 +240,45 @@
if(!user.transferItemToLoc(IC, src))
return FALSE
IC.assembly = src
to_chat(user, "<span class='notice'>You slide [IC] inside [src].</span>")
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, "<span class='warning'>[src]'s hatch is closed, so you can't fiddle with the internal components.</span>")
return FALSE
if(!IC.removable)
to_chat(user, "<span class='warning'>[src] is permanently attached to the case.</span>")
return FALSE
to_chat(user, "<span class='notice'>You pop \the [src] out of the case, and slide it out.</span>")
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, "<span class='notice'>You slide [I] inside [src].</span>")
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
@@ -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, "<span class='notice'>You set \the [src]'s memory to \"[new_data]\".</span>")
@@ -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
@@ -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, "<span class='notice'>The circuit '[src.name]' is now labeled '[input]'.</span>")
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, "<span class='notice'>The circuit '[name]' is now labeled '[input]'.</span>")
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 += "<div align='center'>"
HTML += "<table border='1' style='undefined;table-layout: fixed; width: 80%'>"
HTML += "<br><a href='?src=[REF(src)];return=1'>\[Return to Assembly\]</a>"
if(assembly)
HTML += "<a href='?src=[REF(src)];return=1'>\[Return to Assembly\]</a><br>"
HTML += "<br><a href='?src=[REF(src)];'>\[Refresh\]</a> | "
HTML += "<a href='?src=[REF(src)]'>\[Refresh\]</a> | "
HTML += "<a href='?src=[REF(src)];rename=1'>\[Rename\]</a> | "
HTML += "<a href='?src=[REF(src)];scan=1'>\[Scan with Device\]</a> | "
if(removable)
HTML += "<a href='?src=[REF(src)];remove=1'>\[Remove\]</a><br>"
HTML += "<a href='?src=[REF(src)];scan=1'>\[Scan with Device\]</a>"
if(assembly && removable)
HTML += " | <a href='?src=[REF(assembly)];component=[REF(src)];remove=1'>\[Remove\]</a>"
HTML += "<br>"
HTML += "<colgroup>"
HTML += "<col style='width: [table_edge_width]'>"
@@ -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 += "<b><a href=?src=[REF(src)];pin_name=1;pin=[REF(io)]>[io.display_pin_type()] [io.name]</a> <a href=?src=[REF(src)];pin_data=1;pin=[REF(io)]>[io.display_data(io.data)]</a></b><br>"
words += "<b><a href='?src=[REF(src)];act=wire;pin=[REF(io)]'>[io.display_pin_type()] [io.name]</a> \
<a href='?src=[REF(src)];act=data;pin=[REF(io)]'>[io.display_data(io.data)]</a></b><br>"
if(io.linked.len)
for(var/k in 1 to io.linked.len)
var/datum/integrated_io/linked = io.linked[k]
words += "<a href=?src=[REF(src)];pin_unwire=1;pin=[REF(io)];link=[REF(linked)]>[linked]</a> \
@ <a href=?src=[REF(linked.holder)];examine=1;>[linked.holder.displayed_name]</a><br>"
words += "<a href='?src=[REF(src)];act=unwire;pin=[REF(io)];link=[REF(linked)]'>[linked]</a> \
@ <a href='?src=[REF(linked.holder)]'>[linked.holder.displayed_name]</a><br>"
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 += "<b><a href=?src=[REF(src)];pin_name=1;pin=[REF(io)]>[io.display_pin_type()] [io.name]</a> <a href=?src=[REF(src)];pin_data=1;pin=[REF(io)]>[io.display_data(io.data)]</a></b><br>"
words += "<b><a href='?src=[REF(src)];act=wire;pin=[REF(io)]'>[io.display_pin_type()] [io.name]</a> \
<a href='?src=[REF(src)];act=data;pin=[REF(io)]'>[io.display_data(io.data)]</a></b><br>"
if(io.linked.len)
for(var/k in 1 to io.linked.len)
var/datum/integrated_io/linked = io.linked[k]
words += "<a href=?src=[REF(src)];pin_unwire=1;pin=[REF(io)];link=[REF(linked)]>[linked]</a> \
@ <a href=?src=[REF(linked.holder)];examine=1;>[linked.holder.displayed_name]</a><br>"
words += "<a href='?src=[REF(src)];act=unwire;pin=[REF(io)];link=[REF(linked)]'>[linked]</a> \
@ <a href='?src=[REF(linked.holder)]'>[linked.holder.displayed_name]</a><br>"
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 += "<b><a href=?src=[REF(src)];pin_name=1;pin=[REF(io)]><font color='FF0000'>[io]</font></a> <a href=?src=[REF(src)];pin_data=1;pin=[REF(io)]><font color='FF0000'>[io.data?"\<PULSE OUT\>":"\<PULSE IN\>"]</font></a></b><br>"
words += "<b><a href='?src=[REF(src)];act=wire;pin=[REF(io)]'><font color='FF0000'>[io]</font></a> "
words += "<a href='?src=[REF(src)];act=data;pin=[REF(io)]'><font color='FF0000'>[io.data?"\<PULSE OUT\>":"\<PULSE IN\>"]</font></a></b><br>"
if(io.linked.len)
for(var/k in 1 to io.linked.len)
var/datum/integrated_io/linked = io.linked[k]
words += "<a href=?src=[REF(src)];pin_unwire=1;pin=[REF(io)];link=[REF(linked)]><font color='FF0000'>[linked]</font></a> \
@ <a href=?src=[REF(linked.holder)];examine=1;><font color='FF0000'>[linked.holder.displayed_name]</font></a><br>"
words += "<a href='?src=[REF(src)];act=unwire;pin=[REF(io)];link=[REF(linked)]'><font color='FF0000'>[linked]</font></a> \
@ <a href='?src=[REF(linked.holder)]'><font color='FF0000'>[linked.holder.displayed_name]</font></a><br>"
HTML += "<tr>"
HTML += "<td colspan='3' align='center'>[jointext(words, null)]</td>"
@@ -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, "<span class='warning'>You can't do a whole lot without the proper tools.</span>")
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, "<span class='warning'>You can't do a whole lot without the proper tools.</span>")
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, "<span class='warning'>The debugger's 'ref scanner' needs to be on.</span>")
else
to_chat(usr, "<span class='warning'>You need a multitool/debugger set to 'ref' mode to do that.</span>")
to_chat(usr, "<span class='warning'>You need a debugger set to 'ref' mode to do that.</span>")
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, "<span class='warning'>This circuit is not in an assembly!</span>")
update_to_assembly = TRUE
if(href_list["remove"])
if(!A)
to_chat(usr, "<span class='warning'>This circuit is not in an assembly!</span>")
return
if(!removable)
to_chat(usr, "<span class='warning'>\The [src] seems to be permanently attached to the case.</span>")
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, "<span class='notice'>You pop \the [src] out of the case, and slide it out.</span>")
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.
@@ -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, "<span class='notice'>You input "+new_data+" into the pin.</span>")
return new_data
@@ -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, "<span class='warning'>You need [cost] metal to build that!</span>")
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
@@ -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
@@ -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, "<span class='notice'>You input [new_data ? "new_data" : "NULL"] into the pin.</span>")
write_data_to_pin(new_data)
@@ -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, "<span class='notice'>You input [new_data] into the pin.</span>")
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
@@ -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
@@ -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, "<span class='notice'>You input [new_data ? "[new_data]" : "NULL"] into the pin.</span>")
write_data_to_pin(new_data)
@@ -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, "<span class='warning'>Both \the [io.holder] and \the [selected_io.holder] need to be inside the same assembly.</span>")
return
selected_io.linked |= io
io.linked |= selected_io
selected_io.connect_pin(io)
to_chat(user, "<span class='notice'>You connect \the [selected_io.holder]'s [selected_io.name] to \the [io.holder]'s [io.name].</span>")
mode = WIRE
@@ -64,8 +63,7 @@
the same pin is rather moot.</span>")
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, "<span class='notice'>You disconnect \the [selected_io.holder]'s [selected_io.name] from \
\the [io.holder]'s [io.name].</span>")
selected_io.holder.interact(user) // This is to update the UI.