From 04c27a19133ad53a3ffbf4d23389c2775ce7464a Mon Sep 17 00:00:00 2001 From: Vegapnk Date: Mon, 5 Jun 2023 15:51:15 +0200 Subject: [PATCH] Drafted Orgasmic Mytosis Gene and Behaviour --- CHANGELOG.md | 3 + Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml | 11 + .../HediffDefs/Hediffs_OrgasmicMytosis.xml | 136 ++++++++ Source/GeneDefOf.cs | 5 +- Source/Genes/Special/Patch_OrgasmMytosis.cs | 318 ++++++++++++++++++ Source/HediffDefOf.cs | 3 + Source/Rjw-Genes.csproj | 1 + 7 files changed, 475 insertions(+), 2 deletions(-) create mode 100644 Common/Defs/HediffDefs/Hediffs_OrgasmicMytosis.xml create mode 100644 Source/Genes/Special/Patch_OrgasmMytosis.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index df95576..f7de594 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ - Fix of icon-names (#36) - Changes to the scenario (more building items, throne for start). Wealth is now at 12k, which is the same as crashlanded and lost tribe. +- Added the Orgasmic Mytosis Draft +- Many touches on the Halamyr Hive Logic and Fertilizitation (#37,#38) **Changes:** @@ -15,6 +17,7 @@ - Custom background icons when Vanilla-Expanded-Framework is loaded - Sexual Age Drainer & Youth Fountain now change age as configured in XML - Draft for a Hive-Start Scenario +- Added Orgasmic Mytosis Gene: On Multiple Orgasms, spawn an identical copy of a pawn. Items and Implants are not copied. **Internal:** diff --git a/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml b/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml index b72778d..24ac84c 100644 --- a/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml +++ b/Common/Defs/GeneDefs/GeneDefs_SexSpecial.xml @@ -67,4 +67,15 @@ 1 + + rjw_genes_sexual_mytosis + + + Carriers of this gene grow more unstable with ongoing multiple orgasms - climaxing in a process of mytosis. This will result in an (biologically) identical pawn and both twins are set in a regenerative state. Also, the pawn can have multiple orgasms: In a state of higher unstableness, they come quicker. + UI/Icons/Genes/Gene_PsychicBonding + 5 + 5 + -7 + + \ No newline at end of file diff --git a/Common/Defs/HediffDefs/Hediffs_OrgasmicMytosis.xml b/Common/Defs/HediffDefs/Hediffs_OrgasmicMytosis.xml new file mode 100644 index 0000000..f26d1a9 --- /dev/null +++ b/Common/Defs/HediffDefs/Hediffs_OrgasmicMytosis.xml @@ -0,0 +1,136 @@ + + + + + rjw_genes_orgasmic_mytosis_hediff + HediffWithComps + + Xenotypes with this Gene grow more unstable on orgasm - upon reaching critical level they will initate a process of mytosis. + (240,200,110) + false + 1.0 + false + false + +
  • + -0.9 +
  • +
    + +
  • + + +
  • + Moving + 0.05 +
  • +
  • + Consciousness + 0.08 +
  • + + +
  • + + 0.4 + +
  • + Moving + 0.15 +
  • +
  • + Consciousness + 0.15 +
  • + + +
  • + + 0.7 + +
  • + Moving + -0.1 +
  • +
  • + Consciousness + -0.1 +
  • +
  • + BloodPumping + +0.2 +
  • + + + +
  • + + 0.9 + +
  • + Moving + -0.25 +
  • +
  • + Consciousness + -0.25 +
  • +
  • + BloodPumping + +0.5 +
  • + + +
    +
    + + + rjw_genes_mytosis_shock_hediff + HediffWithComps + + Recently underwent (successful) mytosis. As this is a taxing process, some time for regeneration is required. While regenerating, no new mytosis can be started. + (240,200,110) + false + 1.0 + true + false + +
  • + -0.20 +
  • +
    + +
  • + + +
  • + Moving + -0.25 +
  • +
  • + Consciousness + -0.25 +
  • + + +
  • + + 0.6 + +
  • + Moving + -0.50 +
  • +
  • + Consciousness + -0.7 +
  • + + +
    +
    + + + +
    + diff --git a/Source/GeneDefOf.cs b/Source/GeneDefOf.cs index a364a16..1bc9770 100644 --- a/Source/GeneDefOf.cs +++ b/Source/GeneDefOf.cs @@ -76,9 +76,10 @@ namespace RJW_Genes public static readonly GeneDef rjw_genes_youth_fountain; public static readonly GeneDef rjw_genes_sex_age_drain; public static readonly GeneDef rjw_genes_aphrodisiac_pheromones; + public static readonly GeneDef rjw_genes_sexual_mytosis; - // LifeForce - public static readonly GeneDef rjw_genes_lifeforce; + // LifeForce + public static readonly GeneDef rjw_genes_lifeforce; public static readonly GeneDef rjw_genes_pussyhealing; public static readonly GeneDef rjw_genes_lifeforce_drain; public static readonly GeneDef rjw_genes_cum_eater; diff --git a/Source/Genes/Special/Patch_OrgasmMytosis.cs b/Source/Genes/Special/Patch_OrgasmMytosis.cs new file mode 100644 index 0000000..ecc2a53 --- /dev/null +++ b/Source/Genes/Special/Patch_OrgasmMytosis.cs @@ -0,0 +1,318 @@ +using HarmonyLib; +using RimWorld; +using RimWorld.QuestGen; +using rjw; +using rjw.Modules.Shared.Extensions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace RJW_Genes +{ + + [HarmonyPatch(typeof(JobDriver_Sex), nameof(JobDriver_Sex.Roll_Orgasm_Duration_Reset))] + public static class Patch_OrgasmMytosis + { + + private const float SEVERITY_INCREASE_PER_ORGASM = 0.10f; + + public static void Postfix(JobDriver_Sex __instance, ref int __result) + { + Pawn orgasmingPawn = __instance.pawn; + if (orgasmingPawn != null && GeneUtility.HasGeneNullCheck(orgasmingPawn, GeneDefOf.rjw_genes_sexual_mytosis) && ! orgasmingPawn.health.hediffSet.HasHediff(HediffDefOf.rjw_genes_mytosis_shock_hediff)) + { + var mytosisHediff = GetOrgasmMytosisHediff(orgasmingPawn); + mytosisHediff.Severity += SEVERITY_INCREASE_PER_ORGASM; + + if (mytosisHediff.Severity >= 1.0) + { + orgasmingPawn.health.RemoveHediff(mytosisHediff); + + var copy = Multiply(orgasmingPawn); + + ApplyMytosisShock(copy); + ApplyMytosisShock(orgasmingPawn); + + orgasmingPawn.Strip(); + + } + else + { + float reduction = Math.Max(1.0f - mytosisHediff.Severity, 0.1f); + __result = (int)(reduction * __result); + } + + } + + } + + private static void ApplyMytosisShock(Pawn copy) + { + var stunA = HediffMaker.MakeHediff(HediffDefOf.rjw_genes_mytosis_shock_hediff, copy); + stunA.Severity = 1; + copy.health.AddHediff(stunA); + } + + /// + /// Helps to get the Orgasm Mytosis Hediff of a Pawn. If it does not exist, one is added. + /// + /// The pawn that had the orgasm, for which a hediff is looked up or created. + /// + public static Hediff GetOrgasmMytosisHediff(Pawn orgasmed) + { + Hediff orgasmicMytosisHediff = orgasmed.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.rjw_genes_orgasmic_mytosis_hediff); + if (orgasmicMytosisHediff == null) + { + orgasmicMytosisHediff = HediffMaker.MakeHediff(HediffDefOf.rjw_genes_orgasmic_mytosis_hediff, orgasmed); + orgasmicMytosisHediff.Severity = 0; + orgasmed.health.AddHediff(orgasmicMytosisHediff); + } + return orgasmicMytosisHediff; + } + + public static Pawn Multiply(Pawn toMultiply) + { + ModLog.Message("Hitting Multiply of Mytosis Pawn!"); + + PawnGenerationRequest request = new PawnGenerationRequest( + kind: toMultiply.kindDef, + faction: toMultiply.Faction, + forceGenerateNewPawn: true, + developmentalStages: DevelopmentalStage.Adult, + allowDowned: true, + canGeneratePawnRelations: false, + colonistRelationChanceFactor: 0, + allowFood: false, + allowAddictions: false, + relationWithExtraPawnChanceFactor: 0, + forbidAnyTitle: true, + forceNoBackstory: true, + fixedGender: toMultiply.gender + ); + + /* + * Devnote: Adding these will lead to deadly issues! + fixedBiologicalAge: toMultiply.ageTracker.AgeBiologicalTicks, + fixedChronologicalAge: toMultiply.ageTracker.AgeChronologicalTicks, + */ + + Pawn copy = PawnGenerator.GeneratePawn(request); + + + copy.gender = toMultiply.gender; + copy.ageTracker = toMultiply.ageTracker; + copy.Name = CreateCloneName(toMultiply,2); + + copy.health = CopyRelevantHediffs(copy, toMultiply); + copy.genes = CopyGeneTracker(copy,toMultiply.genes); + + copy.ideo = toMultiply.ideo; + copy.records = new Pawn_RecordsTracker(copy); + copy.outfits = toMultiply.outfits; + + copy.relations = toMultiply.relations; + copy.skills = CopySkillTracker(copy,toMultiply.skills); + + copy.equipment.DestroyAllEquipment(); + copy.apparel.DestroyAll(); + + //TODO: + // Birthmother doesn't show as relation (See log below) + // It is not blue :( + + + PawnUtility.TrySpawnHatchedOrBornPawn(copy, toMultiply); + // Move the copy in front of the origin, rather than on top + if (toMultiply.Spawned) + if (toMultiply.CurrentBed() != null) + { + copy.Position = copy.Position + new IntVec3(0, 0, 1).RotatedBy(toMultiply.CurrentBed().Rotation); + } + + copy.relations.AddDirectRelation(PawnRelationDefOf.ParentBirth, toMultiply); + + + copy.style = CopyStyleTracker(copy, toMultiply.style); + copy.story = CopyStoryTracker(copy, toMultiply.story); + + copy.Draw(); + return copy; + } + + private static Name CreateCloneName(Pawn toCopyFrom, int additions=1) + { + if (toCopyFrom.Name is NameTriple) + { + NameTriple casted = (NameTriple)toCopyFrom.Name; + String Postfix = " " + RandomNamePostFix(additions); + Name newName = new NameTriple(first:casted.First + Postfix, nick: casted.Nick + Postfix, last: casted.Last); + if (newName.UsedThisGame) + return CreateCloneName(toCopyFrom, additions); + return newName; + } + return toCopyFrom.Name; + } + + private static Pawn_GeneTracker CopyGeneTracker(Pawn toCopyTo, Pawn_GeneTracker toCopyFrom) + { + var tracker = new Pawn_GeneTracker(toCopyTo); + + // Due to Overwrite logics, we first add Endogenes and then a second pass on xenogenes + + // Pass 1: Endogenes + foreach (Gene gene in toCopyFrom.GenesListForReading) { + GeneDef def = gene.def; + if (!toCopyFrom.Xenogenes.Contains(gene)) + tracker.AddGene(def, false); + } + + // Pass 2: Xenogenes + foreach (Gene gene in toCopyFrom.GenesListForReading) + { + GeneDef def = gene.def; + if (toCopyFrom.Xenogenes.Contains(gene)) + tracker.AddGene(def, true); + } + + tracker.Reset(); + var skin = tracker.GetMelaninGene(); + var hair = tracker.GetHairColorGene(); + + ModLog.Message($"{toCopyTo} had Skin {skin.defName} and {hair.defName} as colour-genes"); + + + return tracker; + } + + private static Pawn_StoryTracker CopyStoryTracker(Pawn toCopyTo, Pawn_StoryTracker toCopyFrom) + { + var tracker = new Pawn_StoryTracker(toCopyTo); + + tracker.Childhood = toCopyFrom.Childhood; + tracker.Adulthood = toCopyFrom.Adulthood; + + tracker.headType = toCopyFrom.headType; + tracker.bodyType = toCopyFrom.bodyType; + tracker.hairDef = toCopyFrom.hairDef; + tracker.furDef = toCopyFrom.furDef; + + tracker.traits = toCopyFrom.traits; + + tracker.skinColorOverride = toCopyFrom.skinColorOverride; + tracker.HairColor = toCopyFrom.HairColor; + + + return tracker; + } + + private static Pawn_SkillTracker CopySkillTracker(Pawn toCopyTo, Pawn_SkillTracker toCopyFrom) + { + var tracker = new Pawn_SkillTracker(toCopyTo); + + tracker.skills = toCopyFrom.skills; + + return tracker; + } + + private static Pawn_HealthTracker CopyRelevantHediffs(Pawn toCopyTo, Pawn copiedFrom) + { + var toCopyFrom = copiedFrom.health; + var tracker = toCopyTo.health; + // Step 0: Remove everything, Reset + tracker.RemoveAllHediffs(); + tracker.Reset(); + // Step 1: Copy ALL Hediffs + foreach (Hediff hed in toCopyFrom.hediffSet.hediffs) + { + // DevNote: There were a lot of issues around bodyparts: + // Some Hediffs really need to know their bodypart, e.g. an implanted arm can either be left or right. + // Ignoring this will lead to many errors, mostly around nullpointers. + + BodyPartRecord originalBPR = hed.Part; + if (originalBPR != null) { + BodyPartRecord copyBPR = toCopyTo.RaceProps?.body.AllParts.Find(bpr => bpr.def == originalBPR.def); + if (copyBPR != null && !copyBPR.IsMissingForPawn(toCopyTo)) { + Hediff copiedHediff = HediffMaker.MakeHediff(hed.def, toCopyTo, copyBPR); + tracker.AddHediff(copiedHediff); + } + } else + { + Hediff copiedHediff = HediffMaker.MakeHediff(hed.def, toCopyTo); + tracker.AddHediff(copiedHediff); + } + } + // Step 2: Remove all Artifical Parts + List hediffsToRemove = new List(); + foreach (Hediff hed in tracker.hediffSet.hediffs) + { + if (hed is Hediff_AddedPart && ((Hediff_AddedPart)hed).def.countsAsAddedPartOrImplant) + { + hediffsToRemove.Add(hed); + } + } + tracker.hediffSet.hediffs.RemoveAll(x => hediffsToRemove.Contains(x)); + + // Step 3: Tend issues from Removal + foreach (Hediff copiedHediff in tracker.hediffSet.hediffs) + { + if (copiedHediff.Bleeding) + copiedHediff.Tended(1.0f,1.0f); + } + + return tracker; + } + + private static Pawn_StyleTracker CopyStyleTracker(Pawn toCopyTo, Pawn_StyleTracker toCopyFrom) + { + var tracker = new Pawn_StyleTracker(toCopyTo); + + tracker.beardDef = toCopyFrom.beardDef; + tracker.BodyTattoo = toCopyFrom.BodyTattoo; + tracker.FaceTattoo = toCopyFrom.FaceTattoo; + + return tracker; + } + + private static String RandomNamePostFix(int numberOfParts) + { + List additions = new List() + { + "A","B","C","D","E","F","X","Y","Z", + "Two", + "Alpha","Beta","Gamma","Delta","Epsilon","Zeta","Eta","Theta","Iota","Kappa","Lambda","Mu","Nu","Xi","Omicron","Pi","Rho","Sigma","Tau","Upsilon","Phi","Chi","Psi","Omega" + }; + + additions.Shuffle(); + return String.Join(" ",additions.Take(numberOfParts)); + } + } + + +} + +/* +* +*Warning: +*Tried to add pawn relation ParentBirth with self, pawn=Henri +UnityEngine.StackTraceUtility:ExtractStackTrace () +Verse.Log:Warning (string) +RimWorld.Pawn_RelationsTracker:AddDirectRelation (RimWorld.PawnRelationDef,Verse.Pawn) +RJW_Genes.Patch_OrgasmMytosis:Multiply (Verse.Pawn) +RJW_Genes.Patch_OrgasmMytosis:Postfix (rjw.JobDriver_Sex,int&) +(wrapper dynamic-method) rjw.JobDriver_Sex:rjw.JobDriver_Sex.Roll_Orgasm_Duration_Reset_Patch1 (rjw.JobDriver_Sex) +(wrapper dynamic-method) rjw.JobDriver_Sex:rjw.JobDriver_Sex.Orgasm_Patch2 (rjw.JobDriver_Sex) +(wrapper dynamic-method) rjw.JobDriver_Sex:rjw.JobDriver_Sex.SexTick_Patch1 (rjw.JobDriver_Sex,Verse.Pawn,Verse.Thing,bool,bool) +rjw.JobDriver_Rape/<>c__DisplayClass1_0:b__6 () +(wrapper dynamic-method) Verse.AI.JobDriver:Verse.AI.JobDriver.DriverTick_Patch0 (Verse.AI.JobDriver) +Verse.AI.Pawn_JobTracker:JobTrackerTick () +Verse.Pawn:Tick () +Verse.TickList:Tick () +(wrapper dynamic-method) Verse.TickManager:Verse.TickManager.DoSingleTick_Patch2 (Verse.TickManager) +Verse.TickManager:TickManagerUpdate () +Verse.Game:UpdatePlay () +Verse.Root_Play:Update () + + */ \ No newline at end of file diff --git a/Source/HediffDefOf.cs b/Source/HediffDefOf.cs index 4d59a41..4e3b052 100644 --- a/Source/HediffDefOf.cs +++ b/Source/HediffDefOf.cs @@ -16,5 +16,8 @@ namespace RJW_Genes public static readonly HediffDef rjw_genes_succubus_drained; public static readonly HediffDef rjw_genes_orgasm_rush_hediff; public static readonly HediffDef rjw_genes_fertilin_craving; + + public static readonly HediffDef rjw_genes_orgasmic_mytosis_hediff; + public static readonly HediffDef rjw_genes_mytosis_shock_hediff; } } diff --git a/Source/Rjw-Genes.csproj b/Source/Rjw-Genes.csproj index bbbe0c9..a8bfaa3 100644 --- a/Source/Rjw-Genes.csproj +++ b/Source/Rjw-Genes.csproj @@ -141,6 +141,7 @@ +