2023-01-15 16:48:11 +00:00
using System.Collections.Generic ;
2022-12-01 14:29:26 +00:00
using Verse ;
using RimWorld ;
2023-01-06 10:43:18 +00:00
using rjw ;
2022-12-01 14:29:26 +00:00
namespace RJW_BGS
{
public class InheritanceUtility
{
public static List < GeneDef > AnimalInheritedGenes ( Pawn father , Pawn mother )
{
List < GeneDef > genelist = new List < GeneDef > ( ) ;
2022-12-18 09:25:57 +00:00
//If Both are Humans, or Both are animals, do nothing & return empty GeneList
if ( ! mother . RaceProps . Humanlike & & ! father . RaceProps . Humanlike )
return genelist ;
if ( mother . RaceProps . Humanlike & & father . RaceProps . Humanlike )
return genelist ;
2023-01-15 16:48:11 +00:00
ModLog . Message ( $"Trigger an Animal-Gene-Inheritance for {father.Name} and {mother.Name}" ) ;
2022-12-18 09:25:57 +00:00
//One parent must be an animal and the other must be human, so only one needs to return
2022-12-01 14:29:26 +00:00
if ( father ! = null & & ! father . RaceProps . Humanlike )
{
2023-01-15 16:48:11 +00:00
if ( RJW_BGSSettings . rjw_bgs_detailed_debug )
ModLog . Message ( $"Father was found to be animal - looking up genes for {father.Name}" ) ;
2022-12-01 14:29:26 +00:00
return SelectGenes ( father ) ;
}
if ( mother ! = null & & ! mother . RaceProps . Humanlike )
{
2023-01-15 16:48:11 +00:00
if ( RJW_BGSSettings . rjw_bgs_detailed_debug )
ModLog . Message ( $"Mother was found to be animal - looking up genes for {mother.Name}" ) ;
2022-12-01 14:29:26 +00:00
return SelectGenes ( mother ) ;
}
2022-12-18 09:25:57 +00:00
2022-12-01 14:29:26 +00:00
return genelist ;
}
2022-12-18 09:25:57 +00:00
/// <summary>
/// Looks up potential genes for an animal,
/// checks their chance and returns all 'triggered' genes.
/// </summary>
/// <param name="pawn">The animal for which to look up genes (Animals are Pawns in RW)</param>
/// <returns>The genes that will be inherited from this animal.</returns>
2022-12-01 14:29:26 +00:00
public static List < GeneDef > SelectGenes ( Pawn pawn )
{
List < GeneDef > genelist = new List < GeneDef > ( ) ;
2022-12-22 18:04:56 +00:00
RaceGeneDef raceGeneDef = RaceGeneDef_Helper . GetRaceGeneDefInternal ( pawn ) ;
2022-12-01 14:29:26 +00:00
if ( raceGeneDef ! = null )
{
2022-12-18 09:25:57 +00:00
foreach ( BestialityGeneInheritanceDef gene in raceGeneDef . genes )
2022-12-01 14:29:26 +00:00
{
2023-01-15 16:48:11 +00:00
if ( gene . chance * RJW_BGSSettings . rjw_bgs_global_gene_chance > = Rand . Range ( 0.01f , 1f ) )
2022-12-01 14:29:26 +00:00
{
2022-12-17 19:52:10 +00:00
genelist . Add ( DefDatabase < GeneDef > . GetNamed ( gene . defName ) ) ;
2022-12-01 14:29:26 +00:00
}
}
}
2023-01-15 16:48:11 +00:00
if ( RJW_BGSSettings . rjw_bgs_detailed_debug )
ModLog . Message ( $"From {raceGeneDef.genes.Count} possible genes in {raceGeneDef.defName}, {genelist.Count} were added by chance ({RJW_BGSSettings.rjw_bgs_global_gene_chance} chance multiplier from Settings)." ) ;
2022-12-01 14:29:26 +00:00
return genelist ;
}
2023-01-15 16:48:11 +00:00
/// <summary>
/// Adds a list of Genes to the pawns existing GeneSet.
/// Whether it is added as a Xenogene or Endogene is configured in Mod-Settings.
/// </summary>
/// <param name="pawn">The pawn for which Genes will be added</param>
/// <param name="genes">The Genes to add (Endogene by default, Xenogene with Mod Settings)</param>
2022-12-01 14:29:26 +00:00
public static void AddGenes ( Pawn pawn , List < GeneDef > genes )
{
foreach ( GeneDef gene in genes )
{
2023-01-15 16:48:11 +00:00
pawn . genes . AddGene ( gene , RJW_BGSSettings . rjw_bgs_animal_genes_as_xenogenes ) ;
2022-12-01 14:29:26 +00:00
}
}
2023-01-15 16:48:11 +00:00
/// <summary>
/// Initiates a bestiality baby with genes if the baby does not exist earlier.
/// This is used to make rjw-egg-pregnancies work.
/// Related file: PatchRJWHediffInsect_Egg.cs
/// </summary>
/// <param name="mother">The mother of the baby.</param>
/// <param name="dad">The father of the baby.</param>
/// <param name="baby">The baby created in non-pregnancy-way (has 0 Genes yet)</param>
2022-12-01 14:29:26 +00:00
public static void NewGenes ( Pawn mother , Pawn dad , Pawn baby )
{
2023-01-15 16:48:11 +00:00
if ( ! RJW_BGSSettings . rjw_bgs_enabled )
2022-12-25 11:38:05 +00:00
{
return ;
}
2023-01-15 16:48:11 +00:00
ModLog . Message ( $"Triggering an New-Gene Animal-Gene-Inheritance for {baby.Name} ({dad.Name} + {mother.Name})" ) ;
2022-12-01 14:29:26 +00:00
if ( baby . RaceProps . Humanlike )
{
if ( baby . genes = = null )
{
baby . genes = new Pawn_GeneTracker ( baby ) ;
}
//Remove the hair and skin genes pawns always start with, should get correct ones from human parent anyway.
for ( int i = baby . genes . Endogenes . Count - 1 ; i > = 0 ; i - - )
{
baby . genes . RemoveGene ( baby . genes . Endogenes [ i ] ) ;
}
List < GeneDef > genes = PregnancyUtility . GetInheritedGenes ( dad , mother ) ;
List < GeneDef > beastgenes = InheritanceUtility . AnimalInheritedGenes ( dad , mother ) ;
InheritanceUtility . AddGenes ( baby , beastgenes ) ;
InheritanceUtility . AddGenes ( baby , genes ) ;
if ( baby . genes . GetFirstEndogeneByCategory ( EndogeneCategory . Melanin ) = = null )
{
AddSkinColor ( mother , dad , baby ) ;
}
}
}
public static void AddSkinColor ( Pawn mother , Pawn father , Pawn baby )
{
if ( mother ! = null & & mother . genes ! = null )
{
GeneDef gene = mother . genes . GetFirstEndogeneByCategory ( EndogeneCategory . Melanin ) ;
if ( gene ! = null )
{
baby . genes . AddGene ( gene , false ) ;
}
}
else if ( father ! = null & & father . genes ! = null )
{
GeneDef gene = father . genes . GetFirstEndogeneByCategory ( EndogeneCategory . Melanin ) ;
if ( gene ! = null )
{
baby . genes . AddGene ( gene , false ) ;
}
}
else
{
Log . Message ( "Could not find skincolor of " + baby . Name + "'s parents, giving random skincolor." ) ;
baby . genes . AddGene ( PawnSkinColors . RandomSkinColorGene ( baby ) , false ) ;
}
}
2023-01-06 10:43:18 +00:00
/// <summary>
/// Used only for debugging, to see what you loaded and how it looks.
/// </summary>
private static void logAllFoundRaceGroupGenes ( )
{
foreach ( RaceGroupDef def in DefDatabase < RaceGroupDef > . AllDefs )
{
Log . Message ( "defName = " + def . defName ) ;
if ( def . raceNames ! = null )
{
foreach ( string race in def . raceNames )
{
Log . Message ( race ) ;
}
}
}
}
2022-12-01 14:29:26 +00:00
}
}