Botany Mutation Rework

Reworked the mutation system for Botany to use a "tier system",
adjusting mutation chances and the potential type of mutation based on
the amount of the reagent(s) added.

Updated handling for Floral Somatoray to work properly with new Botany
Mutation Rework.
Adjusted Floral Somatoray's Yield setting to adjust the yield stat of
the plant instead of yield_mod stat of the tray.

Also added additional information to the Plant Analyzer when scanning
trays. Will now include information such as age, yield modifier, and
toxicity in the report. This will not be shown when scanning harvested
goods or seeds.

Fixed some typos and missing words in podmen.dm in preparation of
planned attempt to reintegrate pod-cloning functionality.

Fixed hydroponics trays setting "waterlevel = maxwater" and "nutrilevel
= 3" whenever RefreshParts() is called, and fixed sanity check for water
and nutrients above previous max levels.

Unreported change from my previous commit (this is for the sake of
documentation): End of round score will factor Hydroponics harvests into
the calculations.
This commit is contained in:
FalseIncarnate
2014-11-23 03:14:21 -05:00
parent 99c7c4b667
commit a7c63e4a06
3 changed files with 178 additions and 49 deletions
+139 -48
View File
@@ -41,7 +41,7 @@
// Construction
var/unwrenchable = 1
// Reagent information for process(), consider moving this to a controller along
// with cycle information under 'mechanical concerns' at some point.
var/global/list/toxic_reagents = list(
@@ -116,23 +116,26 @@
"left4zed" = list( 0, 0, 0.2 )
)
// Mutagen list specifies minimum value for the mutation to take place, rather
// than a bound as the lists above specify.
//--FalseIncarnate
// Mutagen list specifies reagent_min_value and reagent_step
// Reagent_min_value (value 1) is the minimum number of units needed to begin mutations
// Reagent_step (value 2) is the number of units between each mutation threshold
var/global/list/mutagenic_reagents = list(
"radium" = list(8,3),
"mutagen" = list(3,8)
"radium" = list(10,10),
"mutagen" = list(1,5)
)
//--FalseIncarnate
/obj/machinery/portable_atmospherics/hydroponics/New()
..()
component_parts = list()
component_parts += new /obj/item/weapon/circuitboard/hydroponics(src)
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
RefreshParts()
create_reagents(200)
connect()
update_icon()
@@ -145,22 +148,24 @@
tmp_capacity += M.rating
maxwater = tmp_capacity * 50 // Up to 300
maxnutri = tmp_capacity * 5 // Up to 30
waterlevel = maxwater
nutrilevel = 3
//waterlevel = maxwater
//nutrilevel = 3
/obj/machinery/portable_atmospherics/hydroponics/bullet_act(var/obj/item/projectile/Proj)
//Don't act on seeds like dionaea that shouldn't change.
if(seed && seed.immutable > 0)
return
//Override for somatoray projectiles.
if(istype(Proj ,/obj/item/projectile/energy/floramut) && prob(20))
mutate(1)
//--FalseIncarnate
//Override for somatoray projectiles, updated to work with new mutation rework
if(istype(Proj ,/obj/item/projectile/energy/floramut))
mutate("F1")
return
else if(istype(Proj ,/obj/item/projectile/energy/florayield) && prob(20))
yield_mod = min(10,yield_mod+rand(1,2))
else if(istype(Proj ,/obj/item/projectile/energy/florayield))
mutate("F2")
return
//--FalseIncarnate
..()
@@ -358,15 +363,27 @@
mutation_mod += beneficial_reagents[R.id][3] * reagent_total
// Mutagen is distinct from the previous types and mostly has a chance of proccing a mutation.
//--FalseIncarnate
// Mutation rework, will now use "thresholds" for proccing types of mutations and their respective chances.
// This should make it easier to avoid species shifts when trying to only affect stats like potency.
// Additionally, the chance of mutations will vary depending on the amount of mutagenic reagents added.
if(mutagenic_reagents[R.id])
var/reagent_min_value = mutagenic_reagents[R.id][1]
var/reagent_value = mutagenic_reagents[R.id][2]+mutation_mod
var/reagent_min_value = mutagenic_reagents[R.id][1] //10 for radium, 1 for unstable mutagen
var/reagent_step = mutagenic_reagents[R.id][2] //10 for radium, 5 for unstable mutagen
if(reagent_total >= reagent_min_value)
if(prob(min(reagent_total*reagent_value,100)))
mutate(reagent_total > 10 ? 2 : 1)
if(reagent_total >= reagent_min_value + (3 * reagent_step)) //31+ for radium, 16+ for unstable mutagen
mutate(4)
else if(reagent_total >= reagent_min_value + (2 * reagent_step)) //21-30 for radium, 11-15 for unstable mutagen
mutate(3)
else if(reagent_total >= reagent_min_value + reagent_step) //11-20 for radium, 6-10 for unstable mutagen
mutate(2)
else if(reagent_total >= reagent_min_value) //1-10 for radium, 1-5 for unstable mutagen
mutate(1)
// Handle nutrient refilling.
//--FalseIncarnate
// Handle nutrient refilling
if(nutrient_reagents[R.id])
nutrilevel += nutrient_reagents[R.id] * reagent_total
@@ -506,26 +523,6 @@
return
/obj/machinery/portable_atmospherics/hydroponics/proc/mutate(var/severity)
// No seed, no mutations.
if(!seed)
return
// Check if we should even bother working on the current seed datum.
if(seed.mutants. && seed.mutants.len && severity > 1 && prob(10+mutation_mod))
mutate_species()
return
// We need to make sure we're not modifying one of the global seed datums.
// If it's not in the global list, then no products of the line have been
// harvested yet and it's safe to assume it's restricted to this tray.
if(!isnull(seed_types[seed.name]))
seed = seed.diverge()
seed.mutate(severity,get_turf(src))
return
/obj/machinery/portable_atmospherics/hydroponics/proc/check_level_sanity()
//Make sure various values are sane.
if(seed)
@@ -534,14 +531,108 @@
health = 0
dead = 0
nutrilevel = max(nutrilevel, 0)
nutrilevel = min(nutrilevel, maxnutri)
waterlevel = max(waterlevel, 0)
waterlevel = min(waterlevel, maxwater)
nutrilevel = max(0,min(nutrilevel,maxnutri))
waterlevel = max(0,min(waterlevel,maxwater))
pestlevel = max(0,min(pestlevel,10))
weedlevel = max(0,min(weedlevel,10))
toxins = max(0,min(toxins,10))
/obj/machinery/portable_atmospherics/hydroponics/proc/mutate(var/severity)
// No seed, no mutations.
if(!seed)
return
/*
--FalseIncarnate
New mutation system, now uses "Mutation Tiers" to adjust the chances of mutations
Tier 1 has a low chance of causing a stat mutation
Tier 2 has a higher chance of causing a stat mutation
Tier 3 has a low chance of causing a species shift (if possible), and will ALWAYS cause a stat mutation if it does not shift species
Tier 4 has a higher chance of causing a species shift (if possible), and will ALWAYS cause a stat mutation if it does not shift species
Tier 4 also has a low chance to cause a SECOND stat mutation when it does not shift species
All mutation chances are increased by the mutation_mod value. Mutation_mod is not transferred into seeds/harvests, and is reset when the plant dies
*/
switch(severity)
//Reagent Tiers
if(1) //Tier 1
if(prob(20+mutation_mod)) //Low chance of stat mutation
if(!isnull(seed_types[seed.name]))
seed = seed.diverge()
seed.mutate(1,get_turf(src))
return
if(2) //Tier 2
if(prob(60+mutation_mod)) //Higher chance of stat mutation
if(!isnull(seed_types[seed.name]))
seed = seed.diverge()
seed.mutate(1,get_turf(src))
return
if(3) //Tier 3
if(prob(20+mutation_mod)) //Low chance of species shift mutation
if(seed.mutants. && seed.mutants.len) //Check if current seed/plant has mutant species
mutate_species()
else //No mutant species, mutate stats instead
if(!isnull(seed_types[seed.name]))
seed = seed.diverge()
seed.mutate(1,get_turf(src))
return
else //Failed to shift, mutate stats instead
if(!isnull(seed_types[seed.name]))
seed = seed.diverge()
seed.mutate(1,get_turf(src))
return
if(4) //Tier 4
if(prob(60+mutation_mod)) //Higher chance of species shift mutation
if(seed.mutants. && seed.mutants.len) //Check if current seed/plant has mutant species
mutate_species()
else //No mutant species, mutate stats instead
if(!isnull(seed_types[seed.name]))
seed = seed.diverge()
seed.mutate(1,get_turf(src))
if(prob(20+mutation_mod)) //Low chance for second stat mutation
if(!isnull(seed_types[seed.name]))
seed = seed.diverge()
seed.mutate(1,get_turf(src))
return
else //Failed to shift, mutate stats instead
if(!isnull(seed_types[seed.name]))
seed = seed.diverge()
seed.mutate(1,get_turf(src))
if(prob(20+mutation_mod)) //Low chance for second stat mutation
if(!isnull(seed_types[seed.name]))
seed = seed.diverge()
seed.mutate(1,get_turf(src))
return
//Floral Somatoray Tiers
if("F1") //Random Stat Tier
if(prob(80+mutation_mod)) //EVEN Higher chance of stat mutation
if(!isnull(seed_types[seed.name]))
seed = seed.diverge()
seed.mutate(1,get_turf(src))
return
if("F2") //Yield Tier
if(prob(40+mutation_mod)) //Medium chance of Yield stat mutation
if(!isnull(seed_types[seed.name]))
seed = seed.diverge()
if(seed.immutable <= 0 && seed.yield != -1) //Check if the plant can be mutated and has a yield to mutate
seed.yield = seed.yield + rand(-2, 2) //Randomly adjust yield
if(seed.yield < 0) //If yield would drop below 0 after adjustment, set to 0 to allow further attempts
seed.yield = 0
return
/* code references
// We need to make sure we're not modifying one of the global seed datums.
// If it's not in the global list, then no products of the line have been
// harvested yet and it's safe to assume it's restricted to this tray.
if(!isnull(seed_types[seed.name]))
seed = seed.diverge()
seed.mutate(severity,get_turf(src))
*/
//--FalseIncarnate
/obj/machinery/portable_atmospherics/hydroponics/proc/mutate_species()
var/previous_plant = seed.display_name
@@ -552,7 +643,7 @@
return
dead = 0
mutate(1)
//mutate(1)
age = 0
health = seed.endurance
lastcycle = world.time
@@ -573,7 +664,7 @@
user << "Unscrew the hoses first!"
return
default_deconstruction_crowbar(O, 1)
//--FalseIncarnate
//Check if held item is an open container
if (O.is_open_container())
@@ -643,7 +734,7 @@
update_icon()
else
user << "There's nothing in [src] to spray!"
else if(istype(O, /obj/item/weapon/wrench) && unwrenchable)
if(anchored == 2)
user << "Unscrew the hoses first!"
+2 -1
View File
@@ -47,11 +47,12 @@ Growing it to term with nothing injected will grab a ghost from the observers. *
for(var/mob/O in respawnable_list)
if(O.mind == source.mind && config.revival_pod_plants)
message_admins("Found mind, asking for respawn")
switch(alert(O,"Your corpse has been placed into a pod plant. Do you want to be resurrected/cloned? Please not if you select 'No', you will be able to be cloned or borged again this round.","Pod Alert","Yes","No"))
switch(alert(O,"Your corpse has been placed into a pod plant. Do you want to be resurrected/cloned? Please note if you select 'No', you will still be able to be cloned or borged again this round.","Pod Alert","Yes","No"))
if("Yes")
source.key = O.key
return
if("No")
user << "The seeds seem to reject the blood, returning to their original size as they stop quivering."
return
else
user << "Nothing happens."
+37
View File
@@ -18,6 +18,17 @@
var/datum/seed/grown_seed
var/datum/reagents/grown_reagents
//--FalseIncarnate
var/IS_TRAY = 0 //used to track if the target is a hydroponics tray or soil. 1 if true, otherwise 0
var/tray_age //age of the plant in the tray
var/tray_weed_level //weed level of tray
var/tray_pest_level //pest level of tray
var/tray_toxins //toxicity of the tray
var/tray_yield_mod //yield modifier of the tray
var/tray_mutation_mod //mutation modifier of the tray
//--FalseIncarnate
if(istype(target,/obj/item/weapon/reagent_containers/food/snacks/grown))
var/obj/item/weapon/reagent_containers/food/snacks/grown/G = target
@@ -38,6 +49,19 @@
else if(istype(target,/obj/machinery/portable_atmospherics/hydroponics))
var/obj/machinery/portable_atmospherics/hydroponics/H = target
//--FalseIncarnate
//Flag the target as a tray for showing tray-specific stats
IS_TRAY = 1
//Save tray data to matching variables
tray_age = H.age
tray_weed_level = H.weedlevel
tray_pest_level = H.pestlevel
tray_toxins = H.toxins
tray_yield_mod = H.yield_mod
tray_mutation_mod = H.mutation_mod
//--FalseIncarnate
grown_seed = H.seed
grown_reagents = H.reagents
@@ -57,6 +81,19 @@
dat += "<tr><td><b>Maturation time</b></td><td>[grown_seed.maturation]</td></tr>"
dat += "<tr><td><b>Production time</b></td><td>[grown_seed.production]</td></tr>"
dat += "<tr><td><b>Potency</b></td><td>[grown_seed.potency]</td></tr>"
//--FalseIncarnate
//Tray-specific stats like Age and Mutation Modifier, not shown if target was not a hydroponics tray or soil
if(IS_TRAY == 1)
dat += "<tr><td></td></tr>"
dat += "<tr><td><b>Age</b></td><td>[tray_age]</td></tr>"
dat += "<tr><td><b>Weed Level</b></td><td>[tray_weed_level]</td></tr>"
dat += "<tr><td><b>Pest Level</b></td><td>[tray_pest_level]</td></tr>"
dat += "<tr><td><b>Toxins</b></td><td>[tray_toxins]</td></tr>"
dat += "<tr><td><b>Yield Modifier</b></td><td>[tray_yield_mod]</td></tr>"
dat += "<tr><td><b>Mutation Modifier</b></td><td>[tray_mutation_mod]</td></tr>"
//--FalseIncarnate
dat += "</table>"
if(grown_reagents && grown_reagents.reagent_list && grown_reagents.reagent_list.len)