diff --git a/code/modules/hydroponics/grafts.dm b/code/modules/hydroponics/grafts.dm index 105cd40ec29..b3cfbb825c8 100644 --- a/code/modules/hydroponics/grafts.dm +++ b/code/modules/hydroponics/grafts.dm @@ -1,6 +1,6 @@ -/* -A new subsystem for hydroponics, as a way to share specific traits into plants, as a way to phase out the DNA manipulator. -*/ +/** + *A new subsystem for hydroponics, as a way to share specific traits into plants, as a way to phase out the DNA manipulator. + */ /obj/item/graft name = "plant graft" desc = "A carefully cut graft off of a freshly grown plant. Can be grafted onto a plant in order to share unique plant traits onto a plant." @@ -29,9 +29,9 @@ A new subsystem for hydroponics, as a way to share specific traits into plants, to_chat(user, get_graft_text()) return ..() -/* -Adds text to the plant analyzer which describes the graft's parent plant and any stored trait it has, if any. -*/ +/** + *Adds text to the plant analyzer which describes the graft's parent plant and any stored trait it has, if any. + */ /obj/item/graft/proc/get_graft_text() var/text = "- Plant Graft -\n" if(parent_seed) diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm index 7c063500f6a..59a3769cfe6 100644 --- a/code/modules/hydroponics/hydroitemdefines.dm +++ b/code/modules/hydroponics/hydroitemdefines.dm @@ -185,6 +185,25 @@ attack_verb = list("slashed", "sliced", "cut", "clawed") hitsound = 'sound/weapons/bladeslice.ogg' +/obj/item/geneshears + name = "Botanogenetic Plant Shears" + desc = "A high tech, high fidelity pair of plant shears, capable of cutting genetic traits out of a plant." + icon = 'icons/obj/hydroponics/equipment.dmi' + icon_state = "genesheers" + item_state = "secateurs" + lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi' + flags_1 = CONDUCT_1 + force = 10 + throwforce = 8 + w_class = WEIGHT_CLASS_SMALL + slot_flags = ITEM_SLOT_BELT + material_flags = MATERIAL_NO_EFFECTS + custom_materials = list(/datum/material/iron=4000, /datum/material/uranium=1500, /datum/material/gold=500) + attack_verb = list("slashed", "sliced", "cut") + hitsound = 'sound/weapons/bladeslice.ogg' + + // ************************************* // Nutrient defines for hydroponics // ************************************* diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index d50fcc6d38d..a1c23480c67 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -1,6 +1,7 @@ #define TRAY_NAME_UPDATE name = myseed ? "[initial(name)] ([myseed.plantname])" : initial(name) #define YIELD_WEED_MINIMUM 3 #define YIELD_WEED_MAXIMUM 10 +#define STATIC_NUTRIENT_CAPACITY 10 /obj/machinery/hydroponics @@ -62,7 +63,7 @@ /obj/machinery/hydroponics/Initialize() //ALRIGHT YOU DEGENERATES. YOU HAD REAGENT HOLDERS FOR AT LEAST 4 YEARS AND NONE OF YOU MADE HYDROPONICS TRAYS HOLD NUTRIENT CHEMS INSTEAD OF USING "Points". //SO HERE LIES THE "nutrilevel" VAR. IT'S DEAD AND I PUT IT OUT OF IT'S MISERY. USE "reagents" INSTEAD. ~ArcaneMusic, accept no substitutes. - create_reagents(10) + create_reagents(20) . = ..() @@ -78,7 +79,7 @@ for (var/obj/item/stock_parts/manipulator/M in component_parts) rating = M.rating maxwater = tmp_capacity * 50 // Up to 300 - maxnutri = tmp_capacity * 5 // Up to 30 + maxnutri = (tmp_capacity * 5) + STATIC_NUTRIENT_CAPACITY // Up to 50 Maximum reagents.maximum_volume = maxnutri nutridrain = 1/rating @@ -150,7 +151,6 @@ update_icon() else if(self_sustaining) - nutridrain = min(0.5, nutridrain) //By just upgrading your trays you will outpace your trays sustainability. adjustWater(rand(1,2)) adjustWeeds(-1) adjustPests(-1) @@ -169,7 +169,10 @@ //Nutrients////////////////////////////////////////////////////////////// // Nutrients deplete at a constant rate, since new nutrients can boost stats far easier. apply_chemicals(lastuser) - reagents.remove_any(nutridrain) + if(self_sustaining) + reagents.remove_any(min(0.5, nutridrain)) + else + reagents.remove_any(nutridrain) // Lack of nutrients hurts non-weeds if(reagents.total_volume <= 0 && !myseed.get_gene(/datum/plant_gene/trait/plant_type/weed_hardy)) @@ -252,10 +255,9 @@ //This is where stability mutations exist now. switch(myseed.instability) - if(80 to 100) - if(prob(20)) - mutate(0, 0, 0, 0, 0, 0, 0, 10, 0) //Exceedingly low odds of gaining a trait. - if(60 to 79) + if(100 to 80) + mutate(0, 0, 0, 0, 0, 0, 0, 2, 0) //Exceedingly low odds of gaining a trait. + if(79 to 60) if(prob((myseed.instability)/2) && !self_sustaining) mutatespecie() myseed.instability = myseed.instability/2 @@ -382,11 +384,10 @@ else . += "It's empty." - if(!self_sustaining) - . += "Water: [waterlevel]/[maxwater].\n"+\ - "Nutrient: [reagents.total_volume]/[maxnutri]." - else - . += "It doesn't require any water or nutrients." + . += "Water: [waterlevel]/[maxwater].\n"+\ + "Nutrient: [reagents.total_volume]/[maxnutri]." + if(self_sustaining) + . += "The tray's autogrow is active, protecting it from species mutations, weeds, and pests." if(weedlevel >= 5) to_chat(user, "It's filled with weeds!") @@ -394,8 +395,11 @@ to_chat(user, "It's filled with tiny worms!") to_chat(user, "" ) - -/obj/machinery/hydroponics/proc/weedinvasion() // If a weed growth is sufficient, this happens. +/** + * What happens when a tray's weeds grow too large. + * Plants a new weed in an empty tray, then resets the tray. + */ +/obj/machinery/hydroponics/proc/weedinvasion() dead = FALSE var/oldPlantName if(myseed) // In case there's nothing in the tray beforehand @@ -487,8 +491,11 @@ else to_chat(usr, "The few weeds in [src] seem to react, but only for a moment...") - -/obj/machinery/hydroponics/proc/plantdies() // OH NOES!!!!! I put this all in one function to make things easier +/** + * Plant Death Proc. + * Cleans up various stats for the plant upon death, including pests, harvestability, and plant health. + */ +/obj/machinery/hydroponics/proc/plantdies() plant_health = 0 harvest = FALSE pestlevel = 0 // Pests die @@ -497,6 +504,12 @@ update_icon() dead = TRUE +/** + * Plant Cross-Pollination. + * Checks all plants in the tray's oview range, then averages out the seed's potency, instability, and yield values. + * If the seed's instability is >= 20, the seed donates one of it's reagents to that nearby plant. + * * Range - The Oview range of trays to which to look for plants to donate reagents. + */ /obj/machinery/hydroponics/proc/pollinate(var/range = 1) for(var/obj/machinery/hydroponics/T in oview(src, range)) if(T.myseed && !T.dead) @@ -509,9 +522,13 @@ if(reagent_gene.can_add(myseed)) myseed.genes += reagent_gene myseed.reagents_from_genes() - return - + continue +/** + * Pest Mutation Proc. + * When a tray is mutated with high pest values, it will spawn spiders. + * * User - Person who last added chemicals to the tray for logging purposes. + */ /obj/machinery/hydroponics/proc/mutatepest(mob/user) if(pestlevel > 5) message_admins("[ADMIN_LOOKUPFLW(user)] last altered a hydro tray's contents which spawned spiderlings") @@ -536,6 +553,10 @@ to_chat(user, "[reagent_source] is empty!") return 1 + if(reagents.total_volume >= reagents.maximum_volume) + to_chat(user, "[src] is full.") + return + var/list/trays = list(src)//makes the list just this in cases of syringes and compost etc var/target = myseed ? myseed.plantname : src var/visi_msg = "" @@ -619,7 +640,6 @@ var/list/text_string = myseed.get_analyzer_text() if(text_string) to_chat(user, text_string) - return else to_chat(user, "No plant found.") to_chat(user, "- Weed level: [weedlevel] / 10") @@ -660,6 +680,37 @@ adjustHealth(-5) return + else if(istype(O, /obj/item/geneshears)) + if(!myseed) + to_chat(user, "The tray is empty.") + return + if(plant_health <= 15) + to_chat(user, "This plant looks too unhealty to be sheared right now.") + return + + var/list/current_traits = list() + for(var/datum/plant_gene/gene in myseed.genes) + if(istype(gene, /datum/plant_gene/core) || (istype(gene,/datum/plant_gene/trait/plant_type)) || islist(gene)) + continue + if(!(gene.mutability_flags & PLANT_GENE_REMOVABLE) || !(gene.mutability_flags & PLANT_GENE_EXTRACTABLE)) + continue //No bypassing unextractable or essential genes. + current_traits[gene.name] = gene + var/removed_trait = (input(user, "Select a trait to remove from the [myseed.plantname].", "Plant Trait Removal") as null|anything in sortList(current_traits)) + if(removed_trait == null) + return + if(!user.canUseTopic(src, BE_CLOSE)) + return + for(var/datum/plant_gene/gene in myseed.genes) + if(gene.name == removed_trait) + if(myseed.genes.Remove(gene)) + qdel(gene) + break + myseed.reagents_from_genes() + adjustHealth(-15) + to_chat(user, "You carefully shear the genes off of the [myseed.plantname], but leaving the plant looking a bit weak.") + update_icon() + return + else if(istype(O, /obj/item/graft)) var/obj/item/graft/snip = O var/datum/plant_gene/trait/new_trait = snip.stored_trait @@ -765,6 +816,8 @@ if(!powered()) to_chat(user, "[name] has no power.") return + if(!anchored) + return self_sustaining = !self_sustaining idle_power_usage = self_sustaining ? 5000 : 0 to_chat(user, "You [self_sustaining ? "activate" : "deactivated"] [src]'s autogrow function[self_sustaining ? ", maintaining the tray's health while using high amounts of power" : ""].") @@ -777,6 +830,13 @@ reagents.clear_reagents() to_chat(user, "You empty [src]'s nutrient tank.") +/** + * Update Tray Proc + * Handles plant harvesting on the tray side, by clearing the sead, names, description, and dead stat. + * Shuts off autogrow if enabled. + * Sends messages to the cleaer about plants harvested, or if nothing was harvested at all. + * * User - The mob who clears the tray. + */ /obj/machinery/hydroponics/proc/update_tray(mob/user) harvest = FALSE lastproduce = age @@ -798,37 +858,61 @@ self_sustaining = FALSE update_icon() -/// Tray Setters - The following procs adjust the tray or plants variables, and make sure that the stat doesn't go out of bounds./// +/// Tray Setters - The following procs adjust the tray or plants variables, and make sure that the stat doesn't go out of bounds. +/** + * Adjust water. + * Raises or lowers tray water values by a set value. Adding water will dillute toxicity from the tray. + * * adjustamt - determines how much water the tray will be adjusted upwards or downwards. + */ /obj/machinery/hydroponics/proc/adjustWater(adjustamt) waterlevel = clamp(waterlevel + adjustamt, 0, maxwater) if(adjustamt>0) adjustToxic(-round(adjustamt/4))//Toxicity dilutation code. The more water you put in, the lesser the toxin concentration. +/** + * Adjust Health. + * Raises the tray's plant_health stat by a given amount, with total health determined by the seed's endurance. + * * adjustamt - Determines how much the plant_health will be adjusted upwards or downwards. + */ /obj/machinery/hydroponics/proc/adjustHealth(adjustamt) if(myseed && !dead) plant_health = clamp(plant_health + adjustamt, 0, myseed.endurance) +/** + * Adjust Health. + * Raises the plant's plant_health stat by a given amount, with total health determined by the seed's endurance. + * * adjustamt - Determines how much the plant_health will be adjusted upwards or downwards. + */ /obj/machinery/hydroponics/proc/adjustToxic(adjustamt) toxic = clamp(toxic + adjustamt, 0, 100) +/** + * Adjust Pests. + * Raises the tray's pest level stat by a given amount. + * * adjustamt - Determines how much the pest level will be adjusted upwards or downwards. + */ /obj/machinery/hydroponics/proc/adjustPests(adjustamt) pestlevel = clamp(pestlevel + adjustamt, 0, 10) +/** + * Adjust Weeds. + * Raises the plant's weed level stat by a given amount. + * * adjustamt - Determines how much the weed level will be adjusted upwards or downwards. + */ /obj/machinery/hydroponics/proc/adjustWeeds(adjustamt) weedlevel = clamp(weedlevel + adjustamt, 0, 10) +/** + * Spawn Plant. + * Upon using strange reagent on a tray, it will spawn a killer tomato or killer tree at random. + */ /obj/machinery/hydroponics/proc/spawnplant() // why would you put strange reagent in a hydro tray you monster I bet you also feed them blood var/list/livingplants = list(/mob/living/simple_animal/hostile/tree, /mob/living/simple_animal/hostile/killertomato) var/chosen = pick(livingplants) var/mob/living/simple_animal/hostile/C = new chosen C.faction = list("plants") -/obj/machinery/hydroponics/proc/become_self_sufficient() // Ambrosia Gaia effect - visible_message("[src] begins to glow with a beautiful light!") - self_sustaining = TRUE - update_icon() - ////////////////////////////////////////////////////////////////////////////////// /obj/machinery/hydroponics/irrigated //Pre-Irrigated trays! Maybe map a couple on each map, just so they get used? using_irrigation = TRUE diff --git a/code/modules/hydroponics/hydroponics_chemreact.dm b/code/modules/hydroponics/hydroponics_chemreact.dm index 4f460458c43..a4ef78a21fe 100644 --- a/code/modules/hydroponics/hydroponics_chemreact.dm +++ b/code/modules/hydroponics/hydroponics_chemreact.dm @@ -6,11 +6,11 @@ ///Contains the reagents within the tray. if(myseed) myseed.on_chem_reaction(reagents) //In case seeds have some special interactions with special chems, currently only used by vines - //FINE WE'LL DO IT THIS WAY. for(var/c in reagents.reagent_list) var/datum/reagent/chem = c chem.on_hydroponics_apply(myseed, reagents, src, user) + /obj/machinery/hydroponics/proc/mutation_roll(mob/user) switch(rand(100)) if(91 to 100) diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm index 75cb45bd121..f3e9e434af8 100644 --- a/code/modules/hydroponics/seeds.dm +++ b/code/modules/hydroponics/seeds.dm @@ -536,13 +536,3 @@ for(var/i in 1 to amount_random_reagents) var/datum/reagent/chemical = pick(reagents_add) qdel(chemical) - -/obj/item/seeds/proc/remove_random_traits(lower = 0, upper = 2) - var/list/genepool = list() - var/amount_random_traits = rand(lower, upper) - for(var/datum/plant_gene/trait in genes) - genepool += trait - - for(var/i in 1 to amount_random_traits) - var/datum/plant_gene/planted_gene = pick(genepool) - qdel(planted_gene) diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 761ae035b11..c0c466e68d9 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -972,41 +972,3 @@ to_chat(M, "Ah, what was that? You thought you heard something...") M.confused += 5 return ..() - -/datum/reagent/toxin/plantthinner - name = "Plant Thinner" - description = "Contains a chemical that can help in weeding out unwanted chemical traits in plants." - color = "#3b7269" // rgb: 127, 132, 0 - toxpwr = 0.6 - taste_description = "burnt grass" - -/datum/reagent/plantthinner/on_mob_life(mob/living/carbon/M) - M.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.3) - M.confused += 1 - return ..() - -//It's paint thinner, for plants! -/datum/reagent/plantthinner/on_hydroponics_apply(obj/item/seeds/myseed, datum/reagents/chems, obj/machinery/hydroponics/mytray, mob/user) - . = ..() - if(prob(40)) - myseed.remove_random_reagents(1,1) - mytray.adjustToxic(3) - -/datum/reagent/toxin/plantthinner/trait - name = "Trait Thinner" - description = "Contains a stronger variant of plant thinner, capable of genetically stunting certain traits out of plants." - color = "#31100a" // rgb: 127, 132, 0 - toxpwr = 1.5 - taste_description = "burnt hair" - -/datum/reagent/plantthinner/trait/on_mob_life(mob/living/carbon/M) - M.adjustOrganLoss(ORGAN_SLOT_LUNGS, 1.1) - M.confused += 3 - return ..() - -//It's paint thinner, for plants! -/datum/reagent/plantthinner/trait/on_hydroponics_apply(obj/item/seeds/myseed, datum/reagents/chems, obj/machinery/hydroponics/mytray, mob/user) - . = ..() - if(prob(40)) - myseed.remove_random_traits(1,1) - mytray.adjustToxic(6) diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm index 285e057d338..af6bfb29029 100644 --- a/code/modules/reagents/chemistry/recipes/others.dm +++ b/code/modules/reagents/chemistry/recipes/others.dm @@ -49,6 +49,15 @@ for(var/i = 1, i <= created_volume, i++) new /obj/item/stack/sheet/mineral/gold(location) +/datum/chemical_reaction/uraniumsolidification + required_reagents = list(/datum/reagent/consumable/frostoil = 5, /datum/reagent/uranium = 20, /datum/reagent/potassium = 1) + mob_react = FALSE + +/datum/chemical_reaction/uraniumsolidification/on_reaction(datum/reagents/holder, created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/stack/sheet/mineral/uranium(location) + /datum/chemical_reaction/capsaicincondensation results = list(/datum/reagent/consumable/condensedcapsaicin = 5) required_reagents = list(/datum/reagent/consumable/capsaicin = 1, /datum/reagent/consumable/ethanol = 5) diff --git a/code/modules/research/designs/tool_designs.dm b/code/modules/research/designs/tool_designs.dm index bb48b7676fc..3eb106ce1ef 100644 --- a/code/modules/research/designs/tool_designs.dm +++ b/code/modules/research/designs/tool_designs.dm @@ -93,6 +93,16 @@ category = list("Tool Designs") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_CARGO +/datum/design/geneshears + name = "Botanogenetic Plant Shears" + desc = "A high tech, high fidelity pair of plant shears, capable of cutting genetic traits out of a plant." + id = "gene_shears" + build_path = /obj/item/geneshears + build_type = PROTOLATHE + materials = list(/datum/material/iron=4000, /datum/material/uranium=1500, /datum/material/silver=500) + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + ///////////////////////////////////////// //////////////Alien Tools//////////////// ///////////////////////////////////////// diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index b48997565ab..437db42f585 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -563,7 +563,7 @@ id = "exp_tools" display_name = "Experimental Tools" description = "Highly advanced tools." - design_ids = list("exwelder", "jawsoflife", "handdrill", "laserscalpel", "mechanicalpinches", "searingtool") + design_ids = list("exwelder", "jawsoflife", "handdrill", "laserscalpel", "mechanicalpinches", "searingtool", "gene_shears") prereq_ids = list("adv_engi") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 diff --git a/icons/obj/hydroponics/equipment.dmi b/icons/obj/hydroponics/equipment.dmi index e7c45f27ceb..343c88a0dff 100644 Binary files a/icons/obj/hydroponics/equipment.dmi and b/icons/obj/hydroponics/equipment.dmi differ