diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 071dab20b1..362b099829 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -536,3 +536,5 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
#define LOOT_RESTRICTION_CKEY_PILE 4 //Idem
#define WANTED_FILE "wanted_message.json"
+
+#define UTF8HEADER "" //I WOULD LOVE TO DEFINE THIS IN SANDCODE BUT FREAKING CODE DOESN'T GET IT THEN
diff --git a/code/modules/integrated_electronics/core/analyzer.dm b/code/modules/integrated_electronics/core/analyzer.dm
index 7e30529bf4..c3851cdb32 100644
--- a/code/modules/integrated_electronics/core/analyzer.dm
+++ b/code/modules/integrated_electronics/core/analyzer.dm
@@ -9,6 +9,11 @@
/obj/item/integrated_electronics/analyzer/afterattack(var/atom/A, var/mob/living/user)
. = ..()
if(istype(A, /obj/item/electronic_assembly))
+ var/obj/item/electronic_assembly/EA = A
+ if(EA.idlock)
+ to_chat(user, "[A] is currently identity-locked and can't be analyzed.")
+ return FALSE
+
var/saved = "[A.name] analyzed! On circuit printers with cloning enabled, you may use the code below to clone the circuit:
[SScircuit.save_electronic_assembly(A)]"
if(saved)
to_chat(user, "You scan [A].")
diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm
index c3e0a7abcc..007caa7c06 100644
--- a/code/modules/integrated_electronics/core/assemblies.dm
+++ b/code/modules/integrated_electronics/core/assemblies.dm
@@ -33,6 +33,9 @@
var/prefered_hud_icon = "hudstat" // Used by the AR circuit to change the hud icon.
var/creator // circuit creator if any
var/static/next_assembly_id = 0
+ var/sealed = FALSE
+ var/datum/weakref/idlock = null
+
hud_possible = list(DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD, DIAG_CIRCUIT_HUD) //diagnostic hud overlays
max_integrity = 50
pass_flags = 0
@@ -65,7 +68,7 @@
src.max_complexity = round(max_complexity)
/obj/item/electronic_assembly/GenerateTag()
- tag = "assembly_[next_assembly_id++]"
+ tag = "assembly_[next_assembly_id++]"
/obj/item/electronic_assembly/examine(mob/user)
. = ..()
@@ -77,15 +80,14 @@
if((isobserver(user) && ckeys_allowed_to_scan[user.ckey]) || IsAdminGhost(user))
. += "You can scan this circuit."
- for(var/I in assembly_components)
- var/obj/item/integrated_circuit/IC = I
- var/text = IC.external_examine(user)
- if(text)
- . += text
+ for(var/obj/item/integrated_circuit/I in assembly_components)
+ I.external_examine(user)
if(opened)
interact(user)
/obj/item/electronic_assembly/proc/check_interactivity(mob/user)
+ if(!istype(user, /mob))
+ return
return user.canUseTopic(src, BE_CLOSE)
/obj/item/electronic_assembly/Bump(atom/AM)
@@ -128,77 +130,185 @@
diag_hud_set_circuitcell()
/obj/item/electronic_assembly/proc/handle_idle_power()
+
// First we generate power.
for(var/obj/item/integrated_circuit/passive/power/P in assembly_components)
P.make_energy()
// Now spend it.
- 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()
+ for(var/obj/item/integrated_circuit/I in assembly_components)
+ if(I.power_draw_idle)
+ if(!draw_power(I.power_draw_idle))
+ I.power_fail()
-/obj/item/electronic_assembly/interact(mob/user)
- ui_interact(user)
+/obj/item/electronic_assembly/interact(mob/user, circuit)
+ ui_interact(user, circuit)
-/obj/item/electronic_assembly/ui_interact(mob/user)
+/obj/item/electronic_assembly/ui_interact(mob/user, obj/item/integrated_circuit/circuit_pins)
. = ..()
if(!check_interactivity(user))
return
var/total_part_size = return_total_size()
var/total_complexity = return_total_complexity()
- var/HTML = ""
+ var/datum/browser/popup = new(user, "scannernew", name, 800, 630) // Set up the popup browser window
+ popup.add_stylesheet("scannernew", 'html/browser/assembly_ui.css')
- HTML += "
[name]"
-
- 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.
"
+ var/HTML = "[UTF8HEADER][name]\
+ \
+ Refresh | Rename
\
+ [total_part_size]/[max_components] ([round((total_part_size / max_components) * 100, 0.1)]%) space taken up in the assembly.
\
+ [total_complexity]/[max_complexity] ([round((total_complexity / max_complexity) * 100, 0.1)]%) maximum complexity.
"
if(battery)
- HTML += "[round(battery.charge, 0.1)]/[battery.maxcharge] ([round(battery.percent(), 0.1)]%) cell charge. \[Remove\]"
+ HTML += "[round(battery.charge, 0.1)]/[battery.maxcharge] ([round(battery.percent(), 0.1)]%) cell charge. Remove"
else
HTML += "No power cell detected!"
- HTML += "
"
+ HTML += "
"
+ //Getting the newest viewed circuit to compare with new circuit list
+ if(!circuit_pins || !istype(circuit_pins,/obj/item/integrated_circuit) || !(circuit_pins in assembly_components))
+ if(assembly_components.len > 0)
+ circuit_pins = assembly_components[1]
- HTML += "Components:"
+
+ HTML += " | "
+
+
+ HTML += " |
"
+
+ popup.set_content(HTML)
+ popup.open()
/obj/item/electronic_assembly/Topic(href, href_list)
if(..())
@@ -229,49 +339,70 @@
battery = null
diag_hud_set_circuitstat() //update diagnostic hud
+ var/obj/item/integrated_circuit/component
+
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
+ component = locate(href_list["component"]) in assembly_components
- add_allowed_scanner(usr.ckey)
+ if(!component)
+ 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)
+ if(href_list["scan"])
+ var/obj/held_item = usr.get_active_held_item()
+ if(istype(held_item, /obj/item/integrated_electronics/debugger))
+ var/obj/item/integrated_electronics/debugger/D = held_item
+ if(D.accepting_refs)
+ D.afterattack(component, usr, TRUE)
+ else
+ to_chat(usr, "The debugger's 'ref scanner' needs to be on.")
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
+ to_chat(usr, "You need a debugger set to 'ref' mode to do that.")
- // 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
+ // Builtin components are not supposed to be removed or rearranged
+ if(!component.removable)
+ return
- assembly_components.Remove(component)
- assembly_components.Insert(current_pos, component)
+ add_allowed_scanner(usr.ckey)
- interact(usr) // To refresh the UI.
+ // Find the position of a first removable component
+ var/first_removable_pos = 0
+ for(var/i in assembly_components)
+ first_removable_pos++
+ var/obj/item/integrated_circuit/temp_component = i
+ if(temp_component.removable)
+ break
+
+ if(href_list["remove"])
+ if(try_remove_component(component, usr))
+ component = null
+
+ if(href_list["rename_component"])
+ component.rename_component(usr)
+ if(component.assembly)
+ component.assembly.add_allowed_scanner(usr.ckey)
+
+ if(href_list["interact"])
+ var/obj/item/I = usr.get_active_held_item()
+ if(istype(I))
+ I.melee_attack_chain(usr, component)
+ else
+ component.attack_hand(usr)
+
+ // Adjust the position
+ if(href_list["change_pos"])
+ var/new_pos = max(input(usr,"Write the new number","New position") as num,1)
+
+ if(new_pos > assembly_components.len)
+ new_pos = assembly_components.len
+
+ if(new_pos < first_removable_pos)
+ new_pos = first_removable_pos
+
+ assembly_components.Remove(component)
+ assembly_components.Insert(new_pos, component)
+
+ interact(usr, component) // To refresh the UI.
/obj/item/electronic_assembly/pickup(mob/living/user)
. = ..()
@@ -307,31 +438,29 @@
/obj/item/electronic_assembly/proc/can_move()
return FALSE
-/obj/item/electronic_assembly/update_icon_state()
+/obj/item/electronic_assembly/update_icon()
if(opened)
icon_state = initial(icon_state) + "-open"
else
icon_state = initial(icon_state)
-
-/obj/item/electronic_assembly/update_overlays()
- . = ..()
+ cut_overlays()
if(detail_color == COLOR_ASSEMBLY_BLACK) //Black colored overlay looks almost but not exactly like the base sprite, so just cut the overlay and avoid it looking kinda off.
return
- . += mutable_appearance('icons/obj/assemblies/electronic_setups.dmi', "[icon_state]-color", color = detail_color)
+ var/mutable_appearance/detail_overlay = mutable_appearance('icons/obj/assemblies/electronic_setups.dmi', "[icon_state]-color")
+ detail_overlay.color = detail_color
+ add_overlay(detail_overlay)
/obj/item/electronic_assembly/proc/return_total_complexity()
- . = 0
- var/obj/item/integrated_circuit/part
- for(var/p in assembly_components)
- part = p
- . += part.complexity
+ var/returnvalue = 0
+ for(var/obj/item/integrated_circuit/part in assembly_components)
+ returnvalue += part.complexity
+ return(returnvalue)
/obj/item/electronic_assembly/proc/return_total_size()
- . = 0
- var/obj/item/integrated_circuit/part
- for(var/p in assembly_components)
- part = p
- . += part.size
+ var/returnvalue = 0
+ for(var/obj/item/integrated_circuit/part in assembly_components)
+ returnvalue += part.size
+ return(returnvalue)
// Returns true if the circuit made it inside.
/obj/item/electronic_assembly/proc/try_add_component(obj/item/integrated_circuit/IC, mob/user)
@@ -411,9 +540,10 @@
component.disconnect_all()
component.forceMove(drop_location())
component.assembly = null
- assembly_components.Remove(component)
- //decriment numbers for diagnostic hud
+ assembly_components -= component
+
+ //decrement numbers for diagnostic hud
if(component.action_flags & IC_ACTION_COMBAT)
combat_circuits -= 1;
if(component.action_flags & IC_ACTION_LONG_RANGE)
@@ -432,6 +562,9 @@
/obj/item/electronic_assembly/screwdriver_act(mob/living/user, obj/item/I)
+ if(sealed)
+ to_chat(user,"The assembly is sealed. Any attempt to force it open would break it.")
+ return FALSE
if(..())
return TRUE
I.play_tool_sound(src)
@@ -440,9 +573,75 @@
update_icon()
return TRUE
+/obj/item/electronic_assembly/welder_act(mob/living/user, obj/item/I)
+ var/type_to_use
+
+ if(!sealed)
+ type_to_use = input("What would you like to do?","[src] type setting") as null|anything in list("repair", "seal")
+ else
+ type_to_use = input("What would you like to do?","[src] type setting") as null|anything in list("repair", "unseal")
+
+ switch(type_to_use)
+ if("repair")
+ to_chat(world,"Integrity: [obj_integrity] / [max_integrity]")
+ if(obj_integrity < max_integrity)
+ obj_integrity = min(obj_integrity + 20,max_integrity)
+ to_chat(world,"Integrity: [obj_integrity] / [max_integrity]")
+ to_chat(user,"You fix the dents and scratches of the assembly.")
+ to_chat(world,user)
+ return TRUE
+
+ else
+ to_chat(user,"The assembly is already in impeccable condition.")
+ return FALSE
+
+ if("seal")
+ if(!opened)
+ sealed = TRUE
+ if(I.use_tool(src, user, 50, volume=100, amount=3))
+ to_chat(user,"You seal the assembly, making it impossible to be opened.")
+ return TRUE
+
+ else
+ to_chat(user,"You need to close the assembly first before sealing it indefinitely!")
+ return FALSE
+
+ if("unseal")
+ to_chat(user,"You start unsealing the assembly carefully...")
+ if(I.use_tool(src, user, 50, volume=250, amount=3))
+ for(var/obj/item/integrated_circuit/IC in assembly_components)
+ if(prob(50))
+ IC.disconnect_all()
+
+ to_chat(user,"You unsealed the assembly.")
+ sealed = FALSE
+ return TRUE
+
/obj/item/electronic_assembly/attackby(obj/item/I, mob/living/user)
if(can_anchor && default_unfasten_wrench(user, I, 20))
return
+
+ // ID-Lock part: check if we have an id-lock and only lock if we're not trying to get values from it, to prevent accidents
+ if(istype(I, /obj/item/integrated_electronics/debugger))
+ var/obj/item/integrated_electronics/debugger/debugger = I
+ if(debugger.idlock)
+ // check if unlocked to lock
+ if(!idlock)
+ idlock = debugger.idlock
+ to_chat(user,"You lock \the [src].")
+
+ //if locked, unlock if ids match
+ else
+ if(idlock.resolve() == debugger.idlock.resolve())
+ idlock = null
+ to_chat(user,"You unlock \the [src].")
+
+ else
+ to_chat(user,"The scanned ID doesn't match with \the [src]'s lock.")
+
+ debugger.idlock = null
+ return
+
if(istype(I, /obj/item/integrated_circuit))
if(!user.canUnEquip(I))
return FALSE
@@ -452,6 +651,7 @@
for(var/obj/item/integrated_circuit/input/S in assembly_components)
S.attackby_react(I,user,user.a_intent)
return ..()
+
else if(istype(I, /obj/item/multitool) || istype(I, /obj/item/integrated_electronics/wirer) || istype(I, /obj/item/integrated_electronics/debugger))
if(opened)
interact(user)
@@ -461,6 +661,7 @@
for(var/obj/item/integrated_circuit/input/S in assembly_components)
S.attackby_react(I,user,user.a_intent)
return ..()
+
else if(istype(I, /obj/item/stock_parts/cell))
if(!opened)
to_chat(user, "[src]'s hatch is closed, so you can't access \the [src]'s power supplier.")
@@ -478,10 +679,12 @@
playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
to_chat(user, "You slot the [I] inside \the [src]'s power supplier.")
return TRUE
+
else if(istype(I, /obj/item/integrated_electronics/detailer))
var/obj/item/integrated_electronics/detailer/D = I
detail_color = D.detail_color
update_icon()
+
else
if(user.a_intent != INTENT_HELP)
return ..()
@@ -492,7 +695,7 @@
var/i = 0
//Check if there is another component with the same name and append a number for identification
for(var/s in input_selection)
- var/obj/item/integrated_circuit/s_circuit = input_selection[s]
+ var/obj/item/integrated_circuit/s_circuit = input_selection[s] //The for-loop iterates the keys of the associative list.
if(s_circuit.name == input.name && s_circuit.displayed_name == input.displayed_name && s_circuit != input)
i++
var/disp_name= "[input.displayed_name] \[[input]\]"
@@ -531,7 +734,7 @@
var/i = 0
//Check if there is another component with the same name and append a number for identification
for(var/s in input_selection)
- var/obj/item/integrated_circuit/s_circuit = input_selection[s]
+ var/obj/item/integrated_circuit/s_circuit = input_selection[s] //The for-loop iterates the keys of an associative list.
if(s_circuit.name == input.name && s_circuit.displayed_name == input.displayed_name && s_circuit != input)
i++
var/disp_name= "[input.displayed_name] \[[input]\]"
@@ -617,11 +820,6 @@
return
..()
-/obj/item/electronic_assembly/can_trigger_gun(mob/living/user) //sanity checks against pocket death weapon circuits
- if(!can_fire_equipped || !user.is_holding(src))
- return FALSE
- return ..()
-
/obj/item/electronic_assembly/default //The /default electronic_assemblys are to allow the introduction of the new naming scheme without breaking old saves.
name = "type-a electronic assembly"
@@ -736,7 +934,6 @@
icon_state = "setup_dildo_large"
desc = "It's a case, for building medium-sized electronics with. This one has a phallic design."
-
/obj/item/electronic_assembly/large
name = "electronic machine"
icon_state = "setup_large"
diff --git a/code/modules/integrated_electronics/core/debugger.dm b/code/modules/integrated_electronics/core/debugger.dm
index e3fded3a82..4b50af56c3 100644
--- a/code/modules/integrated_electronics/core/debugger.dm
+++ b/code/modules/integrated_electronics/core/debugger.dm
@@ -10,9 +10,11 @@
var/data_to_write = null
var/accepting_refs = FALSE
var/copy_values = FALSE
+ var/copy_id = FALSE
+ var/datum/weakref/idlock = null
/obj/item/integrated_electronics/debugger/attack_self(mob/user)
- var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref","copy","null")
+ var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref","copy","null","id lock")
if(!user.IsAdvancedToolUser())
return
@@ -21,6 +23,7 @@
if("string")
accepting_refs = FALSE
copy_values = FALSE
+ copy_id = FALSE
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
@@ -28,6 +31,7 @@
if("number")
accepting_refs = FALSE
copy_values = FALSE
+ copy_id = FALSE
new_data = input(user, "Now type in a number.","[src] number writing") as null|num
if(isnum(new_data) && user.IsAdvancedToolUser())
data_to_write = new_data
@@ -35,17 +39,25 @@
if("ref")
accepting_refs = TRUE
copy_values = FALSE
+ copy_id = FALSE
to_chat(user, "You turn \the [src]'s ref scanner on. Slide it across \
an object for a ref of that object to save it in memory.")
if("copy")
accepting_refs = FALSE
copy_values = TRUE
+ copy_id = FALSE
to_chat(user, "You turn \the [src]'s value copier on. Use it on a pin \
to save its current value in memory.")
if("null")
data_to_write = null
copy_values = FALSE
to_chat(user, "You set \the [src]'s memory to absolutely nothing.")
+ if("id lock")
+ accepting_refs = FALSE
+ copy_values = FALSE
+ copy_id = TRUE
+ to_chat(user, "You turn \the [src]'s id card scanner on. Use your own card \
+ to store the identity and id-lock an assembly.")
/obj/item/integrated_electronics/debugger/afterattack(atom/target, mob/living/user, proximity)
. = ..()
@@ -56,6 +68,18 @@
now off.")
accepting_refs = FALSE
+ else if(copy_id && proximity)
+ if(istype(target,/obj/item/card/id))
+ idlock = WEAKREF(target)
+ to_chat(user, "You set \the [src]'s card memory to [target.name]. The id card scanner is \
+ now off.")
+
+ else
+ to_chat(user, "You turn the id card scanner is off.")
+
+ copy_id = FALSE
+ return
+
/obj/item/integrated_electronics/debugger/proc/write_data(var/datum/integrated_io/io, mob/user)
//If the pin can take data:
if(io.io_type == DATA_CHANNEL)
diff --git a/code/modules/integrated_electronics/core/detailer.dm b/code/modules/integrated_electronics/core/detailer.dm
index 9720bccfe5..653992c0d3 100644
--- a/code/modules/integrated_electronics/core/detailer.dm
+++ b/code/modules/integrated_electronics/core/detailer.dm
@@ -34,10 +34,11 @@
.=..()
update_icon()
-/obj/item/integrated_electronics/detailer/update_overlays()
- . = ..()
- . += mutable_appearance('icons/obj/assemblies/electronic_tools.dmi', "detailer-color", color = detail_color)
-
+/obj/item/integrated_electronics/detailer/update_icon()
+ cut_overlays()
+ var/mutable_appearance/detail_overlay = mutable_appearance('icons/obj/assemblies/electronic_tools.dmi', "detailer-color")
+ detail_overlay.color = detail_color
+ add_overlay(detail_overlay)
/obj/item/integrated_electronics/detailer/attack_self(mob/user)
var/color_choice = input(user, "Select color.", "Assembly Detailer") as null|anything in color_list
diff --git a/code/modules/integrated_electronics/core/helpers.dm b/code/modules/integrated_electronics/core/helpers.dm
index 5567683006..172b14eba4 100644
--- a/code/modules/integrated_electronics/core/helpers.dm
+++ b/code/modules/integrated_electronics/core/helpers.dm
@@ -140,4 +140,3 @@
for(var/i = 1 to length(string))
r += ascii2text(text2ascii(string,i) ^ text2ascii(key,(i-1)%length(string)+1))
return r
-
diff --git a/code/modules/integrated_electronics/core/integrated_circuit.dm b/code/modules/integrated_electronics/core/integrated_circuit.dm
index f90b584d76..f391ceae26 100644
--- a/code/modules/integrated_electronics/core/integrated_circuit.dm
+++ b/code/modules/integrated_electronics/core/integrated_circuit.dm
@@ -35,10 +35,8 @@ a creative player the means to solve many problems. Circuits are held inside an
/obj/item/integrated_circuit/examine(mob/user)
interact(user)
+ external_examine(user)
. = ..()
- var/text = external_examine(user)
- if(text)
- . += text
// Can be called via electronic_assembly/attackby()
/obj/item/integrated_circuit/proc/additem(var/obj/item/I, var/mob/living/user)
@@ -47,24 +45,24 @@ a creative player the means to solve many problems. Circuits are held inside an
// This should be used when someone is examining while the case is opened.
/obj/item/integrated_circuit/proc/internal_examine(mob/user)
to_chat(user, "This board has [inputs.len] input pin\s, [outputs.len] output pin\s and [activators.len] activation pin\s.")
- for(var/k in 1 to inputs.len)
- var/datum/integrated_io/I = inputs[k]
+ for(var/k in inputs)
+ var/datum/integrated_io/I = k
if(I.linked.len)
to_chat(user, "The '[I]' is connected to [I.get_linked_to_desc()].")
- for(var/k in 1 to outputs.len)
- var/datum/integrated_io/O = outputs[k]
+ for(var/k in outputs)
+ var/datum/integrated_io/O = k
if(O.linked.len)
to_chat(user, "The '[O]' is connected to [O.get_linked_to_desc()].")
- for(var/k in 1 to activators.len)
- var/datum/integrated_io/activate/A = activators[k]
+ for(var/k in activators)
+ var/datum/integrated_io/activate/A = k
if(A.linked.len)
to_chat(user, "The '[A]' is connected to [A.get_linked_to_desc()].")
- to_chat(user, any_examine(user))
+ any_examine(user)
interact(user)
// This should be used when someone is examining from an 'outside' perspective, e.g. reading a screen or LED.
/obj/item/integrated_circuit/proc/external_examine(mob/user)
- return any_examine(user)
+ any_examine(user)
/obj/item/integrated_circuit/proc/any_examine(mob/user)
return
@@ -99,14 +97,14 @@ a creative player the means to solve many problems. Circuits are held inside an
. = ..()
/obj/item/integrated_circuit/emp_act(severity)
- for(var/k in 1 to inputs.len)
- var/datum/integrated_io/I = inputs[k]
+ for(var/k in inputs)
+ var/datum/integrated_io/I = k
I.scramble()
- for(var/k in 1 to outputs.len)
- var/datum/integrated_io/O = outputs[k]
+ for(var/k in outputs)
+ var/datum/integrated_io/O = k
O.scramble()
- for(var/k in 1 to activators.len)
- var/datum/integrated_io/activate/A = activators[k]
+ for(var/k in activators)
+ var/datum/integrated_io/activate/A = k
A.scramble()
@@ -134,32 +132,35 @@ a creative player the means to solve many problems. Circuits are held inside an
if(!check_interactivity(user))
return
- var/window_height = 350
- var/window_width = 655
+ if(assembly)
+ assembly.ui_interact(user, src)
+ return
var/table_edge_width = "30%"
var/table_middle_width = "40%"
- var/HTML = ""
- HTML += "[src.displayed_name]"
- HTML += ""
- HTML += "
"
+ var/datum/browser/popup = new(user, "scannernew", name, 800, 630) // Set up the popup browser window
+ popup.add_stylesheet("scannernew", 'html/browser/assembly_ui.css')
+
+ var/HTML = "[UTF8HEADER][src.displayed_name] \
+ \
+
"
if(assembly)
- HTML += "\[Return to Assembly\]
"
+ HTML += "Return to Assembly
"
+
+ HTML += "Refresh | \
+ Rename | \
+ Copy Ref"
- HTML += "\[Refresh\] | "
- HTML += "\[Rename\] | "
- HTML += "\[Copy Ref\]"
if(assembly && removable)
- HTML += " | \[Remove\]"
- HTML += "
"
+ HTML += " | Remove"
- HTML += ""
- HTML += ""
- HTML += ""
- HTML += ""
- HTML += ""
+ HTML += "
\
+ \
+ \
+ \
+ "
var/column_width = 3
var/row_height = max(inputs.len, outputs.len, 1)
@@ -168,25 +169,27 @@ a creative player the means to solve many problems. Circuits are held inside an
HTML += ""
for(var/j = 1 to column_width)
var/datum/integrated_io/io = null
- var/words = list()
+ var/words
var/height = 1
switch(j)
if(1)
io = get_pin_ref(IC_INPUT, i)
if(io)
words += "[io.display_pin_type()] [io.name] \
- [io.display_data(io.data)]
"
+ [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 += ""
if(outputs.len > inputs.len)
height = 1
if(2)
if(i == 1)
- words += "[src.displayed_name]
[src.name != src.displayed_name ? "([src.name])":""]
[src.desc]"
+ words += "[displayed_name]
[name != displayed_name ? "([name])":""]
[desc]"
height = row_height
else
continue
@@ -194,54 +197,52 @@ a creative player the means to solve many problems. Circuits are held inside an
io = get_pin_ref(IC_OUTPUT, i)
if(io)
words += "[io.display_pin_type()] [io.name] \
- [io.display_data(io.data)]
"
+ [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 += ""
if(inputs.len > outputs.len)
height = 1
- HTML += "[jointext(words, null)] | "
+ HTML += "[words] | "
HTML += "
"
for(var/activator in activators)
var/datum/integrated_io/io = activator
- var/words = list()
+ var/words
+
+ 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 += ""
+ for(var/k in io.linked)
+ var/datum/integrated_io/linked = k
+ words += "- [linked] \
+ @ [linked.holder.displayed_name]
"
+ words += ""
- HTML += ""
- HTML += "| [jointext(words, null)] | "
- HTML += "
"
+ HTML += "| [words] |
"
- HTML += "
"
- HTML += "
"
+ HTML += "
\
+
Complexity: [complexity] \
+
Cooldown per use: [cooldown_per_use/10] sec"
- HTML += "
Complexity: [complexity]"
- HTML += "
Cooldown per use: [cooldown_per_use/10] sec"
if(ext_cooldown)
- HTML += "
External manipulation cooldown: [ext_cooldown/10] sec"
+ HTML += "
External manipulation cooldown: [ext_cooldown/10] sec"
if(power_draw_idle)
- HTML += "
Power Draw: [power_draw_idle] W (Idle)"
+ HTML += "
Power Draw: [power_draw_idle] W (Idle)"
if(power_draw_per_use)
- HTML += "
Power Draw: [power_draw_per_use] W (Active)" // Borgcode says that powercells' checked_use() takes joules as input.
- HTML += "
[extended_desc]"
+ HTML += "
Power Draw: [power_draw_per_use] W (Active)" // Borgcode says that powercells' checked_use() takes joules as input.
- HTML += ""
- if(assembly)
- user << browse(HTML, "window=assembly-[REF(assembly)];size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1")
- else
- user << browse(HTML, "window=circuit-[REF(src)];size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1")
+ HTML += "
[extended_desc]"
- onclose(user, "assembly-[REF(src.assembly)]")
+ popup.set_content(HTML)
+ popup.open()
/obj/item/integrated_circuit/Topic(href, href_list)
if(!check_interactivity(usr))
@@ -268,7 +269,7 @@ a creative player the means to solve many problems. Circuits are held inside an
linked = locate(href_list["link"]) in pin.linked
if(istype(held_item, /obj/item/integrated_electronics) || istype(held_item, /obj/item/multitool))
- pin.handle_wire(linked, held_item, href_list["act"], usr)
+ update_to_assembly = 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.")
success = FALSE
@@ -291,18 +292,18 @@ a creative player the means to solve many problems. Circuits are held inside an
if(update)
if(assembly && update_to_assembly)
- assembly.interact(usr)
+ assembly.interact(usr, src)
else
interact(usr) // To refresh the UI.
/obj/item/integrated_circuit/proc/push_data()
- for(var/k in 1 to outputs.len)
- var/datum/integrated_io/O = outputs[k]
+ for(var/k in outputs)
+ var/datum/integrated_io/O = k
O.push_data()
/obj/item/integrated_circuit/proc/pull_data()
- for(var/k in 1 to inputs.len)
- var/datum/integrated_io/I = inputs[k]
+ for(var/k in inputs)
+ var/datum/integrated_io/I = k
I.push_data()
/obj/item/integrated_circuit/proc/draw_idle_power()
diff --git a/code/modules/integrated_electronics/core/pins.dm b/code/modules/integrated_electronics/core/pins.dm
index c1bbb900fa..eaeeeb6dfd 100644
--- a/code/modules/integrated_electronics/core/pins.dm
+++ b/code/modules/integrated_electronics/core/pins.dm
@@ -1,22 +1,15 @@
/*
Pins both hold data for circuits, as well move data between them. Some also cause circuits to do their function. DATA_CHANNEL pins are the data holding/moving kind,
where as PULSE_CHANNEL causes circuits to work() when their pulse hits them.
-
-
A visualization of how pins work is below. Imagine the below image involves an addition circuit.
When the bottom pin, the activator, receives a pulse, all the numbers on the left (input) get added, and the answer goes on the right side (output).
-
Inputs Outputs
-
A [2]\ /[8] result
B [1]-\|++|/
C [4]-/|++|
D [1]/ ||
||
Activator
-
-
-
*/
/datum/integrated_io
var/name = "input/output"
@@ -29,7 +22,7 @@ D [1]/ ||
/datum/integrated_io/New(loc, _name, _data, _pin_type,_ord)
name = _name
- if(_data)
+ if(!isnull(_data))
data = _data
if(_pin_type)
pin_type = _pin_type
diff --git a/code/modules/integrated_electronics/core/printer.dm b/code/modules/integrated_electronics/core/printer.dm
index 5f6440bffb..b3e5a122b3 100644
--- a/code/modules/integrated_electronics/core/printer.dm
+++ b/code/modules/integrated_electronics/core/printer.dm
@@ -14,6 +14,7 @@
var/cloning = FALSE // If the printer is currently creating a circuit
var/recycling = FALSE // If an assembly is being emptied into this printer
var/list/program // Currently loaded save, in form of list
+ var/datum/weakref/idlock = null
/obj/item/integrated_circuit_printer/proc/check_interactivity(mob/user)
return user.canUseTopic(src, BE_CLOSE)
@@ -33,8 +34,7 @@
/obj/item/integrated_circuit_printer/Initialize()
. = ..()
- var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, list(/datum/material/iron), MINERAL_MATERIAL_AMOUNT * 25, TRUE, list(/obj/item/stack, /obj/item/integrated_circuit, /obj/item/electronic_assembly))
- materials.precise_insertion = TRUE
+ AddComponent(/datum/component/material_container, list(/datum/material/iron), MINERAL_MATERIAL_AMOUNT * 25, TRUE, list(/obj/item/stack, /obj/item/integrated_circuit, /obj/item/electronic_assembly))
/obj/item/integrated_circuit_printer/proc/print_program(mob/user)
if(!cloning)
@@ -43,6 +43,8 @@
visible_message("[src] has finished printing its assembly!")
playsound(src, 'sound/items/poster_being_created.ogg', 50, TRUE)
var/obj/item/electronic_assembly/assembly = SScircuit.load_electronic_assembly(get_turf(src), program)
+ if(idlock)
+ assembly.idlock = idlock
assembly.creator = key_name(user)
assembly.investigate_log("was printed by [assembly.creator].", INVESTIGATE_CIRCUIT)
cloning = FALSE
@@ -102,13 +104,30 @@
recycling = FALSE
return TRUE
+ if(istype(O, /obj/item/integrated_electronics/debugger))
+ var/obj/item/integrated_electronics/debugger/debugger = O
+ if(!debugger.idlock)
+ return
+
+ if(!idlock)
+ idlock = debugger.idlock
+ debugger.idlock = null
+ to_chat(user, "You set \the [src] to print out id-locked assemblies only.")
+ return
+
+ if(debugger.idlock.resolve() == idlock.resolve())
+ idlock = null
+ debugger.idlock = null
+ to_chat(user, "You reset \the [src]'s protection settings.")
+ return
+
return ..()
/obj/item/integrated_circuit_printer/attack_self(mob/user)
interact(user)
/obj/item/integrated_circuit_printer/interact(mob/user)
- if(!(in_range(src, user) || hasSiliconAccessInArea(user)))
+ if(!(in_range(src, user) || issilicon(user)))
return
if(isnull(current_category))
@@ -125,6 +144,13 @@
else
HTML += "Metal: [materials.total_amount]/[materials.max_amount].
"
+ HTML += "Identity-lock: "
+ if(idlock)
+ var/obj/item/card/id = idlock.resolve()
+ HTML+= "[id.name] | Reset
"
+ else
+ HTML += "None | Reset
"
+
if(CONFIG_GET(flag/ic_printing) || debug)
HTML += "Assembly cloning: [can_clone ? (fast_clone ? "Instant" : "Available") : "Unavailable"].
"
@@ -136,7 +162,7 @@
if((can_clone && CONFIG_GET(flag/ic_printing)) || debug)
HTML += "Here you can load script for your assembly.
"
if(!cloning)
- HTML += " {Load Program} "
+ HTML += " Load Program "
else
HTML += " Load Program"
if(!program)
@@ -150,9 +176,9 @@
HTML += "Categories:"
for(var/category in SScircuit.circuit_fabricator_recipe_list)
if(category != current_category)
- HTML += " \[[category]\] "
+ HTML += " [category] "
else // Bold the button if it's already selected.
- HTML += " \[[category]\] "
+ HTML += " [category] "
HTML += "
"
HTML += "[current_category]
"
@@ -179,6 +205,9 @@
return TRUE
add_fingerprint(usr)
+ if(href_list["id-lock"])
+ idlock = null
+
if(href_list["category"])
current_category = href_list["category"]
diff --git a/code/modules/integrated_electronics/core/saved_circuits.dm b/code/modules/integrated_electronics/core/saved_circuits.dm
index 61ada24b25..3bbf05ea25 100644
--- a/code/modules/integrated_electronics/core/saved_circuits.dm
+++ b/code/modules/integrated_electronics/core/saved_circuits.dm
@@ -361,4 +361,3 @@
assembly.forceMove(loc)
return assembly
-
diff --git a/code/modules/integrated_electronics/core/special_pins/color_pin.dm b/code/modules/integrated_electronics/core/special_pins/color_pin.dm
index 64e4114357..7d4a01b169 100644
--- a/code/modules/integrated_electronics/core/special_pins/color_pin.dm
+++ b/code/modules/integrated_electronics/core/special_pins/color_pin.dm
@@ -46,4 +46,4 @@
/datum/integrated_io/color/display_data(var/input)
if(!isnull(data))
return "([data])"
- return ..()
\ No newline at end of file
+ return ..()
diff --git a/code/modules/integrated_electronics/core/wirer.dm b/code/modules/integrated_electronics/core/wirer.dm
index 95f46564cb..ed27354b6c 100644
--- a/code/modules/integrated_electronics/core/wirer.dm
+++ b/code/modules/integrated_electronics/core/wirer.dm
@@ -15,7 +15,7 @@
var/datum/integrated_io/selected_io = null
var/mode = WIRE
-/obj/item/integrated_electronics/wirer/update_icon_state()
+/obj/item/integrated_electronics/wirer/update_icon()
icon_state = "wirer-[mode]"
/obj/item/integrated_electronics/wirer/proc/wire(var/datum/integrated_io/io, mob/user)
diff --git a/html/browser/assembly_ui.css b/html/browser/assembly_ui.css
new file mode 100644
index 0000000000..02d32c7394
--- /dev/null
+++ b/html/browser/assembly_ui.css
@@ -0,0 +1,29 @@
+div.scrollleft
+{
+ bottom: 0;
+ margin: 0;
+ overflow: scroll;
+ overflow-x: auto;
+ position: absolute;
+ text-indent: 15px;
+ top: 120px;
+ width: 200px;
+}
+
+div.scrollright
+{
+ bottom: 0;
+ left: 210px;
+ margin: 0;
+ right: 0;
+ overflow: scroll;
+ overflow-x: auto;
+ position: absolute;
+ text-indent: 15px;
+ top: 120px;
+}
+
+font.lowtext
+{
+ bottom: 0;
+}