mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
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:
@@ -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"
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
..()
|
..()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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.")
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
|
||||||
@@ -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
|
|
||||||
341
code/modules/integrated_electronics/core/saved_circuits.dm
Normal file
341
code/modules/integrated_electronics/core/saved_circuits.dm
Normal 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
|
||||||
|
|
||||||
@@ -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)"
|
||||||
|
|||||||
@@ -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.
|
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
..()
|
..()
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user