#define MAX_CIRCUIT_CLONE_TIME 3 MINUTES //circuit slow-clones can only take up this amount of time to complete /obj/item/integrated_circuit_printer name = "integrated circuit printer" desc = "A portable(ish) machine made to print tiny modular circuitry out of metal." icon = 'icons/obj/assemblies/electronic_tools.dmi' icon_state = "circuit_printer" w_class = WEIGHT_CLASS_BULKY var/upgraded = FALSE // When hit with an upgrade disk, will turn true, allowing it to print the higher tier circuits. var/can_clone = TRUE // Allows the printer to clone circuits, either instantly or over time depending on upgrade. Set to FALSE to disable entirely. var/fast_clone = FALSE // If this is false, then cloning will take an amount of deciseconds equal to the metal cost divided by 100. var/debug = FALSE // If it's upgraded and can clone, even without config settings. var/current_category = null var/cloning = FALSE // If the printer is currently creating a circuit var/clone_countdown = 0 // Timestamp for when to print the circuit var/recycling = FALSE // If an assembly is being emptied into this printer var/list/program // Currently loaded save, in form of list /obj/item/integrated_circuit_printer/proc/check_interactivity(mob/user) return user.canUseTopic(src, BE_CLOSE) /obj/item/integrated_circuit_printer/upgraded upgraded = TRUE can_clone = TRUE fast_clone = TRUE /obj/item/integrated_circuit_printer/debug //translation: "integrated_circuit_printer/local_server" name = "debug circuit printer" debug = TRUE upgraded = TRUE can_clone = TRUE w_class = WEIGHT_CLASS_TINY /obj/item/integrated_circuit_printer/Initialize() . = ..() AddComponent(/datum/component/material_container, list(MAT_METAL), MINERAL_MATERIAL_AMOUNT * 25, TRUE, list(/obj/item/stack, /obj/item/integrated_circuit, /obj/item/electronic_assembly)) /obj/item/integrated_circuit_printer/Destroy() STOP_PROCESSING(SSprocessing, src) return ..() /obj/item/integrated_circuit_printer/process() if(!cloning) STOP_PROCESSING(SSprocessing, src) if(world.time >= clone_countdown || fast_clone) var/turf/T = get_turf(src) T.visible_message("[src] has finished printing its assembly!") playsound(get_turf(T), 'sound/items/poster_being_created.ogg', 50, TRUE) SScircuit.load_electronic_assembly(T, program) cloning = FALSE STOP_PROCESSING(SSprocessing, src) /obj/item/integrated_circuit_printer/attackby(obj/item/O, mob/user) if(istype(O, /obj/item/disk/integrated_circuit/upgrade/advanced)) if(upgraded) to_chat(user, "[src] already has this upgrade. ") return TRUE to_chat(user, "You install [O] into [src]. ") upgraded = TRUE interact(user) return TRUE if(istype(O, /obj/item/disk/integrated_circuit/upgrade/clone)) if(fast_clone) to_chat(user, "[src] already has this upgrade. ") return TRUE to_chat(user, "You install [O] into [src]. Circuit cloning will now be instant. ") fast_clone = TRUE interact(user) return TRUE if(istype(O, /obj/item/electronic_assembly)) var/obj/item/electronic_assembly/EA = O //microtransactions not included if(EA.assembly_components.len) if(recycling) return if(!EA.opened) to_chat(user, "You can't reach [EA]'s components to remove them!") return if(EA.battery) to_chat(user, "Remove [EA]'s power cell first!") return for(var/V in EA.assembly_components) var/obj/item/integrated_circuit/IC = V if(!IC.removable) to_chat(user, "[EA] has irremovable components in the casing, preventing you from emptying it.") return to_chat(user, "You begin recycling [EA]'s components...") playsound(src, 'sound/items/electronic_assembly_emptying.ogg', 50, TRUE) if(!do_after(user, 30, target = src)) //short channel so you don't accidentally start emptying out a complex assembly return recycling = TRUE var/datum/component/material_container/mats = GetComponent(/datum/component/material_container) for(var/V in EA.assembly_components) var/obj/item/integrated_circuit/IC = V if(!mats.has_space(mats.get_item_material_amount(IC))) to_chat(user, "[src] can't hold any more materials!") break if(!do_after(user, 5, target = user)) recycling = FALSE return playsound(src, 'sound/items/crowbar.ogg', 50, TRUE) if(EA.try_remove_component(IC, user, TRUE)) mats.user_insert(IC, user) to_chat(user, "You recycle all the components[EA.assembly_components.len ? " you could " : " "]from [EA]!") playsound(src, 'sound/items/electronic_assembly_empty.ogg', 50, TRUE) recycling = FALSE return TRUE return ..() /obj/item/integrated_circuit_printer/attack_self(mob/user) interact(user) /obj/item/integrated_circuit_printer/interact(mob/user) if(isnull(current_category)) current_category = SScircuit.circuit_fabricator_recipe_list[1] var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) var/HTML = "

Integrated Circuit Printer


" if(debug) HTML += "

DEBUG PRINTER -- Infinite materials. Cloning available.

" else HTML += "Metal: [materials.total_amount]/[materials.max_amount].

" if(CONFIG_GET(flag/ic_printing) || debug) HTML += "Assembly cloning: [can_clone ? (fast_clone ? "Instant" : "Available") : "Unavailable"].
" HTML += "Circuits available: [upgraded || debug ? "Advanced":"Regular"]." if(!upgraded) HTML += "
Crossed out circuits mean that the printer is not sufficiently upgraded to create that circuit." HTML += "
" if((can_clone && CONFIG_GET(flag/ic_printing)) || debug) HTML += "Here you can load script for your assembly.
" if(!cloning) HTML += " {Load Program} " else HTML += " {Load Program}" if(!program) HTML += " {[fast_clone ? "Print" : "Begin Printing"] Assembly}" else if(cloning) HTML += " {Cancel Print} - [DisplayTimeText(max(0, clone_countdown - world.time))] remaining until completion" else HTML += " {[fast_clone ? "Print" : "Begin Printing"] Assembly}" HTML += "

" HTML += "Categories:" for(var/category in SScircuit.circuit_fabricator_recipe_list) if(category != current_category) HTML += " \[[category]\] " else // Bold the button if it's already selected. HTML += " \[[category]\] " HTML += "
" HTML += "

[current_category]

" var/list/current_list = SScircuit.circuit_fabricator_recipe_list[current_category] for(var/path in current_list) var/obj/O = path var/can_build = TRUE if(ispath(path, /obj/item/integrated_circuit)) var/obj/item/integrated_circuit/IC = path if((initial(IC.spawn_flags) & IC_SPAWN_RESEARCH) && (!(initial(IC.spawn_flags) & IC_SPAWN_DEFAULT)) && !upgraded) can_build = FALSE if(can_build) HTML += "\[[initial(O.name)]\]: [initial(O.desc)]
" else HTML += "\[[initial(O.name)]\]: [initial(O.desc)]
" user << browse(HTML, "window=integrated_printer;size=600x500;border=1;can_resize=1;can_close=1;can_minimize=1") /obj/item/integrated_circuit_printer/Topic(href, href_list) if(!check_interactivity(usr)) return if(..()) return TRUE add_fingerprint(usr) if(href_list["category"]) current_category = href_list["category"] if(href_list["build"]) var/build_type = text2path(href_list["build"]) if(!build_type || !ispath(build_type)) return TRUE var/cost = 400 if(ispath(build_type, /obj/item/electronic_assembly)) var/obj/item/electronic_assembly/E = SScircuit.cached_assemblies[build_type] cost = E.materials[MAT_METAL] else if(ispath(build_type, /obj/item/integrated_circuit)) var/obj/item/integrated_circuit/IC = SScircuit.cached_components[build_type] cost = IC.materials[MAT_METAL] else if(!build_type in SScircuit.circuit_fabricator_recipe_list["Tools"]) return var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) if(!debug && !materials.use_amount_type(cost, MAT_METAL)) to_chat(usr, "You need [cost] metal to build that!") return TRUE var/obj/item/built = new build_type(drop_location()) usr.put_in_hands(built) if(istype(built, /obj/item/electronic_assembly)) var/obj/item/electronic_assembly/E = built E.opened = TRUE E.update_icon() //reupdate diagnostic hud because it was put_in_hands() and not pickup()'ed E.diag_hud_set_circuithealth() E.diag_hud_set_circuitcell() E.diag_hud_set_circuitstat() E.diag_hud_set_circuittracking() to_chat(usr, "[capitalize(built.name)] printed.") playsound(src, 'sound/items/jaws_pry.ogg', 50, TRUE) if(href_list["print"]) if(!CONFIG_GET(flag/ic_printing) && !debug) to_chat(usr, "CentCom has disabled printing of custom circuitry due to recent allegations of copyright infringement.") return if(!can_clone) // Copying and printing ICs is cloning to_chat(usr, "This printer does not have the cloning upgrade.") return switch(href_list["print"]) if("load") var/input = input("Put your code there:", "loading", null, null) as message | null if(!check_interactivity(usr)) return if(!input) program = null return var/validation = SScircuit.validate_electronic_assembly(input) // Validation error codes are returned as text. if(istext(validation)) to_chat(usr, "Error: [validation]") return else if(islist(validation)) program = validation to_chat(usr, "This is a valid program for [program["assembly"]["type"]].") if(program["requires_upgrades"]) if(upgraded) to_chat(usr, "It uses advanced component designs.") else to_chat(usr, "It uses unknown component designs. Printer upgrade is required to proceed.") if(program["unsupported_circuit"]) to_chat(usr, "This program uses components not supported by the specified assembly. Please change the assembly type in the save file to a supported one.") to_chat(usr, "Used space: [program["used_space"]]/[program["max_space"]].") to_chat(usr, "Complexity: [program["complexity"]]/[program["max_complexity"]].") to_chat(usr, "Metal cost: [program["metal_cost"]].") if("print") if(!program) return if(program["requires_upgrades"] && !upgraded && !debug) to_chat(usr, "This program uses unknown component designs. Printer upgrade is required to proceed.") if(program["unsupported_circuit"] && !debug) to_chat(usr, "This program uses components not supported by the specified assembly. Please change the assembly type in the save file to a supported one.") else if(fast_clone || debug) var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) if(debug || materials.use_amount_type(program["metal_cost"], MAT_METAL)) var/obj/item/assembly = SScircuit.load_electronic_assembly(get_turf(src), program) to_chat(usr, "[assembly] has been printed from the provided template!") playsound(src, 'sound/items/poster_being_created.ogg', 50, TRUE) else to_chat(usr, "You need [program["metal_cost"]] metal to build that!") else var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) if(!materials.use_amount_type(program["metal_cost"], MAT_METAL)) to_chat(usr, "You need [program["metal_cost"]] metal to build that!") return var/cloning_time = round(program["metal_cost"] / 15) cloning_time = min(cloning_time, MAX_CIRCUIT_CLONE_TIME) cloning = TRUE clone_countdown = world.time + cloning_time to_chat(usr, "You begin printing a custom assembly. This will take approximately [DisplayTimeText(cloning_time)]. You can still print \ off normal parts during this time.") playsound(src, 'sound/items/poster_being_created.ogg', 50, TRUE) START_PROCESSING(SSprocessing, src) if("cancel") if(!cloning || !program) return to_chat(usr, "Cloning has been canceled. Metal cost has been refunded.") cloning = FALSE clone_countdown = FALSE var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) materials.use_amount_type(-program["metal_cost"], MAT_METAL) //use negative amount to regain the cost interact(usr) // FUKKEN UPGRADE DISKS /obj/item/disk/integrated_circuit/upgrade name = "integrated circuit printer upgrade disk" desc = "Install this into your integrated circuit printer to enhance it." icon = 'icons/obj/assemblies/electronic_tools.dmi' icon_state = "upgrade_disk" item_state = "card-id" w_class = WEIGHT_CLASS_SMALL /obj/item/disk/integrated_circuit/upgrade/advanced name = "integrated circuit printer upgrade disk - advanced designs" desc = "Install this into your integrated circuit printer to enhance it. This one adds new, advanced designs to the printer." /obj/item/disk/integrated_circuit/upgrade/clone name = "integrated circuit printer upgrade disk - instant cloner" desc = "Install this into your integrated circuit printer to enhance it. This one allows the printer to duplicate assemblies instantaneously." icon_state = "upgrade_disk_clone"