/obj/machinery/plantgenes name = "plant DNA manipulator" desc = "An advanced device designed to manipulate plant genetic makeup." icon = 'icons/obj/hydroponics/equipment.dmi' icon_state = "dnamod" density = 1 anchored = 1 var/obj/item/seeds/seed var/obj/item/weapon/disk/plantgene/disk var/list/core_genes = list() var/list/reagent_genes = list() var/list/trait_genes = list() var/datum/plant_gene/target var/operation = "" var/rating = 0 var/max_extract_pot = 50 // The cap on potency gene extraction. // This number is for T1, each upgraded part adds 5% for a tech level above T1. // At T4, it reaches 95%. /obj/machinery/plantgenes/New() ..() component_parts = list() component_parts += new /obj/item/weapon/circuitboard/plantgenes(null) component_parts += new /obj/item/weapon/stock_parts/console_screen(null) component_parts += new /obj/item/weapon/stock_parts/scanning_module(null) component_parts += new /obj/item/weapon/stock_parts/micro_laser(null) component_parts += new /obj/item/weapon/stock_parts/manipulator(null) RefreshParts() /obj/machinery/plantgenes/Destroy() core_genes.Cut() reagent_genes.Cut() trait_genes.Cut() target = null QDEL_NULL(seed) QDEL_NULL(disk) return ..() /obj/machinery/plantgenes/RefreshParts() rating = 0 for(var/I in component_parts) if(istype(I, /obj/item/weapon/stock_parts)) var/obj/item/weapon/stock_parts/S = I rating += S.rating-1 max_extract_pot = initial(max_extract_pot) + rating*5 /obj/machinery/plantgenes/update_icon() ..() overlays.Cut() if((stat & (BROKEN|NOPOWER))) icon_state = "dnamod-off" else icon_state = "dnamod" if(seed) overlays += "dnamod-dna" if(panel_open) overlays += "dnamod-open" /obj/machinery/plantgenes/attackby(obj/item/I, mob/user, params) if(default_deconstruction_screwdriver(user, "dnamod", "dnamod", I)) update_icon() return if(exchange_parts(user, I)) return if(default_deconstruction_crowbar(I)) return if(isrobot(user)) return if(istype(I, /obj/item/seeds)) if(seed) to_chat(user, "A sample is already loaded into the machine!") else if(!user.drop_item()) return insert_seed(I) to_chat(user, "You add [I] to the machine.") interact(user) return else if(istype(I, /obj/item/weapon/disk/plantgene)) if(disk) to_chat(user, "A data disk is already loaded into the machine!") else if(!user.drop_item()) return disk = I disk.forceMove(src) to_chat(user, "You add [I] to the machine.") interact(user) else ..() /obj/machinery/plantgenes/attack_hand(mob/user) if(..()) return interact(user) /obj/machinery/plantgenes/attack_ghost(mob/user) interact(user) /obj/machinery/plantgenes/interact(mob/user) add_fingerprint(user) user.set_machine(src) if(!user) return var/datum/browser/popup = new(user, "plantdna", "Plant DNA Manipulator", 450, 600) var/dat = "" if(operation) if(!seed || (!target && operation != "insert")) operation = "" target = null interact(user) return if((operation == "replace" || operation == "insert") && (!disk || !disk.gene)) operation = "" target = null interact(user) return dat += "

Confirm Operation

" dat += "
Are you sure you want to [operation] " switch(operation) if("remove") dat += "[target.get_name()] gene from \the [seed]?
" if("extract") dat += "[target.get_name()] gene from \the [seed]?
" dat += "The sample will be destroyed in process!" if(istype(target, /datum/plant_gene/core/potency)) var/datum/plant_gene/core/gene = target if(gene.value > max_extract_pot) dat += "

This device's extraction capabilities are currently limited to [max_extract_pot] potency. " dat += "Target gene will be degraded to [max_extract_pot] potency on extraction." if("replace") dat += "[target.get_name()] gene with [disk.gene.get_name()]?
" if("insert") dat += "[disk.gene.get_name()] gene into \the [seed]?
" dat += "
Confirm " dat += "Abort
" popup.set_content(dat) popup.open() return dat+= "
" dat += "
Plant Sample:
" dat += "
Data Disk:
" dat += "
" if(seed) var/can_insert = disk && disk.gene && disk.gene.can_add(seed) var/can_extract = disk && !disk.read_only dat += "

Core Genes

" for(var/a in core_genes) var/datum/plant_gene/G = a if(!G) continue dat += "" dat += "
[G.get_name()]" if(can_extract) dat += "Extract" if(can_insert && istype(disk.gene, G.type)) dat += "Replace" dat += "
" if(seed.yield != -1) dat += "

Content Genes

" if(reagent_genes.len) dat += "" for(var/a in reagent_genes) var/datum/plant_gene/G = a dat += "" dat += "
[G.get_name()]" if(can_extract) dat += "Extract" dat += "Remove" dat += "
" else dat += "No content-related genes detected in sample.
" dat += "
" if(can_insert && istype(disk.gene, /datum/plant_gene/reagent)) dat += "Insert: [disk.gene.get_name()]" dat += "

Trait Genes

" if(trait_genes.len) dat += "" for(var/a in trait_genes) var/datum/plant_gene/G = a dat += "" dat += "
[G.get_name()]" if(can_extract) dat += "Extract" dat += "Remove" dat += "
" else dat += "No trait-related genes detected in sample.
" if(can_insert && istype(disk.gene, /datum/plant_gene/trait)) dat += "Insert: [disk.gene.get_name()]" dat += "
" else dat += "
No sample found.
Please, insert a plant sample to use this device." popup.set_content(dat) popup.open() /obj/machinery/plantgenes/Topic(var/href, var/list/href_list) if(..()) return 1 usr.set_machine(src) if(href_list["eject_seed"] && !operation) if(seed) seed.forceMove(loc) seed.verb_pickup() seed = null update_genes() update_icon() else var/obj/item/I = usr.get_active_hand() if(istype(I, /obj/item/seeds)) if(!usr.drop_item()) return insert_seed(I) to_chat(usr, "You add [I] to the machine.") update_icon() else if(href_list["eject_disk"] && !operation) if(disk) disk.forceMove(loc) disk.verb_pickup() disk = null update_genes() else var/obj/item/I = usr.get_active_hand() if(istype(I, /obj/item/weapon/disk/plantgene)) if(!usr.drop_item()) return disk = I disk.forceMove(src) to_chat(usr, "You add [I] to the machine.") else if(href_list["op"] == "insert" && disk && disk.gene && seed) if(!operation) // Wait for confirmation operation = "insert" else if(!istype(disk.gene, /datum/plant_gene/core) && disk.gene.can_add(seed)) seed.genes += disk.gene.Copy() if(istype(disk.gene, /datum/plant_gene/reagent)) seed.reagents_from_genes() update_genes() repaint_seed() operation = "" target = null else if(href_list["gene"] && seed) var/datum/plant_gene/G = seed.get_gene(href_list["gene"]) if(!G || !href_list["op"] || !(href_list["op"] in list("remove", "extract", "replace"))) interact(usr) return if(!operation || target != G) // Wait for confirmation target = G operation = href_list["op"] else if(operation == href_list["op"] && target == G) switch(href_list["op"]) if("remove") if(!istype(G, /datum/plant_gene/core)) seed.genes -= G if(istype(G, /datum/plant_gene/reagent)) seed.reagents_from_genes() repaint_seed() if("extract") if(disk && !disk.read_only) disk.gene = G.Copy() if(istype(disk.gene, /datum/plant_gene/core/potency)) var/datum/plant_gene/core/gene = disk.gene gene.value = min(gene.value, max_extract_pot) disk.update_name() qdel(seed) seed = null update_icon() if("replace") if(disk && disk.gene && istype(disk.gene, G.type) && istype(G, /datum/plant_gene/core)) seed.genes -= G var/datum/plant_gene/core/C = disk.gene.Copy() seed.genes += C C.apply_stat(seed) repaint_seed() if("insert") if(disk && disk.gene && !istype(disk.gene, /datum/plant_gene/core) && disk.gene.can_add(seed)) seed.genes += disk.gene.Copy() if(istype(disk.gene, /datum/plant_gene/reagent)) seed.reagents_from_genes() repaint_seed() update_genes() operation = "" target = null else if(href_list["abort"]) operation = "" target = null interact(usr) /obj/machinery/plantgenes/proc/insert_seed(obj/item/seeds/S) if(!istype(S) || seed) return S.forceMove(src) seed = S update_genes() update_icon() /obj/machinery/plantgenes/proc/update_genes() core_genes = list() reagent_genes = list() trait_genes = list() if(seed) var/gene_paths = list( /datum/plant_gene/core/potency, /datum/plant_gene/core/yield, /datum/plant_gene/core/production, /datum/plant_gene/core/endurance, /datum/plant_gene/core/lifespan, /datum/plant_gene/core/weed_rate, /datum/plant_gene/core/weed_chance ) for(var/a in gene_paths) core_genes += seed.get_gene(a) for(var/datum/plant_gene/reagent/G in seed.genes) reagent_genes += G for(var/datum/plant_gene/trait/G in seed.genes) trait_genes += G /obj/machinery/plantgenes/proc/repaint_seed() if(!seed) return if(copytext(seed.name, 1, 13) == "experimental") return // Already modded name and icon seed.name = "experimental " + seed.name seed.icon_state = "seed-x" /* * Plant DNA disk */ /obj/item/weapon/disk/plantgene name = "plant data disk" desc = "A disk for storing plant genetic data." icon_state = "datadisk_hydro" materials = list(MAT_METAL=30, MAT_GLASS=10) var/datum/plant_gene/gene var/read_only = 0 //Well, it's still a floppy disk /obj/item/weapon/disk/plantgene/New() ..() overlays += "datadisk_gene" pixel_x = rand(-5, 5) pixel_y = rand(-5, 5) /obj/item/weapon/disk/plantgene/Destroy() QDEL_NULL(gene) return ..() /obj/item/weapon/disk/plantgene/attackby(obj/item/weapon/W, mob/user, params) ..() if(istype(W, /obj/item/weapon/pen)) var/t = stripped_input(user, "What would you like the label to be?", name, null) if(user.get_active_hand() != W) return if(!in_range(src, user) && loc != user) return if(t) name = "plant data disk - '[t]'" else name = "plant data disk" /obj/item/weapon/disk/plantgene/proc/update_name() if(gene) name = "plant data disk - '[gene.get_name()]'" else name = "plant data disk" /obj/item/weapon/disk/plantgene/attack_self(mob/user) read_only = !read_only to_chat(user, "You flip the write-protect tab to [read_only ? "protected" : "unprotected"].") /obj/item/weapon/disk/plantgene/examine(mob/user) ..() to_chat(user, "The write-protect tab is set to [read_only ? "protected" : "unprotected"].") /* * Plant DNA Disks Box */ /obj/item/weapon/storage/box/disks_plantgene name = "plant data disks box" icon_state = "disk_kit" /obj/item/weapon/storage/box/disks_plantgene/New() ..() for(var/i in 1 to 7) new /obj/item/weapon/disk/plantgene(src)