Integrated circuit fixes and code improvements (#32773)

* Fucking conflicts

* Small code changes

* Makes the IC printer start upgraded to offset balance concerns caused by a fixed bug
This commit is contained in:
ACCount
2017-11-21 12:04:09 +03:00
committed by AnturK
parent 255a9c2941
commit b161b18599
21 changed files with 713 additions and 753 deletions

View File

@@ -1,6 +1,6 @@
#define IC_INPUT "input" #define IC_INPUT "I"
#define IC_OUTPUT "output" #define IC_OUTPUT "O"
#define IC_ACTIVATOR "activator" #define IC_ACTIVATOR "A"
// Pin functionality. // Pin functionality.
#define DATA_CHANNEL "data channel" #define DATA_CHANNEL "data channel"

View File

@@ -9,8 +9,12 @@ PROCESSING_SUBSYSTEM_DEF(circuit)
var/list/all_exonet_connections = list() //Address = connection datum. var/list/all_exonet_connections = list() //Address = connection datum.
var/list/obj/machinery/exonet_node/all_exonet_nodes = list() 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/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) /datum/controller/subsystem/processing/circuit/Initialize(start_timeofday)
SScircuit.cipherkey = random_string(2000+rand(0,10), GLOB.alphabet) 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() /datum/controller/subsystem/processing/circuit/proc/circuits_init()
//Cached lists for free performance //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)) for(var/path in typesof(/obj/item/integrated_circuit))
var/obj/item/integrated_circuit/IC = path var/obj/item/integrated_circuit/IC = path
var/name = initial(IC.name) 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))) if(!(initial(IC.spawn_flags) & (IC_SPAWN_DEFAULT | IC_SPAWN_RESEARCH)))
continue continue
@@ -35,13 +38,19 @@ PROCESSING_SUBSYSTEM_DEF(circuit)
var/list/category_list = circuit_fabricator_recipe_list[category] var/list/category_list = circuit_fabricator_recipe_list[category]
category_list += IC // Populating the fabricator categories 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( circuit_fabricator_recipe_list["Assemblies"] = list(
/obj/item/device/electronic_assembly, /obj/item/device/electronic_assembly,
/obj/item/device/electronic_assembly/medium, /obj/item/device/electronic_assembly/medium,
/obj/item/device/electronic_assembly/large, /obj/item/device/electronic_assembly/large,
/obj/item/device/electronic_assembly/drone /obj/item/device/electronic_assembly/drone
//new /obj/item/weapon/implant/integrated_circuit, ///obj/item/weapon/implant/integrated_circuit
//new /obj/item/device/assembly/electronic_assembly
) )
circuit_fabricator_recipe_list["Tools"] = list( circuit_fabricator_recipe_list["Tools"] = list(

View File

@@ -109,10 +109,7 @@
use_power(250 * recharge_coeff) use_power(250 * recharge_coeff)
using_power = 1 using_power = 1
update_icon(using_power) 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)) if(istype(charging, /obj/item/ammo_box/magazine/recharge))
var/obj/item/ammo_box/magazine/recharge/R = charging var/obj/item/ammo_box/magazine/recharge/R = charging
if(R.stored_ammo.len < R.max_ammo) if(R.stored_ammo.len < R.max_ammo)

View File

@@ -119,7 +119,7 @@
user.visible_message("[user] starts recharging [A] with [src].","<span class='notice'>You start recharging [A] with [src].</span>") user.visible_message("[user] starts recharging [A] with [src].","<span class='notice'>You start recharging [A] with [src].</span>")
while(C.charge < C.maxcharge) while(C.charge < C.maxcharge)
if(E) 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) if(do_after(user, 10, target = user) && cell.charge)
done_any = TRUE done_any = TRUE
induce(C, coefficient) induce(C, coefficient)
@@ -129,7 +129,7 @@
else else
break break
if(E) 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 if(done_any) // Only show a message if we succeeded at least once
user.visible_message("[user] recharged [A]!","<span class='notice'>You recharged [A]!</span>") user.visible_message("[user] recharged [A]!","<span class='notice'>You recharged [A]!</span>")
recharging = FALSE recharging = FALSE

View File

@@ -1,5 +1,3 @@
/obj/item/device/integrated_electronics/analyzer /obj/item/device/integrated_electronics/analyzer
name = "circuit analyzer" name = "circuit analyzer"
desc = "This tool can scan an assembly and generate code necessary to recreate it in a circuit printer." 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" icon_state = "analyzer"
flags_1 = CONDUCT_1 flags_1 = CONDUCT_1
w_class = WEIGHT_CLASS_SMALL 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) /obj/item/device/integrated_electronics/analyzer/afterattack(var/atom/A, var/mob/living/user)
visible_message( "<span class='notice'>attempt to scan</span>") if(istype(A, /obj/item/device/electronic_assembly))
if(ispath(A.type,/obj/item/device/electronic_assembly)) var/saved = SScircuit.save_electronic_assembly(A)
var/i = 0 if(saved)
var/j = 0 to_chat(user, "<span class='notice'>You scan [A].</span>")
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. user << browse(saved, "window=circuit_scan;size=500x600;border=1;can_resize=1;can_close=1;can_minimize=1")
visible_message( "<span class='notice'>start of scan</span>") else
for(var/ix in 1 to assembly_list.len) to_chat(user, "<span class='warning'>[A] is not complete enough to be encoded!</span>")
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( "<span class='notice'>[A] has been scanned,</span>")
user << browse(jointext(HTML, null), "window=analyzer;size=[500]x[600];border=1;can_resize=1;can_close=1;can_minimize=1")
else else
..() ..()

View File

@@ -8,6 +8,7 @@
icon = 'icons/obj/electronic_assemblies.dmi' icon = 'icons/obj/electronic_assemblies.dmi'
icon_state = "setup_small" icon_state = "setup_small"
flags_1 = NOBLUDGEON_1 flags_1 = NOBLUDGEON_1
materials = list() // To be filled later
var/max_components = IC_MAX_SIZE_BASE var/max_components = IC_MAX_SIZE_BASE
var/max_complexity = IC_COMPLEXITY_BASE var/max_complexity = IC_COMPLEXITY_BASE
var/opened = FALSE var/opened = FALSE
@@ -23,52 +24,12 @@
return user.canUseTopic(src,be_close = TRUE) 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() /obj/item/device/electronic_assembly/Initialize()
.=..() .=..()
START_PROCESSING(SScircuit, src) START_PROCESSING(SScircuit, src)
materials[MAT_METAL] = round((max_complexity + max_components) / 4) * SScircuit.cost_multiplier
/obj/item/device/electronic_assembly/Destroy() /obj/item/device/electronic_assembly/Destroy()
STOP_PROCESSING(SScircuit, src) STOP_PROCESSING(SScircuit, src)
@@ -95,7 +56,7 @@
var/total_part_size = return_total_size() var/total_part_size = return_total_size()
var/total_complexity = return_total_complexity() var/total_complexity = return_total_complexity()
var/HTML = list() var/HTML = ""
HTML += "<html><head><title>[name]</title></head><body>" HTML += "<html><head><title>[name]</title></head><body>"
HTML += "<br><a href='?src=[REF(src)]'>\[Refresh\]</a> | " HTML += "<br><a href='?src=[REF(src)]'>\[Refresh\]</a> | "
@@ -105,25 +66,37 @@
if(battery) if(battery)
HTML += "[round(battery.charge, 0.1)]/[battery.maxcharge] ([round(battery.percent(), 0.1)]%) cell charge. <a href='?src=[REF(src)];remove_cell=1'>\[Remove\]</a>" HTML += "[round(battery.charge, 0.1)]/[battery.maxcharge] ([round(battery.percent(), 0.1)]%) cell charge. <a href='?src=[REF(src)];remove_cell=1'>\[Remove\]</a>"
else else
HTML += "<span class='danger'>No powercell detected!</span>" HTML += "<span class='danger'>No power cell detected!</span>"
HTML += "<br><br>" HTML += "<br><br>"
HTML += "Components:<hr>"
HTML += "Built in:<br>"
//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) if(!circuit.removable)
HTML += "<a href=?src=[REF(circuit)];examine=1;from_assembly=1>[circuit.displayed_name]</a> | " builtin_components += "<a href=?src=[REF(circuit)];examine=1;from_assembly=1>[circuit.displayed_name]</a> | "
HTML += "<a href=?src=[REF(circuit)];rename=1;from_assembly=1>\[Rename\]</a> | " builtin_components += "<a href=?src=[REF(circuit)];rename=1;from_assembly=1>\[Rename\]</a> | "
HTML += "<a href=?src=[REF(circuit)];scan=1;from_assembly=1>\[Scan with Debugger\]</a> | " builtin_components += "<a href=?src=[REF(circuit)];scan=1;from_assembly=1>\[Scan with Debugger\]</a> | "
HTML += "<a href=?src=[REF(circuit)];bottom=[REF(circuit)];from_assembly=1>\[Move to Bottom\]</a>" builtin_components += "<a href=?src=[REF(circuit)];bottom=[REF(circuit)];from_assembly=1>\[Move to Bottom\]</a>"
builtin_components += "<br>"
// Put removable circuits (if any) in separate categories from non-removable
if(builtin_components)
HTML += "<hr>"
HTML += "Built in:<br>"
HTML += builtin_components
HTML += "<hr>"
HTML += "Removable:"
HTML += "<br>" HTML += "<br>"
HTML += "<hr>" for(var/c in components)
HTML += "Removable:<br>" var/obj/item/integrated_circuit/circuit = c
for(var/obj/item/integrated_circuit/circuit in contents)
if(circuit.removable) if(circuit.removable)
HTML += "<a href=?src=[REF(circuit)];examine=1;from_assembly=1>[circuit.displayed_name]</a> | " HTML += "<a href=?src=[REF(circuit)];examine=1;from_assembly=1>[circuit.displayed_name]</a> | "
HTML += "<a href=?src=[REF(circuit)];rename=1;from_assembly=1>\[Rename\]</a> | " HTML += "<a href=?src=[REF(circuit)];rename=1;from_assembly=1>\[Rename\]</a> | "
@@ -133,9 +106,9 @@
HTML += "<br>" HTML += "<br>"
HTML += "</body></html>" HTML += "</body></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(..()) if(..())
return 1 return 1
@@ -155,12 +128,11 @@
interact(usr) // To refresh the UI. interact(usr) // To refresh the UI.
/obj/item/device/electronic_assembly/proc/rename() /obj/item/device/electronic_assembly/proc/rename()
var/mob/M = usr var/mob/M = usr
if(!check_interactivity(M)) if(!check_interactivity(M))
return 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)) if(!check_interactivity(M))
return return
if(src && input) if(src && input)
@@ -200,10 +172,15 @@
for(var/obj/item/integrated_circuit/part in contents) for(var/obj/item/integrated_circuit/part in contents)
. += part.size . += 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. // Returns true if the circuit made it inside.
/obj/item/device/electronic_assembly/proc/add_circuit(var/obj/item/integrated_circuit/IC, var/mob/user) /obj/item/device/electronic_assembly/proc/add_circuit(var/obj/item/integrated_circuit/IC, var/mob/user)
if(!opened) if(!opened)
to_chat(user, "<span class='warning'>\The [src] isn't opened, so you can't put anything inside. Try using a crowbar.</span>") to_chat(user, "<span class='warning'>\The [src]'s hatch is closed, you can't put anything inside.</span>")
return FALSE return FALSE
if(IC.w_class > w_class) if(IC.w_class > w_class)
@@ -245,7 +222,15 @@
visible_message("<span class='notice'> [user] waves [src] around [target].</span>") visible_message("<span class='notice'> [user] waves [src] around [target].</span>")
/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, "<span class='notice'>You [opened ? "open" : "close"] the maintenance hatch of [src].</span>")
update_icon()
return TRUE
/obj/item/device/electronic_assembly/attackby(obj/item/I, mob/living/user)
if(istype(I, /obj/item/integrated_circuit)) if(istype(I, /obj/item/integrated_circuit))
if(!user.canUnEquip(I)) if(!user.canUnEquip(I))
return FALSE return FALSE
@@ -254,24 +239,17 @@
playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
interact(user) interact(user)
return TRUE return TRUE
else if(istype(I, /obj/item/crowbar)) else if(istype(I, /obj/item/device/integrated_electronics/wirer) || istype(I, /obj/item/device/integrated_electronics/debugger))
playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1)
opened = !opened
to_chat(user, "<span class='notice'>You [opened ? "opened" : "closed"] [src].</span>")
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))
if(opened) if(opened)
interact(user) interact(user)
else else
to_chat(user, "<span class='warning'> [src] isn't opened, so you can't fiddle with the internal components. \ to_chat(user, "<span class='warning'>[src]'s hatch is closed, so you can't fiddle with the internal components.</span>")
Try using a crowbar.</span>")
else if(istype(I, /obj/item/stock_parts/cell)) else if(istype(I, /obj/item/stock_parts/cell))
if(!opened) if(!opened)
to_chat(user, "<span class='warning'> [src] isn't opened, so you can't put anything inside. Try using a crowbar.</span>") to_chat(user, "<span class='warning'>[src]'s hatch is closed, so you can't put anything inside.</span>")
return FALSE return FALSE
if(battery) if(battery)
to_chat(user, "<span class='warning'> [src] already has \a [battery] inside. Remove it first if you want to replace it.</span>") to_chat(user, "<span class='warning'>[src] already has \a [battery] installed. Remove it first if you want to replace it.</span>")
return FALSE return FALSE
var/obj/item/stock_parts/cell = I var/obj/item/stock_parts/cell = I
user.transferItemToLoc(I, loc) user.transferItemToLoc(I, loc)
@@ -340,3 +318,48 @@
/obj/item/device/electronic_assembly/Moved(oldLoc, dir) /obj/item/device/electronic_assembly/Moved(oldLoc, dir)
for(var/obj/item/integrated_circuit/IC in contents) for(var/obj/item/integrated_circuit/IC in contents)
IC.ext_moved(oldLoc, dir) 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

View File

@@ -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() var/list/io_list_copy = io_list.Copy()
io_list.Cut() io_list.Cut()
for(var/i in 1 to io_list_copy.len) for(var/i in 1 to io_list_copy.len)
var/io_entry = io_list_copy[i] var/io_entry = io_list_copy[i]
var/default_data = null var/default_data = null
var/io_type_override = null var/io_type_override = null
// Override the default data. // 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. default_data = io_default_list["[i]"] // This is deliberately text because the index is a number in text form.
// Override the pin type. // Override the pin type.
if(io_list_copy[io_entry]) if(io_list_copy[io_entry])
io_type_override = io_list_copy[io_entry] io_type_override = io_list_copy[io_entry]
if(io_type_override) 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 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)) if (istype(new_data) && !isweakref(new_data))
new_data = WEAKREF(new_data) new_data = WEAKREF(new_data)
var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number) var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number)
return pin.write_data_to_pin(new_data) 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) var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number)
return pin.get_data() 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) var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number)
return pin.data_as_type(as_type) 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] var/datum/integrated_io/activate/A = activators[pin_number]
A.push_data() A.push_data()
/datum/integrated_io/proc/get_data() /obj/item/integrated_circuit/proc/get_pin_ref(pin_type, pin_number)
if(isweakref(data))
return data.resolve()
return data
/obj/item/integrated_circuit/proc/get_pin_ref(var/pin_type, var/pin_number)
switch(pin_type) switch(pin_type)
if(IC_INPUT) if(IC_INPUT)
if(pin_number > inputs.len) if(pin_number > inputs.len)
@@ -72,60 +69,75 @@
return FALSE return FALSE
/obj/item/integrated_circuit/proc/asc2b64(var/S) /datum/integrated_io/proc/get_data()
var/static/list/b64 = list( if(isweakref(data))
"A"=0,"B"=1,"C"=2,"D"=3, return data.resolve()
"E"=4,"F"=5,"G"=6,"H"=7, return data
"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
/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)) if(!string || !key ||!istext(string)||!istext(key))
return return
var/r var/r

View File

@@ -4,6 +4,7 @@
icon = 'icons/obj/electronic_assemblies.dmi' icon = 'icons/obj/electronic_assemblies.dmi'
icon_state = "template" icon_state = "template"
w_class = WEIGHT_CLASS_TINY 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/obj/item/device/electronic_assembly/assembly // Reference to the assembly holding this circuit, if any.
var/extended_desc var/extended_desc
var/list/inputs = list() var/list/inputs = list()
@@ -67,10 +68,11 @@ a creative player the means to solve many problems. Circuits are held inside an
/obj/item/integrated_circuit/Initialize() /obj/item/integrated_circuit/Initialize()
displayed_name = name displayed_name = name
setup_io(inputs, /datum/integrated_io, inputs_default) setup_io(inputs, /datum/integrated_io, inputs_default, IC_INPUT)
setup_io(outputs, /datum/integrated_io, outputs_default) setup_io(outputs, /datum/integrated_io, outputs_default, IC_OUTPUT)
setup_io(activators, /datum/integrated_io/activate) 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. /obj/item/integrated_circuit/proc/on_data_written() //Override this for special behaviour when new data gets pushed to the circuit.
return 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_edge_width = "30%"
var/table_middle_width = "40%" var/table_middle_width = "40%"
var/HTML = list() var/HTML = ""
HTML += "<html><head><title>[src.displayed_name]</title></head><body>" HTML += "<html><head><title>[src.displayed_name]</title></head><body>"
HTML += "<div align='center'>" HTML += "<div align='center'>"
HTML += "<table border='1' style='undefined;table-layout: fixed; width: 80%'>" HTML += "<table border='1' style='undefined;table-layout: fixed; width: 80%'>"
@@ -127,7 +129,7 @@ a creative player the means to solve many problems. Circuits are held inside an
HTML += "<br><a href='?src=[REF(src)];'>\[Refresh\]</a> | " HTML += "<br><a href='?src=[REF(src)];'>\[Refresh\]</a> | "
HTML += "<a href='?src=[REF(src)];rename=1'>\[Rename\]</a> | " HTML += "<a href='?src=[REF(src)];rename=1'>\[Rename\]</a> | "
HTML += "<a href='?src=[REF(src)];scan=1'>\[Scan with Device\]</a> | " HTML += "<a href='?src=[REF(src)];scan=1'>\[Scan with Device\]</a> | "
if(src.removable) if(removable)
HTML += "<a href='?src=[REF(src)];remove=1'>\[Remove\]</a><br>" HTML += "<a href='?src=[REF(src)];remove=1'>\[Remove\]</a><br>"
HTML += "<colgroup>" HTML += "<colgroup>"
@@ -205,10 +207,10 @@ a creative player the means to solve many problems. Circuits are held inside an
HTML += "<br><font color='0000AA'>[extended_desc]</font>" HTML += "<br><font color='0000AA'>[extended_desc]</font>"
HTML += "</body></html>" HTML += "</body></html>"
if(src.assembly) if(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") 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 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)]") 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) if(D.accepting_refs)
D.afterattack(src, usr, TRUE) D.afterattack(src, usr, TRUE)
else else
to_chat(usr, "<span class='warning'>The Debugger's 'ref scanner' needs to be on.</span>") to_chat(usr, "<span class='warning'>The debugger's 'ref scanner' needs to be on.</span>")
else else
to_chat(usr, "<span class='warning'>You need a multitool/debugger set to 'ref' mode to do that.</span>") to_chat(usr, "<span class='warning'>You need a multitool/debugger set to 'ref' mode to do that.</span>")
@@ -378,16 +380,22 @@ a creative player the means to solve many problems. Circuits are held inside an
return return
/obj/item/integrated_circuit/proc/disconnect_all() /obj/item/integrated_circuit/proc/disconnect_all()
var/datum/integrated_io/I
for(var/k in 1 to inputs.len) for(var/i in inputs)
var/datum/integrated_io/I = inputs[k] I = i
I.disconnect()
for(var/i in outputs)
I = i
I.disconnect()
for(var/i in activators)
I = i
I.disconnect() 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) /obj/item/integrated_circuit/proc/ext_moved(oldLoc, dir)
return return

View File

@@ -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/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/list/linked = list()
var/io_type = DATA_CHANNEL 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)) if(!istype(holder))
message_admins("ERROR: An integrated_io ([name]) spawned without a valid holder! This is a bug.") message_admins("ERROR: An integrated_io ([name]) spawned without a valid holder! This is a bug.")

View File

@@ -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( "<span class='notice'>started successful</span>")
if(chap[2] != "")
if(debug)
visible_message( "<span class='notice'>assembly</span>")
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( "<span class='notice'>components[elements_input.len]</span>")
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( "<span class='notice'>components[elements.len]</span>")
if(!length(elements_input))
return
if(debug)
visible_message( "<span class='notice'>inserting components[elements.len]</span>")
var/obj/item/integrated_circuit/comp
i=0
for(var/E in elements)
i=i+1
element = splittext( E ,"=-=")
if(debug)
visible_message( "<span class='notice'>[E]</span>")
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( "<span class='notice'>[i]i[j]</span>")
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( "<span class='notice'>[i]o[j]</span>")
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( "<span class='notice'>[i]a[j]</span>")
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( "<span class='notice'>values[elements_input.len]</span>")
i=0
elements = list()
for(var/elem in elements_input)
i=i+1
if(i>1)
elements.Add(elem)
if(debug)
visible_message( "<span class='notice'>values[elements.len]</span>")
if(elements.len>0)
if(debug)
visible_message( "<span class='notice'>setting values[elements.len]</span>")
for(var/E in elements)
element = splittext( E ,":+:")
if(debug)
visible_message( "<span class='notice'>[E]</span>")
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( "<span class='notice'>wires[elements_input.len]</span>")
for(var/elem in elements_input)
i=i+1
if(i>1)
elements.Add(elem)
if(debug)
visible_message( "<span class='notice'>wires[elements.len]</span>")
if(elements.len>0)
if(debug)
visible_message( "<span class='notice'>setting wires[elements.len]</span>")
for(var/E in elements)
element = splittext( E ,"=-=")
if(debug)
visible_message( "<span class='notice'>[E]</span>")
IO = ioa[element[1]]
IO2 = ioa[element[2]]
IO.linked |= IO2
AS.forceMove(loc)
qdel(src)

View File

@@ -4,22 +4,13 @@
icon = 'icons/obj/electronic_assemblies.dmi' icon = 'icons/obj/electronic_assemblies.dmi'
icon_state = "circuit_printer" icon_state = "circuit_printer"
w_class = WEIGHT_CLASS_BULKY w_class = WEIGHT_CLASS_BULKY
var/metal = 0 var/upgraded = TRUE // When hit with an upgrade disk, will turn true, allowing it to print the higher tier circuits.
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/can_clone = FALSE // Same for above, but will allow the printer to duplicate a specific assembly. 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/current_category = null
var/as_printing = FALSE var/list/program // Currently loaded save, in form of list
var/as_needs = 0
var/program ="blank"
var/obj/item/device/integrated_electronics/prefab/PR = null
/obj/item/device/integrated_circuit_printer/proc/check_interactivity(mob/user) /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 /obj/item/device/integrated_circuit_printer/upgraded
upgraded = TRUE upgraded = TRUE
@@ -27,42 +18,10 @@
/obj/item/device/integrated_circuit_printer/Initialize() /obj/item/device/integrated_circuit_printer/Initialize()
. = ..() . = ..()
if(!recipe_list) AddComponent(/datum/component/material_container, list(MAT_METAL), MINERAL_MATERIAL_AMOUNT * 25, TRUE, list(/obj/item/stack, /obj/item/integrated_circuit))
recipe_list = SScircuit.circuit_fabricator_recipe_list
/obj/item/device/integrated_circuit_printer/attackby(var/obj/item/O, var/mob/user) /obj/item/device/integrated_circuit_printer/attackby(var/obj/item/O, var/mob/user)
if(istype(O,/obj/item/stack/sheet/metal)) if(istype(O, /obj/item/disk/integrated_circuit/upgrade/advanced))
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, "<span class='warning'>\The [src] is too full to add more metal.</span>")
return
if(stack.use(num))
to_chat(user, "<span class='notice'>You add [num] sheet\s to \the [src].</span>")
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, "<span class='notice'>Assembly has been printed.</span>")
as_printing = FALSE
as_needs = 0
max_metal = init_max_metal
else
to_chat(user, "<span class='notice'>Please insert [(as_needs-metal)/10] more metal!</span>")
interact(user)
return TRUE
if(istype(O,/obj/item/integrated_circuit))
to_chat(user, "<span class='notice'>You insert the circuit into \the [src]. </span>")
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(upgraded) if(upgraded)
to_chat(user, "<span class='warning'>\The [src] already has this upgrade. </span>") to_chat(user, "<span class='warning'>\The [src] already has this upgrade. </span>")
return TRUE return TRUE
@@ -72,7 +31,7 @@
interact(user) interact(user)
return TRUE 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) if(can_clone)
to_chat(user, "<span class='warning'>\The [src] already has this upgrade. </span>") to_chat(user, "<span class='warning'>\The [src] already has this upgrade. </span>")
return TRUE return TRUE
@@ -88,37 +47,33 @@
interact(user) interact(user)
/obj/item/device/integrated_circuit_printer/interact(mob/user) /obj/item/device/integrated_circuit_printer/interact(mob/user)
var/window_height = 600
var/window_width = 500
if(isnull(current_category)) 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 = "<center><h2>Integrated Circuit Printer</h2></center><br>" var/HTML = "<center><h2>Integrated Circuit Printer</h2></center><br>"
HTML += "Metal: [metal/metal_per_sheet]/[max_metal/metal_per_sheet] sheets.<br>" HTML += "Metal: [materials.total_amount]/[materials.max_amount].<br><br>"
if(CONFIG_GET(flag/ic_printing))
HTML += "Assembly cloning: [can_clone ? "Available": "Unavailable"].<br>"
HTML += "Circuits available: [upgraded ? "Advanced":"Regular"]." HTML += "Circuits available: [upgraded ? "Advanced":"Regular"]."
HTML += "Assembly Cloning: [can_clone ? "Available": "Unavailable"]." if(!upgraded)
HTML += "Crossed out circuits mean that the printer is not sufficiently upgraded to create that circuit.<br>" HTML += "<br>Crossed out circuits mean that the printer is not sufficiently upgraded to create that circuit."
HTML += "<hr>" HTML += "<hr>"
if(can_clone) if(can_clone && CONFIG_GET(flag/ic_printing))
HTML += "Here you can load script for your assembly.<br>" HTML += "Here you can load script for your assembly.<br>"
if(as_printing)
HTML += " {Load Program} "
else
HTML += " <A href='?src=[REF(src)];print=load'>{Load Program}</a> " HTML += " <A href='?src=[REF(src)];print=load'>{Load Program}</a> "
if(program == "blank") if(!program)
HTML += " {Check Program} " HTML += " {Print Assembly}"
else else
HTML += " <A href='?src=[REF(src)];print=check'>{Check Program}</a> " HTML += " <A href='?src=[REF(src)];print=print'>{Print Assembly}</a>"
if((program == "blank")|as_printing)
HTML += " {Print assembly} "
else
HTML += " <A href='?src=[REF(src)];print=print'>{Print assembly}</a> "
if(as_printing)
HTML += "<br> printing in process. Please insert more metal. "
HTML += "<br><hr>" HTML += "<br><hr>"
HTML += "Categories:" HTML += "Categories:"
for(var/category in recipe_list) for(var/category in SScircuit.circuit_fabricator_recipe_list)
if(category != current_category) if(category != current_category)
HTML += " <a href='?src=[REF(src)];category=[category]'>\[[category]\]</a> " HTML += " <a href='?src=[REF(src)];category=[category]'>\[[category]\]</a> "
else // Bold the button if it's already selected. else // Bold the button if it's already selected.
@@ -126,28 +81,26 @@
HTML += "<hr>" HTML += "<hr>"
HTML += "<center><h4>[current_category]</h4></center>" HTML += "<center><h4>[current_category]</h4></center>"
var/list/current_list = recipe_list[current_category] var/list/current_list = SScircuit.circuit_fabricator_recipe_list[current_category]
for(var/k in 1 to current_list.len) for(var/path in current_list)
var/obj/O = current_list[k] var/obj/O = path
var/can_build = TRUE var/can_build = TRUE
if(istype(O, /obj/item/integrated_circuit)) if(ispath(path, /obj/item/integrated_circuit))
var/obj/item/integrated_circuit/IC = current_list[k] var/obj/item/integrated_circuit/IC = path
if((initial(IC.spawn_flags) & IC_SPAWN_RESEARCH) && (!(initial(IC.spawn_flags) & IC_SPAWN_DEFAULT)) && !upgraded) if((initial(IC.spawn_flags) & IC_SPAWN_RESEARCH) && (!(initial(IC.spawn_flags) & IC_SPAWN_DEFAULT)) && !upgraded)
can_build = FALSE can_build = FALSE
if(can_build) if(can_build)
HTML += "<A href='?src=[REF(src)];build=[current_list[k]]'>\[[initial(O.name)]\]</A>: [initial(O.desc)]<br>" HTML += "<A href='?src=[REF(src)];build=[path]'>\[[initial(O.name)]\]</A>: [initial(O.desc)]<br>"
else else
HTML += "<s>\[[initial(O.name)]\]: [initial(O.desc)]</s><br>" HTML += "<s>\[[initial(O.name)]\]</s>: [initial(O.desc)]<br>"
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) /obj/item/device/integrated_circuit_printer/Topic(href, href_list)
if(!check_interactivity(usr)) if(!check_interactivity(usr))
return return
if(..()) if(..())
return TRUE return TRUE
var/sc = 0
add_fingerprint(usr)
if(href_list["category"]) if(href_list["category"])
current_category = href_list["category"] current_category = href_list["category"]
@@ -165,10 +118,15 @@
var/obj/item/integrated_circuit/IC = build_type var/obj/item/integrated_circuit/IC = build_type
cost = initial(IC.w_class) cost = initial(IC.w_class)
if(metal - cost < 0)
to_chat(usr, "<span class='warning'>You need [cost] metal to build that!.</span>") 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, "<span class='warning'>You need [cost] metal to build that!</span>")
return TRUE return TRUE
metal -= cost
new build_type(get_turf(loc)) new build_type(get_turf(loc))
if(href_list["print"]) if(href_list["print"])
@@ -177,39 +135,48 @@
return return
switch(href_list["print"]) switch(href_list["print"])
if("load") if("load")
program = input("Put your code there:", "loading", null, null) var/input = input("Put your code there:", "loading", null, null) as message | null
if("check") if(!check_interactivity(usr))
sc = sanity_check(program,usr) return
if(sc == 0) if(!input)
to_chat(usr, "<span class='warning'>Invalid program.</span>") program = null
else if(sc == -1) return
to_chat(usr, "<span class='warning'>Unknown circuits found. Upgrades required to process this design.</span>")
else if(sc == null) var/validation = SScircuit.validate_electronic_assembly(input)
to_chat(usr, "<span class='warning'>Invalid program.</span>")
// Validation error codes are returned as text.
if(istext(validation))
to_chat(usr, "<span class='warning'>Error: [validation]</span>")
return
else if(islist(validation))
program = validation
to_chat(usr, "<span class='notice'>This is a valid program for [program["assembly"]["type"]].</span>")
if(program["requires_upgrades"])
if(upgraded)
to_chat(usr, "<span class='notice'>It uses advanced component designs.</span>")
else else
to_chat(usr, "<span class='notice'>Program is correct.You'll need [sc/10] sheets of metal</span>") to_chat(usr, "<span class='warning'>It uses unknown component designs. Printer upgrade is required to proceed.</span>")
to_chat(usr, "<span class='notice'>Used space: [program["used_space"]]/[program["max_space"]].</span>")
to_chat(usr, "<span class='notice'>Complexity: [program["complexity"]]/[program["max_complexity"]].</span>")
to_chat(usr, "<span class='notice'>Metal cost: [program["metal_cost"]].</span>")
if("print") if("print")
sc = sanity_check(program,usr) if(!program)
if(sc == 0 || sc == null) return
to_chat(usr, "<span class='warning'>Invalid program.</span>")
else if(sc == -1) if(program["requires_upgrades"] && !upgraded)
to_chat(usr, "<span class='warning'>Unknown circuits found. Upgrades required to process this design.</span>") to_chat(usr, "<span class='warning'>This program uses unknown component designs. Printer upgrade is required to proceed.</span>")
else else
as_printing = TRUE var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
if(sc <= metal) if(materials.use_amount_type(program["metal_cost"], MAT_METAL))
PR = new/obj/item/device/integrated_electronics/prefab(get_turf(loc)) SScircuit.load_electronic_assembly(get_turf(src), program)
PR.program = program
metal = metal - sc
to_chat(usr, "<span class='notice'>Assembly has been printed.</span>") to_chat(usr, "<span class='notice'>Assembly has been printed.</span>")
as_printing = FALSE
as_needs = 0
max_metal=init_max_metal
else else
max_metal = sc + metal_per_sheet to_chat(usr, "<span class='warning'>You need [program["metal_cost"]] metal to build that!</span>")
as_needs = sc
to_chat(usr, "<span class='notice'>Please insert [(as_needs-metal)/10] more metal!</span>")
interact(usr) interact(usr)
// FUKKEN UPGRADE DISKS // FUKKEN UPGRADE DISKS
/obj/item/disk/integrated_circuit/upgrade /obj/item/disk/integrated_circuit/upgrade
name = "integrated circuit printer upgrade disk" name = "integrated circuit printer upgrade disk"
@@ -228,180 +195,3 @@
name = "integrated circuit printer upgrade disk - circuit cloner" 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." desc = "Install this into your integrated circuit printer to enhance it. This one allows the printer to duplicate assemblies."
icon_state = "upgrade_disk_clone" 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( "<span class='notice'>started successful</span>")
if(chap[2] != "")
if(debug)
visible_message( "<span class='notice'>assembly</span>")
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( "<span class='notice'>maxcap[maxcap]maxcomp[maxcomp]</span>")
else
return 0
to_chat(usr, "<span class='notice'>This is program for [element[2]]</span>")
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( "<span class='notice'>components[elements_input.len]</span>")
i = 0
elements = list()
for(var/elem in elements_input)
i=i+1
if(i>1)
elements.Add(elem)
if(debug)
visible_message( "<span class='notice'>components[elements.len]</span>")
if(elements_input.len<1)
return 0
if(debug)
visible_message( "<span class='notice'>inserting components[elements.len]</span>")
i=0
for(var/E in elements)
i=i+1
element = splittext( E ,"=-=")
if(debug)
visible_message( "<span class='notice'>[E]</span>")
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( "<span class='notice'>[i]i[j]</span>")
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( "<span class='notice'>[i]o[j]</span>")
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( "<span class='notice'>[i]a[j]</span>")
if(i<elements.len)
return 0
else
return 0
if(debug)
visible_message( "<span class='notice'>cap[cap]compl[compl]maxcompl[maxcomp]maxcap[maxcap]</span>")
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( "<span class='notice'>values[elements_input.len]</span>")
i=0
elements = list()
for(var/elem in elements_input)
i=i+1
if(i>1)
elements.Add(elem)
if(debug)
visible_message( "<span class='notice'>values[elements.len]</span>")
if(elements.len>0)
if(debug)
visible_message( "<span class='notice'>setting values[elements.len]</span>")
for(var/E in elements)
element = splittext( E ,":+:")
if(debug)
visible_message( "<span class='notice'>[E]</span>")
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( "<span class='notice'>wires[elements_input.len]</span>")
for(var/elem in elements_input)
i=i+1
if(i>1)
elements.Add(elem)
if(debug)
visible_message( "<span class='notice'>wires[elements.len]</span>")
if(elements.len>0)
if(debug)
visible_message( "<span class='notice'>setting wires[elements.len]</span>")
for(var/E in elements)
element = splittext( E ,"=-=")
if(debug)
visible_message( "<span class='notice'>[E]</span>")
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

View File

@@ -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

View File

@@ -5,7 +5,7 @@
/datum/integrated_io/boolean/ask_for_pin_data(mob/user) // 'Ask' is a bit misleading, acts more like a toggle. /datum/integrated_io/boolean/ask_for_pin_data(mob/user) // 'Ask' is a bit misleading, acts more like a toggle.
var/new_data = !data var/new_data = !data
to_chat(user, "<span class='notice'>You switch the data bit to [data? "true" : "false"].</span>") to_chat(user, "<span class='notice'>You switch the data bit to [new_data ? "TRUE" : "FALSE"].</span>")
write_data_to_pin(new_data) write_data_to_pin(new_data)
/datum/integrated_io/boolean/write_data_to_pin(var/new_data) /datum/integrated_io/boolean/write_data_to_pin(var/new_data)
@@ -21,6 +21,6 @@
return IC_FORMAT_BOOLEAN return IC_FORMAT_BOOLEAN
/datum/integrated_io/boolean/display_data(var/input) /datum/integrated_io/boolean/display_data(var/input)
if(data == TRUE) if(data)
return "(True)" return "(TRUE)"
return "(False)" return "(FALSE)"

View File

@@ -53,28 +53,51 @@
name = "tesla power relay" name = "tesla power relay"
desc = "A seemingly enigmatic device which connects to nearby APCs wirelessly and draws power from them." desc = "A seemingly enigmatic device which connects to nearby APCs wirelessly and draws power from them."
w_class = WEIGHT_CLASS_SMALL 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." from the 'equipment' power channel."
icon_state = "power_relay" icon_state = "power_relay"
complexity = 7 complexity = 7
spawn_flags = IC_SPAWN_RESEARCH spawn_flags = IC_SPAWN_RESEARCH
var/power_amount = 50 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 /obj/item/integrated_circuit/passive/power/chemical_cell
name = "fuel cell" name = "fuel cell"
desc = "Produces electricity from chemicals." desc = "Produces electricity from chemicals."
icon_state = "chemical_cell" 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." 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 container_type = OPENCONTAINER_1
complexity = 4 complexity = 4
inputs = list() 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() activators = list()
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
var/volume = 60 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() /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((assembly.battery.maxcharge-assembly.battery.charge) / GLOB.CELLRATE > fuel[I])
if(reagents.remove_reagent(I, 1)) if(reagents.remove_reagent(I, 1))
assembly.give_power(fuel[I]) 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.

View File

@@ -675,7 +675,7 @@
return TRUE return TRUE
/obj/item/integrated_circuit/input/sensor/ranged /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." 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." extended_desc = "If 'ignore storage' pin is set to true, the sensor will disregard scanning various storage containers such as backpacks."
icon_state = "recorder" icon_state = "recorder"

View File

@@ -306,16 +306,14 @@
set_pin_data(IC_INPUT, 1, FALSE) set_pin_data(IC_INPUT, 1, FALSE)
/obj/item/integrated_circuit/output/led/external_examine(mob/user) /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. if(name == displayed_name)
text_output += "There is "
if(name == displayed_name )
text_output += "\an [name]" text_output += "\an [name]"
else else
text_output += "\an ["\improper[name]"] labeled '[displayed_name ]'" text_output += "\an ["\improper[name]"] labeled '[displayed_name]'"
text_output += " which is currently [(get_pin_data(IC_INPUT, 1)==1) ? "lit <font color=[led_color]>*</font>" : "unlit."]" text_output += " which is currently [get_pin_data(IC_INPUT, 1) ? "lit <font color=[led_color]>*</font>" : "unlit"]."
to_chat(user,jointext(text_output,null)) to_chat(user, text_output)
/obj/item/integrated_circuit/output/led/red /obj/item/integrated_circuit/output/led/red
name = "red LED" name = "red LED"

View File

@@ -58,6 +58,10 @@
return FALSE return FALSE
if(transfer_amount && assembly.draw_power(amount_to_move)) // CELLRATE is already handled in draw_power() if(transfer_amount && assembly.draw_power(amount_to_move)) // CELLRATE is already handled in draw_power()
cell.give(transfer_amount * GLOB.CELLRATE) cell.give(transfer_amount * GLOB.CELLRATE)
if(istype(AM, /obj/item))
var/obj/item/I = AM
I.update_icon()
return TRUE return TRUE
else else
set_pin_data(IC_OUTPUT, 1, null) set_pin_data(IC_OUTPUT, 1, null)

View File

@@ -102,6 +102,16 @@
chambered = null //either way, released the prepared shot chambered = null //either way, released the prepared shot
recharge_newshot() //try to charge a new 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) /obj/item/gun/energy/proc/select_fire(mob/living/user)
select++ select++
if (select > ammo_type.len) if (select > ammo_type.len)

View File

@@ -125,7 +125,6 @@
/obj/item/gun/energy/kinetic_accelerator/proc/reload() /obj/item/gun/energy/kinetic_accelerator/proc/reload()
cell.give(cell.maxcharge) cell.give(cell.maxcharge)
recharge_newshot(1)
if(!suppressed) if(!suppressed)
playsound(src.loc, 'sound/weapons/kenetic_reload.ogg', 60, 1) playsound(src.loc, 'sound/weapons/kenetic_reload.ogg', 60, 1)
else else

View File

@@ -139,12 +139,10 @@
var/obj/item/stack/sheet/S = A var/obj/item/stack/sheet/S = A
S.use(1) S.use(1)
cell.give(1000) cell.give(1000)
recharge_newshot(1)
to_chat(user, "<span class='notice'>You insert [A] in [src], recharging it.</span>") to_chat(user, "<span class='notice'>You insert [A] in [src], recharging it.</span>")
else if(istype(A, /obj/item/ore/plasma)) else if(istype(A, /obj/item/ore/plasma))
qdel(A) qdel(A)
cell.give(500) cell.give(500)
recharge_newshot(1)
to_chat(user, "<span class='notice'>You insert [A] in [src], recharging it.</span>") to_chat(user, "<span class='notice'>You insert [A] in [src], recharging it.</span>")
else else
..() ..()

View File

@@ -1481,8 +1481,8 @@
#include "code\modules\integrated_electronics\core\helpers.dm" #include "code\modules\integrated_electronics\core\helpers.dm"
#include "code\modules\integrated_electronics\core\integrated_circuit.dm" #include "code\modules\integrated_electronics\core\integrated_circuit.dm"
#include "code\modules\integrated_electronics\core\pins.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\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\wirer.dm"
#include "code\modules\integrated_electronics\core\special_pins\boolean_pin.dm" #include "code\modules\integrated_electronics\core\special_pins\boolean_pin.dm"
#include "code\modules\integrated_electronics\core\special_pins\char_pin.dm" #include "code\modules\integrated_electronics\core\special_pins\char_pin.dm"