/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 = TRUE anchored = TRUE circuit = /obj/item/circuitboard/machine/plantgenes var/obj/item/seeds/seed var/obj/item/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/max_potency = 50 // See RefreshParts() for how these work var/max_yield = 2 var/min_production = 12 var/max_endurance = 10 // IMPT: ALSO AFFECTS LIFESPAN var/min_wchance = 67 var/min_wrate = 10 /obj/machinery/plantgenes/RefreshParts() // Comments represent the max you can set per tier, respectively. seeds.dm [219] clamps these for us but we don't want to mislead the viewer. for(var/obj/item/stock_parts/manipulator/M in component_parts) if(M.rating > 3) max_potency = 95 else max_potency = initial(max_potency) + (M.rating**3) // 53,59,77,95 Clamps at 100 max_yield = initial(max_yield) + (M.rating*2) // 4,6,8,10 Clamps at 10 for(var/obj/item/stock_parts/scanning_module/SM in component_parts) if(SM.rating > 3) //If you create t5 parts I'm a step ahead mwahahaha! min_production = 1 else min_production = 12 - (SM.rating * 3) //9,6,3,1. Requires if to avoid going below clamp [1] max_endurance = initial(max_endurance) + (SM.rating * 25) // 35,60,85,100 Clamps at 10min 100max for(var/obj/item/stock_parts/micro_laser/ML in component_parts) var/wratemod = ML.rating * 2.5 min_wrate = FLOOR(10-wratemod,1) // 7,5,2,0 Clamps at 0 and 10 You want this low min_wchance = 67-(ML.rating*16) // 48,35,19,3 Clamps at 0 and 67 You want this low for(var/obj/item/circuitboard/machine/plantgenes/vaultcheck in component_parts) if(istype(vaultcheck, /obj/item/circuitboard/machine/plantgenes/vault)) // TRAIT_DUMB BOTANY TUTS max_potency = 100 max_yield = 10 min_production = 1 max_endurance = 100 min_wchance = 0 min_wrate = 0 /obj/machinery/plantgenes/update_icon() ..() cut_overlays() if((stat & (BROKEN|NOPOWER))) icon_state = "dnamod-off" else icon_state = "dnamod" if(seed) add_overlay("dnamod-dna") if(panel_open) add_overlay("dnamod-open") /obj/machinery/plantgenes/attackby(obj/item/I, mob/user, params) if(default_deconstruction_screwdriver(user, "dnamod", "dnamod", I)) update_icon() return if(default_deconstruction_crowbar(I)) return if(iscyborg(user)) return if(istype(I, /obj/item/seeds)) if(seed) to_chat(user, "A sample is already loaded into the machine!") else if(!user.temporarilyRemoveItemFromInventory(I)) return insert_seed(I) to_chat(user, "You add [I] to the machine.") interact(user) return else if(istype(I, /obj/item/disk/plantgene)) if(disk) to_chat(user, "A data disk is already loaded into the machine!") else if(!user.transferItemToLoc(I, src)) return disk = I to_chat(user, "You add [I] to the machine.") interact(user) else ..() /obj/machinery/plantgenes/ui_interact(mob/user) . = ..() if(!user) return var/datum/browser/popup = new(user, "plantdna", "Plant DNA Manipulator", 450, 600) if(!(in_range(src, user) || issilicon(user))) popup.close() return 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)) var/datum/plant_gene/core/gene = target if(istype(target, /datum/plant_gene/core/potency)) if(gene.value > max_potency) dat += "

This device's extraction capabilities are currently limited to [max_potency] potency. " dat += "Target gene will be degraded to [max_potency] potency on extraction." else if(istype(target, /datum/plant_gene/core/lifespan)) if(gene.value > max_endurance) dat += "

This device's extraction capabilities are currently limited to [max_endurance] lifespan. " dat += "Target gene will be degraded to [max_endurance] Lifespan on extraction." else if(istype(target, /datum/plant_gene/core/endurance)) if(gene.value > max_endurance) dat += "

This device's extraction capabilities are currently limited to [max_endurance] endurance. " dat += "Target gene will be degraded to [max_endurance] endurance on extraction." else if(istype(target, /datum/plant_gene/core/yield)) if(gene.value > max_yield) dat += "

This device's extraction capabilities are currently limited to [max_yield] yield. " dat += "Target gene will be degraded to [max_yield] yield on extraction." else if(istype(target, /datum/plant_gene/core/production)) if(gene.value < min_production) dat += "

This device's extraction capabilities are currently limited to [min_production] production. " dat += "Target gene will be degraded to [min_production] production on extraction." else if(istype(target, /datum/plant_gene/core/weed_rate)) if(gene.value < min_wrate) dat += "

This device's extraction capabilities are currently limited to [min_wrate] weed rate. " dat += "Target gene will be degraded to [min_wrate] weed rate on extraction." else if(istype(target, /datum/plant_gene/core/weed_chance)) if(gene.value < min_wchance) dat += "

This device's extraction capabilities are currently limited to [min_wchance] weed chance. " dat += "Target gene will be degraded to [min_wchance] weed chance 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 usr.set_machine(src) if(href_list["eject_seed"] && !operation) if (seed) seed.forceMove(drop_location()) seed.verb_pickup() seed = null update_genes() update_icon() else var/obj/item/I = usr.get_active_held_item() if (istype(I, /obj/item/seeds)) if(!usr.temporarilyRemoveItemFromInventory(I)) 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(drop_location()) disk.verb_pickup() disk = null update_genes() else var/obj/item/I = usr.get_active_held_item() if(istype(I, /obj/item/disk/plantgene)) if(!usr.transferItemToLoc(I, src)) return disk = I 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 if(istype(G, /datum/plant_gene/core)) var/datum/plant_gene/core/gene = G if(istype(G, /datum/plant_gene/core/potency)) gene.value = min(gene.value, max_potency) else if(istype(G, /datum/plant_gene/core/lifespan)) gene.value = min(gene.value, max_endurance) //INTENDED else if(istype(G, /datum/plant_gene/core/endurance)) gene.value = min(gene.value, max_endurance) else if(istype(G, /datum/plant_gene/core/production)) gene.value = max(gene.value, min_production) else if(istype(G, /datum/plant_gene/core/yield)) gene.value = min(gene.value, max_yield) else if(istype(G, /datum/plant_gene/core/weed_rate)) gene.value = max(gene.value, min_wrate) else if(istype(G, /datum/plant_gene/core/weed_chance)) gene.value = max(gene.value, min_wchance) 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() disk.gene.apply_vars(seed) 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" // Gene modder for seed vault ship, built with high tech alien parts. /obj/machinery/plantgenes/seedvault circuit = /obj/item/circuitboard/machine/plantgenes/vault /* * Plant DNA disk */ /obj/item/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_flags = UNIQUE_RENAME /obj/item/disk/plantgene/Initialize() . = ..() add_overlay("datadisk_gene") src.pixel_x = rand(-5, 5) src.pixel_y = rand(-5, 5) /obj/item/disk/plantgene/proc/update_name() if(gene) name = "[gene.get_name()] (Plant Data Disk)" else name = "plant data disk" /obj/item/disk/plantgene/attack_self(mob/user) read_only = !read_only to_chat(user, "You flip the write-protect tab to [src.read_only ? "protected" : "unprotected"].") /obj/item/disk/plantgene/examine(mob/user) ..() to_chat(user, "The write-protect tab is set to [src.read_only ? "protected" : "unprotected"].")