From d00834049b55e5d4fcc18a08dd56542d48002417 Mon Sep 17 00:00:00 2001 From: Vegapnk Date: Wed, 10 May 2023 16:19:45 +0200 Subject: [PATCH 1/3] Expose of ResizingGenes, fixing #34 --- .../Gene_GenitaliaResizingGene.cs | 38 +++++++++++++++---- .../Patch_ResizingOnAdulthood.cs | 6 ++- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/Source/Genes/GenitaliaSize/Gene_GenitaliaResizingGene.cs b/Source/Genes/GenitaliaSize/Gene_GenitaliaResizingGene.cs index ee24126..1a9cc73 100644 --- a/Source/Genes/GenitaliaSize/Gene_GenitaliaResizingGene.cs +++ b/Source/Genes/GenitaliaSize/Gene_GenitaliaResizingGene.cs @@ -1,16 +1,34 @@ -namespace RJW_Genes +using Verse; + +namespace RJW_Genes { /// /// Parent Gene for Genitalia Resizing. All Resizing genes should inherit for this class. + /// There is a companion-patch `Patch_ResizingOnAdulthood`. /// /// This helps with some functions (e.g. "hasGenitaliaResizingGenes(pawn)") but also to fire genitalia resizing later in life for Pawns. /// (No Children with huge ding dongs, and I don't want kids with tight anuses I am not that degenerate) + /// + /// + /// There was an Issue (#34) that re-sized the genitalia over multiple birthdays. + /// Before the addition of `ExposeData`, it lost track whether the resizing was already run, + /// leading to a change with every birthday over multiple game starts. /// public abstract class Gene_GenitaliaResizingGene : RJW_Gene { - public const int RESIZING_AGE = 20; - public bool WasApplied { get; set; } + /// + /// The age (in years) at which the Pawns Genes will take effect, resizing their genitalia. + /// + public const int RESIZING_AGE = 20; + + /// + /// Whether or not the gene was already applied. + /// If not, it is checked on every birthday and will be applied accordingly. + /// + private bool resizingWasApplied = false; + public bool ResizingWasApplied { get => resizingWasApplied; set => resizingWasApplied = value; } + public override void PostMake() { @@ -18,7 +36,7 @@ if (pawn.ageTracker.AgeBiologicalYears >= RESIZING_AGE) { Resize(); - WasApplied = true; + ResizingWasApplied = true; } } @@ -28,19 +46,25 @@ if (pawn.ageTracker.AgeBiologicalYears >= RESIZING_AGE) { Resize(); - WasApplied = true; + ResizingWasApplied = true; } } + public override void ExposeData() + { + base.ExposeData(); + Scribe_Values.Look(ref resizingWasApplied, "wasApplied"); + } + /// /// Used to resize the pawns genitalia. /// All Logic should be put here: /// 1. Filters for Gender - /// 2. Filters for Genitalia Existance + /// 2. Filters for Genitalia Existence /// 3. Selection of right Genitalia /// 4. Adjustment of Size /// - /// I kept it intentionally broad, so that e.g. the Penis Resize can resize multiple penises and also for futas, + /// I kept it intentionally broad, so that e.g. the Penis Resize can resize multiple penises and or futas, /// while the breast-gene is female only. /// public abstract void Resize(); diff --git a/Source/Genes/GenitaliaSize/Patch_ResizingOnAdulthood.cs b/Source/Genes/GenitaliaSize/Patch_ResizingOnAdulthood.cs index b8542a0..4fa1904 100644 --- a/Source/Genes/GenitaliaSize/Patch_ResizingOnAdulthood.cs +++ b/Source/Genes/GenitaliaSize/Patch_ResizingOnAdulthood.cs @@ -7,6 +7,8 @@ namespace RJW_Genes /// This Patch adds behavior to all resizing genes: /// At Age RESIZING_MIN_AGE the Pawns Resizing Genes will trigger again, if not already triggered somewhere else. /// This is meant to allow kids to grow up without resized genitals, and resize later (Fixing #11). + /// + /// See `Gene_GenitaliaResizingGene` for a short summary of Issue #34. /// [HarmonyPatch(typeof(Pawn_AgeTracker), "BirthdayBiological")] public class Patch_ResizingOnAdulthood @@ -18,10 +20,10 @@ namespace RJW_Genes { foreach(Gene_GenitaliaResizingGene gene in GeneUtility.GetGenitaliaResizingGenes(___pawn)) { - if (!gene.WasApplied) + if (!gene.ResizingWasApplied) { gene.Resize(); - gene.WasApplied = true; + gene.ResizingWasApplied = true; } } } From 2a7a1be7e1456c8e12a1a329d66b80bf508c53b0 Mon Sep 17 00:00:00 2001 From: Vegapnk Date: Wed, 10 May 2023 20:57:49 +0200 Subject: [PATCH 2/3] Added a configurable AgeTransferExtension for AgeDrain and YouthFountain, some logging #35 --- Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml | 26 ++++++--- Source/Genes/Special/AgeTransferExtension.cs | 17 ++++++ Source/Genes/Special/Patch_AgeDrain.cs | 56 ++++++++++++++++---- Source/Genes/Special/Patch_Youth_Fountain.cs | 35 +++++++++--- Source/Rjw-Genes.csproj | 1 + 5 files changed, 111 insertions(+), 24 deletions(-) create mode 100644 Source/Genes/Special/AgeTransferExtension.cs diff --git a/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml b/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml index f68126f..b72778d 100644 --- a/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml +++ b/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml @@ -12,17 +12,17 @@ - + rjw_genes_orgasm_rush - On Orgasm, carriers of this gene get a boost in activity. (rest-need is partially filled) + On orgasm, carriers of this gene get a boost in activity. (rest-need is partially filled) 1 -2 UI/Memes/FleshPurity 1 - + rjw_genes_youth_fountain Having sex with a carrier of this gene makes the partner slightly younger. (Partner stays adult) @@ -30,9 +30,16 @@ -2 UI/Ideoligions/FireLeaves 2 + +
  • + + 60000 + 18 +
  • +
    - + rjw_genes_sex_age_drain Having sex transfers some of the partners life-time to themselves. (Pawn stays adult) @@ -40,12 +47,19 @@ -1 UI/Icons/ColonistBar/Idle 3 + +
  • + + 120000 + 18 +
  • +
    - + rjw_genes_aphrodisiac_pheromones - RJW_Genes.Gene_Aphrodisiac_Pheromones + RJW_Genes.Gene_Aphrodisiac_Pheromones Pheremones of this pawn induce an incressed sexdrive to others nearby. Genes/Icons/Pheromones 4 diff --git a/Source/Genes/Special/AgeTransferExtension.cs b/Source/Genes/Special/AgeTransferExtension.cs new file mode 100644 index 0000000..e309381 --- /dev/null +++ b/Source/Genes/Special/AgeTransferExtension.cs @@ -0,0 +1,17 @@ +using Verse; + +namespace RJW_Genes +{ + public class AgeTransferExtension : DefModExtension + { + /// + /// Amount by which the Biological Age Ticks will be changed. + /// + public int ageTickChange; + + /// + /// Minimum Age for youthing to take place - pawns cannot end up underaged. + /// + public int minAgeInYears; + } +} \ No newline at end of file diff --git a/Source/Genes/Special/Patch_AgeDrain.cs b/Source/Genes/Special/Patch_AgeDrain.cs index 4138a78..060c20d 100644 --- a/Source/Genes/Special/Patch_AgeDrain.cs +++ b/Source/Genes/Special/Patch_AgeDrain.cs @@ -5,6 +5,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using UnityEngine; +using Verse; namespace RJW_Genes.Genes.Special { @@ -18,9 +20,9 @@ namespace RJW_Genes.Genes.Special * I am not sure how I feel about this, but as some people that I consider "normal" asked me about this I changed it as requested in #26 and #28 */ - const long AGE_TRANSFERED = 120000; // 120k == 2 days + const long AGE_TRANSFERED_FALLBACK = 120000; // 120k == 2 days // 18 Years * 60 Days / Year * 60k Ticks/Day + 1 for safety - const long MINIMUM_AGE = 18 * 60 * 60000 + 1; + const long MINIMUM_AGE_FALLBACK = 18 * 60 * 60000 + 1; public static void Postfix(SexProps props) { @@ -28,18 +30,50 @@ namespace RJW_Genes.Genes.Special { return; } - if (GeneUtility.IsAgeDrainer(props.pawn) && props.pawn.ageTracker.AgeBiologicalTicks > MINIMUM_AGE) + + Pawn pawn = props.pawn; + Pawn partner = props.partner; + + if (GeneUtility.IsAgeDrainer(pawn) && !GeneUtility.IsAgeDrainer(partner)) { - var pawnAge = props.pawn.ageTracker.AgeBiologicalTicks; - //ModLog.Error($"Firing Age Drain \nMinimum Age is \t{MINIMUM_AGE} \nPawn Age is \t{pawnAge} \nTransferred \t{AGE_TRANSFERED}\nResulting in \t{pawnAge - AGE_TRANSFERED}"); - - // Make Partner older - props.partner.ageTracker.AgeBiologicalTicks += AGE_TRANSFERED; - // Make Pawn younger if he is older than minimum age - if (pawnAge - AGE_TRANSFERED > MINIMUM_AGE) - props.pawn.ageTracker.AgeBiologicalTicks = Math.Max(MINIMUM_AGE, (pawnAge - AGE_TRANSFERED)); + TransferAge(pawn, partner); } + else if (GeneUtility.IsAgeDrainer(partner) && !GeneUtility.IsAgeDrainer(pawn)) + { + TransferAge(partner,pawn); + } + else if (GeneUtility.IsAgeDrainer(partner) && GeneUtility.IsAgeDrainer(pawn) && RJW_Genes_Settings.rjw_genes_detailed_debug) + { + ModLog.Message($"[Sexual Age Drainer] both {pawn} and {partner} are sexual-age-drainers - nothing happens."); + } + } + /// + /// Transfers age from the giver to the receiver. + /// + /// The pawn that will receive biological-Age-Ticks, and becomes younger if they are not already young. + /// The pawn that will be giving biological-Age-Ticks. This pawn is always aged, even if the other pawn is too young. + private static void TransferAge(Pawn receiver, Pawn giver) + { + AgeTransferExtension transferExt = GeneDefOf.rjw_genes_sex_age_drain.GetModExtension(); + long age_transfered = transferExt?.ageTickChange ?? AGE_TRANSFERED_FALLBACK; + long minimum_age = transferExt?.minAgeInYears * 60 * 60000 + 1 ?? MINIMUM_AGE_FALLBACK; + + var pawnAge = receiver.ageTracker.AgeBiologicalTicks; + + if (RJW_Genes_Settings.rjw_genes_detailed_debug) + ModLog.Message($"[Sexual Age Drainer] {receiver} is aging {giver} by {age_transfered} ({Math.Round(age_transfered / 60000.0, 2)} days)"); + + // Giver ALWAYS ages + giver.ageTracker.AgeBiologicalTicks += age_transfered; + + // Make Receiver younger if they are older than minimum age + if (pawnAge - age_transfered > minimum_age) + receiver.ageTracker.AgeBiologicalTicks = Math.Max(minimum_age, (pawnAge - age_transfered)); + else { + if (RJW_Genes_Settings.rjw_genes_detailed_debug) + ModLog.Message($"[Sexual Age Drainer] {receiver} was too young ({receiver.ageTracker.AgeBiologicalYears}), and remains unchanged."); + } } } } diff --git a/Source/Genes/Special/Patch_Youth_Fountain.cs b/Source/Genes/Special/Patch_Youth_Fountain.cs index bc07f1b..b64ca83 100644 --- a/Source/Genes/Special/Patch_Youth_Fountain.cs +++ b/Source/Genes/Special/Patch_Youth_Fountain.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Verse; namespace RJW_Genes.Genes.Special { @@ -18,9 +19,9 @@ namespace RJW_Genes.Genes.Special * I am not sure how I feel about this, but as some people that I consider "normal" asked me about this I changed it as requested in #26 and #28 */ - const long AGE_REDUCTION = 60000; // 60k == 1 day + const long AGE_REDUCTION_FALLBACK = 60000; // 60k == 1 day // 18 Years * 60 Days / Year * 60k Ticks/Day + 1 for safety - const long MINIMUM_AGE = 18 * 60 * 60000 + 1; + const long MINIMUM_AGE_FALLBACK = 18 * 60 * 60000 + 1; public static void Postfix(SexProps props) { @@ -28,16 +29,36 @@ namespace RJW_Genes.Genes.Special { return; } - if (GeneUtility.IsYouthFountain(props.pawn) && props.pawn.ageTracker.AgeBiologicalTicks >= MINIMUM_AGE) - { - var partnerAge = props.partner.ageTracker.AgeBiologicalTicks; - if(partnerAge - AGE_REDUCTION > MINIMUM_AGE) - props.partner.ageTracker.AgeBiologicalTicks = Math.Max(MINIMUM_AGE, partnerAge - AGE_REDUCTION); + if (GeneUtility.IsYouthFountain(props.pawn)) + { + ChangeAgeForPawn(props.partner, props.pawn); + } + if (GeneUtility.IsYouthFountain(props.partner)) + { + ChangeAgeForPawn(props.pawn,props.partner); } } + private static void ChangeAgeForPawn(Pawn ToYouth, Pawn YouthingPawn) + { + AgeTransferExtension transferExt = GeneDefOf.rjw_genes_youth_fountain.GetModExtension(); + long age_reduction = transferExt?.ageTickChange ?? AGE_REDUCTION_FALLBACK; + long minimum_age = transferExt?.minAgeInYears * 60 * 60000 + 1 ?? MINIMUM_AGE_FALLBACK; + + var partnerAge = ToYouth.ageTracker.AgeBiologicalTicks; + + if (RJW_Genes_Settings.rjw_genes_detailed_debug) + ModLog.Message($"Firing Youth Fountain - {YouthingPawn} is youthing {ToYouth} by {age_reduction} ({Math.Round(age_reduction / 60000.0, 2)} days)"); + + if (partnerAge - age_reduction > minimum_age) { + ToYouth.ageTracker.AgeBiologicalTicks = Math.Max(minimum_age, partnerAge - age_reduction); + } + else if (RJW_Genes_Settings.rjw_genes_detailed_debug) + ModLog.Message($"[Youth Fountain] {ToYouth} was too young ({ToYouth.ageTracker.AgeBiologicalYears}), and remains unchanged."); + } + } } diff --git a/Source/Rjw-Genes.csproj b/Source/Rjw-Genes.csproj index 3084f31..21e7967 100644 --- a/Source/Rjw-Genes.csproj +++ b/Source/Rjw-Genes.csproj @@ -137,6 +137,7 @@ + From f1e2826f35af6a0d2a8b8d7e4678ed4dd95f724a Mon Sep 17 00:00:00 2001 From: Vegapnk Date: Wed, 10 May 2023 21:06:41 +0200 Subject: [PATCH 3/3] Updated docs --- CHANGELOG.md | 2 ++ KNOWN_BUGS.md | 14 ++++++++++++++ TODOS.md | 2 ++ 3 files changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index af67de6..82a7e78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Addition to InsectIncubator: Now fertilizes eggs once placed inside a host, and breeds out eggs twice as fast. - Many new icons - Custom background icons when Vanilla-Expanded-Framework is loaded +- Sexual Age Drainer & Youth Fountain now change age as configured in XML **Internal:** @@ -20,6 +21,7 @@ - Cockeater now leaves a bite wound! - Pythokin-Patch checks for Licentialabs (#30) - Removed Sex-Change thoughts for pawns born or spawned with a gender-altering gene (Issue #32, PR #33 by @callavico) +- More consistent behavior for genitalia resizing over multiple game-starts (Issue #34) **Queen & Caste Logic** diff --git a/KNOWN_BUGS.md b/KNOWN_BUGS.md index f9bc556..b836d4e 100644 --- a/KNOWN_BUGS.md +++ b/KNOWN_BUGS.md @@ -2,6 +2,20 @@ Collection of Known Bugs and reasons for their origin. +## My Youth Fountain / Age Drainer Pawns do not alter Ages!!! + +Issue: You had a pawn with Youth Fountain have Sex with another Pawn, and the other pawn did not get younger. + +Please Check: + +- Are both pawns in OK Age? +- Did they maybe change age but you didn't notice? Default settings only change by days. +- Did they finish sex? If they are interrupted, nothing happens + +Otherwise: + +Enable the Debug-Settings and provide me with a log. + ## I changed Parts of a pawn and my genes do not apply! Issue: You had a pawn with "huge genitalia" and add a horse-cock with licentia or surgery. This new genitalia is not huge. diff --git a/TODOS.md b/TODOS.md index 16c5906..cdd40a5 100644 --- a/TODOS.md +++ b/TODOS.md @@ -8,6 +8,8 @@ Any help is very appreciated, even if it is just pointing me to existing similar **Incubi** - Add a forced striptease Ability +**Age Transfer Genes** - Add (configurable) option to satisfy Bodymodders and their AgeReversalDemand + ## Planned Genes **Adjustable Cock-Size** like e.g. artificial genitalia have