diff --git a/code/__DEFINES/integrated_electronics.dm b/code/__DEFINES/integrated_electronics.dm
index e2467af26879..8e9e1b7cea62 100644
--- a/code/__DEFINES/integrated_electronics.dm
+++ b/code/__DEFINES/integrated_electronics.dm
@@ -1,6 +1,6 @@
-#define IC_INPUT "input"
-#define IC_OUTPUT "output"
-#define IC_ACTIVATOR "activator"
+#define IC_INPUT "I"
+#define IC_OUTPUT "O"
+#define IC_ACTIVATOR "A"
// Pin functionality.
#define DATA_CHANNEL "data channel"
diff --git a/code/controllers/subsystem/processing/circuit.dm b/code/controllers/subsystem/processing/circuit.dm
index cb10503a8011..73e9ee669df0 100644
--- a/code/controllers/subsystem/processing/circuit.dm
+++ b/code/controllers/subsystem/processing/circuit.dm
@@ -9,8 +9,12 @@ PROCESSING_SUBSYSTEM_DEF(circuit)
var/list/all_exonet_connections = list() //Address = connection datum.
var/list/obj/machinery/exonet_node/all_exonet_nodes = list()
- var/list/all_circuits = list() // Associative list of [circuit_name]:[circuit_path] pairs
+ var/list/all_components = list() // Associative list of [component_name]:[component_path] pairs
+ var/list/cached_components = list() // Associative list of [component_path]:[component] pairs
+ var/list/all_assemblies = list() // Associative list of [assembly_name]:[assembly_path] pairs
+ var/list/cached_assemblies = list() // Associative list of [assembly_path]:[assembly] pairs
var/list/circuit_fabricator_recipe_list = list() // Associative list of [category_name]:[list_of_circuit_paths] pairs
+ var/cost_multiplier = MINERAL_MATERIAL_AMOUNT / 10 // Each circuit cost unit is 200cm3
/datum/controller/subsystem/processing/circuit/Initialize(start_timeofday)
SScircuit.cipherkey = random_string(2000+rand(0,10), GLOB.alphabet)
@@ -19,12 +23,11 @@ PROCESSING_SUBSYSTEM_DEF(circuit)
/datum/controller/subsystem/processing/circuit/proc/circuits_init()
//Cached lists for free performance
- var/list/all_circuits = src.all_circuits
- var/list/circuit_fabricator_recipe_list = src.circuit_fabricator_recipe_list
for(var/path in typesof(/obj/item/integrated_circuit))
var/obj/item/integrated_circuit/IC = path
var/name = initial(IC.name)
- all_circuits[name] = IC // Populating the complete list
+ all_components[name] = path // Populating the component lists
+ cached_components[IC] = new path
if(!(initial(IC.spawn_flags) & (IC_SPAWN_DEFAULT | IC_SPAWN_RESEARCH)))
continue
@@ -35,13 +38,19 @@ PROCESSING_SUBSYSTEM_DEF(circuit)
var/list/category_list = circuit_fabricator_recipe_list[category]
category_list += IC // Populating the fabricator categories
+ for(var/path in typesof(/obj/item/device/electronic_assembly))
+ var/obj/item/device/electronic_assembly/A = path
+ var/name = initial(A.name)
+ all_assemblies[name] = path
+ cached_assemblies[A] = new path
+
+
circuit_fabricator_recipe_list["Assemblies"] = list(
/obj/item/device/electronic_assembly,
/obj/item/device/electronic_assembly/medium,
/obj/item/device/electronic_assembly/large,
/obj/item/device/electronic_assembly/drone
- //new /obj/item/weapon/implant/integrated_circuit,
- //new /obj/item/device/assembly/electronic_assembly
+ ///obj/item/weapon/implant/integrated_circuit
)
circuit_fabricator_recipe_list["Tools"] = list(
diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm
index 5523e582dd4a..fa4a31cfc362 100755
--- a/code/game/machinery/recharger.dm
+++ b/code/game/machinery/recharger.dm
@@ -109,10 +109,7 @@
use_power(250 * recharge_coeff)
using_power = 1
update_icon(using_power)
- if(istype(charging, /obj/item/gun/energy))
- var/obj/item/gun/energy/E = charging
- E.recharge_newshot()
- return
+
if(istype(charging, /obj/item/ammo_box/magazine/recharge))
var/obj/item/ammo_box/magazine/recharge/R = charging
if(R.stored_ammo.len < R.max_ammo)
diff --git a/code/game/objects/items/inducer.dm b/code/game/objects/items/inducer.dm
index e23b2e4a8d04..8f380772e216 100644
--- a/code/game/objects/items/inducer.dm
+++ b/code/game/objects/items/inducer.dm
@@ -119,7 +119,7 @@
user.visible_message("[user] starts recharging [A] with [src].","You start recharging [A] with [src].")
while(C.charge < C.maxcharge)
if(E)
- E.chambered = null // Prevents someone from firing continuously while recharging the gun.
+ E.semicd = TRUE // Prevents someone from firing continuously while recharging the gun.
if(do_after(user, 10, target = user) && cell.charge)
done_any = TRUE
induce(C, coefficient)
@@ -129,7 +129,7 @@
else
break
if(E)
- E.recharge_newshot() //We're done charging, so we'll let someone fire it now.
+ E.reset_semicd() //We're done charging, so we'll let someone fire it now.
if(done_any) // Only show a message if we succeeded at least once
user.visible_message("[user] recharged [A]!","You recharged [A]!")
recharging = FALSE
diff --git a/code/modules/integrated_electronics/core/analyzer.dm b/code/modules/integrated_electronics/core/analyzer.dm
index 6365d7a69581..02b8c88accab 100644
--- a/code/modules/integrated_electronics/core/analyzer.dm
+++ b/code/modules/integrated_electronics/core/analyzer.dm
@@ -1,5 +1,3 @@
-
-
/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."
@@ -7,92 +5,14 @@
icon_state = "analyzer"
flags_1 = CONDUCT_1
w_class = WEIGHT_CLASS_SMALL
- var/list/circuit_list = list()
- var/list/assembly_list = list(/obj/item/device/electronic_assembly,
- /obj/item/device/electronic_assembly/medium,
- /obj/item/device/electronic_assembly/large,
- /obj/item/device/electronic_assembly/drone)
/obj/item/device/integrated_electronics/analyzer/afterattack(var/atom/A, var/mob/living/user)
- visible_message( "attempt to scan")
- if(ispath(A.type,/obj/item/device/electronic_assembly))
- var/i = 0
- var/j = 0
- var/HTML ="start.assembly{{*}}" //1-st in chapters.1-st block is just to secure start of program from excess symbols.{{*}} is delimeter for chapters.
- visible_message( "start of scan")
- for(var/ix in 1 to assembly_list.len)
- var/obj/item/I = assembly_list[ix]
- if( A.type == I )
- HTML += initial(I.name) +"=-="+A.name //2-nd block.assembly type and name. Maybe in future there will also be color and accesories.
- break
-
- HTML += "{{*}}components" //3-rd block.components. First element is useless.delimeter for elements is ^%^.In element first circuit's default name.Second is user given name.delimiter is =-=
-
- for(var/obj/item/integrated_circuit/IC in A.contents)
- i =i + 1
- HTML += "^%^"+IC.name+"=-="+IC.displayed_name
- if(i == 0)
- return
- HTML += "{{*}}values" //4-th block.values. First element is useless.delimeter for elements is ^%^.In element first i/o id.Second is data type.third is value.delimiter is :+:
-
- i = 0
- var/val
- var/list/inp=list()
- var/list/out=list()
- var/list/act=list()
- var/list/ioa=list()
- for(var/obj/item/integrated_circuit/IC in A.contents)
- i += 1
- if(IC.inputs && IC.inputs.len)
- for(j in 1 to IC.inputs.len)
- var/datum/integrated_io/IN =IC.inputs[j]
- inp[IN] = "[i]i[j]"
- if(islist(IN.data))
- val = list2params(IN.data)
- HTML += "^%^"+"[i]i[j]:+:list:+:[val]"
- else if(isnum(IN.data))
- val= IN.data
- HTML += "^%^"+"[i]i[j]:+:num:+:[val]"
- else if(istext(IN.data))
- val = IN.data
- HTML += "^%^"+"[i]i[j]:+:text:+:[val]"
- if(IC.outputs && IC.outputs.len)
- for(j in 1 to IC.outputs.len) //Also this block uses for setting all i/o id's
- var/datum/integrated_io/OUT = IC.outputs[j]
- out[OUT] = "[i]o[j]"
- if(IC.activators && IC.activators.len)
- for(j in 1 to IC.activators.len)
- var/datum/integrated_io/ACT = IC.activators[j]
- act[ACT] = "[i]a[j]"
- ioa.Add(inp)
- ioa.Add(out)
- ioa.Add(act)
- HTML += "{{*}}wires"
- if(inp && inp.len)
- for(i in 1 to inp.len) //5-th block.wires. First element is useless.delimeter for elements is ^%^.In element first i/o id.Second too.delimiter is =-=
- var/datum/integrated_io/P = inp[i]
- for(j in 1 to P.linked.len)
- var/datum/integrated_io/C = P.linked[j]
- HTML += "^%^"+inp[P]+"=-="+ioa[C]
- if(out && out.len)
- for(i in 1 to out.len) //5-th block.wires. First element is useless.delimeter for elements is ^%^.In element first i/o id.Second too.delimiter is =-=
- var/datum/integrated_io/P = out[i]
- for(j in 1 to P.linked.len)
- var/datum/integrated_io/C = P.linked[j]
- HTML += "^%^"+out[P]+"=-="+ioa[C]
- if(act && act.len)
- for(i in 1 to act.len) //5-th block.wires. First element is useless.delimeter for elements is ^%^.In element first i/o id.Second too.delimiter is =-=
- var/datum/integrated_io/P = act[i]
- for(j in 1 to P.linked.len)
- var/datum/integrated_io/C = P.linked[j]
- HTML += "^%^"+act[P]+"=-="+ioa[C]
-
- HTML += "{{*}}end" //6 block.like 1.
- visible_message( "[A] has been scanned,")
- user << browse(jointext(HTML, null), "window=analyzer;size=[500]x[600];border=1;can_resize=1;can_close=1;can_minimize=1")
+ if(istype(A, /obj/item/device/electronic_assembly))
+ var/saved = SScircuit.save_electronic_assembly(A)
+ if(saved)
+ to_chat(user, "You scan [A].")
+ user << browse(saved, "window=circuit_scan;size=500x600;border=1;can_resize=1;can_close=1;can_minimize=1")
+ else
+ to_chat(user, "[A] is not complete enough to be encoded!")
else
..()
-
-
-
-
diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm
index d992718bc745..6f552e1df447 100644
--- a/code/modules/integrated_electronics/core/assemblies.dm
+++ b/code/modules/integrated_electronics/core/assemblies.dm
@@ -8,6 +8,7 @@
icon = 'icons/obj/electronic_assemblies.dmi'
icon_state = "setup_small"
flags_1 = NOBLUDGEON_1
+ materials = list() // To be filled later
var/max_components = IC_MAX_SIZE_BASE
var/max_complexity = IC_COMPLEXITY_BASE
var/opened = FALSE
@@ -23,52 +24,12 @@
return user.canUseTopic(src,be_close = TRUE)
-/obj/item/device/electronic_assembly/medium
- name = "electronic mechanism"
- icon_state = "setup_medium"
- desc = "It's a case, for building medium-sized electronics with."
- w_class = WEIGHT_CLASS_NORMAL
- max_components = IC_MAX_SIZE_BASE * 2
- max_complexity = IC_COMPLEXITY_BASE * 2
-
-/obj/item/device/electronic_assembly/large
- name = "electronic machine"
- icon_state = "setup_large"
- desc = "It's a case, for building large electronics with."
- w_class = WEIGHT_CLASS_BULKY
- max_components = IC_MAX_SIZE_BASE * 4
- max_complexity = IC_COMPLEXITY_BASE * 4
- anchored = FALSE
-
-/obj/item/device/electronic_assembly/large/attackby(var/obj/item/O, var/mob/user)
- if(default_unfasten_wrench(user, O, 20))
- return
- ..()
-
-/obj/item/device/electronic_assembly/large/attack_tk(mob/user)
- if(anchored)
- return
- ..()
-
-/obj/item/device/electronic_assembly/large/attack_hand(mob/user)
- if(anchored)
- attack_self(user)
- return
- ..()
-
-/obj/item/device/electronic_assembly/drone
- name = "electronic drone"
- icon_state = "setup_drone"
- desc = "It's a case, for building mobile electronics with."
- w_class = WEIGHT_CLASS_SMALL
- max_components = IC_MAX_SIZE_BASE * 3
- max_complexity = IC_COMPLEXITY_BASE * 3
-
-
-
/obj/item/device/electronic_assembly/Initialize()
.=..()
START_PROCESSING(SScircuit, src)
+ materials[MAT_METAL] = round((max_complexity + max_components) / 4) * SScircuit.cost_multiplier
+
+
/obj/item/device/electronic_assembly/Destroy()
STOP_PROCESSING(SScircuit, src)
@@ -95,7 +56,7 @@
var/total_part_size = return_total_size()
var/total_complexity = return_total_complexity()
- var/HTML = list()
+ var/HTML = ""
HTML += "
[name]"
HTML += "
\[Refresh\] | "
@@ -105,25 +66,37 @@
if(battery)
HTML += "[round(battery.charge, 0.1)]/[battery.maxcharge] ([round(battery.percent(), 0.1)]%) cell charge. \[Remove\]"
else
- HTML += "No powercell detected!"
+ HTML += "No power cell detected!"
HTML += "
"
- HTML += "Components:
"
- HTML += "Built in:
"
-//Put removable circuits in separate categories from non-removable
- for(var/obj/item/integrated_circuit/circuit in contents)
+
+ HTML += "Components:"
+
+ var/list/components = return_all_components()
+ var/builtin_components = ""
+
+ for(var/c in components)
+ var/obj/item/integrated_circuit/circuit = c
if(!circuit.removable)
- HTML += "[circuit.displayed_name] | "
- HTML += "\[Rename\] | "
- HTML += "\[Scan with Debugger\] | "
- HTML += "\[Move to Bottom\]"
- HTML += "
"
+ builtin_components += "[circuit.displayed_name] | "
+ builtin_components += "\[Rename\] | "
+ builtin_components += "\[Scan with Debugger\] | "
+ builtin_components += "\[Move to Bottom\]"
+ builtin_components += "
"
- HTML += "
"
- HTML += "Removable:
"
+ // Put removable circuits (if any) in separate categories from non-removable
+ if(builtin_components)
+ HTML += "
"
+ HTML += "Built in:
"
+ HTML += builtin_components
+ HTML += "
"
+ HTML += "Removable:"
- for(var/obj/item/integrated_circuit/circuit in contents)
+ HTML += "
"
+
+ for(var/c in components)
+ var/obj/item/integrated_circuit/circuit = c
if(circuit.removable)
HTML += "[circuit.displayed_name] | "
HTML += "\[Rename\] | "
@@ -133,9 +106,9 @@
HTML += "
"
HTML += ""
- user << browse(jointext(HTML,null), "window=assembly-\[REF(src)];size=600x350;border=1;can_resize=1;can_close=1;can_minimize=1")
+ user << browse(HTML, "window=assembly-[REF(src)];size=600x350;border=1;can_resize=1;can_close=1;can_minimize=1")
-/obj/item/device/electronic_assembly/Topic(href, href_list[])
+/obj/item/device/electronic_assembly/Topic(href, href_list)
if(..())
return 1
@@ -155,12 +128,11 @@
interact(usr) // To refresh the UI.
/obj/item/device/electronic_assembly/proc/rename()
-
var/mob/M = usr
if(!check_interactivity(M))
return
- var/input = reject_bad_name(input("What do you want to name this?", "Rename", src.name) as null|text,1)
+ var/input = reject_bad_name(input("What do you want to name this?", "Rename", src.name) as null|text, TRUE)
if(!check_interactivity(M))
return
if(src && input)
@@ -200,10 +172,15 @@
for(var/obj/item/integrated_circuit/part in contents)
. += 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)
if(!opened)
- to_chat(user, "\The [src] isn't opened, so you can't put anything inside. Try using a crowbar.")
+ to_chat(user, "\The [src]'s hatch is closed, you can't put anything inside.")
return FALSE
if(IC.w_class > w_class)
@@ -245,7 +222,15 @@
visible_message(" [user] waves [src] around [target].")
-/obj/item/device/electronic_assembly/attackby(var/obj/item/I, var/mob/user)
+
+/obj/item/device/electronic_assembly/screwdriver_act(mob/living/user, obj/item/S)
+ playsound(src, S.usesound, 50, 1)
+ opened = !opened
+ to_chat(user, "You [opened ? "open" : "close"] the maintenance hatch of [src].")
+ update_icon()
+ return TRUE
+
+/obj/item/device/electronic_assembly/attackby(obj/item/I, mob/living/user)
if(istype(I, /obj/item/integrated_circuit))
if(!user.canUnEquip(I))
return FALSE
@@ -254,24 +239,17 @@
playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
interact(user)
return TRUE
- else if(istype(I, /obj/item/crowbar))
- playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1)
- opened = !opened
- to_chat(user, "You [opened ? "opened" : "closed"] [src].")
- update_icon()
- return TRUE
- else if(istype(I, /obj/item/device/integrated_electronics/wirer) || istype(I, /obj/item/device/integrated_electronics/debugger) || istype(I, /obj/item/screwdriver))
+ else if(istype(I, /obj/item/device/integrated_electronics/wirer) || istype(I, /obj/item/device/integrated_electronics/debugger))
if(opened)
interact(user)
else
- to_chat(user, " [src] isn't opened, so you can't fiddle with the internal components. \
- Try using a crowbar.")
+ to_chat(user, "[src]'s hatch is closed, so you can't fiddle with the internal components.")
else if(istype(I, /obj/item/stock_parts/cell))
if(!opened)
- to_chat(user, " [src] isn't opened, so you can't put anything inside. Try using a crowbar.")
+ to_chat(user, "[src]'s hatch is closed, so you can't put anything inside.")
return FALSE
if(battery)
- to_chat(user, " [src] already has \a [battery] inside. Remove it first if you want to replace it.")
+ to_chat(user, "[src] already has \a [battery] installed. Remove it first if you want to replace it.")
return FALSE
var/obj/item/stock_parts/cell = I
user.transferItemToLoc(I, loc)
@@ -340,3 +318,48 @@
/obj/item/device/electronic_assembly/Moved(oldLoc, dir)
for(var/obj/item/integrated_circuit/IC in contents)
IC.ext_moved(oldLoc, dir)
+
+
+
+
+
+/obj/item/device/electronic_assembly/medium
+ name = "electronic mechanism"
+ icon_state = "setup_medium"
+ desc = "It's a case, for building medium-sized electronics with."
+ w_class = WEIGHT_CLASS_NORMAL
+ max_components = IC_MAX_SIZE_BASE * 2
+ max_complexity = IC_COMPLEXITY_BASE * 2
+
+/obj/item/device/electronic_assembly/large
+ name = "electronic machine"
+ icon_state = "setup_large"
+ desc = "It's a case, for building large electronics with."
+ w_class = WEIGHT_CLASS_BULKY
+ max_components = IC_MAX_SIZE_BASE * 4
+ max_complexity = IC_COMPLEXITY_BASE * 4
+ anchored = FALSE
+
+/obj/item/device/electronic_assembly/large/attackby(obj/item/O, mob/user)
+ if(default_unfasten_wrench(user, O, 20))
+ return
+ ..()
+
+/obj/item/device/electronic_assembly/large/attack_tk(mob/user)
+ if(anchored)
+ return
+ ..()
+
+/obj/item/device/electronic_assembly/large/attack_hand(mob/user)
+ if(anchored)
+ attack_self(user)
+ return
+ ..()
+
+/obj/item/device/electronic_assembly/drone
+ name = "electronic drone"
+ icon_state = "setup_drone"
+ desc = "It's a case, for building mobile electronics with."
+ w_class = WEIGHT_CLASS_SMALL
+ max_components = IC_MAX_SIZE_BASE * 3
+ max_complexity = IC_COMPLEXITY_BASE * 3
diff --git a/code/modules/integrated_electronics/core/helpers.dm b/code/modules/integrated_electronics/core/helpers.dm
index 45b48198c8ee..04137a4d052b 100644
--- a/code/modules/integrated_electronics/core/helpers.dm
+++ b/code/modules/integrated_electronics/core/helpers.dm
@@ -1,47 +1,44 @@
-/obj/item/integrated_circuit/proc/setup_io(var/list/io_list, var/io_type, var/list/io_default_list)
+/obj/item/integrated_circuit/proc/setup_io(list/io_list, io_type, list/io_default_list, pin_type)
var/list/io_list_copy = io_list.Copy()
io_list.Cut()
for(var/i in 1 to io_list_copy.len)
var/io_entry = io_list_copy[i]
var/default_data = null
var/io_type_override = null
+
// Override the default data.
- if(io_default_list && io_default_list.len) // List containing special pin types that need to be added.
+ if(length(io_default_list)) // List containing special pin types that need to be added.
default_data = io_default_list["[i]"] // This is deliberately text because the index is a number in text form.
+
// Override the pin type.
if(io_list_copy[io_entry])
io_type_override = io_list_copy[io_entry]
if(io_type_override)
- io_list.Add(new io_type_override(src, io_entry, default_data))
+ io_list.Add(new io_type_override(src, io_entry, default_data, pin_type))
else
- io_list.Add(new io_type(src, io_entry, default_data))
+ io_list.Add(new io_type(src, io_entry, default_data, pin_type))
-/obj/item/integrated_circuit/proc/set_pin_data(var/pin_type, var/pin_number, datum/new_data)
+/obj/item/integrated_circuit/proc/set_pin_data(pin_type, pin_number, datum/new_data)
if (istype(new_data) && !isweakref(new_data))
new_data = WEAKREF(new_data)
var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number)
return pin.write_data_to_pin(new_data)
-/obj/item/integrated_circuit/proc/get_pin_data(var/pin_type, var/pin_number)
+/obj/item/integrated_circuit/proc/get_pin_data(pin_type, pin_number)
var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number)
return pin.get_data()
-/obj/item/integrated_circuit/proc/get_pin_data_as_type(var/pin_type, var/pin_number, var/as_type)
+/obj/item/integrated_circuit/proc/get_pin_data_as_type(pin_type, pin_number, as_type)
var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number)
return pin.data_as_type(as_type)
-/obj/item/integrated_circuit/proc/activate_pin(var/pin_number)
+/obj/item/integrated_circuit/proc/activate_pin(pin_number)
var/datum/integrated_io/activate/A = activators[pin_number]
A.push_data()
-/datum/integrated_io/proc/get_data()
- if(isweakref(data))
- return data.resolve()
- return data
-
-/obj/item/integrated_circuit/proc/get_pin_ref(var/pin_type, var/pin_number)
+/obj/item/integrated_circuit/proc/get_pin_ref(pin_type, pin_number)
switch(pin_type)
if(IC_INPUT)
if(pin_number > inputs.len)
@@ -72,60 +69,75 @@
return FALSE
-/obj/item/integrated_circuit/proc/asc2b64(var/S)
- var/static/list/b64 = list(
- "A"=0,"B"=1,"C"=2,"D"=3,
- "E"=4,"F"=5,"G"=6,"H"=7,
- "I"=8,"J"=9,"K"=10,"L"=11,
- "M"=12,"N"=13,"O"=14,"P"=15,
- "Q"=16,"R"=17,"S"=18,"T"=19,
- "U"=20,"V"=21,"W"=22,"X"=23,
- "Y"=24,"Z"=25,"a"=26,"b"=27,
- "c"=28,"d"=29,"e"=30,"f"=31,
- "g"=32,"h"=33,"i"=34,"j"=35,
- "k"=36,"l"=37,"m"=38,"n"=39,
- "o"=40,"p"=41,"q"=42,"r"=43,
- "s"=44,"t"=45,"u"=46,"v"=47,
- "w"=48,"x"=49,"y"=50,"z"=51,
- "0"=52,"1"=53,"2"=54,"3"=55,
- "4"=56,"5"=57,"6"=58,"7"=59,
- "8"=60,"9"=61,","=62,"."=63
- )
- var/ls = lentext(S)
- var/c
- var/i=1
- while(i <= ls)
- var/sb1=text2ascii(S,i)
- var/sb2=text2ascii(S,i+1)
- var/sb3=text2ascii(S,i+2)
- var/cb1 = (sb1 & 252)>>2
- var/cb2 = ((sb1 & 3)<<6 | (sb2 & 240)>>2)>>2
- var/cb3 = (sb2 & 15)<<2 | (sb3 & 192)>>6
- var/cb4 = (sb3 & 63)
- c=c+b64[cb1+1]+b64[cb2+1]+b64[cb3+1]+b64[cb4+1]
- i=i+3
- return c
+/datum/integrated_io/proc/get_data()
+ if(isweakref(data))
+ return data.resolve()
+ return data
-/obj/item/integrated_circuit/proc/b642asc(var/S)
- var/static/list/b64 = list("A"=1,"B"=2,"C"=3,"D"=4,"E"=5,"F"=6,"G"=7,"H"=8,"I"=9,"J"=10,"K"=11,"L"=12,"M"=13,"N"=14,"O"=15,"P"=16,"Q"=17,"R"=18,
- "S"=19,"T"=20,"U"=21,"V"=22,"W"=23,"X"=24,"Y"=25,"Z"=26,"a"=27,"b"=28,"c"=29,"d"=30,"e"=31,"f"=32,"g"=33,"h"=34,"i"=35,"j"=36,"k"=37,"l"=38,"m"=39,"n"=40,"o"=41,
- "p"=42,"q"=43,"r"=44,"s"=45,"t"=46,"u"=47,"v"=48,"w"=49,"x"=50,"y"=51,"z"=52,"0"=53,"1"=54,"2"=55,"3"=56,"4"=57,"5"=58,"6"=59,"7"=60,"8"=61,"9"=62,","=63,"."=64)
- var/ls = lentext(S)
- var/c
- var/i=1
- while(i<=ls)
- var/cb1=b64[copytext(S,i,i+1)]-1
- var/cb2=b64[copytext(S,i+1,i+2)]-1
- var/cb3=b64[copytext(S,i+2,i+3)]-1
- var/cb4=b64[copytext(S,i+3,i+4)]-1
- var/sb1=cb1<<2 | (cb2 & 48)>>4
- var/sb2=(cb2 & 15) <<4 | (cb3 & 60)>>2
- var/sb3=(cb3 & 3)<<6 | cb4
- c=c+ascii2text(sb1)+ascii2text(sb2)+ascii2text(sb3)
- i=i+4
- return c
-/proc/XorEncrypt(string,key)
+// 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
+/datum/integrated_io/proc/get_pin_parameters(list/components)
+ if(!holder)
+ return
+
+ if(!components)
+ if(!holder.assembly)
+ return
+ components = holder.assembly.return_all_components()
+
+ var/component_number = components.Find(holder)
+
+ var/list/pin_holder_list
+ switch(pin_type)
+ if(IC_INPUT)
+ pin_holder_list = holder.inputs
+ if(IC_OUTPUT)
+ pin_holder_list = holder.outputs
+ if(IC_ACTIVATOR)
+ pin_holder_list = holder.activators
+ else
+ return
+
+ var/pin_number = pin_holder_list.Find(src)
+
+ return list(component_number, pin_type, pin_number)
+
+
+// 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
+/obj/item/device/electronic_assembly/proc/get_pin_ref(component_number, pin_type, pin_number, list/components)
+ if(!components)
+ components = return_all_components()
+
+ if(component_number > components.len)
+ return
+
+ var/obj/item/integrated_circuit/component = components[component_number]
+ return component.get_pin_ref(pin_type, pin_number)
+
+
+// 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(!islist(parameters) || parameters.len != 3)
+ return
+
+ // Those are supposed to be list indexes, check them for sanity
+ if(!isnum(parameters[1]) || parameters[1] % 1 || parameters[1] < 1)
+ return
+
+ if(!isnum(parameters[3]) || parameters[3] % 1 || parameters[3] < 1)
+ return
+
+ return get_pin_ref(parameters[1], parameters[2], parameters[3], components)
+
+
+
+
+// Used to obfuscate object refs imported/exported as strings.
+// Not very secure, but if someone still finds a way to abuse refs, they deserve it.
+/proc/XorEncrypt(string, key)
if(!string || !key ||!istext(string)||!istext(key))
return
var/r
diff --git a/code/modules/integrated_electronics/core/integrated_circuit.dm b/code/modules/integrated_electronics/core/integrated_circuit.dm
index 908a9bcfbe0a..042e93a2aa63 100644
--- a/code/modules/integrated_electronics/core/integrated_circuit.dm
+++ b/code/modules/integrated_electronics/core/integrated_circuit.dm
@@ -4,6 +4,7 @@
icon = 'icons/obj/electronic_assemblies.dmi'
icon_state = "template"
w_class = WEIGHT_CLASS_TINY
+ materials = list() // To be filled later
var/obj/item/device/electronic_assembly/assembly // Reference to the assembly holding this circuit, if any.
var/extended_desc
var/list/inputs = list()
@@ -13,7 +14,7 @@
var/list/activators = list()
var/next_use = 0 // Uses world.time
var/complexity = 1 // This acts as a limitation on building machines, more resource-intensive components cost more 'space'.
- var/size = 1 // This acts as a limitation on building machines, bigger components cost more 'space'. -1 for size 0
+ var/size = 1 // This acts as a limitation on building machines, bigger components cost more 'space'. -1 for size 0
var/cooldown_per_use = 9 // Circuits are limited in how many times they can be work()'d by this variable.
var/power_draw_per_use = 0 // How much power is drawn when work()'d.
var/power_draw_idle = 0 // How much power is drawn when doing nothing.
@@ -67,10 +68,11 @@ a creative player the means to solve many problems. Circuits are held inside an
/obj/item/integrated_circuit/Initialize()
displayed_name = name
- setup_io(inputs, /datum/integrated_io, inputs_default)
- setup_io(outputs, /datum/integrated_io, outputs_default)
- setup_io(activators, /datum/integrated_io/activate)
- ..()
+ setup_io(inputs, /datum/integrated_io, inputs_default, IC_INPUT)
+ setup_io(outputs, /datum/integrated_io, outputs_default, IC_OUTPUT)
+ setup_io(activators, /datum/integrated_io/activate, null, IC_ACTIVATOR)
+ materials[MAT_METAL] = w_class * SScircuit.cost_multiplier
+ . = ..()
/obj/item/integrated_circuit/proc/on_data_written() //Override this for special behaviour when new data gets pushed to the circuit.
return
@@ -117,7 +119,7 @@ a creative player the means to solve many problems. Circuits are held inside an
var/table_edge_width = "30%"
var/table_middle_width = "40%"
- var/HTML = list()
+ var/HTML = ""
HTML += "[src.displayed_name]"
HTML += ""
HTML += "
"
@@ -127,7 +129,7 @@ a creative player the means to solve many problems. Circuits are held inside an
HTML += "
\[Refresh\] | "
HTML += "\[Rename\] | "
HTML += "\[Scan with Device\] | "
- if(src.removable)
+ if(removable)
HTML += "\[Remove\]
"
HTML += ""
@@ -205,10 +207,10 @@ a creative player the means to solve many problems. Circuits are held inside an
HTML += "
[extended_desc]"
HTML += ""
- if(src.assembly)
- user << browse(jointext(HTML, null), "window=assembly-[REF(src.assembly)];size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1")
+ 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(jointext(HTML, null), "window=circuit-[REF(src)];size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1")
+ user << browse(HTML, "window=circuit-[REF(src)];size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1")
onclose(user, "assembly-[REF(src.assembly)]")
@@ -300,7 +302,7 @@ a creative player the means to solve many problems. Circuits are held inside an
if(D.accepting_refs)
D.afterattack(src, usr, TRUE)
else
- to_chat(usr, "The Debugger's 'ref scanner' needs to be on.")
+ 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.")
@@ -378,16 +380,22 @@ a creative player the means to solve many problems. Circuits are held inside an
return
/obj/item/integrated_circuit/proc/disconnect_all()
+ var/datum/integrated_io/I
- for(var/k in 1 to inputs.len)
- var/datum/integrated_io/I = inputs[k]
+ for(var/i in inputs)
+ I = i
+ I.disconnect()
+
+ for(var/i in outputs)
+ I = i
+ I.disconnect()
+
+ for(var/i in activators)
+ I = i
I.disconnect()
- for(var/k in 1 to outputs.len)
- var/datum/integrated_io/O = outputs[k]
- O.disconnect()
- for(var/k in 1 to activators.len)
- var/datum/integrated_io/activate/A = activators[k]
- A.disconnect()
/obj/item/integrated_circuit/proc/ext_moved(oldLoc, dir)
return
+
+
+
diff --git a/code/modules/integrated_electronics/core/pins.dm b/code/modules/integrated_electronics/core/pins.dm
index a472ae894999..25ef3b80b8d1 100644
--- a/code/modules/integrated_electronics/core/pins.dm
+++ b/code/modules/integrated_electronics/core/pins.dm
@@ -24,12 +24,18 @@ D [1]/ ||
var/datum/weakref/data // This is a weakref, to reduce typecasts. Note that oftentimes numbers and text may also occupy this.
var/list/linked = list()
var/io_type = DATA_CHANNEL
+ var/pin_type // IC_INPUT, IC_OUTPUT, IC_ACTIVATOR - used in saving assembly wiring
+
+
+/datum/integrated_io/New(loc, _name, _data, _pin_type)
+ name = _name
+ if(_data)
+ data = _data
+ if(_pin_type)
+ pin_type = _pin_type
+
+ holder = loc
-/datum/integrated_io/New(newloc, name1, new_data)
- name = name1
- if(new_data)
- data = new_data
- holder = newloc
if(!istype(holder))
message_admins("ERROR: An integrated_io ([name]) spawned without a valid holder! This is a bug.")
diff --git a/code/modules/integrated_electronics/core/prefab.dm b/code/modules/integrated_electronics/core/prefab.dm
deleted file mode 100644
index 3dc3f2d6efaf..000000000000
--- a/code/modules/integrated_electronics/core/prefab.dm
+++ /dev/null
@@ -1,156 +0,0 @@
-/obj/item/device/integrated_electronics/prefab
- var/debug = FALSE
- name = "prefab"
- desc = "new machine in package"
- icon = 'icons/obj/electronic_assemblies.dmi'
- icon_state = "box_template"
- w_class = WEIGHT_CLASS_BULKY
- var/program="blank"
- var/list/as_names = list()
-
-/obj/item/device/integrated_electronics/prefab/attack_self(var/mob/user)
- if(program && program != "blank")
- assemble(program)
- else
- return ..()
-
-/obj/item/device/integrated_electronics/prefab/Initialize()
- . = ..()
- var/list/assembly_list = list(
- /obj/item/device/electronic_assembly,
- /obj/item/device/electronic_assembly/medium,
- /obj/item/device/electronic_assembly/large,
- /obj/item/device/electronic_assembly/drone,
- )
- for(var/k in 1 to assembly_list.len)
- var/obj/item/I = assembly_list[k]
- as_names[initial(I.name)] = I
- addtimer(CALLBACK(src, .proc/attack_self), 2) //IDK, why it's need dely,but otherwise it doesn't work.
-
-/obj/item/device/integrated_electronics/prefab/proc/assemble(var/program)
- var/list/all_circuits = SScircuit.all_circuits //cached lists = free performance
- var/list/chap = splittext( program ,"{{*}}")
- var/list/elements = list()
- var/list/elements_input = list()
- var/list/element = list()
- var/obj/item/AS
- var/PA
- var/i = 0
-
- var/list/ioa = list()
- var/datum/integrated_io/IO
- var/datum/integrated_io/IO2
- if(debug)
- visible_message( "started successful")
- if(chap[2] != "")
- if(debug)
- visible_message( "assembly")
- element = splittext( chap[2] ,"=-=")
- PA = as_names[element[1]]
- AS = new PA(null)
- AS.loc = src
- AS.name = element[2]
- else
- return //what's the point if there is no assembly?
- if(chap[3] != "components") //if there is only one word,there is no components.
- elements_input = splittext( chap[3] ,"^%^")
- if(debug)
- visible_message( "components[elements_input.len]")
- i = 0
- elements = list()
- for(var/elem in elements_input)
- i=i+1
- if(i>1)
- elements.Add(elem) //I don't know,why Cut or copy don't works. If somebody can fix it, it should be fixed.
- if(debug)
- visible_message( "components[elements.len]")
- if(!length(elements_input))
- return
- if(debug)
- visible_message( "inserting components[elements.len]")
- var/obj/item/integrated_circuit/comp
- i=0
- for(var/E in elements)
- i=i+1
- element = splittext( E ,"=-=")
- if(debug)
- visible_message( "[E]")
- var/path_to_use = all_circuits[element[1]]
- comp = new path_to_use(null)
- comp.loc = AS
- comp.displayed_name = element[2]
- comp.assembly = AS
- if(comp.inputs && comp.inputs.len)
- for(var/j in 1 to comp.inputs.len)
- var/datum/integrated_io/IN = comp.inputs[j]
- ioa["[i]i[j]"] = IN
- if(debug)
- visible_message( "[i]i[j]")
- if(comp.outputs && comp.outputs.len)
- for(var/j in 1 to comp.outputs.len) //Also this block uses for setting all i/o id's
- var/datum/integrated_io/OUT = comp.outputs[j]
- ioa["[i]o[j]"] = OUT
- if(debug)
- visible_message( "[i]o[j]")
- if(comp.activators && comp.activators.len)
- for(var/j in 1 to comp.activators.len)
- var/datum/integrated_io/ACT = comp.activators[j]
- ioa["[i]a[j]"] = ACT
- if(debug)
- visible_message( "[i]a[j]")
-
- else
- return
- if(!AS.contents.len)
- return
- if(chap[4] != "values") //if there is only one word,there is no values
- elements_input = splittext( chap[4] ,"^%^")
- if(debug)
- visible_message( "values[elements_input.len]")
- i=0
- elements = list()
- for(var/elem in elements_input)
- i=i+1
- if(i>1)
- elements.Add(elem)
- if(debug)
- visible_message( "values[elements.len]")
- if(elements.len>0)
- if(debug)
- visible_message( "setting values[elements.len]")
- for(var/E in elements)
- element = splittext( E ,":+:")
- if(debug)
- visible_message( "[E]")
- IO = ioa[element[1]]
- if(element[2]=="text")
- IO.write_data_to_pin(element[3])
- else if(element[2]=="num")
- IO.write_data_to_pin(text2num(element[3]))
- else if(element[2]=="list")
- IO.write_data_to_pin(params2list(element[3]))
- if(chap[5] != "wires") //if there is only one word,there is no wires
- elements_input = splittext( chap[5] ,"^%^")
- i=0
- elements = list()
- if(debug)
- visible_message( "wires[elements_input.len]")
- for(var/elem in elements_input)
- i=i+1
- if(i>1)
- elements.Add(elem)
- if(debug)
- visible_message( "wires[elements.len]")
- if(elements.len>0)
- if(debug)
- visible_message( "setting wires[elements.len]")
- for(var/E in elements)
- element = splittext( E ,"=-=")
- if(debug)
- visible_message( "[E]")
- IO = ioa[element[1]]
- IO2 = ioa[element[2]]
- IO.linked |= IO2
-
- AS.forceMove(loc)
- qdel(src)
diff --git a/code/modules/integrated_electronics/core/printer.dm b/code/modules/integrated_electronics/core/printer.dm
index 5bffdc780471..e2d979603fd6 100644
--- a/code/modules/integrated_electronics/core/printer.dm
+++ b/code/modules/integrated_electronics/core/printer.dm
@@ -4,22 +4,13 @@
icon = 'icons/obj/electronic_assemblies.dmi'
icon_state = "circuit_printer"
w_class = WEIGHT_CLASS_BULKY
- var/metal = 0
- var/init_max_metal = 100
- var/max_metal = 100
- var/metal_per_sheet = 10 // One sheet equals this much metal.
- var/debug = FALSE
- var/upgraded = FALSE // When hit with an upgrade disk, will turn true, allowing it to print the higher tier circuits.
+ var/upgraded = TRUE // When hit with an upgrade disk, will turn true, allowing it to print the higher tier circuits.
var/can_clone = FALSE // Same for above, but will allow the printer to duplicate a specific assembly.
- var/static/list/recipe_list //category = list(paths in category)
var/current_category = null
- var/as_printing = FALSE
- var/as_needs = 0
- var/program ="blank"
- var/obj/item/device/integrated_electronics/prefab/PR = null
+ var/list/program // Currently loaded save, in form of list
/obj/item/device/integrated_circuit_printer/proc/check_interactivity(mob/user)
- return user.canUseTopic(src,be_close = TRUE)
+ return user.canUseTopic(src, be_close = TRUE)
/obj/item/device/integrated_circuit_printer/upgraded
upgraded = TRUE
@@ -27,56 +18,24 @@
/obj/item/device/integrated_circuit_printer/Initialize()
. = ..()
- if(!recipe_list)
- recipe_list = SScircuit.circuit_fabricator_recipe_list
+ AddComponent(/datum/component/material_container, list(MAT_METAL), MINERAL_MATERIAL_AMOUNT * 25, TRUE, list(/obj/item/stack, /obj/item/integrated_circuit))
/obj/item/device/integrated_circuit_printer/attackby(var/obj/item/O, var/mob/user)
- if(istype(O,/obj/item/stack/sheet/metal))
- var/obj/item/stack/sheet/metal/stack = O
- var/num = min((max_metal - metal) / metal_per_sheet, stack.amount)
- if(num < 1)
- to_chat(user, "\The [src] is too full to add more metal.")
- return
- if(stack.use(num))
- to_chat(user, "You add [num] sheet\s to \the [src].")
- metal += num * metal_per_sheet
- if(as_printing)
- if(as_needs <= metal)
- PR = new/obj/item/device/integrated_electronics/prefab(get_turf(loc))
- PR.program = program
- metal = metal - as_needs
- to_chat(user, "Assembly has been printed.")
- as_printing = FALSE
- as_needs = 0
- max_metal = init_max_metal
- else
- to_chat(user, "Please insert [(as_needs-metal)/10] more metal!")
- interact(user)
- return TRUE
-
- if(istype(O,/obj/item/integrated_circuit))
- to_chat(user, "You insert the circuit into \the [src]. ")
- user.temporarilyRemoveItemFromInventory(O)
- metal = min(metal + O.w_class, max_metal)
- qdel(O)
- interact(user)
- return TRUE
-
- if(istype(O,/obj/item/disk/integrated_circuit/upgrade/advanced))
+ if(istype(O, /obj/item/disk/integrated_circuit/upgrade/advanced))
if(upgraded)
to_chat(user, "\The [src] already has this upgrade. ")
return TRUE
- to_chat(user, "You install \the [O] into \the [src]. ")
+ to_chat(user, "You install \the [O] into \the [src]. ")
upgraded = TRUE
qdel(O)
interact(user)
return TRUE
- if(istype(O,/obj/item/disk/integrated_circuit/upgrade/clone))
+ if(istype(O, /obj/item/disk/integrated_circuit/upgrade/clone))
if(can_clone)
to_chat(user, "\The [src] already has this upgrade. ")
return TRUE
- to_chat(user, "You install \the [O] into \the [src]. ")
+ to_chat(user, "You install \the [O] into \the [src]. ")
can_clone = TRUE
qdel(O)
interact(user)
@@ -88,37 +47,33 @@
interact(user)
/obj/item/device/integrated_circuit_printer/interact(mob/user)
- var/window_height = 600
- var/window_width = 500
-
if(isnull(current_category))
- current_category = recipe_list[1]
+ current_category = SScircuit.circuit_fabricator_recipe_list[1]
+
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/HTML = "Integrated Circuit Printer
"
- HTML += "Metal: [metal/metal_per_sheet]/[max_metal/metal_per_sheet] sheets.
"
+ HTML += "Metal: [materials.total_amount]/[materials.max_amount].
"
+
+ if(CONFIG_GET(flag/ic_printing))
+ HTML += "Assembly cloning: [can_clone ? "Available": "Unavailable"].
"
+
HTML += "Circuits available: [upgraded ? "Advanced":"Regular"]."
- HTML += "Assembly Cloning: [can_clone ? "Available": "Unavailable"]."
- HTML += "Crossed out circuits mean that the printer is not sufficiently upgraded to create that circuit.
"
+ if(!upgraded)
+ HTML += "
Crossed out circuits mean that the printer is not sufficiently upgraded to create that circuit."
+
HTML += "
"
- if(can_clone)
+ if(can_clone && CONFIG_GET(flag/ic_printing))
HTML += "Here you can load script for your assembly.
"
- if(as_printing)
- HTML += " {Load Program} "
+ HTML += " {Load Program} "
+ if(!program)
+ HTML += " {Print Assembly}"
else
- HTML += " {Load Program} "
- if(program == "blank")
- HTML += " {Check Program} "
- else
- HTML += " {Check Program} "
- if((program == "blank")|as_printing)
- HTML += " {Print assembly} "
- else
- HTML += " {Print assembly} "
- if(as_printing)
- HTML += "
printing in process. Please insert more metal. "
+ HTML += " {Print Assembly}"
+
HTML += "
"
HTML += "Categories:"
- for(var/category in recipe_list)
+ for(var/category in SScircuit.circuit_fabricator_recipe_list)
if(category != current_category)
HTML += " \[[category]\] "
else // Bold the button if it's already selected.
@@ -126,28 +81,26 @@
HTML += "
"
HTML += "[current_category]
"
- var/list/current_list = recipe_list[current_category]
- for(var/k in 1 to current_list.len)
- var/obj/O = current_list[k]
+ var/list/current_list = SScircuit.circuit_fabricator_recipe_list[current_category]
+ for(var/path in current_list)
+ var/obj/O = path
var/can_build = TRUE
- if(istype(O, /obj/item/integrated_circuit))
- var/obj/item/integrated_circuit/IC = current_list[k]
+ if(ispath(path, /obj/item/integrated_circuit))
+ var/obj/item/integrated_circuit/IC = path
if((initial(IC.spawn_flags) & IC_SPAWN_RESEARCH) && (!(initial(IC.spawn_flags) & IC_SPAWN_DEFAULT)) && !upgraded)
can_build = FALSE
if(can_build)
- HTML += "\[[initial(O.name)]\]: [initial(O.desc)]
"
+ HTML += "\[[initial(O.name)]\]: [initial(O.desc)]
"
else
- HTML += "\[[initial(O.name)]\]: [initial(O.desc)]
"
+ HTML += "\[[initial(O.name)]\]: [initial(O.desc)]
"
- user << browse(jointext(HTML, null), "window=integrated_printer;size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1")
+ user << browse(HTML, "window=integrated_printer;size=600x500;border=1;can_resize=1;can_close=1;can_minimize=1")
/obj/item/device/integrated_circuit_printer/Topic(href, href_list)
if(!check_interactivity(usr))
return
if(..())
return TRUE
- var/sc = 0
- add_fingerprint(usr)
if(href_list["category"])
current_category = href_list["category"]
@@ -165,10 +118,15 @@
var/obj/item/integrated_circuit/IC = build_type
cost = initial(IC.w_class)
- if(metal - cost < 0)
- to_chat(usr, "You need [cost] metal to build that!.")
+
+ cost *= SScircuit.cost_multiplier
+
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
+
+ if(!materials.use_amount_type(cost, MAT_METAL))
+ to_chat(usr, "You need [cost] metal to build that!")
return TRUE
- metal -= cost
+
new build_type(get_turf(loc))
if(href_list["print"])
@@ -177,39 +135,48 @@
return
switch(href_list["print"])
if("load")
- program = input("Put your code there:", "loading", null, null)
- if("check")
- sc = sanity_check(program,usr)
- if(sc == 0)
- to_chat(usr, "Invalid program.")
- else if(sc == -1)
- to_chat(usr, "Unknown circuits found. Upgrades required to process this design.")
- else if(sc == null)
- to_chat(usr, "Invalid program.")
- else
- to_chat(usr, "Program is correct.You'll need [sc/10] sheets of metal")
+ var/input = input("Put your code there:", "loading", null, null) as message | null
+ if(!check_interactivity(usr))
+ return
+ if(!input)
+ program = null
+ return
+
+ var/validation = SScircuit.validate_electronic_assembly(input)
+
+ // Validation error codes are returned as text.
+ if(istext(validation))
+ to_chat(usr, "Error: [validation]")
+ return
+ else if(islist(validation))
+ program = validation
+ to_chat(usr, "This is a valid program for [program["assembly"]["type"]].")
+ if(program["requires_upgrades"])
+ if(upgraded)
+ to_chat(usr, "It uses advanced component designs.")
+ else
+ to_chat(usr, "It uses unknown component designs. Printer upgrade is required to proceed.")
+ to_chat(usr, "Used space: [program["used_space"]]/[program["max_space"]].")
+ to_chat(usr, "Complexity: [program["complexity"]]/[program["max_complexity"]].")
+ to_chat(usr, "Metal cost: [program["metal_cost"]].")
+
if("print")
- sc = sanity_check(program,usr)
- if(sc == 0 || sc == null)
- to_chat(usr, "Invalid program.")
- else if(sc == -1)
- to_chat(usr, "Unknown circuits found. Upgrades required to process this design.")
+ if(!program)
+ return
+
+ if(program["requires_upgrades"] && !upgraded)
+ to_chat(usr, "This program uses unknown component designs. Printer upgrade is required to proceed.")
else
- as_printing = TRUE
- if(sc <= metal)
- PR = new/obj/item/device/integrated_electronics/prefab(get_turf(loc))
- PR.program = program
- metal = metal - sc
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
+ if(materials.use_amount_type(program["metal_cost"], MAT_METAL))
+ SScircuit.load_electronic_assembly(get_turf(src), program)
to_chat(usr, "Assembly has been printed.")
- as_printing = FALSE
- as_needs = 0
- max_metal=init_max_metal
else
- max_metal = sc + metal_per_sheet
- as_needs = sc
- to_chat(usr, "Please insert [(as_needs-metal)/10] more metal!")
+ to_chat(usr, "You need [program["metal_cost"]] metal to build that!")
+
interact(usr)
+
// FUKKEN UPGRADE DISKS
/obj/item/disk/integrated_circuit/upgrade
name = "integrated circuit printer upgrade disk"
@@ -228,180 +195,3 @@
name = "integrated circuit printer upgrade disk - circuit cloner"
desc = "Install this into your integrated circuit printer to enhance it. This one allows the printer to duplicate assemblies."
icon_state = "upgrade_disk_clone"
-
-/obj/item/device/integrated_circuit_printer/proc/sanity_check(var/program,var/mob/user)
- var/list/chap = splittext( program ,"{{*}}")
- if(chap.len != 6)
- return 0 //splitting incorrect
- var/list/elements = list()
- var/list/elements_input = list()
- var/list/element = list()
- var/obj/item/PA
- var/obj/item/device/electronic_assembly/PF
- var/datum/integrated_io/IO
- var/datum/integrated_io/IO2
- var/i = 0
- var/obj/item/integrated_circuit/comp
- var/list/ioa = list()
- var/list/as_samp = list()
- var/list/all_circuits = SScircuit.all_circuits // It's free. Performance. We're giving you cpu time. It's free. We're giving you time. It's performance, free. It's free cpu time for you jim!
- var/list/assembly_list = list(
- /obj/item/device/electronic_assembly,
- /obj/item/device/electronic_assembly/medium,
- /obj/item/device/electronic_assembly/large,
- /obj/item/device/electronic_assembly/drone,
- )
- var/compl = 0
- var/maxcomp = 0
- var/cap = 0
- var/maxcap = 0
- var/metalcost = 0
- for(var/k in 1 to assembly_list.len)
- var/obj/item/I = assembly_list[k]
- as_samp[initial(I.name)] = I
- if(debug)
- visible_message( "started successful")
- if(chap[2] != "")
- if(debug)
- visible_message( "assembly")
- element = splittext( chap[2] ,"=-=")
- PA = as_samp[element[1]]
- if(ispath(PA,/obj/item/device/electronic_assembly))
- PF = PA
- maxcap = initial(PF.max_components)
- maxcomp = initial(PF.max_complexity)
- metalcost = metalcost + round( (initial(PF.max_complexity) + initial(PF.max_components) ) / 4)
- if(debug)
- visible_message( "maxcap[maxcap]maxcomp[maxcomp]")
- else
- return 0
- to_chat(usr, "This is program for [element[2]]")
-
- else
- return 0 //what's the point if there is no assembly?
- if(chap[3] != "components") //if there is only one word,there is no components.
- elements_input = splittext( chap[3] ,"^%^")
- if(debug)
- visible_message( "components[elements_input.len]")
- i = 0
- elements = list()
- for(var/elem in elements_input)
- i=i+1
- if(i>1)
- elements.Add(elem)
- if(debug)
- visible_message( "components[elements.len]")
- if(elements_input.len<1)
- return 0
- if(debug)
- visible_message( "inserting components[elements.len]")
- i=0
- for(var/E in elements)
- i=i+1
- element = splittext( E ,"=-=")
- if(debug)
- visible_message( "[E]")
- comp = all_circuits[element[1]]
- if(!comp)
- break
- if(!upgraded)
- var/obj/item/integrated_circuit/IC = comp
- if(!(initial(IC.spawn_flags) & IC_SPAWN_DEFAULT))
- return -1
- compl = compl + initial(comp.complexity)
- cap = cap + initial(comp.size)
- metalcost = metalcost + initial(initial(comp.w_class))
- var/obj/item/integrated_circuit/circuit = new comp
- var/list/ini = circuit.inputs
- if(length(ini))
- for(var/j in 1 to ini.len)
- var/datum/integrated_io/IN = ini[j]
- ioa["[i]i[j]"] = IN
- if(debug)
- visible_message( "[i]i[j]")
- ini = circuit.outputs
- if(length(ini))
- for(var/j in 1 to ini.len) //Also this block uses for setting all i/o id's
- var/datum/integrated_io/OUT = ini[j]
- ioa["[i]o[j]"] = OUT
- if(debug)
- visible_message( "[i]o[j]")
- ini = circuit.activators
- if(length(ini))
- for(var/j in 1 to ini.len)
- var/datum/integrated_io/ACT = ini.[j]
- ioa["[i]a[j]"] = ACT
- if(debug)
- visible_message( "[i]a[j]")
- if(icap[cap]compl[compl]maxcompl[maxcomp]maxcap[maxcap]")
- if(cap == 0)
- return 0
- if(cap>maxcap)
- return 0
- if(compl>maxcomp)
- return 0
- if(chap[4] != "values") //if there is only one word,there is no values
- elements_input = splittext( chap[4] ,"^%^")
- if(debug)
- visible_message( "values[elements_input.len]")
- i=0
- elements = list()
- for(var/elem in elements_input)
- i=i+1
- if(i>1)
- elements.Add(elem)
- if(debug)
- visible_message( "values[elements.len]")
- if(elements.len>0)
- if(debug)
- visible_message( "setting values[elements.len]")
- for(var/E in elements)
- element = splittext( E ,":+:")
- if(debug)
- visible_message( "[E]")
- if(!ioa[element[1]])
- return 0
- if(element[2]=="text")
- continue
- else if(element[2]=="num")
- continue
- else if(element[2]=="list")
- continue
- else
- return 0
-
- if(chap[5] != "wires") //if there is only one word,there is no wires
- elements_input = splittext( chap[5] ,"^%^")
- i=0
- elements = list()
- if(debug)
- visible_message( "wires[elements_input.len]")
- for(var/elem in elements_input)
- i=i+1
- if(i>1)
- elements.Add(elem)
- if(debug)
- visible_message( "wires[elements.len]")
- if(elements.len>0)
- if(debug)
- visible_message( "setting wires[elements.len]")
- for(var/E in elements)
- element = splittext( E ,"=-=")
- if(debug)
- visible_message( "[E]")
- IO = ioa[element[1]]
- IO2 = ioa[element[2]]
- if(!((element[2]+"=-="+element[1]) in elements))
- return 0
- if(!IO)
- return 0
- if(!IO2)
- return 0
- if(initial(IO.io_type) != initial(IO2.io_type))
- return 0
- return metalcost
\ No newline at end of file
diff --git a/code/modules/integrated_electronics/core/saved_circuits.dm b/code/modules/integrated_electronics/core/saved_circuits.dm
new file mode 100644
index 000000000000..cbbe58f16d53
--- /dev/null
+++ b/code/modules/integrated_electronics/core/saved_circuits.dm
@@ -0,0 +1,341 @@
+// Helpers for saving/loading integrated circuits.
+
+
+// Saves type, modified name and modified inputs (if any) to a list
+// The list is converted to JSON down the line.
+/obj/item/integrated_circuit/proc/save()
+ var/list/component_params = list()
+
+ // Save initial name used for differentiating assemblies
+ component_params["type"] = name
+
+ // Save the modified name.
+ if(name != displayed_name)
+ component_params["name"] = displayed_name
+
+ // Saving input values
+ if(length(inputs))
+ var/list/saved_inputs = list()
+
+ for(var/index in 1 to inputs.len)
+ var/datum/integrated_io/input = inputs[index]
+
+ // Don't waste space saving the default values
+ if(input.data == inputs_default["[index]"])
+ continue
+
+ var/list/input_value = list(index, FALSE, input.data)
+ // Index, Type, Value
+ // FALSE is default type used for num/text/list/null
+ // TODO: support for special input types, such as internal refs and maybe typepaths
+
+ if(islist(input.data) || isnum(input.data) || istext(input.data) || isnull(input.data))
+ saved_inputs.Add(list(input_value))
+
+ if(saved_inputs.len)
+ component_params["inputs"] = saved_inputs
+
+ return component_params
+
+
+// Verifies a list of component parameters
+// Returns null on success, error name on failure
+/obj/item/integrated_circuit/proc/verify_save(list/component_params)
+ // Validate name
+ if(component_params["name"] && !reject_bad_name(component_params["name"], TRUE))
+ return "Bad component name at [name]."
+
+ // Validate input values
+ if(component_params["inputs"])
+ var/list/loaded_inputs = component_params["inputs"]
+ if(!islist(loaded_inputs))
+ return "Malformed input values list at [name]."
+
+ var/inputs_amt = length(inputs)
+
+ // Too many inputs? Inputs for input-less component? This is not good.
+ if(!inputs_amt || inputs_amt < length(loaded_inputs))
+ return "Input values list out of bounds at [name]."
+
+ for(var/list/input in loaded_inputs)
+ if(input.len != 3)
+ return "Malformed input data at [name]."
+
+ var/input_id = input[1]
+ var/input_type = input[2]
+ //var/input_value = input[3]
+
+ // No special type support yet.
+ if(input_type)
+ return "Unidentified input type at [name]!"
+ // TODO: support for special input types, such as typepaths and internal refs
+
+ // Input ID is a list index, make sure it's sane.
+ if(!isnum(input_id) || input_id % 1 || input_id > inputs_amt || input_id < 1)
+ return "Invalid input index at [name]."
+
+
+// Loads component parameters from a list
+// Doesn't verify any of the parameters it loads, this is the job of verify_save()
+/obj/item/integrated_circuit/proc/load(list/component_params)
+ // Load name
+ if(component_params["name"])
+ displayed_name = component_params["name"]
+
+ // Load input values
+ if(component_params["inputs"])
+ var/list/loaded_inputs = component_params["inputs"]
+
+ for(var/list/input in loaded_inputs)
+ var/index = input[1]
+ //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
+ // 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()
+ var/list/assembly_params = list()
+
+ // Save initial name used for differentiating assemblies
+ assembly_params["type"] = initial(name)
+
+ // Save modified name
+ if(initial(name) != name)
+ assembly_params["name"] = name
+
+ // Save panel status
+ if(opened)
+ assembly_params["opened"] = TRUE
+
+ return assembly_params
+
+
+// Verifies a list of assembly parameters
+// Returns null on success, error name on failure
+/obj/item/device/electronic_assembly/proc/verify_save(list/assembly_params)
+ // Validate name
+ if(assembly_params["name"] && !reject_bad_name(assembly_params["name"], TRUE))
+ return "Bad assembly name."
+
+
+// Loads assembly parameters from a list
+// Doesn't verify any of the parameters it loads, this is the job of verify_save()
+/obj/item/device/electronic_assembly/proc/load(list/assembly_params)
+ // Load modified name, if any.
+ if(assembly_params["name"])
+ name = assembly_params["name"]
+
+ // Load panel status
+ if(assembly_params["opened"])
+ opened = TRUE
+ update_icon()
+
+
+
+// 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))
+ return
+
+
+ var/list/blocks = list()
+
+ // Block 1. Assembly.
+ blocks["assembly"] = assembly.save()
+ // (implant assemblies are not yet supported)
+
+
+ // Block 2. Components.
+ var/list/components = list()
+ for(var/c in assembly_components)
+ var/obj/item/integrated_circuit/component = c
+ components.Add(list(component.save()))
+ blocks["components"] = components
+
+
+ // Block 3. Wires.
+ var/list/wires = list()
+ var/list/saved_wires = list()
+
+ for(var/c in 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/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/text_params2 = params2.Join()
+
+ // Check if we already saved an opposite version of this wire
+ // (do not save the same wire twice)
+ if((text_params2 + "=" + text_params) in saved_wires)
+ continue
+
+ // If not, add a wire "hash" for future checks and save it
+ saved_wires.Add(text_params + "=" + text_params2)
+ wires.Add(list(list(params, params2)))
+
+ if(wires.len)
+ blocks["wires"] = wires
+
+ return json_encode(blocks)
+
+
+
+// Checks assembly save and calculates some of the parameters.
+// Returns assembly (type: list) if the save is valid.
+// Returns error code (type: text) if loading has failed.
+// The following parameters area calculated during validation and added to the returned save list:
+// "requires_upgrades", "metal_cost", "complexity", "max_complexity", "used_space", "max_space"
+/datum/controller/subsystem/processing/circuit/proc/validate_electronic_assembly(program)
+ var/list/blocks = json_decode(program)
+ if(!blocks)
+ return
+
+ var/error
+
+
+ // Block 1. Assembly.
+ var/list/assembly_params = blocks["assembly"]
+
+ if(!islist(assembly_params) || !length(assembly_params))
+ return "Invalid assembly data." // No assembly, damaged assembly or empty assembly
+
+ // Validate type, get a temporary component
+ var/assembly_path = all_assemblies[assembly_params["type"]]
+ var/obj/item/device/electronic_assembly/assembly = cached_assemblies[assembly_path]
+ if(!assembly)
+ return "Invalid assembly type."
+
+ // Check assembly save data for errors
+ error = assembly.verify_save(assembly_params)
+ if(error)
+ return error
+
+
+ // Read space & complexity limits and start keeping track of them
+ blocks["complexity"] = 0
+ blocks["max_complexity"] = assembly.max_complexity
+ blocks["used_space"] = 0
+ blocks["max_space"] = assembly.max_components
+
+ // Start keeping track of total metal cost
+ blocks["metal_cost"] = assembly.materials[MAT_METAL]
+
+
+ // Block 2. Components.
+ if(!islist(blocks["components"]) || !length(blocks["components"]))
+ return "Invalid components list." // No components or damaged components list
+
+ var/list/assembly_components = list()
+ for(var/C in blocks["components"])
+ var/list/component_params = C
+
+ if(!islist(component_params) || !length(component_params))
+ return "Invalid component data."
+
+ // Validate type, get a temporary component
+ var/component_path = all_components[component_params["type"]]
+ var/obj/item/integrated_circuit/component = cached_components[component_path]
+ if(!component)
+ return "Invalid component type."
+
+ // Add temporary component to assembly_components list, to be used later when verifying the wires
+ assembly_components.Add(component)
+
+ // Check component save data for errors
+ error = component.verify_save(component_params)
+ if(error)
+ return error
+
+ // Update estimated assembly complexity, taken space and material cost
+ blocks["complexity"] += component.complexity
+ blocks["used_space"] += component.size
+ blocks["metal_cost"] += component.materials[MAT_METAL]
+
+ // Check if the assembly requires printer upgrades
+ if(!(component.spawn_flags & IC_SPAWN_DEFAULT))
+ blocks["requires_upgrades"] = TRUE
+
+
+ // Check complexity and space limitations
+ if(blocks["used_space"] > blocks["max_space"])
+ return "Used space overflow."
+ if(blocks["complexity"] > blocks["max_complexity"])
+ return "Complexity overflow."
+
+
+ // Block 3. Wires.
+ if(blocks["wires"])
+ if(!islist(blocks["wires"]))
+ return "Invalid wiring list." // Damaged wires list
+
+ for(var/w in blocks["wires"])
+ var/list/wire = w
+
+ if(!islist(wire) || wire.len != 2)
+ return "Invalid wire data."
+
+ 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)
+ if(!IO || !IO2)
+ return "Invalid wire data."
+
+ if(initial(IO.io_type) != initial(IO2.io_type))
+ return "Wire type mismatch."
+
+ return blocks
+
+
+// Loads assembly (in form of list) into an object and returns it.
+// No sanity checks are performed, save file is expected to be validated by validate_electronic_assembly
+/datum/controller/subsystem/processing/circuit/proc/load_electronic_assembly(loc, list/blocks)
+
+ // Block 1. Assembly.
+ var/list/assembly_params = blocks["assembly"]
+ var/obj/item/device/electronic_assembly/assembly_path = all_assemblies[assembly_params["type"]]
+ var/obj/item/device/electronic_assembly/assembly = new assembly_path(null)
+ assembly.load(assembly_params)
+
+
+
+ // 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
+ 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
+
+ assembly.forceMove(loc)
+ return assembly
+
diff --git a/code/modules/integrated_electronics/core/special_pins/boolean_pin.dm b/code/modules/integrated_electronics/core/special_pins/boolean_pin.dm
index 46b1f4c759f9..da59434b6534 100644
--- a/code/modules/integrated_electronics/core/special_pins/boolean_pin.dm
+++ b/code/modules/integrated_electronics/core/special_pins/boolean_pin.dm
@@ -5,7 +5,7 @@
/datum/integrated_io/boolean/ask_for_pin_data(mob/user) // 'Ask' is a bit misleading, acts more like a toggle.
var/new_data = !data
- to_chat(user, "You switch the data bit to [data? "true" : "false"].")
+ to_chat(user, "You switch the data bit to [new_data ? "TRUE" : "FALSE"].")
write_data_to_pin(new_data)
/datum/integrated_io/boolean/write_data_to_pin(var/new_data)
@@ -21,6 +21,6 @@
return IC_FORMAT_BOOLEAN
/datum/integrated_io/boolean/display_data(var/input)
- if(data == TRUE)
- return "(True)"
- return "(False)"
\ No newline at end of file
+ if(data)
+ return "(TRUE)"
+ return "(FALSE)"
diff --git a/code/modules/integrated_electronics/passive/power.dm b/code/modules/integrated_electronics/passive/power.dm
index 87ed709fcf19..4b67f08a0308 100644
--- a/code/modules/integrated_electronics/passive/power.dm
+++ b/code/modules/integrated_electronics/passive/power.dm
@@ -53,28 +53,51 @@
name = "tesla power relay"
desc = "A seemingly enigmatic device which connects to nearby APCs wirelessly and draws power from them."
w_class = WEIGHT_CLASS_SMALL
- extended_desc = "The siphon generates 50 W of power, so long as an APC is in the same room, with a cell that has energy. It will always drain \
+ extended_desc = "The siphon generates 50 W of energy, so long as an APC is in the same room, with a cell that has energy. It will always drain \
from the 'equipment' power channel."
icon_state = "power_relay"
complexity = 7
spawn_flags = IC_SPAWN_RESEARCH
var/power_amount = 50
-//fuel cell
+
+/obj/item/integrated_circuit/passive/power/relay/make_energy()
+ if(!assembly)
+ return
+ var/area/A = get_area(src)
+ if(A && A.powered(EQUIP) && assembly.give_power(power_amount))
+ A.use_power(power_amount, EQUIP)
+ // give_power() handles CELLRATE on its own.
+
+
+// For really fat machines.
+/obj/item/integrated_circuit/passive/power/relay/large
+ name = "large tesla power relay"
+ desc = "A seemingly enigmatic device which connects to nearby APCs wirelessly and draws power from them, now in industiral size!"
+ w_class = WEIGHT_CLASS_BULKY
+ extended_desc = "The siphon generates 2 kW of energy, so long as an APC is in the same room, with a cell that has energy. It will always drain \
+ from the 'equipment' power channel."
+ icon_state = "power_relay"
+ complexity = 15
+ spawn_flags = IC_SPAWN_RESEARCH
+ power_amount = 1000
+
+
+//fuel cell
/obj/item/integrated_circuit/passive/power/chemical_cell
name = "fuel cell"
desc = "Produces electricity from chemicals."
icon_state = "chemical_cell"
- extended_desc = "This is effectively an internal beaker.It will consume and produce power from phoron, slime jelly, welding fuel, carbon,\
+ extended_desc = "This is effectively an internal beaker. It will consume and produce power from plasma, slime jelly, welding fuel, carbon,\
ethanol, nutriments and blood , in order of decreasing efficiency. It will consume fuel only if the battery can take more energy."
container_type = OPENCONTAINER_1
complexity = 4
inputs = list()
- outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF)
+ outputs = list("volume used" = IC_PINTYPE_NUMBER, "self reference" = IC_PINTYPE_REF)
activators = list()
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
var/volume = 60
- var/list/fuel = list("plasma" = 10000, "welding_fuel" = 3000, "carbon" = 2000, "ethanol"= 2000, "nutriment" =1600, "blood" = 1000)
+ var/list/fuel = list("plasma" = 10000, "welding_fuel" = 3000, "carbon" = 2000, "ethanol" = 2000, "nutriment" = 1600, "blood" = 1000)
/obj/item/integrated_circuit/passive/power/chemical_cell/New()
..()
@@ -96,25 +119,3 @@
if((assembly.battery.maxcharge-assembly.battery.charge) / GLOB.CELLRATE > fuel[I])
if(reagents.remove_reagent(I, 1))
assembly.give_power(fuel[I])
-
-
-// For really fat machines.
-/obj/item/integrated_circuit/passive/power/relay/large
- name = "large tesla power relay"
- desc = "A seemingly enigmatic device which connects to nearby APCs wirelessly and draws power from them, now in industiral size!"
- w_class = WEIGHT_CLASS_BULKY
- extended_desc = "The siphon generates 1 kW of power, so long as an APC is in the same room, with a cell that has energy. It will always drain \
- from the 'equipment' power channel."
- icon_state = "power_relay"
- complexity = 15
- spawn_flags = IC_SPAWN_RESEARCH
- power_amount = 1000
-
-/obj/item/integrated_circuit/passive/power/relay/make_energy()
- if(!assembly)
- return
- var/area/A = get_area(src)
- if(A)
- if(A.powered(EQUIP) && assembly.give_power(power_amount))
- A.use_power(power_amount, EQUIP)
- // give_power() handles CELLRATE on its own.
diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm
index 56626afac2ed..0680f62e7724 100644
--- a/code/modules/integrated_electronics/subtypes/input.dm
+++ b/code/modules/integrated_electronics/subtypes/input.dm
@@ -675,7 +675,7 @@
return TRUE
/obj/item/integrated_circuit/input/sensor/ranged
- name = "Ranged sensor"
+ name = "ranged sensor"
desc = "Scans and obtains a reference for any objects or persons in range. All you need to do is point the machine towards target."
extended_desc = "If 'ignore storage' pin is set to true, the sensor will disregard scanning various storage containers such as backpacks."
icon_state = "recorder"
diff --git a/code/modules/integrated_electronics/subtypes/output.dm b/code/modules/integrated_electronics/subtypes/output.dm
index b48b6feaff0c..62de766f5ac5 100644
--- a/code/modules/integrated_electronics/subtypes/output.dm
+++ b/code/modules/integrated_electronics/subtypes/output.dm
@@ -306,16 +306,14 @@
set_pin_data(IC_INPUT, 1, FALSE)
/obj/item/integrated_circuit/output/led/external_examine(mob/user)
- var/text_output = list()
+ var/text_output = "There is "
- // Doing all this work just to have a color-blind friendly output.
- text_output += "There is "
- if(name == displayed_name )
+ if(name == displayed_name)
text_output += "\an [name]"
else
- text_output += "\an ["\improper[name]"] labeled '[displayed_name ]'"
- text_output += " which is currently [(get_pin_data(IC_INPUT, 1)==1) ? "lit *" : "unlit."]"
- to_chat(user,jointext(text_output,null))
+ 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"
diff --git a/code/modules/integrated_electronics/subtypes/power.dm b/code/modules/integrated_electronics/subtypes/power.dm
index a781716e353f..de9055acfae9 100644
--- a/code/modules/integrated_electronics/subtypes/power.dm
+++ b/code/modules/integrated_electronics/subtypes/power.dm
@@ -58,6 +58,10 @@
return FALSE
if(transfer_amount && assembly.draw_power(amount_to_move)) // CELLRATE is already handled in draw_power()
cell.give(transfer_amount * GLOB.CELLRATE)
+ if(istype(AM, /obj/item))
+ var/obj/item/I = AM
+ I.update_icon()
+
return TRUE
else
set_pin_data(IC_OUTPUT, 1, null)
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index 06fa4f6f8ab6..aa5b137a5b2c 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -102,6 +102,16 @@
chambered = null //either way, released the prepared shot
recharge_newshot() //try to charge a new shot
+/obj/item/gun/energy/process_fire()
+ if(!chambered && can_shoot())
+ process_chamber() // If the gun was drained and then recharged, load a new shot.
+ return ..()
+
+/obj/item/gun/energy/process_burst()
+ if(!chambered && can_shoot())
+ process_chamber() // Ditto.
+ return ..()
+
/obj/item/gun/energy/proc/select_fire(mob/living/user)
select++
if (select > ammo_type.len)
diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
index 0ca71451be89..3b93a960ca62 100644
--- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
+++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
@@ -125,7 +125,6 @@
/obj/item/gun/energy/kinetic_accelerator/proc/reload()
cell.give(cell.maxcharge)
- recharge_newshot(1)
if(!suppressed)
playsound(src.loc, 'sound/weapons/kenetic_reload.ogg', 60, 1)
else
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index 127637d3292d..06bda36c664c 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -139,12 +139,10 @@
var/obj/item/stack/sheet/S = A
S.use(1)
cell.give(1000)
- recharge_newshot(1)
to_chat(user, "You insert [A] in [src], recharging it.")
else if(istype(A, /obj/item/ore/plasma))
qdel(A)
cell.give(500)
- recharge_newshot(1)
to_chat(user, "You insert [A] in [src], recharging it.")
else
..()
diff --git a/tgstation.dme b/tgstation.dme
index 662798a171bd..5f8118e83f6f 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -1481,8 +1481,8 @@
#include "code\modules\integrated_electronics\core\helpers.dm"
#include "code\modules\integrated_electronics\core\integrated_circuit.dm"
#include "code\modules\integrated_electronics\core\pins.dm"
-#include "code\modules\integrated_electronics\core\prefab.dm"
#include "code\modules\integrated_electronics\core\printer.dm"
+#include "code\modules\integrated_electronics\core\saved_circuits.dm"
#include "code\modules\integrated_electronics\core\wirer.dm"
#include "code\modules\integrated_electronics\core\special_pins\boolean_pin.dm"
#include "code\modules\integrated_electronics\core\special_pins\char_pin.dm"