From 0a3e18c0043cc940c099ceab3bcba6aeb2ec1391 Mon Sep 17 00:00:00 2001 From: anoobindisguise <56016372+anoobindisguise@users.noreply.github.com> Date: Sat, 20 Apr 2024 22:13:30 -0700 Subject: [PATCH] Fix active transformable mutations not contributing instability (#72919) * count transformed unvalid muts too * missing parenthesis * Update src/mutation.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * fixes * Update src/mutation.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * this is a lot simpler * Update src/mutation.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * oh, document it too --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- doc/MUTATIONS.md | 12 ++++-------- src/mutation.cpp | 5 +++-- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/doc/MUTATIONS.md b/doc/MUTATIONS.md index a5fc3b13e6104..7ac4e1385de99 100644 --- a/doc/MUTATIONS.md +++ b/doc/MUTATIONS.md @@ -51,17 +51,13 @@ The mutation system works in several steps. All time references are in game time ### Instability and the odds of a good mutation -The odds of a mutation being good or bad is directly determined by Instability, which is a stat tracked using a vitamin. It represents long-term genetic damage; a character will begin the game with 0 Instability and obtain only positive or neutral mutations, but with enough Instability, they will become almost exclusively negative ones. +The odds of a mutation being good or bad is directly determined by Instability, which is a hidden value derived on a per-tree basis (it is possible for the chances of a bad mutation to be different across multiple mutation trees simultaneously). This value is determined by counting all mutations you have that aren't negative, and counting double any mutations that don't belong as double. For example, for the Feline mutation tree, "Feline Ears" is worth a single point of instability, while "Hooves" would count as two points. "Sleepy" counts as no points of instability, since it is a negative mutation. Only traits you have gained as mutations count; ones you started with don't matter. Traits which cannot be gained as mutations, such as the Exodii's "Standard Neurobionic Matrix" mutation, also do not count. Currently, the Robust Genetics trait negates the double penalty for out-of-tree mutations. All mutations are counted as "in tree" that way. Lastly, mutations count their prior forms. "Very Strong" is worth two instability raw, since it counts "Strong" too which you had to mutate in order to obtain it even though it only shows one mutation in your character's list. So if neither "Very Strong" nor "Strong" are in the tree, having "Very Strong" gives four instability; if Strong is in the tree but Very Strong isn't, 3 instability. -These chances are determined on a curve, ranging from 0 Instability (default) to 8000 Instability (the maximum): -* Neutral mutations (those which are neither negative nor positive) are always eligible. -* From roughly 0 to 800 Instability, there is a 100% chance for a positive or neutral mutation and a 0% chance for a negative one. -* Positive and negative chances then quickly slope to meet each other at roughly 2800 Instability. At this point, there are equal chances for positive and negative mutations. -* Chances then gradually continue their current trends until reaching the limit. At the maximum of 8000 Instability, there is roughly a 70% chance for a negative mutation to be selected and a 30% chance for a positive one. As before, regardless of whether a positive or negative mutation is selected, a neutral mutation is also possible. +This value is added up and then compared to the number of mutations that are non negative in the given tree. For example, Alpha has 21 non negative mutations, while Troglobite has 28, and Chimera has even more. Half of your instability for that tree divided by the prior tally is your chance of rolling a bad mutation. For example if your Alpha instability was 7 you'd have a 1/3 chance of getting a bad mutation instead of a good one, and if for Trog your instability was also 7 you would have a 1/4 chance of getting a bad mutation. -Instability very slowly decreases on its own, at a rate of 12 per day. Traits can influence this; for instance, the Robust Genetics trait vastly speeds this up by removing a further 1 Instability per 2 hours, for a total of 24 per day. The Genetic Downward Spiral trait does the opposite, *increasing* Instability at the extremely fast rate of 1 per minute. +Instability cannot decrease over time. It is a static value that can only be lowered by lowering your number of mutations by using Purifier. If you purify back to baseline after becoming heavily mutated, it like getting a reset on your instability value, but it cannot otherwise be lowered without giving up your mutations. -Instability can't currently be viewed numerically in normal play, but the player will receive a visible effect on their character sheet whenever they have any Instability. This serves to give a general ballpark of how unstable the character is without telling them the exact amount. +Finally, there are some sources of true-random mutations that can be inflicted by certain nether monsters for example. These are always completely random regardless of instability, but any beneficial mutations obtained will cause instability as usual. ### tl;dr diff --git a/src/mutation.cpp b/src/mutation.cpp index 991c53a6ddaec..fd3d3a3fdf4c1 100644 --- a/src/mutation.cpp +++ b/src/mutation.cpp @@ -178,8 +178,9 @@ int Character::get_instability_per_category( const mutation_category_id &categ ) bool robust = has_trait( trait_ROBUST ); // For each and every trait we have... for( const trait_id &mut : get_mutations() ) { - // only count muts that have 0 or more points, aren't a threshold, are valid, and aren't a base trait. - if( mut.obj().points > -1 && !mut.obj().threshold && mut.obj().valid && !has_base_trait( mut ) ) { + // only count muts that have 0 or more points, aren't a threshold, have a category, and aren't a base trait. + if( mut.obj().points > -1 && !mut.obj().threshold && !mut.obj().category.empty() && + !has_base_trait( mut ) ) { bool in_categ = false; // If among all allowed categories the mutation has, the input category is one of them. for( const mutation_category_id &Ch_cat : mut.obj().category ) {