diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5b63394..b087e0e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -81,6 +81,7 @@ but they are meant mostly to have infectors immune against their own diseases.
- Gene: Sexual Genetic Swap. Pawns have a chance to switch a random gene with their sexpartner.
- (Archite) Gene: Sexual Genetic Thief. Pawns have a chance to steal a gene from their sexpartner. Genetic Disease Immunity shields against this.
- Pawns will have negative thoughts about pawns with more genetic diseases than themselves.
+- Faction Penalties for spreading diseases, stealing genes and aging pawns with age transfer
**Fixes:**
diff --git a/Common/Defs/GeneDefs/GeneDefs_Breeding.xml b/Common/Defs/GeneDefs/GeneDefs_Breeding.xml
index b3a9844..832621a 100644
--- a/Common/Defs/GeneDefs/GeneDefs_Breeding.xml
+++ b/Common/Defs/GeneDefs/GeneDefs_Breeding.xml
@@ -152,4 +152,16 @@
1
0
+
+
+ rjw_genes_pregnancy_overwrite
+
+ Carriers of this gene can 'overwrite' an existing pregnancy, keeping the progress but effectively replacing the father.
+ Genes/Icons/RJW_Genes_PheromoneSpit
+ 75
+
+ 4
+ -2
+
+
\ No newline at end of file
diff --git a/Common/Defs/HistoryEventDefs/DiseaseHistoryEventDefs.xml b/Common/Defs/HistoryEventDefs/DiseaseHistoryEventDefs.xml
new file mode 100644
index 0000000..488fa5f
--- /dev/null
+++ b/Common/Defs/HistoryEventDefs/DiseaseHistoryEventDefs.xml
@@ -0,0 +1,18 @@
+
+
+
+ rjw_genes_GoodwillChangedReason_StoleGene
+
+
+
+
+ rjw_genes_GoodwillChangedReason_infected_with_disease
+
+
+
+
+ rjw_genes_GoodwillChangedReason_spread_genetic_disease
+
+
+
+
\ No newline at end of file
diff --git a/Common/Defs/HistoryEventDefs/SpecialHistoryEventDefs.xml b/Common/Defs/HistoryEventDefs/SpecialHistoryEventDefs.xml
new file mode 100644
index 0000000..c5668ad
--- /dev/null
+++ b/Common/Defs/HistoryEventDefs/SpecialHistoryEventDefs.xml
@@ -0,0 +1,13 @@
+
+
+
+ rjw_genes_GoodwillChangedReason_aged_pawn_with_sex_gene
+
+
+
+
+ rjw_genes_GoodwillChangedReason_youthed_pawn_with_sex_gene
+
+
+
+
\ No newline at end of file
diff --git a/Source/Common/Helpers/FactionUtility.cs b/Source/Common/Helpers/FactionUtility.cs
new file mode 100644
index 0000000..10a4e7c
--- /dev/null
+++ b/Source/Common/Helpers/FactionUtility.cs
@@ -0,0 +1,42 @@
+using RimWorld;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Verse;
+
+namespace RJW_Genes
+{
+ public class FactionUtility
+ {
+
+ ///
+ /// Tries to change the goodwill between the factions of two pawns.
+ /// Exceptions when nothing happens:
+ /// - Pawns, or Pawns Factions, are null
+ /// - The `actors` Faction is not the players faction
+ /// - Both pawns have the same faction
+ /// - The Event is not found
+ ///
+ /// The pawn that initiated a faction-goodwill change by his actions
+ /// The pawn that was harmed/affected by the action
+ /// The event defname, for proper reporting
+ /// How much (positive or negative) the goodwill will change
+ public static void HandleFactionGoodWillPenalties(Pawn actor, Pawn target, string HistoryEventDefname, int goodWillChange, bool canSendHostileLetter=true)
+ {
+ if (actor == null) return;
+ if (target == null) return;
+ if (
+ target.Faction != null && actor.Faction != null
+ && target.Faction != actor.Faction
+ && target.Faction != Faction.OfPlayer)
+ {
+ HistoryEventDef reason = DefDatabase.GetNamedSilentFail(HistoryEventDefname);
+ if (reason == null) return;
+
+ target.Faction.TryAffectGoodwillWith(actor.Faction, goodWillChange, true, canSendHostileLetter, reason, target);
+ }
+ }
+ }
+}
diff --git a/Source/GeneDefOf.cs b/Source/GeneDefOf.cs
index 873df6f..f4a2d08 100644
--- a/Source/GeneDefOf.cs
+++ b/Source/GeneDefOf.cs
@@ -107,6 +107,7 @@ namespace RJW_Genes
public static readonly GeneDef rjw_genes_sex_tamer;
public static readonly GeneDef rjw_genes_sexual_genetic_swap;
public static readonly GeneDef rjw_genes_sexual_genetic_thief;
+ public static readonly GeneDef rjw_genes_pregnancy_overwrite;
// Cosmetic
public static readonly GeneDef rjw_genes_succubus_tail;
diff --git a/Source/Genes/Diseases/Patches/Patch_AfterSexUtility_ApplyGeneticInfectors.cs b/Source/Genes/Diseases/Patches/Patch_AfterSexUtility_ApplyGeneticInfectors.cs
index 1ee1e9f..06b0998 100644
--- a/Source/Genes/Diseases/Patches/Patch_AfterSexUtility_ApplyGeneticInfectors.cs
+++ b/Source/Genes/Diseases/Patches/Patch_AfterSexUtility_ApplyGeneticInfectors.cs
@@ -1,4 +1,5 @@
using HarmonyLib;
+using RimWorld;
using rjw;
using System;
using System.Collections.Generic;
@@ -14,6 +15,9 @@ namespace RJW_Genes
[HarmonyPatch(typeof(SexUtility), "Aftersex")]
public class Patch_AfterSexUtility_ApplyGeneticInfectors
{
+
+ const int FACTION_GOODWILL_CHANGE = -3;
+
public static void Postfix(SexProps props)
{
if (props == null || props.pawn == null || props.partner == null) return;
@@ -48,7 +52,10 @@ namespace RJW_Genes
continue;
if ((new Random()).NextDouble() < application_chance)
+ {
partner.genes.AddGene(diseaseGeneDef, !RJW_Genes_Settings.rjw_genes_genetic_disease_as_endogenes);
+ FactionUtility.HandleFactionGoodWillPenalties(infector, partner, "rjw_genes_GoodwillChangedReason_infected_with_disease",FACTION_GOODWILL_CHANGE);
+ }
}
}
}
diff --git a/Source/Genes/Diseases/Patches/Patch_AftersexUtility_TransferGeneticDiseases.cs b/Source/Genes/Diseases/Patches/Patch_AftersexUtility_TransferGeneticDiseases.cs
index e33079f..a00d40f 100644
--- a/Source/Genes/Diseases/Patches/Patch_AftersexUtility_TransferGeneticDiseases.cs
+++ b/Source/Genes/Diseases/Patches/Patch_AftersexUtility_TransferGeneticDiseases.cs
@@ -1,4 +1,5 @@
using HarmonyLib;
+using RimWorld;
using rjw;
using System;
using System.Collections.Generic;
@@ -13,6 +14,8 @@ namespace RJW_Genes
public class Patch_AftersexUtility_TransferGeneticDiseases
{
+ public const int FACTION_GOODWILL_CHANGE = -2;
+
public static void Postfix(SexProps props)
{
if (!RJW_Genes_Settings.rjw_genes_genetic_disease_spread) return;
@@ -48,6 +51,7 @@ namespace RJW_Genes
if ((new Random()).NextDouble() <= DiseaseHelper.LookupDiseaseInfectionChance(disease))
{
infected.genes.AddGene(disease, !RJW_Genes_Settings.rjw_genes_genetic_disease_as_endogenes);
+ FactionUtility.HandleFactionGoodWillPenalties(infector, infected, "rjw_genes_GoodwillChangedReason_spread_genetic_disease", FACTION_GOODWILL_CHANGE);
}
}
}
diff --git a/Source/Genes/Special/Patches/Patch_AgeDrain.cs b/Source/Genes/Special/Patches/Patch_AgeDrain.cs
index ab159b1..059baef 100644
--- a/Source/Genes/Special/Patches/Patch_AgeDrain.cs
+++ b/Source/Genes/Special/Patches/Patch_AgeDrain.cs
@@ -1,4 +1,5 @@
using HarmonyLib;
+using RimWorld;
using rjw;
using System;
using System.Collections.Generic;
@@ -24,6 +25,8 @@ namespace RJW_Genes.Genes.Special
// 18 Years * 60 Days / Year * 60k Ticks/Day + 1 for safety
const long MINIMUM_AGE_FALLBACK = 18 * 60 * 60000 + 1;
+ const int FACTION_GOODWILL_CHANGE = -1;
+
public static void Postfix(SexProps props)
{
if (props == null || props.pawn == null || props.partner == null || props.partner.IsAnimal() )
@@ -80,6 +83,9 @@ namespace RJW_Genes.Genes.Special
if (RJW_Genes_Settings.rjw_genes_detailed_debug)
ModLog.Message($"[Sexual Age Drainer] {receiver} was too young ({receiver.ageTracker.AgeBiologicalYears}), and remains unchanged.");
}
+
+ FactionUtility.HandleFactionGoodWillPenalties(receiver, giver, "rjw_genes_GoodwillChangedReason_aged_pawn_with_sex_gene",FACTION_GOODWILL_CHANGE);
}
+
}
}
diff --git a/Source/Genes/Special/Patches/Patch_GeneticSexThief.cs b/Source/Genes/Special/Patches/Patch_GeneticSexThief.cs
index ecc2201..d61f0bd 100644
--- a/Source/Genes/Special/Patches/Patch_GeneticSexThief.cs
+++ b/Source/Genes/Special/Patches/Patch_GeneticSexThief.cs
@@ -1,4 +1,6 @@
using HarmonyLib;
+using RimWorld;
+using RimWorld.Planet;
using rjw;
using System;
using System.Collections.Generic;
@@ -13,6 +15,9 @@ namespace RJW_Genes
[HarmonyPatch(typeof(SexUtility), "Aftersex")]
public class Patch_GeneticSexThief
{
+
+ public const int FACTION_GOODWILL_CHANGE = -10;
+
public static void Postfix(SexProps props)
{
if (props == null || props.pawn == null || props.partner == null || props.partner.IsAnimal())
@@ -62,6 +67,8 @@ namespace RJW_Genes
stealer.genes.AddGene(stolenGene.def, AddAsXenogene);
victim.genes.RemoveGene(stolenGene);
+
+ FactionUtility.HandleFactionGoodWillPenalties(stealer, victim, "rjw_genes_GoodwillChangedReason_StoleGene", FACTION_GOODWILL_CHANGE);
}
}
diff --git a/Source/Genes/Special/Patches/Patch_PregnancyOverwrite.cs b/Source/Genes/Special/Patches/Patch_PregnancyOverwrite.cs
new file mode 100644
index 0000000..b7b35a6
--- /dev/null
+++ b/Source/Genes/Special/Patches/Patch_PregnancyOverwrite.cs
@@ -0,0 +1,80 @@
+using HarmonyLib;
+using RimWorld;
+using rjw;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Verse;
+using static HarmonyLib.Code;
+
+namespace RJW_Genes
+{
+ [HarmonyPatch(typeof(SexUtility), "Aftersex")]
+ public class Patch_PregnancyOverwrite
+ {
+ public const int FACTION_GOODWILL_CHANGE = -5;
+
+ public static void Postfix(SexProps props)
+ {
+ if (props == null || props.pawn == null || props.partner == null || props.partner.IsAnimal())
+ {
+ return;
+ }
+
+ Pawn pawn = props.pawn;
+ Pawn partner = props.partner;
+
+ if (pawn.genes == null || partner.genes == null) return;
+
+ // If both have the swap gene, nothing happens
+ if (GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_pregnancy_overwrite)
+ && GeneUtility.HasGeneNullCheck(partner, GeneDefOf.rjw_genes_pregnancy_overwrite))
+ return;
+
+ // If both are pregnant, we have some weird interaction. Exit Early
+ if (pawn.IsPregnant() && partner.IsPregnant())
+ return;
+ // If neither are pregnant, nothing can happen.
+ if (!pawn.IsPregnant() && !partner.IsPregnant())
+ return;
+
+ ModLog.Debug("Firing Pregnancy Overwrite Patch - Passed Simple NullChecks");
+
+ if (pawn.IsPregnant()
+ && GeneUtility.HasGeneNullCheck(partner, GeneDefOf.rjw_genes_pregnancy_overwrite))
+ TryReplacePregnancy(partner, pawn);
+
+ if (partner.IsPregnant()
+ && GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_pregnancy_overwrite))
+ TryReplacePregnancy(pawn, partner);
+ }
+
+ public static void TryReplacePregnancy(Pawn replacer, Pawn pregnant)
+ {
+ // TODO: This mostly works, but needs some more checks.
+ // - Check if there is a pregnancy occurring
+ // - Check for Disease Immunity
+ // - Add Faction Penalties
+
+ ModLog.Debug($"Firing Pregnancy Overwrite for {replacer} and {pregnant}");
+
+ // The "CanImpregnate" does not work as I want, as the pawn is already pregnant, so it wont allow to be pregnated.
+ //PregnancyHelper.CanImpregnate(pawn, partner, props.sexType)
+
+ Hediff pregnancyHediff = PregnancyUtility.GetPregnancyHediff(pregnant);
+ if (pregnancyHediff == null)
+ return;
+
+ float gestationProgress = pregnancyHediff.Severity;
+
+ PregnancyUtility.ForceEndPregnancy(pregnant);
+
+ PregnancyHelper.StartVanillaPregnancy(pregnant, replacer);
+ Hediff replacementPregnancyHediff = PregnancyUtility.GetPregnancyHediff(pregnant);
+ replacementPregnancyHediff.Severity = gestationProgress;
+ }
+
+ }
+}
diff --git a/Source/Genes/Special/Patches/Patch_Youth_Fountain.cs b/Source/Genes/Special/Patches/Patch_Youth_Fountain.cs
index d810bc6..96ba204 100644
--- a/Source/Genes/Special/Patches/Patch_Youth_Fountain.cs
+++ b/Source/Genes/Special/Patches/Patch_Youth_Fountain.cs
@@ -1,4 +1,5 @@
using HarmonyLib;
+using RimWorld;
using rjw;
using System;
using System.Collections.Generic;
@@ -23,6 +24,8 @@ namespace RJW_Genes.Genes.Special
// 18 Years * 60 Days / Year * 60k Ticks/Day + 1 for safety
const long MINIMUM_AGE_FALLBACK = 18 * 60 * 60000 + 1;
+ const int FACTION_GOODWILL_CHANGE = 1;
+
public static void Postfix(SexProps props)
{
if (props == null || props.pawn == null || props.partner == null || props.partner.IsAnimal())
@@ -39,10 +42,12 @@ namespace RJW_Genes.Genes.Special
if (GeneUtility.IsYouthFountain(props.pawn))
{
ChangeAgeForPawn(props.partner, props.pawn);
+ FactionUtility.HandleFactionGoodWillPenalties(props.pawn, props.partner, "rjw_genes_GoodwillChangedReason_youthed_pawn_with_sex_gene",+1);
}
if (GeneUtility.IsYouthFountain(props.partner))
{
ChangeAgeForPawn(props.pawn,props.partner);
+ FactionUtility.HandleFactionGoodWillPenalties(props.pawn, props.partner, "rjw_genes_GoodwillChangedReason_youthed_pawn_with_sex_gene", +1);
}
}
@@ -65,6 +70,7 @@ namespace RJW_Genes.Genes.Special
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 306bcb7..8354632 100644
--- a/Source/Rjw-Genes.csproj
+++ b/Source/Rjw-Genes.csproj
@@ -61,6 +61,7 @@
+
@@ -193,6 +194,7 @@
+