From 54bd569d583dd148d5d978b0f1f3ca4c5f3cdc3f Mon Sep 17 00:00:00 2001 From: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Date: Sat, 14 Feb 2026 03:04:01 -0600 Subject: [PATCH] Removes rng fail from cyto (#95140) ## About The Pull Request Cytology samples no longer have an RNG chance to fail from other mid-grown samples present The two cell lines that used failure for unique events had them reworked slightly - Clown cell lines: Now get boosted by mutagen, but using mutagen has a chance of spawning a mutant clown instead. - Queen bee cell line: Every other successful growth will spawn a swarm of bees instead of a queen bee. Also, grown bees can mutate into random toxin bees. ## Why It's Good For The Game Collecting the necessary reagents and samples to grow something in cyology can take you between thirty minutes to a full hour of your round And if you're unlucky, your hard grown mob can just get nuked, wasting all the reagents you collected! That's VERY unfun. You are *supposed* to mitigate it by using suppressants and whatnot, but sometimes you get samples like this which are nigh impossible to mix successfully image Thus, in the interest of making cytology less of a time waste, I think removing RNG failures is a step in the right direction The minigame still exists - you still need to outpace the other samples to grow successfully. You just no longer get owned for not managing to get enough random suppressants and boosters. ## Changelog :cl: Melbert del: Cytology creations no longer have a random chance to fail if another sample in the vat has growth process. All growth is still reset on any successful creation. As growth failure has been removed, some cell lines that had unique fail interactions have been altered. add: Clown cell lines are now all boosted by supplying mutagen. However, using mutagen may cause a mutant clown to spawn. (Before, failure caused a mutant clown to spawn.) add: Queen bee lines now alternate between spawning a queen bee and a swarm of bees. (Before, failure caused a swarm of bees to spawn.) add: Cytology created bees have a rare chance of having a random toxin. /:cl: --------- Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com> --- .../mob/living/basic/farm_animals/bee/_bee.dm | 26 ++++++++++++- .../vatgrowing/samples/_micro_organism.dm | 37 ++++++------------- .../vatgrowing/samples/cell_lines/common.dm | 33 ++++++++++++----- 3 files changed, 59 insertions(+), 37 deletions(-) diff --git a/code/modules/mob/living/basic/farm_animals/bee/_bee.dm b/code/modules/mob/living/basic/farm_animals/bee/_bee.dm index 4f0fd61f1ba..75d09831358 100644 --- a/code/modules/mob/living/basic/farm_animals/bee/_bee.dm +++ b/code/modules/mob/living/basic/farm_animals/bee/_bee.dm @@ -197,6 +197,29 @@ AddElement(/datum/element/venomous, beegent.type, injection_range, thrown_effect = TRUE) generate_bee_visuals() +/// Picks a random toxin and assigns it to the bee +/mob/living/basic/bee/proc/assign_random_toxin_reagent(respect_can_synth = TRUE) + var/list/toxin_pool = typesof(/datum/reagent/toxin) + var/datum/reagent/toxin + var/sanity = 0 + + do + if(sanity > 20 || !length(toxin_pool)) + toxin = pick(/datum/reagent/toxin, /datum/reagent/toxin/histamine, /datum/reagent/toxin/venom) + respect_can_synth = FALSE // in case someone removes cansynth from all of the above for some goofy reason + else + toxin = pick_n_take(toxin_pool) + sanity += 1 + while(respect_can_synth && !(toxin::chemical_flags & REAGENT_CAN_BE_SYNTHESIZED)) + + assign_reagent(GLOB.chemical_reagents_list[toxin]) + +/mob/living/basic/bee/mutate() + . = ..() + if(!.) + assign_random_toxin_reagent() + . = TRUE + /mob/living/basic/bee/queen name = "queen bee" desc = "She's the queen of bees, BZZ BZZ!" @@ -212,8 +235,7 @@ /mob/living/basic/bee/toxin/Initialize(mapload) . = ..() - var/datum/reagent/toxin = pick(typesof(/datum/reagent/toxin)) - assign_reagent(GLOB.chemical_reagents_list[toxin]) + assign_random_toxin_reagent() /// A bee which despawns after a short amount of time (beespawns?) /mob/living/basic/bee/timed diff --git a/code/modules/research/xenobiology/vatgrowing/samples/_micro_organism.dm b/code/modules/research/xenobiology/vatgrowing/samples/_micro_organism.dm index 0b73e235140..94f12230950 100644 --- a/code/modules/research/xenobiology/vatgrowing/samples/_micro_organism.dm +++ b/code/modules/research/xenobiology/vatgrowing/samples/_micro_organism.dm @@ -29,6 +29,8 @@ var/atom/resulting_atom ///The number of resulting atoms var/resulting_atom_count = 1 + /// Counts how many times this cell line has been grown successfully + VAR_FINAL/grow_count = 0 ///Handles growth of the micro_organism. This only runs if the micro organism is in the growing vat. Reagents is the growing vats reagents /datum/micro_organism/cell_line/proc/handle_growth(obj/machinery/vatgrower/vat) @@ -75,26 +77,11 @@ ///Called once a cell line reaches 100 growth. Then we check if any cell_line is too far so we can perform an epic fail roll /datum/micro_organism/cell_line/proc/finish_growing(obj/machinery/vatgrower/vat) - var/risk = 0 //Penalty for failure, goes up based on how much growth the other cell_lines have - - for(var/datum/micro_organism/cell_line/cell_line in vat.biological_sample.micro_organisms) - if(cell_line == src) //well duh - continue - if(cell_line.growth >= VATGROWING_DANGER_MINIMUM) - risk += cell_line.growth * 0.6 //60% per cell_line potentially. Kryson should probably tweak this playsound(vat, 'sound/effects/splat.ogg', 50, TRUE) - if(rand(1, 100) < risk) //Fail roll! - fuck_up_growing(vat) - . = FALSE - else - succeed_growing(vat) - . = TRUE + succeed_growing(vat) SEND_SIGNAL(vat.biological_sample, COMSIG_SAMPLE_GROWTH_COMPLETED) - -/datum/micro_organism/cell_line/proc/fuck_up_growing(obj/machinery/vatgrower/vat) - vat.visible_message(span_warning("The biological sample in [vat] seems to have dissipated!")) - if(prob(50)) - new /obj/effect/gibspawner/generic(get_turf(vat)) //Spawn some gibs. + grow_count += 1 + return TRUE /datum/micro_organism/cell_line/proc/succeed_growing(obj/machinery/vatgrower/vat) do_smoke(0, vat, vat.loc) @@ -103,13 +90,13 @@ ADD_TRAIT(thing, TRAIT_VATGROWN, "vatgrowing") vat.visible_message(span_nicegreen("[thing] pops out of [vat]!")) //We maybe add some color. the chance is static for now, but idewally we would be able to manipulate it in the future. - if(prob(CYTO_SHINY_CHANCE)) - if(isbasicmob(thing)) - var/mob/living/basic/vat_creature = thing - //if the mob has a special mutation interaction don't do any other mutations. Once we add more mutations that are stackable with shiny we should probably roll for each type independently. - if(vat_creature.mutate()) - return - mutate_color(thing) + if(prob(CYTO_SHINY_CHANCE) && isbasicmob(thing)) + var/mob/living/basic/vat_creature = thing + //if the mob has a special mutation interaction don't do any other mutations. + // Once we add more mutations that are stackable with shiny we should probably roll for each type independently. + if(!vat_creature.mutate()) + mutate_color(thing) + SEND_SIGNAL(vat.biological_sample, COMSIG_SAMPLE_DEPOSITED, thing) ///Overriden to show more info like needs, supplementary and supressive reagents and also growth. diff --git a/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm b/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm index 1aba2f34578..87e6fce25e9 100644 --- a/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm +++ b/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm @@ -468,7 +468,8 @@ /datum/reagent/wittel = 10, //stupid rare /datum/reagent/medicine/omnizine/protozine = 5, /datum/reagent/plasma_oxide = 3, - /datum/reagent/clf3 = 1)//since this is also chemistry it's worth near nothing + /datum/reagent/clf3 = 1, + )//since this is also chemistry it's worth near nothing suppressive_reagents = list(//generics you would regularly put in a vat kill abberant residue /datum/reagent/consumable/nutriment/peptides = -6, @@ -482,12 +483,20 @@ resulting_atom = pick(/mob/living/basic/creature, /mob/living/basic/migo, /mob/living/basic/blankbody) //i looked myself, pretty much all of them are reasonably strong and somewhat on the same level. except migo is the jackpot and the blank body is whiff. return ..() -/datum/micro_organism/cell_line/clown/fuck_up_growing(obj/machinery/vatgrower/vat) - vat.visible_message(span_warning("The biological sample in [vat] seems to have created something horrific!")) +/datum/micro_organism/cell_line/clown - var/mob/selected_mob = pick(list(/mob/living/basic/clown/mutant, /mob/living/basic/clown/fleshclown)) +/datum/micro_organism/cell_line/clown/succeed_growing(obj/machinery/vatgrower/vat) + if(vat.reagents.has_reagent(/datum/reagent/toxin/mutagen) && prob(CYTO_SHINY_CHANCE)) + resulting_atom = pick(/mob/living/basic/clown/mutant, /mob/living/basic/clown/fleshclown) + vat.visible_message(span_warning("The biological sample in [vat] mutates into something horrific!")) + else + resulting_atom = initial(resulting_atom) + return ..() - new selected_mob(get_turf(vat)) +/datum/micro_organism/cell_line/clown/New() + . = ..() + // all clown mutations get a huge boost from mutagen, at the cost of causing occasional mutations + supplementary_reagents[/datum/reagent/toxin/mutagen] = 8 /datum/micro_organism/cell_line/clown/bananaclown desc = "Clown bits with banana chunks" @@ -655,11 +664,15 @@ virus_suspectibility = 0 resulting_atom = /obj/item/queen_bee/bought -/datum/micro_organism/cell_line/queen_bee/fuck_up_growing(obj/machinery/vatgrower/vat) //we love job hazards - vat.visible_message(span_warning("You hear angry buzzing coming from the inside of the vat!")) - for(var/i in 1 to 5) - new /mob/living/basic/bee(get_turf(vat)) - +/datum/micro_organism/cell_line/queen_bee/succeed_growing(obj/machinery/vatgrower/vat) + if(grow_count % 2) // every other growth cycle spawns a horde of bees insteads + resulting_atom_count = 5 + resulting_atom = /mob/living/basic/bee + vat.visible_message(span_warning("You hear angry buzzing coming from the inside of the vat!")) + else + resulting_atom_count = initial(resulting_atom_count) + resulting_atom = initial(resulting_atom) + return ..() /datum/micro_organism/cell_line/butterfly desc = "Papilionoidea cells"