27
									
								
								CHANGELOG.md
									
										
									
									
									
								
							
							
						
						| 
						 | 
					@ -1,3 +1,30 @@
 | 
				
			||||||
 | 
					# 1.3.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Changes:**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- New Gene for Evergrowing Cocks. Be careful. 
 | 
				
			||||||
 | 
					- New Gene for Genderfluid Pawns - daily chance to change sex. Futas just change "display" and keep genitalia, other pawns switch genitalia. XML configurable times & chances. 
 | 
				
			||||||
 | 
					- New Drawings for the Succubi Wings & Tail, thanks to @Monti (donated via Discord)
 | 
				
			||||||
 | 
					- Simple Gene that removes Sex need (called asexual, `rjw_genes_no_sex_need`)
 | 
				
			||||||
 | 
					- New Gene that grows Penisses on Oral sex. Configurable in XML. 
 | 
				
			||||||
 | 
					- New Gene Lifeforce Empath: Gain Lifeforce for sexually satisfied pawns, loose for frustrated pawns.
 | 
				
			||||||
 | 
					- More genes are configurable with XML, e.g. tick speed, distances or multipliers. I am getting the hang of it. 
 | 
				
			||||||
 | 
					- Halfed Succubus Fertilin-Need, increased cost of abilities.
 | 
				
			||||||
 | 
					- Translation Keys for some letters
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Fixes:**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- New attempt at fixing condom consumption for Fertilin, adressing #41 & #48 provided by Infi
 | 
				
			||||||
 | 
					- Copy of Infis patch for eating cum from sexperience, #41 and #48
 | 
				
			||||||
 | 
					- Updated some Icons to have better backgrounds (thanks @WasmachenDennSachenSo #53)
 | 
				
			||||||
 | 
					- Custom Queen- and Drone-Xenotypes should work now. 
 | 
				
			||||||
 | 
					- Some more checks if Queen is on Map or not (fixing #60)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*Notes*: 
 | 
				
			||||||
 | 
					The pawns that are gender fluid can get pregnant. 
 | 
				
			||||||
 | 
					However, with RJW 5.3.7 these pregnancies disappear. 
 | 
				
			||||||
 | 
					This is a change needed upstream, but I will have a look. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 1.2.1 
 | 
					# 1.2.1 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**Fixes**: 
 | 
					**Fixes**: 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,7 +38,7 @@
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
	  <li Class="RJW_Genes.CompProperties_CasterIsNaked"/>
 | 
						  <li Class="RJW_Genes.CompProperties_CasterIsNaked"/>
 | 
				
			||||||
	  <li Class="RJW_Genes.CompProperties_AbilityLifeForceCost">
 | 
						  <li Class="RJW_Genes.CompProperties_AbilityLifeForceCost">
 | 
				
			||||||
        <fertilinCost>0.1</fertilinCost>
 | 
					        <fertilinCost>0.15</fertilinCost>
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
    </comps>
 | 
					    </comps>
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,7 +37,7 @@
 | 
				
			||||||
        <fleckDef>rjw_genes_lips</fleckDef> <!--Will change to kiss when I have a good icon/fleck for it-->
 | 
					        <fleckDef>rjw_genes_lips</fleckDef> <!--Will change to kiss when I have a good icon/fleck for it-->
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
	  <li Class="RJW_Genes.CompProperties_AbilityLifeForceCost">
 | 
						  <li Class="RJW_Genes.CompProperties_AbilityLifeForceCost">
 | 
				
			||||||
        <fertilinCost>0.05</fertilinCost>
 | 
					        <fertilinCost>0.1</fertilinCost>
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
    </comps> 
 | 
					    </comps> 
 | 
				
			||||||
  </AbilityDef>
 | 
					  </AbilityDef>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,7 @@
 | 
				
			||||||
    </verbProperties>
 | 
					    </verbProperties>
 | 
				
			||||||
    <comps>
 | 
					    <comps>
 | 
				
			||||||
	  <li Class="RJW_Genes.CompProperties_AbilityLifeForceCost">
 | 
						  <li Class="RJW_Genes.CompProperties_AbilityLifeForceCost">
 | 
				
			||||||
        <fertilinCost>0.2</fertilinCost>
 | 
					        <fertilinCost>0.3</fertilinCost>
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
      <li Class="RJW_Genes.CompProperties_AbilityPussyHeal"> 
 | 
					      <li Class="RJW_Genes.CompProperties_AbilityPussyHeal"> 
 | 
				
			||||||
        <tendQualityRange>0.4~0.8</tendQualityRange> 
 | 
					        <tendQualityRange>0.4~0.8</tendQualityRange> 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,7 +36,7 @@
 | 
				
			||||||
        <fleckDef>Heart</fleckDef>
 | 
					        <fleckDef>Heart</fleckDef>
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
	  <li Class="RJW_Genes.CompProperties_AbilityLifeForceCost">
 | 
						  <li Class="RJW_Genes.CompProperties_AbilityLifeForceCost">
 | 
				
			||||||
        <fertilinCost>0.1</fertilinCost>
 | 
					        <fertilinCost>0.20</fertilinCost>
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
    </comps>
 | 
					    </comps>
 | 
				
			||||||
  </AbilityDef>
 | 
					  </AbilityDef>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,9 +27,9 @@
 | 
				
			||||||
    <biostatCpx>1</biostatCpx>
 | 
					    <biostatCpx>1</biostatCpx>
 | 
				
			||||||
	<biostatMet>-1</biostatMet>
 | 
						<biostatMet>-1</biostatMet>
 | 
				
			||||||
    <graphicData>
 | 
					    <graphicData>
 | 
				
			||||||
      <graphicPath>Things/Pawn/Humanlike/BodyAttachments/rjw_genes_Succubus_Wings/Succubus_Wings</graphicPath>
 | 
					      <graphicPath>Things/Pawn/Humanlike/BodyAttachments/RJW_Genes_Succubus_Wings/RJW_Genes_Succubus_Wings</graphicPath>
 | 
				
			||||||
      <colorType>Skin</colorType>
 | 
					      <colorType>Skin</colorType>
 | 
				
			||||||
	  <drawScale>2</drawScale>
 | 
						    <drawScale>2</drawScale>
 | 
				
			||||||
      <drawOffsetNorth>(0.0, 0.01, -0.1)</drawOffsetNorth>
 | 
					      <drawOffsetNorth>(0.0, 0.01, -0.1)</drawOffsetNorth>
 | 
				
			||||||
      <drawOffsetSouth>(0.0, 0.0, -0.1)</drawOffsetSouth>
 | 
					      <drawOffsetSouth>(0.0, 0.0, -0.1)</drawOffsetSouth>
 | 
				
			||||||
      <drawOffsetEast>(0.1, 0.0, 0.0)</drawOffsetEast>
 | 
					      <drawOffsetEast>(0.1, 0.0, 0.0)</drawOffsetEast>
 | 
				
			||||||
| 
						 | 
					@ -59,14 +59,9 @@
 | 
				
			||||||
    <biostatCpx>1</biostatCpx>
 | 
					    <biostatCpx>1</biostatCpx>
 | 
				
			||||||
    <biostatMet>-1</biostatMet>
 | 
					    <biostatMet>-1</biostatMet>
 | 
				
			||||||
    <graphicData>
 | 
					    <graphicData>
 | 
				
			||||||
      <graphicPaths>
 | 
					      <graphicPath>Things/Pawn/Humanlike/BodyAttachments/RJW_Genes_Succubus_Tail/RJW_Genes_Succubus_Tail</graphicPath>
 | 
				
			||||||
		<li>Things/Pawn/Humanlike/BodyAttachments/rjw_genes_Succubus_Tail/Succubus_Tail_L1</li>
 | 
					 | 
				
			||||||
		<li>Things/Pawn/Humanlike/BodyAttachments/rjw_genes_Succubus_Tail/Succubus_Tail_R1</li>
 | 
					 | 
				
			||||||
		<li>Things/Pawn/Humanlike/BodyAttachments/rjw_genes_Succubus_Tail/Succubus_Tail_L2</li>
 | 
					 | 
				
			||||||
		<li>Things/Pawn/Humanlike/BodyAttachments/rjw_genes_Succubus_Tail/Succubus_Tail_R2</li>
 | 
					 | 
				
			||||||
	  </graphicPaths>
 | 
					 | 
				
			||||||
      <colorType>Skin</colorType>
 | 
					      <colorType>Skin</colorType>
 | 
				
			||||||
	  <drawScale>2</drawScale>
 | 
						    <drawScale>2</drawScale>
 | 
				
			||||||
      <drawOffsetNorth>(0, 0.2, -0.1)</drawOffsetNorth>
 | 
					      <drawOffsetNorth>(0, 0.2, -0.1)</drawOffsetNorth>
 | 
				
			||||||
      <drawOffsetSouth>(0, -0.1, 0.1)</drawOffsetSouth>
 | 
					      <drawOffsetSouth>(0, -0.1, 0.1)</drawOffsetSouth>
 | 
				
			||||||
      <drawOffsetEast>(0.2, 0.2, 0.1)</drawOffsetEast>
 | 
					      <drawOffsetEast>(0.2, 0.2, 0.1)</drawOffsetEast>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -111,4 +111,26 @@
 | 
				
			||||||
      <li>AnusSize</li>
 | 
					      <li>AnusSize</li>
 | 
				
			||||||
    </exclusionTags>
 | 
					    </exclusionTags>
 | 
				
			||||||
  </GeneDef>
 | 
					  </GeneDef>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <!-- Extra -->
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  <GeneDef ParentName="GeneGenitaliaSizeBase">
 | 
				
			||||||
 | 
					    <defName>rjw_genes_evergrowth</defName>
 | 
				
			||||||
 | 
					    <label>Evergrowth</label>
 | 
				
			||||||
 | 
					    <description>One of the most regretted gene-modifications in the Glitterworlds: The (primary) genitalia will continue growing forever. This affects size and fluid output. Excessive growth can also effect mental stability! (Resizing takes place at 20th Birthday)</description>
 | 
				
			||||||
 | 
					    <iconPath>Genes/Icons/Big_Male_Genitalia</iconPath>
 | 
				
			||||||
 | 
					    <geneClass>RJW_Genes.Gene_EvergrowingGenitalia</geneClass>
 | 
				
			||||||
 | 
					    <displayOrderInCategory>767</displayOrderInCategory>
 | 
				
			||||||
 | 
					    <exclusionTags>
 | 
				
			||||||
 | 
					      <li>PenisSize</li>
 | 
				
			||||||
 | 
					      <li>VaginaSize</li>
 | 
				
			||||||
 | 
					    </exclusionTags>
 | 
				
			||||||
 | 
					    <modExtensions>
 | 
				
			||||||
 | 
					        	<li Class="RJW_Genes.TickIntervalExtension">
 | 
				
			||||||
 | 
									<!-- One day has 60k ticks-->
 | 
				
			||||||
 | 
									<tickInterval>60000</tickInterval>
 | 
				
			||||||
 | 
								</li>
 | 
				
			||||||
 | 
							</modExtensions>
 | 
				
			||||||
 | 
					  </GeneDef> 
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
</Defs>
 | 
					</Defs>
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,18 @@
 | 
				
			||||||
<?xml version="1.0" encoding="utf-8" ?>
 | 
					<?xml version="1.0" encoding="utf-8" ?>
 | 
				
			||||||
<Defs>
 | 
					<Defs>
 | 
				
			||||||
	<GeneDef>
 | 
						
 | 
				
			||||||
 | 
						<GeneDef Name="LifeForceBase" Abstract="True">
 | 
				
			||||||
 | 
							<displayCategory>rjw_genes_fertilin</displayCategory>
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							<modExtensions>
 | 
				
			||||||
 | 
								<li MayRequire="OskarPotocki.VanillaFactionsExpanded.Core" Class="VanillaGenesExpanded.GeneExtension">
 | 
				
			||||||
 | 
									<backgroundPathEndogenes>Genes/Icons/RJW_Genes_Endogene_Background</backgroundPathEndogenes>
 | 
				
			||||||
 | 
									<backgroundPathXenogenes>Genes/Icons/RJW_Genes_Xenogene_Background</backgroundPathXenogenes>
 | 
				
			||||||
 | 
								</li>
 | 
				
			||||||
 | 
							</modExtensions>
 | 
				
			||||||
 | 
						</GeneDef>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<GeneDef ParentName="LifeForceBase">
 | 
				
			||||||
		<defName>rjw_genes_lifeforce</defName>
 | 
							<defName>rjw_genes_lifeforce</defName>
 | 
				
			||||||
		<label>fertilin</label>
 | 
							<label>fertilin</label>
 | 
				
			||||||
		<description>Carriers of this gene have a reserve of biological strength powered by a resource called fertilin. The resource can be gained and spent in various ways, some of which are unlocked by other genes.\n\nCarriers lose 5 fertilin per day from biological entropy. \n\nGene is inactive until carrier is able to have sex.</description>
 | 
							<description>Carriers of this gene have a reserve of biological strength powered by a resource called fertilin. The resource can be gained and spent in various ways, some of which are unlocked by other genes.\n\nCarriers lose 5 fertilin per day from biological entropy. \n\nGene is inactive until carrier is able to have sex.</description>
 | 
				
			||||||
| 
						 | 
					@ -17,7 +29,6 @@
 | 
				
			||||||
		<resourceDescription>A reserve of biological strength which can be gained and spent in a variety of ways. \n\nFertilin can be increased by absorbing cum, typically through oral sex or stored cum. \n\nIf fertilin reaches zero, {PAWN_nameDef} will become very unhappy and may try to obtain some forcefully.</resourceDescription>
 | 
							<resourceDescription>A reserve of biological strength which can be gained and spent in a variety of ways. \n\nFertilin can be increased by absorbing cum, typically through oral sex or stored cum. \n\nIf fertilin reaches zero, {PAWN_nameDef} will become very unhappy and may try to obtain some forcefully.</resourceDescription>
 | 
				
			||||||
		<iconPath>Genes/Icons/FertilinAlt</iconPath>
 | 
							<iconPath>Genes/Icons/FertilinAlt</iconPath>
 | 
				
			||||||
		<selectionWeight>0</selectionWeight>
 | 
							<selectionWeight>0</selectionWeight>
 | 
				
			||||||
		<displayCategory>rjw_genes_fertilin</displayCategory>
 | 
					 | 
				
			||||||
		<displayOrderInCategory>-2</displayOrderInCategory>
 | 
							<displayOrderInCategory>-2</displayOrderInCategory>
 | 
				
			||||||
    	<minAgeActive>18</minAgeActive>
 | 
					    	<minAgeActive>18</minAgeActive>
 | 
				
			||||||
		<customEffectDescriptions>
 | 
							<customEffectDescriptions>
 | 
				
			||||||
| 
						 | 
					@ -28,43 +39,28 @@
 | 
				
			||||||
			<li><symbol>fert</symbol></li>
 | 
								<li><symbol>fert</symbol></li>
 | 
				
			||||||
		  </prefixSymbols>
 | 
							  </prefixSymbols>
 | 
				
			||||||
		</symbolPack>
 | 
							</symbolPack>
 | 
				
			||||||
		<resourceLossPerDay>0.05</resourceLossPerDay>
 | 
							<resourceLossPerDay>0.025</resourceLossPerDay>
 | 
				
			||||||
		<biostatCpx>1</biostatCpx>
 | 
							<biostatCpx>1</biostatCpx>
 | 
				
			||||||
		<biostatMet>1</biostatMet>
 | 
							<biostatMet>1</biostatMet>
 | 
				
			||||||
 | 
					 | 
				
			||||||
		<modExtensions>
 | 
					 | 
				
			||||||
			<li MayRequire="OskarPotocki.VanillaFactionsExpanded.Core" Class="VanillaGenesExpanded.GeneExtension">
 | 
					 | 
				
			||||||
				<backgroundPathEndogenes>Genes/Icons/RJW_Genes_Endogene_Background</backgroundPathEndogenes>
 | 
					 | 
				
			||||||
				<backgroundPathXenogenes>Genes/Icons/RJW_Genes_Xenogene_Background</backgroundPathXenogenes>
 | 
					 | 
				
			||||||
			</li>
 | 
					 | 
				
			||||||
		</modExtensions>
 | 
					 | 
				
			||||||
	</GeneDef>
 | 
						</GeneDef>
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	<GeneDef>
 | 
						<GeneDef ParentName="LifeForceBase">
 | 
				
			||||||
		<defName>rjw_genes_lifeforce_drain</defName>
 | 
							<defName>rjw_genes_lifeforce_drain</defName>
 | 
				
			||||||
		<label>fertilin drain</label>
 | 
							<label>fertilin drain</label>
 | 
				
			||||||
		<labelShortAdj>draining</labelShortAdj>
 | 
							<labelShortAdj>draining</labelShortAdj>
 | 
				
			||||||
		<description>Carriers lose an additional 15 fertilin per day from biological entropy.</description>
 | 
							<description>Carriers lose an additional 7.5 fertilin per day from biological entropy.</description>
 | 
				
			||||||
		<resourceLabel>fertilin</resourceLabel>
 | 
							<resourceLabel>fertilin</resourceLabel>
 | 
				
			||||||
		<geneClass>RJW_Genes.Gene_LifeForceDrain</geneClass>
 | 
							<geneClass>RJW_Genes.Gene_LifeForceDrain</geneClass>
 | 
				
			||||||
		<iconPath>Genes/Icons/FertilinDrainAlt</iconPath>
 | 
							<iconPath>Genes/Icons/FertilinDrainAlt</iconPath>
 | 
				
			||||||
		<prerequisite>rjw_genes_lifeforce</prerequisite>
 | 
							<prerequisite>rjw_genes_lifeforce</prerequisite>
 | 
				
			||||||
		<resourceLossPerDay>0.15</resourceLossPerDay>
 | 
							<resourceLossPerDay>0.075</resourceLossPerDay>
 | 
				
			||||||
		<displayCategory>rjw_genes_fertilin</displayCategory>
 | 
					 | 
				
			||||||
    	<minAgeActive>18</minAgeActive>
 | 
					    	<minAgeActive>18</minAgeActive>
 | 
				
			||||||
		<displayOrderInCategory>-1</displayOrderInCategory>
 | 
							<displayOrderInCategory>-1</displayOrderInCategory>
 | 
				
			||||||
		<biostatCpx>1</biostatCpx>
 | 
							<biostatCpx>1</biostatCpx>
 | 
				
			||||||
		<biostatMet>6</biostatMet>
 | 
							<biostatMet>6</biostatMet>
 | 
				
			||||||
 | 
					 | 
				
			||||||
		<modExtensions>
 | 
					 | 
				
			||||||
			<li MayRequire="OskarPotocki.VanillaFactionsExpanded.Core" Class="VanillaGenesExpanded.GeneExtension">
 | 
					 | 
				
			||||||
				<backgroundPathEndogenes>Genes/Icons/RJW_Genes_Endogene_Background</backgroundPathEndogenes>
 | 
					 | 
				
			||||||
				<backgroundPathXenogenes>Genes/Icons/RJW_Genes_Xenogene_Background</backgroundPathXenogenes>
 | 
					 | 
				
			||||||
			</li>
 | 
					 | 
				
			||||||
		</modExtensions>
 | 
					 | 
				
			||||||
	</GeneDef>
 | 
						</GeneDef>
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	<GeneDef>
 | 
						<GeneDef ParentName="LifeForceBase">
 | 
				
			||||||
		<defName>rjw_genes_pussyhealing</defName>
 | 
							<defName>rjw_genes_pussyhealing</defName>
 | 
				
			||||||
		<label>Pussy Healer</label>
 | 
							<label>Pussy Healer</label>
 | 
				
			||||||
		<labelShortAdj>pussyhealer</labelShortAdj>
 | 
							<labelShortAdj>pussyhealer</labelShortAdj>
 | 
				
			||||||
| 
						 | 
					@ -72,7 +68,6 @@
 | 
				
			||||||
		<iconPath>Genes/Icons/Healpussy</iconPath>
 | 
							<iconPath>Genes/Icons/Healpussy</iconPath>
 | 
				
			||||||
		<prerequisite>rjw_genes_lifeforce</prerequisite>
 | 
							<prerequisite>rjw_genes_lifeforce</prerequisite>
 | 
				
			||||||
		<displayOrderInCategory>9</displayOrderInCategory>
 | 
							<displayOrderInCategory>9</displayOrderInCategory>
 | 
				
			||||||
		<displayCategory>rjw_genes_fertilin</displayCategory>
 | 
					 | 
				
			||||||
		<abilities>
 | 
							<abilities>
 | 
				
			||||||
			<li>rjw_genes_ability_pussyheal</li>
 | 
								<li>rjw_genes_ability_pussyheal</li>
 | 
				
			||||||
		</abilities>
 | 
							</abilities>
 | 
				
			||||||
| 
						 | 
					@ -88,16 +83,9 @@
 | 
				
			||||||
				<li><symbol>heal</symbol></li>
 | 
									<li><symbol>heal</symbol></li>
 | 
				
			||||||
			</suffixSymbols>
 | 
								</suffixSymbols>
 | 
				
			||||||
		</symbolPack>
 | 
							</symbolPack>
 | 
				
			||||||
 | 
					 | 
				
			||||||
		<modExtensions>
 | 
					 | 
				
			||||||
			<li MayRequire="OskarPotocki.VanillaFactionsExpanded.Core" Class="VanillaGenesExpanded.GeneExtension">
 | 
					 | 
				
			||||||
				<backgroundPathEndogenes>Genes/Icons/RJW_Genes_Endogene_Background</backgroundPathEndogenes>
 | 
					 | 
				
			||||||
				<backgroundPathXenogenes>Genes/Icons/RJW_Genes_Xenogene_Background</backgroundPathXenogenes>
 | 
					 | 
				
			||||||
			</li>
 | 
					 | 
				
			||||||
		</modExtensions>
 | 
					 | 
				
			||||||
	</GeneDef>
 | 
						</GeneDef>
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	<GeneDef>
 | 
						<GeneDef ParentName="LifeForceBase">
 | 
				
			||||||
		<defName>rjw_genes_cockeater</defName>
 | 
							<defName>rjw_genes_cockeater</defName>
 | 
				
			||||||
		<label>Cockeater</label>
 | 
							<label>Cockeater</label>
 | 
				
			||||||
		<labelShortAdj>cockeater</labelShortAdj>
 | 
							<labelShortAdj>cockeater</labelShortAdj>
 | 
				
			||||||
| 
						 | 
					@ -105,7 +93,6 @@
 | 
				
			||||||
		<iconPath>Genes/Icons/cockeater</iconPath>
 | 
							<iconPath>Genes/Icons/cockeater</iconPath>
 | 
				
			||||||
		<prerequisite>rjw_genes_lifeforce</prerequisite>
 | 
							<prerequisite>rjw_genes_lifeforce</prerequisite>
 | 
				
			||||||
		<displayOrderInCategory>11</displayOrderInCategory>
 | 
							<displayOrderInCategory>11</displayOrderInCategory>
 | 
				
			||||||
		<displayCategory>rjw_genes_fertilin</displayCategory>
 | 
					 | 
				
			||||||
		<abilities>
 | 
							<abilities>
 | 
				
			||||||
			<li>rjw_genes_ability_cockeater</li>
 | 
								<li>rjw_genes_ability_cockeater</li>
 | 
				
			||||||
		</abilities>
 | 
							</abilities>
 | 
				
			||||||
| 
						 | 
					@ -121,16 +108,9 @@
 | 
				
			||||||
				<li><symbol>eat</symbol></li>
 | 
									<li><symbol>eat</symbol></li>
 | 
				
			||||||
			</suffixSymbols>
 | 
								</suffixSymbols>
 | 
				
			||||||
		</symbolPack>
 | 
							</symbolPack>
 | 
				
			||||||
 | 
					 | 
				
			||||||
		<modExtensions>
 | 
					 | 
				
			||||||
			<li MayRequire="OskarPotocki.VanillaFactionsExpanded.Core" Class="VanillaGenesExpanded.GeneExtension">
 | 
					 | 
				
			||||||
				<backgroundPathEndogenes>Genes/Icons/RJW_Genes_Endogene_Background</backgroundPathEndogenes>
 | 
					 | 
				
			||||||
				<backgroundPathXenogenes>Genes/Icons/RJW_Genes_Xenogene_Background</backgroundPathXenogenes>
 | 
					 | 
				
			||||||
			</li>
 | 
					 | 
				
			||||||
		</modExtensions>
 | 
					 | 
				
			||||||
	</GeneDef>
 | 
						</GeneDef>
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	<GeneDef>
 | 
						<GeneDef ParentName="LifeForceBase">
 | 
				
			||||||
		<defName>rjw_genes_paralysingkiss</defName>
 | 
							<defName>rjw_genes_paralysingkiss</defName>
 | 
				
			||||||
		<label>paralysing kiss</label>
 | 
							<label>paralysing kiss</label>
 | 
				
			||||||
		<labelShortAdj>paralysing kiss</labelShortAdj>
 | 
							<labelShortAdj>paralysing kiss</labelShortAdj>
 | 
				
			||||||
| 
						 | 
					@ -138,7 +118,6 @@
 | 
				
			||||||
		<iconPath>Genes/Icons/Paralysing_Kiss</iconPath>
 | 
							<iconPath>Genes/Icons/Paralysing_Kiss</iconPath>
 | 
				
			||||||
		<prerequisite>rjw_genes_lifeforce</prerequisite>
 | 
							<prerequisite>rjw_genes_lifeforce</prerequisite>
 | 
				
			||||||
		<displayOrderInCategory>12</displayOrderInCategory>
 | 
							<displayOrderInCategory>12</displayOrderInCategory>
 | 
				
			||||||
		<displayCategory>rjw_genes_fertilin</displayCategory>
 | 
					 | 
				
			||||||
		<abilities>
 | 
							<abilities>
 | 
				
			||||||
			<li>rjw_genes_ability_paralysingkiss</li>
 | 
								<li>rjw_genes_ability_paralysingkiss</li>
 | 
				
			||||||
		</abilities>
 | 
							</abilities>
 | 
				
			||||||
| 
						 | 
					@ -153,16 +132,9 @@
 | 
				
			||||||
				<li><symbol>kiss</symbol></li>
 | 
									<li><symbol>kiss</symbol></li>
 | 
				
			||||||
			</suffixSymbols>
 | 
								</suffixSymbols>
 | 
				
			||||||
		</symbolPack>
 | 
							</symbolPack>
 | 
				
			||||||
 | 
					 | 
				
			||||||
		<modExtensions>
 | 
					 | 
				
			||||||
			<li MayRequire="OskarPotocki.VanillaFactionsExpanded.Core" Class="VanillaGenesExpanded.GeneExtension">
 | 
					 | 
				
			||||||
				<backgroundPathEndogenes>Genes/Icons/RJW_Genes_Endogene_Background</backgroundPathEndogenes>
 | 
					 | 
				
			||||||
				<backgroundPathXenogenes>Genes/Icons/RJW_Genes_Xenogene_Background</backgroundPathXenogenes>
 | 
					 | 
				
			||||||
			</li>
 | 
					 | 
				
			||||||
		</modExtensions>
 | 
					 | 
				
			||||||
	</GeneDef>
 | 
						</GeneDef>
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	<GeneDef>
 | 
						<GeneDef ParentName="LifeForceBase">
 | 
				
			||||||
		<defName>rjw_genes_seduce</defName>
 | 
							<defName>rjw_genes_seduce</defName>
 | 
				
			||||||
		<label>seduction</label>
 | 
							<label>seduction</label>
 | 
				
			||||||
		<labelShortAdj>seduction</labelShortAdj>
 | 
							<labelShortAdj>seduction</labelShortAdj>
 | 
				
			||||||
| 
						 | 
					@ -170,7 +142,6 @@
 | 
				
			||||||
		<iconPath>Genes/Icons/seduce</iconPath>
 | 
							<iconPath>Genes/Icons/seduce</iconPath>
 | 
				
			||||||
		<prerequisite>rjw_genes_lifeforce</prerequisite>
 | 
							<prerequisite>rjw_genes_lifeforce</prerequisite>
 | 
				
			||||||
		<displayOrderInCategory>13</displayOrderInCategory>
 | 
							<displayOrderInCategory>13</displayOrderInCategory>
 | 
				
			||||||
		<displayCategory>rjw_genes_fertilin</displayCategory>
 | 
					 | 
				
			||||||
		<abilities>
 | 
							<abilities>
 | 
				
			||||||
			<li>rjw_genes_ability_seduce</li>
 | 
								<li>rjw_genes_ability_seduce</li>
 | 
				
			||||||
		</abilities>
 | 
							</abilities>
 | 
				
			||||||
| 
						 | 
					@ -186,23 +157,15 @@
 | 
				
			||||||
				<li><symbol>kiss</symbol></li>
 | 
									<li><symbol>kiss</symbol></li>
 | 
				
			||||||
			</suffixSymbols>
 | 
								</suffixSymbols>
 | 
				
			||||||
		</symbolPack>
 | 
							</symbolPack>
 | 
				
			||||||
 | 
					 | 
				
			||||||
		<modExtensions>
 | 
					 | 
				
			||||||
			<li MayRequire="OskarPotocki.VanillaFactionsExpanded.Core" Class="VanillaGenesExpanded.GeneExtension">
 | 
					 | 
				
			||||||
				<backgroundPathEndogenes>Genes/Icons/RJW_Genes_Endogene_Background</backgroundPathEndogenes>
 | 
					 | 
				
			||||||
				<backgroundPathXenogenes>Genes/Icons/RJW_Genes_Xenogene_Background</backgroundPathXenogenes>
 | 
					 | 
				
			||||||
			</li>
 | 
					 | 
				
			||||||
		</modExtensions>
 | 
					 | 
				
			||||||
	</GeneDef>
 | 
						</GeneDef>
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	<GeneDef>
 | 
						<GeneDef ParentName="LifeForceBase">
 | 
				
			||||||
		<defName>rjw_genes_naked_prowess</defName>
 | 
							<defName>rjw_genes_naked_prowess</defName>
 | 
				
			||||||
		<label>naked prowess</label>
 | 
							<label>naked prowess</label>
 | 
				
			||||||
		<description>Carriers of this gene are able to temporarily increase their strength and resilience, while they are naked.</description>
 | 
							<description>Carriers of this gene are able to temporarily increase their strength and resilience, while they are naked.</description>
 | 
				
			||||||
		<iconPath>Genes/Icons/rjw_naked_prowess</iconPath>
 | 
							<iconPath>Genes/Icons/rjw_naked_prowess</iconPath>
 | 
				
			||||||
		<prerequisite>rjw_genes_lifeforce</prerequisite>
 | 
							<prerequisite>rjw_genes_lifeforce</prerequisite>
 | 
				
			||||||
		<displayOrderInCategory>13</displayOrderInCategory>
 | 
							<displayOrderInCategory>14</displayOrderInCategory>
 | 
				
			||||||
		<displayCategory>rjw_genes_fertilin</displayCategory>
 | 
					 | 
				
			||||||
		<abilities>
 | 
							<abilities>
 | 
				
			||||||
			<li>rjw_genes_ability_naked_prowess</li>
 | 
								<li>rjw_genes_ability_naked_prowess</li>
 | 
				
			||||||
		</abilities>
 | 
							</abilities>
 | 
				
			||||||
| 
						 | 
					@ -211,67 +174,64 @@
 | 
				
			||||||
		</descriptionHyperlinks>
 | 
							</descriptionHyperlinks>
 | 
				
			||||||
		<biostatCpx>1</biostatCpx>
 | 
							<biostatCpx>1</biostatCpx>
 | 
				
			||||||
		<biostatMet>-1</biostatMet>
 | 
							<biostatMet>-1</biostatMet>
 | 
				
			||||||
 | 
					 | 
				
			||||||
		<modExtensions>
 | 
					 | 
				
			||||||
			<li MayRequire="OskarPotocki.VanillaFactionsExpanded.Core" Class="VanillaGenesExpanded.GeneExtension">
 | 
					 | 
				
			||||||
				<backgroundPathEndogenes>Genes/Icons/RJW_Genes_Endogene_Background</backgroundPathEndogenes>
 | 
					 | 
				
			||||||
				<backgroundPathXenogenes>Genes/Icons/RJW_Genes_Xenogene_Background</backgroundPathXenogenes>
 | 
					 | 
				
			||||||
			</li>
 | 
					 | 
				
			||||||
		</modExtensions>
 | 
					 | 
				
			||||||
	</GeneDef>
 | 
						</GeneDef>
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	<GeneDef>
 | 
						<GeneDef ParentName="LifeForceBase">
 | 
				
			||||||
		<defName>rjw_genes_cum_eater</defName>
 | 
							<defName>rjw_genes_cum_eater</defName>
 | 
				
			||||||
		<label>Cum eater</label>
 | 
							<label>Cum eater</label>
 | 
				
			||||||
		<description>Carriers of this gene are able to absorb fertilin through eating cum. This includes oral sex, eating cum for food or sucking out cumflated pawns. </description>
 | 
							<description>Carriers of this gene are able to absorb fertilin through eating cum. This includes oral sex, eating cum for food or sucking out cumflated pawns. </description>
 | 
				
			||||||
		<iconPath>Genes/Icons/cumeater</iconPath>
 | 
							<iconPath>Genes/Icons/cumeater</iconPath>
 | 
				
			||||||
		<prerequisite>rjw_genes_lifeforce</prerequisite>
 | 
							<prerequisite>rjw_genes_lifeforce</prerequisite>
 | 
				
			||||||
		<displayOrderInCategory>1</displayOrderInCategory>
 | 
							<displayOrderInCategory>1</displayOrderInCategory>
 | 
				
			||||||
		<displayCategory>rjw_genes_fertilin</displayCategory>
 | 
					 | 
				
			||||||
		<biostatCpx>1</biostatCpx>
 | 
							<biostatCpx>1</biostatCpx>
 | 
				
			||||||
 | 
					 | 
				
			||||||
		<modExtensions>
 | 
					 | 
				
			||||||
			<li MayRequire="OskarPotocki.VanillaFactionsExpanded.Core" Class="VanillaGenesExpanded.GeneExtension">
 | 
					 | 
				
			||||||
				<backgroundPathEndogenes>Genes/Icons/RJW_Genes_Endogene_Background</backgroundPathEndogenes>
 | 
					 | 
				
			||||||
				<backgroundPathXenogenes>Genes/Icons/RJW_Genes_Xenogene_Background</backgroundPathXenogenes>
 | 
					 | 
				
			||||||
			</li>
 | 
					 | 
				
			||||||
		</modExtensions>
 | 
					 | 
				
			||||||
	</GeneDef>
 | 
						</GeneDef>
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	<GeneDef>
 | 
						<GeneDef ParentName="LifeForceBase">
 | 
				
			||||||
		<defName>rjw_genes_fertilin_absorber</defName>
 | 
							<defName>rjw_genes_fertilin_absorber</defName>
 | 
				
			||||||
		<label>Fertilin Absorber</label>
 | 
							<label>Fertilin Absorber</label>
 | 
				
			||||||
		<description>Carriers of this gene are able to absorb the fertilin inside sperm through their vagina and anus.</description>
 | 
							<description>Carriers of this gene are able to absorb the fertilin inside sperm through their vagina and anus.</description>
 | 
				
			||||||
		<iconPath>Genes/Icons/Vaginal_cum_absorption</iconPath>
 | 
							<iconPath>Genes/Icons/Vaginal_cum_absorption</iconPath>
 | 
				
			||||||
		<prerequisite>rjw_genes_lifeforce</prerequisite>
 | 
							<prerequisite>rjw_genes_lifeforce</prerequisite>
 | 
				
			||||||
		<displayOrderInCategory>2</displayOrderInCategory>
 | 
							<displayOrderInCategory>2</displayOrderInCategory>
 | 
				
			||||||
		<displayCategory>rjw_genes_fertilin</displayCategory>
 | 
					 | 
				
			||||||
		<biostatCpx>1</biostatCpx>
 | 
							<biostatCpx>1</biostatCpx>
 | 
				
			||||||
 | 
						</GeneDef>
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						<GeneDef ParentName="LifeForceBase">
 | 
				
			||||||
 | 
							<defName>rjw_genes_lifeforce_empath</defName>
 | 
				
			||||||
 | 
							<label>empathic lifeforce</label>
 | 
				
			||||||
 | 
							<geneClass>RJW_Genes.Gene_LifeForce_Empath</geneClass>
 | 
				
			||||||
 | 
							<description>Carriers of this gene generate lifeforce if nearby pawns are sexually satisfied. Be careful: Sexually frustrated pawns will make your empath loose lifeforce!</description>
 | 
				
			||||||
 | 
							<iconPath>Genes/Icons/Hypersexual</iconPath>
 | 
				
			||||||
 | 
							<prerequisite>rjw_genes_lifeforce</prerequisite>
 | 
				
			||||||
 | 
							<displayOrderInCategory>3</displayOrderInCategory>
 | 
				
			||||||
 | 
							<biostatCpx>3</biostatCpx>
 | 
				
			||||||
 | 
							<biostatMet>-2</biostatMet>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<modExtensions>
 | 
							<modExtensions>
 | 
				
			||||||
			<li MayRequire="OskarPotocki.VanillaFactionsExpanded.Core" Class="VanillaGenesExpanded.GeneExtension">
 | 
								<li Class="RJW_Genes.LifeForceEmpathExtension">
 | 
				
			||||||
				<backgroundPathEndogenes>Genes/Icons/RJW_Genes_Endogene_Background</backgroundPathEndogenes>
 | 
									<aheagoIncrement>0.02</aheagoIncrement>
 | 
				
			||||||
				<backgroundPathXenogenes>Genes/Icons/RJW_Genes_Xenogene_Background</backgroundPathXenogenes>
 | 
									<satisfactionIncrement>0.01</satisfactionIncrement>
 | 
				
			||||||
 | 
									<frustratedDecrement>-0.01</frustratedDecrement>
 | 
				
			||||||
 | 
								</li>
 | 
				
			||||||
 | 
								<li Class="RJW_Genes.TickIntervalExtension">
 | 
				
			||||||
 | 
									<!-- One day has 60k ticks, so we check every hour with 60000/24 = 2500-->
 | 
				
			||||||
 | 
									<tickInterval>2500</tickInterval>
 | 
				
			||||||
 | 
								</li>
 | 
				
			||||||
 | 
								<li Class="RJW_Genes.DistanceExtension">
 | 
				
			||||||
 | 
									<!-- distance 25 means 25 tiles in every direction from the empath.-->
 | 
				
			||||||
 | 
									<distance>25</distance>
 | 
				
			||||||
			</li>
 | 
								</li>
 | 
				
			||||||
		</modExtensions>
 | 
							</modExtensions>
 | 
				
			||||||
	</GeneDef>
 | 
						</GeneDef>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<GeneDef>
 | 
						<GeneDef ParentName="LifeForceBase">
 | 
				
			||||||
		<defName>rjw_genes_drainer</defName>
 | 
							<defName>rjw_genes_drainer</defName>
 | 
				
			||||||
		<label>vitality drainer</label>
 | 
							<label>vitality drainer</label>
 | 
				
			||||||
		<description>Carriers of this gene are able to absorb a great amount of fertilin by draining the vitality of the partner. This is done passively through having sex with a non-drained pawn that does not have this gene.</description>
 | 
							<description>Carriers of this gene are able to absorb a great amount of fertilin by draining the vitality of the partner. This is done passively through having sex with a non-drained pawn that does not have this gene.</description>
 | 
				
			||||||
		<iconPath>Genes/Icons/Vitality_Drainer</iconPath>
 | 
							<iconPath>Genes/Icons/Vitality_Drainer</iconPath>
 | 
				
			||||||
		<prerequisite>rjw_genes_lifeforce</prerequisite>
 | 
							<prerequisite>rjw_genes_lifeforce</prerequisite>
 | 
				
			||||||
		<displayOrderInCategory>4</displayOrderInCategory>
 | 
							<displayOrderInCategory>4</displayOrderInCategory>
 | 
				
			||||||
		<displayCategory>rjw_genes_fertilin</displayCategory>
 | 
					 | 
				
			||||||
		<biostatCpx>1</biostatCpx>
 | 
							<biostatCpx>1</biostatCpx>
 | 
				
			||||||
		<biostatMet>-1</biostatMet>
 | 
							<biostatMet>-1</biostatMet>
 | 
				
			||||||
 | 
					 | 
				
			||||||
		<modExtensions>
 | 
					 | 
				
			||||||
			<li MayRequire="OskarPotocki.VanillaFactionsExpanded.Core" Class="VanillaGenesExpanded.GeneExtension">
 | 
					 | 
				
			||||||
				<backgroundPathEndogenes>Genes/Icons/RJW_Genes_Endogene_Background</backgroundPathEndogenes>
 | 
					 | 
				
			||||||
				<backgroundPathXenogenes>Genes/Icons/RJW_Genes_Xenogene_Background</backgroundPathXenogenes>
 | 
					 | 
				
			||||||
			</li>
 | 
					 | 
				
			||||||
		</modExtensions>
 | 
					 | 
				
			||||||
	</GeneDef>
 | 
						</GeneDef>
 | 
				
			||||||
</Defs>
 | 
					</Defs>
 | 
				
			||||||
| 
						 | 
					@ -94,4 +94,29 @@
 | 
				
			||||||
		</modExtensions>
 | 
							</modExtensions>
 | 
				
			||||||
    </GeneDef>
 | 
					    </GeneDef>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <GeneDef>
 | 
				
			||||||
 | 
					    <defName>rjw_genes_no_sex_need</defName>
 | 
				
			||||||
 | 
					    <label>Asexual</label>
 | 
				
			||||||
 | 
					    <description>Carriers of this gene do not have a sex-need. They can still participate in sex, </description>
 | 
				
			||||||
 | 
					    <iconPath>Genes/Icons/Empty</iconPath>
 | 
				
			||||||
 | 
					    <displayOrderInCategory>5</displayOrderInCategory>
 | 
				
			||||||
 | 
					    <disablesNeeds>
 | 
				
			||||||
 | 
					      <li>Sex</li>
 | 
				
			||||||
 | 
					    </disablesNeeds>
 | 
				
			||||||
 | 
					    <biostatMet>-1</biostatMet>
 | 
				
			||||||
 | 
					    <biostatCpx>2</biostatCpx>
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    <exclusionTags>
 | 
				
			||||||
 | 
					        <li>rjw_genes_sexual_orientation</li>
 | 
				
			||||||
 | 
					    </exclusionTags>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <modExtensions>
 | 
				
			||||||
 | 
					        <li MayRequire="OskarPotocki.VanillaFactionsExpanded.Core" Class="VanillaGenesExpanded.GeneExtension">
 | 
				
			||||||
 | 
					            <backgroundPathEndogenes>Genes/Icons/RJW_Genes_Endogene_Background</backgroundPathEndogenes>
 | 
				
			||||||
 | 
					            <backgroundPathXenogenes>Genes/Icons/RJW_Genes_Xenogene_Background</backgroundPathXenogenes>
 | 
				
			||||||
 | 
					        </li>
 | 
				
			||||||
 | 
					    </modExtensions>
 | 
				
			||||||
 | 
					  </GeneDef>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</Defs>
 | 
					</Defs>
 | 
				
			||||||
| 
						 | 
					@ -65,6 +65,17 @@
 | 
				
			||||||
        <displayOrderInCategory>4</displayOrderInCategory>
 | 
					        <displayOrderInCategory>4</displayOrderInCategory>
 | 
				
			||||||
        <biostatCpx>1</biostatCpx>
 | 
					        <biostatCpx>1</biostatCpx>
 | 
				
			||||||
        <biostatMet>1</biostatMet>
 | 
					        <biostatMet>1</biostatMet>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <modExtensions>
 | 
				
			||||||
 | 
								<li Class="RJW_Genes.TickIntervalExtension">
 | 
				
			||||||
 | 
									<!-- One day has 60k ticks, so we check every hour with 60000/48 = 1250-->
 | 
				
			||||||
 | 
									<tickInterval>1250</tickInterval>
 | 
				
			||||||
 | 
								</li>
 | 
				
			||||||
 | 
								<li Class="RJW_Genes.DistanceExtension">
 | 
				
			||||||
 | 
									<!-- distance 25 means 25 tiles in every direction from the pheromone-pawn.-->
 | 
				
			||||||
 | 
									<distance>25</distance>
 | 
				
			||||||
 | 
								</li>
 | 
				
			||||||
 | 
					        </modExtensions>
 | 
				
			||||||
    </GeneDef>
 | 
					    </GeneDef>
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    <GeneDef ParentName="SpecialBase">
 | 
					    <GeneDef ParentName="SpecialBase">
 | 
				
			||||||
| 
						 | 
					@ -78,4 +89,24 @@
 | 
				
			||||||
        <biostatMet>-5</biostatMet>
 | 
					        <biostatMet>-5</biostatMet>
 | 
				
			||||||
    </GeneDef>    
 | 
					    </GeneDef>    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <GeneDef ParentName="SpecialBase">
 | 
				
			||||||
 | 
					        <defName>rjw_genes_hormonal_saliva</defName>
 | 
				
			||||||
 | 
					        <label>Hormonal Saliva</label>
 | 
				
			||||||
 | 
					        <description>The saliva of this xenotype stimulates growth in penises. Regular contact will lead to noticable growth.</description>
 | 
				
			||||||
 | 
					        <biostatCpx>2</biostatCpx>
 | 
				
			||||||
 | 
					        <biostatMet>-1</biostatMet>
 | 
				
			||||||
 | 
					        <iconPath>Genes/Icons/Big_Male_Genitalia</iconPath>
 | 
				
			||||||
 | 
					        <displayOrderInCategory>6</displayOrderInCategory>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <modExtensions>
 | 
				
			||||||
 | 
					            <li Class="RJW_Genes.HormonalSalivaExtension">
 | 
				
			||||||
 | 
					                <!-- SizeIncrement is applied "flat" -->
 | 
				
			||||||
 | 
					                <sizeIncrement>0.02</sizeIncrement>
 | 
				
			||||||
 | 
					                <maxBodySize>2.5</maxBodySize>
 | 
				
			||||||
 | 
					                <!-- CumMultiplier is applied "exponential" -->
 | 
				
			||||||
 | 
					                <cumMultiplier>1.05</cumMultiplier>
 | 
				
			||||||
 | 
					            </li>
 | 
				
			||||||
 | 
					        </modExtensions>
 | 
				
			||||||
 | 
					    </GeneDef>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</Defs>
 | 
					</Defs>
 | 
				
			||||||
| 
						 | 
					@ -46,4 +46,36 @@
 | 
				
			||||||
        </modExtensions>
 | 
					        </modExtensions>
 | 
				
			||||||
    </GeneDef>
 | 
					    </GeneDef>
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <GeneDef>
 | 
				
			||||||
 | 
					        <defName>rjw_genes_gender_fluid</defName>
 | 
				
			||||||
 | 
					        <displayCategory>rjw_genes_gender</displayCategory>
 | 
				
			||||||
 | 
					        <label>Gender Fluid</label>
 | 
				
			||||||
 | 
					        <description>Everyday carriers of this gene might change their biological sex.</description>
 | 
				
			||||||
 | 
					        <biostatCpx>0</biostatCpx>
 | 
				
			||||||
 | 
					        <iconPath>Genes/Icons/Futa</iconPath>
 | 
				
			||||||
 | 
					        <geneClass>RJW_Genes.Gene_GenderFluid</geneClass>
 | 
				
			||||||
 | 
					        <displayOrderInCategory>2</displayOrderInCategory>
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        <!-- Design Decision: GenderFluids like GenderFluids (slightly) more. -->
 | 
				
			||||||
 | 
					        <missingGeneRomanceChanceFactor>0.9</missingGeneRomanceChanceFactor>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <exclusionTags>
 | 
				
			||||||
 | 
					          <li>AG_Gender</li>
 | 
				
			||||||
 | 
					          <li>Gender</li>          
 | 
				
			||||||
 | 
					        </exclusionTags>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <modExtensions>
 | 
				
			||||||
 | 
					          <li MayRequire="OskarPotocki.VanillaFactionsExpanded.Core" Class="VanillaGenesExpanded.GeneExtension">
 | 
				
			||||||
 | 
					            <backgroundPathEndogenes>Genes/Icons/RJW_Genes_Endogene_Background</backgroundPathEndogenes>
 | 
				
			||||||
 | 
					            <backgroundPathXenogenes>Genes/Icons/RJW_Genes_Xenogene_Background</backgroundPathXenogenes>
 | 
				
			||||||
 | 
					          </li>
 | 
				
			||||||
 | 
					          <li Class="RJW_Genes.GenderFluidExtension">
 | 
				
			||||||
 | 
					                <!-- 120k = 2 days -->
 | 
				
			||||||
 | 
					                <changeInterval>120000</changeInterval>
 | 
				
			||||||
 | 
					                <changeChance>0.25</changeChance>
 | 
				
			||||||
 | 
					          </li>
 | 
				
			||||||
 | 
					        </modExtensions>
 | 
				
			||||||
 | 
					    </GeneDef>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</Defs>
 | 
					</Defs>
 | 
				
			||||||
							
								
								
									
										52
									
								
								Common/Defs/HediffDefs/Hediffs_Evergrowth.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,52 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="utf-8" ?>
 | 
				
			||||||
 | 
					<Defs>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<HediffDef>
 | 
				
			||||||
 | 
							<defName>rjw_genes_evergrowth_sideeffect</defName>
 | 
				
			||||||
 | 
							<hediffClass>HediffWithComps</hediffClass>
 | 
				
			||||||
 | 
							<label>genital hybris</label>
 | 
				
			||||||
 | 
							<description>science has gone too far - a tool like this needs constant attention.</description>
 | 
				
			||||||
 | 
							<defaultLabelColor>(1,0,0.5)</defaultLabelColor>
 | 
				
			||||||
 | 
							<maxSeverity>1.0</maxSeverity>
 | 
				
			||||||
 | 
							<comps>
 | 
				
			||||||
 | 
								<li Class="HediffCompProperties_SeverityPerDay">
 | 
				
			||||||
 | 
									<severityPerDay>-0.025</severityPerDay>
 | 
				
			||||||
 | 
								</li>
 | 
				
			||||||
 | 
							</comps>
 | 
				
			||||||
 | 
							<stages>
 | 
				
			||||||
 | 
								<li>
 | 
				
			||||||
 | 
									<label>minor</label>
 | 
				
			||||||
 | 
									<statFactors>
 | 
				
			||||||
 | 
										<SexFrequency>3</SexFrequency>
 | 
				
			||||||
 | 
									</statFactors>
 | 
				
			||||||
 | 
								</li>
 | 
				
			||||||
 | 
								<li>
 | 
				
			||||||
 | 
									<minSeverity>0.5</minSeverity>
 | 
				
			||||||
 | 
									<label>moderate</label>
 | 
				
			||||||
 | 
									<statFactors>
 | 
				
			||||||
 | 
										<SexFrequency>5</SexFrequency>
 | 
				
			||||||
 | 
									</statFactors>
 | 
				
			||||||
 | 
					                <capMods>
 | 
				
			||||||
 | 
					                        <li>
 | 
				
			||||||
 | 
					                            <capacity>Consciousness</capacity>
 | 
				
			||||||
 | 
					                            <offset>-0.05</offset>
 | 
				
			||||||
 | 
					                        </li>
 | 
				
			||||||
 | 
					                        </capMods>
 | 
				
			||||||
 | 
								</li>
 | 
				
			||||||
 | 
								<li>
 | 
				
			||||||
 | 
									<minSeverity>0.9</minSeverity>
 | 
				
			||||||
 | 
									<label>strong</label>
 | 
				
			||||||
 | 
									<statFactors>
 | 
				
			||||||
 | 
										<SexFrequency>7</SexFrequency>
 | 
				
			||||||
 | 
									</statFactors>
 | 
				
			||||||
 | 
					                    <capMods>
 | 
				
			||||||
 | 
					                    <li>
 | 
				
			||||||
 | 
					                        <capacity>Consciousness</capacity>
 | 
				
			||||||
 | 
					                        <offset>-0.1</offset>
 | 
				
			||||||
 | 
					                    </li>
 | 
				
			||||||
 | 
					                    </capMods>
 | 
				
			||||||
 | 
								</li>
 | 
				
			||||||
 | 
							</stages>
 | 
				
			||||||
 | 
						</HediffDef>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</Defs>
 | 
				
			||||||
							
								
								
									
										7
									
								
								Common/Languages/English/Keyed/Hive.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<LanguageData>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <rjw_genes_queenbirth_letter_label>New Queen</rjw_genes_queenbirth_letter_label>
 | 
				
			||||||
 | 
					    <rjw_genes_queenbirth_letter_description>A new Queen was born! Make sure to adress inheritance before the new queen reaches adolesence.</rjw_genes_queenbirth_letter_description>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</LanguageData>
 | 
				
			||||||
| 
						 | 
					@ -14,4 +14,7 @@
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	<rjw_genes_sexdemon_visit_incident_label>Dirty dreams</rjw_genes_sexdemon_visit_incident_label>
 | 
						<rjw_genes_sexdemon_visit_incident_label>Dirty dreams</rjw_genes_sexdemon_visit_incident_label>
 | 
				
			||||||
	<rjw_genes_sexdemon_visit_incident_description>The dirty dreams of your colonists have attracted succubi.\n\nThey will hang around for a couple of days trying to seduce your colonists. They may decide to join your colony, if they are impressed by your colonists's sexual prowess.</rjw_genes_sexdemon_visit_incident_description>
 | 
						<rjw_genes_sexdemon_visit_incident_description>The dirty dreams of your colonists have attracted succubi.\n\nThey will hang around for a couple of days trying to seduce your colonists. They may decide to join your colony, if they are impressed by your colonists's sexual prowess.</rjw_genes_sexdemon_visit_incident_description>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<rjw_genes_succubus_joins_letter_label>Guest Joins</rjw_genes_succubus_joins>
 | 
				
			||||||
 | 
						<rjw_genes_succubus_joins_letter_description>{0} enjoys it here and has decided to stay.</rjw_genes_succubus_joins_letter_description>
 | 
				
			||||||
</LanguageData>
 | 
					</LanguageData>
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,19 @@
 | 
				
			||||||
<?xml version="1.0" encoding="utf-8" ?>
 | 
					<?xml version="1.0" encoding="utf-8" ?>
 | 
				
			||||||
<Patch>
 | 
					<Patch>
 | 
				
			||||||
	<!-- Add RJW Sex meditation focus icon to VanillaPsycastsExpanded -->
 | 
						<!-- 
 | 
				
			||||||
	<Operation Class="PatchOperationFindMod">
 | 
							DevNote:
 | 
				
			||||||
		<mods>
 | 
							There used to be an issue with a Gene-Mod Called "Cum-Addiction Gene". That mod just overwrote the complete UsedCondom.xml and Sexperience Cum.xml
 | 
				
			||||||
			<li>RimJobWorld</li>
 | 
							This would lead to two types of failures: 
 | 
				
			||||||
		</mods>
 | 
							A) If this mod was before the other mod, changes were just overwritten
 | 
				
			||||||
		<match Class="PatchOperationAdd">
 | 
							B) If this mod was after, there was an issue in targetting the XML throwing a patch error
 | 
				
			||||||
 | 
							Please if you write mods, do not just purge out XMLs. Thanks. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							This patch was kindly provided by Infi over Discord. 
 | 
				
			||||||
 | 
						-->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<Operation Class="PatchOperationConditional">
 | 
				
			||||||
 | 
							<xpath>Defs/ThingDef[defName="UsedCondom"]/ingestible/outcomeDoers</xpath>
 | 
				
			||||||
 | 
							<nomatch Class="PatchOperationAdd">
 | 
				
			||||||
			<xpath>/Defs/ThingDef[defName="UsedCondom"]/ingestible</xpath>
 | 
								<xpath>/Defs/ThingDef[defName="UsedCondom"]/ingestible</xpath>
 | 
				
			||||||
			<value>
 | 
								<value>
 | 
				
			||||||
				<outcomeDoers>
 | 
									<outcomeDoers>
 | 
				
			||||||
| 
						 | 
					@ -14,6 +22,15 @@
 | 
				
			||||||
					</li>
 | 
										</li>
 | 
				
			||||||
				</outcomeDoers>
 | 
									</outcomeDoers>
 | 
				
			||||||
			</value>
 | 
								</value>
 | 
				
			||||||
 | 
							</nomatch>
 | 
				
			||||||
 | 
							<match Class="PatchOperationAdd">
 | 
				
			||||||
 | 
								<xpath>Defs/ThingDef[defName="UsedCondom"]/ingestible/outcomeDoers</xpath>
 | 
				
			||||||
 | 
								<value>
 | 
				
			||||||
 | 
									<li Class="RJW_Genes.IngestionOutcomeDoer_LifeForceOffset">
 | 
				
			||||||
 | 
											<FertilinPerUnit>1</FertilinPerUnit>
 | 
				
			||||||
 | 
										</li>
 | 
				
			||||||
 | 
								</value>
 | 
				
			||||||
		</match>
 | 
							</match>
 | 
				
			||||||
	</Operation>
 | 
						</Operation>
 | 
				
			||||||
 | 
						
 | 
				
			||||||
</Patch>
 | 
					</Patch>
 | 
				
			||||||
| 
						 | 
					@ -1,17 +1,37 @@
 | 
				
			||||||
<?xml version="1.0" encoding="utf-8" ?>
 | 
					<?xml version="1.0" encoding="utf-8" ?>
 | 
				
			||||||
<Patch>
 | 
					<Patch>
 | 
				
			||||||
	<!-- Add RJW Sex meditation focus icon to VanillaPsycastsExpanded -->
 | 
					
 | 
				
			||||||
	<Operation Class="PatchOperationFindMod">
 | 
						<!-- 
 | 
				
			||||||
		<mods>
 | 
							DevNote:
 | 
				
			||||||
			<li>RJW Sexperience</li>
 | 
							There used to be an issue with a Gene-Mod Called "Cum-Addiction Gene". That mod just overwrote the complete UsedCondom.xml and Sexperience Cum.xml
 | 
				
			||||||
		</mods>
 | 
							This would lead to two types of failures: 
 | 
				
			||||||
 | 
							A) If this mod was before the other mod, changes were just overwritten
 | 
				
			||||||
 | 
							B) If this mod was after, there was an issue in targetting the XML throwing a patch error
 | 
				
			||||||
 | 
							Please if you write mods, do not just purge out XMLs. Thanks. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							This patch was kindly mirrored after Infis Patch of UsedCondoms. 
 | 
				
			||||||
 | 
						-->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<Operation Class="PatchOperationConditional">
 | 
				
			||||||
 | 
							<xpath>Defs/ThingDef[defName="GatheredCum"]/ingestible/outcomeDoers</xpath>
 | 
				
			||||||
 | 
							<nomatch Class="PatchOperationAdd">
 | 
				
			||||||
 | 
								<xpath>/Defs/ThingDef[defName="GatheredCum"]/ingestible</xpath>
 | 
				
			||||||
 | 
								<value>
 | 
				
			||||||
 | 
									<outcomeDoers>
 | 
				
			||||||
 | 
										<li Class="RJW_Genes.IngestionOutcomeDoer_LifeForceOffset">
 | 
				
			||||||
 | 
											<FertilinPerUnit>1</FertilinPerUnit>
 | 
				
			||||||
 | 
										</li>
 | 
				
			||||||
 | 
									</outcomeDoers>
 | 
				
			||||||
 | 
								</value>
 | 
				
			||||||
 | 
							</nomatch>
 | 
				
			||||||
		<match Class="PatchOperationAdd">
 | 
							<match Class="PatchOperationAdd">
 | 
				
			||||||
			<xpath>/Defs/ThingDef[defName="GatheredCum"]/ingestible/outcomeDoers</xpath>
 | 
								<xpath>Defs/ThingDef[defName="GatheredCum"]/ingestible/outcomeDoers</xpath>
 | 
				
			||||||
			<value>
 | 
								<value>
 | 
				
			||||||
				<li Class="RJW_Genes.IngestionOutcomeDoer_LifeForceOffset">
 | 
									<li Class="RJW_Genes.IngestionOutcomeDoer_LifeForceOffset">
 | 
				
			||||||
					<FertilinPerUnit>1</FertilinPerUnit>
 | 
											<FertilinPerUnit>1</FertilinPerUnit>
 | 
				
			||||||
				</li>
 | 
										</li>
 | 
				
			||||||
			</value>
 | 
								</value>
 | 
				
			||||||
		</match>
 | 
							</match>
 | 
				
			||||||
	</Operation>
 | 
						</Operation>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</Patch>
 | 
					</Patch>
 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 33 KiB  | 
| 
		 Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 45 KiB  | 
| 
		 Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 29 KiB  | 
| 
		 Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 52 KiB  | 
| 
		 Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 46 KiB  | 
| 
		 Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 56 KiB  | 
| 
		 Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 39 KiB  | 
| 
		 Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 35 KiB  | 
| 
		 Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 33 KiB  | 
| 
		 Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 27 KiB  | 
| 
		 Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 36 KiB  | 
| 
		 Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 30 KiB  | 
| 
		 Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 29 KiB  | 
| 
		 Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 26 KiB  | 
| 
		 Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 26 KiB  | 
| 
		 Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 32 KiB  | 
| 
		 Before Width: | Height: | Size: 940 B After Width: | Height: | Size: 14 KiB  | 
| 
		 Before Width: | Height: | Size: 1,015 B After Width: | Height: | Size: 29 KiB  | 
| 
		 Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 34 KiB  | 
| 
		 Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 34 KiB  | 
| 
		 Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 55 KiB  | 
| 
		 Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 49 KiB  | 
| 
		 Before Width: | Height: | Size: 364 KiB After Width: | Height: | Size: 63 KiB  | 
| 
		 After Width: | Height: | Size: 14 KiB  | 
| 
		 After Width: | Height: | Size: 15 KiB  | 
| 
		 After Width: | Height: | Size: 15 KiB  | 
| 
		 After Width: | Height: | Size: 22 KiB  | 
| 
		 After Width: | Height: | Size: 28 KiB  | 
| 
		 After Width: | Height: | Size: 29 KiB  | 
| 
		 Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB  | 
| 
		 Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB  | 
| 
		 Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB  | 
| 
		 Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB  | 
| 
		 Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB  | 
| 
		 Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB  | 
| 
		 Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB  | 
| 
		 Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB  | 
| 
		 Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB  | 
| 
		 Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB  | 
| 
		 Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB  | 
| 
		 Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB  | 
| 
		 Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB  | 
| 
		 Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB  | 
| 
		 Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB  | 
							
								
								
									
										20
									
								
								Source/Common/Defs/DistanceExtension.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,20 @@
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using Verse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace RJW_Genes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Small Extension that covers distances for Genes.
 | 
				
			||||||
 | 
					    /// This allows to set distance in the XMLs. 
 | 
				
			||||||
 | 
					    /// The distance is measured in tiles, so a distance of ~25 means 25 tiles away from the pawn in any direction. 
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public class DistanceExtension : DefModExtension
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public int distance;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										48
									
								
								Source/Common/Defs/ModExtensionHelper.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,48 @@
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using Verse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace RJW_Genes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    internal class ModExtensionHelper
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static int GetDistanceFromModExtension(GeneDef defOf, int fallback)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            DistanceExtension distanceExt = defOf.GetModExtension<DistanceExtension>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int potentialDistance = distanceExt?.distance ?? fallback;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (potentialDistance > 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return potentialDistance;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                ModLog.Warning($"Retrieved a bad distance ({potentialDistance}) reading the RJW_Genes.DistanceExtension for {defOf.defName}");    
 | 
				
			||||||
 | 
					                return 1; 
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static int GetTickIntervalFromModExtension(GeneDef defOf, int fallback)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            TickIntervalExtension tickExt = defOf.GetModExtension<TickIntervalExtension>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int potentialTickInterval = tickExt?.tickInterval ?? fallback;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (potentialTickInterval > 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return potentialTickInterval;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ModLog.Warning($"Retrieved a bad distance ({potentialTickInterval}) reading the RJW_Genes.DistanceExtension for {defOf.defName}");
 | 
				
			||||||
 | 
					                return 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										18
									
								
								Source/Common/Defs/TickIntervalExtension.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,18 @@
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using Verse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace RJW_Genes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// General DefModExtension to cover various genes that need to tick regularly.
 | 
				
			||||||
 | 
					    /// Defining it like this allows to adjust things in XML. 
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public class TickIntervalExtension : DefModExtension
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public int tickInterval;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										28
									
								
								Source/Common/Either.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,28 @@
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace RJW_Genes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class Either<TL, TR>
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public readonly TL left;
 | 
				
			||||||
 | 
					        public readonly TR right;
 | 
				
			||||||
 | 
					        public readonly bool isLeft;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Either(TL left)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this.left = left;
 | 
				
			||||||
 | 
					            this.isLeft = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Either(TR right)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this.right = right;
 | 
				
			||||||
 | 
					            this.isLeft = false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -32,9 +32,10 @@ namespace RJW_Genes
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_extra_anus;
 | 
							public static readonly GeneDef rjw_genes_extra_anus;
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_no_anus;
 | 
							public static readonly GeneDef rjw_genes_no_anus;
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_futa;
 | 
							public static readonly GeneDef rjw_genes_futa;
 | 
				
			||||||
 | 
							public static readonly GeneDef rjw_genes_featureless_chest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Genitalia Sizes
 | 
					        // Genitalia Sizes
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_big_male_genitalia;
 | 
					        public static readonly GeneDef rjw_genes_big_male_genitalia;
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_small_male_genitalia;
 | 
							public static readonly GeneDef rjw_genes_small_male_genitalia;
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_loose_female_genitalia;
 | 
							public static readonly GeneDef rjw_genes_loose_female_genitalia;
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_tight_female_genitalia;
 | 
							public static readonly GeneDef rjw_genes_tight_female_genitalia;
 | 
				
			||||||
| 
						 | 
					@ -42,10 +43,12 @@ namespace RJW_Genes
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_small_breasts;
 | 
							public static readonly GeneDef rjw_genes_small_breasts;
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_loose_anus;
 | 
							public static readonly GeneDef rjw_genes_loose_anus;
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_tight_anus;
 | 
							public static readonly GeneDef rjw_genes_tight_anus;
 | 
				
			||||||
 | 
							public static readonly GeneDef rjw_genes_evergrowth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Gender 
 | 
							// Gender 
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_female_only;
 | 
							public static readonly GeneDef rjw_genes_female_only;
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_male_only;
 | 
							public static readonly GeneDef rjw_genes_male_only;
 | 
				
			||||||
 | 
							public static readonly GeneDef rjw_genes_gender_fluid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Breeding
 | 
							// Breeding
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_mechbreeder;
 | 
							public static readonly GeneDef rjw_genes_mechbreeder;
 | 
				
			||||||
| 
						 | 
					@ -66,6 +69,7 @@ namespace RJW_Genes
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_rapist;
 | 
							public static readonly GeneDef rjw_genes_rapist;
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_homosexual;
 | 
							public static readonly GeneDef rjw_genes_homosexual;
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_bisexual;
 | 
							public static readonly GeneDef rjw_genes_bisexual;
 | 
				
			||||||
 | 
							public static readonly GeneDef rjw_genes_no_sex_need;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Damage & Side Effects 
 | 
							// Damage & Side Effects 
 | 
				
			||||||
		[MayRequire("LustLicentia.RJWLabs")] public static readonly GeneDef rjw_genes_elasticity;
 | 
							[MayRequire("LustLicentia.RJWLabs")] public static readonly GeneDef rjw_genes_elasticity;
 | 
				
			||||||
| 
						 | 
					@ -77,6 +81,7 @@ namespace RJW_Genes
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_sex_age_drain;
 | 
							public static readonly GeneDef rjw_genes_sex_age_drain;
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_aphrodisiac_pheromones;
 | 
							public static readonly GeneDef rjw_genes_aphrodisiac_pheromones;
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_sexual_mytosis;
 | 
							public static readonly GeneDef rjw_genes_sexual_mytosis;
 | 
				
			||||||
 | 
							public static readonly GeneDef rjw_genes_hormonal_saliva;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // LifeForce
 | 
					        // LifeForce
 | 
				
			||||||
        public static readonly GeneDef rjw_genes_lifeforce;
 | 
					        public static readonly GeneDef rjw_genes_lifeforce;
 | 
				
			||||||
| 
						 | 
					@ -88,9 +93,10 @@ namespace RJW_Genes
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_seduce;
 | 
							public static readonly GeneDef rjw_genes_seduce;
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_paralysingkiss;
 | 
							public static readonly GeneDef rjw_genes_paralysingkiss;
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_cockeater;
 | 
							public static readonly GeneDef rjw_genes_cockeater;
 | 
				
			||||||
 | 
							public static readonly GeneDef rjw_genes_lifeforce_empath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Cosmetic
 | 
					        // Cosmetic
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_succubus_tail;
 | 
					        public static readonly GeneDef rjw_genes_succubus_tail;
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_succubus_wings;
 | 
							public static readonly GeneDef rjw_genes_succubus_wings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Hive 
 | 
							// Hive 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										20
									
								
								Source/Genes/Gender/Defs/GenderFluidExtension.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,20 @@
 | 
				
			||||||
 | 
					using Verse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace RJW_Genes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class GenderFluidExtension : DefModExtension
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Number of ticks until the change can be triggered.
 | 
				
			||||||
 | 
					        /// Just being "triggered" does not mean changing, see the changeChance below. 
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        public int changeInterval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// How high is the chance to change gender?
 | 
				
			||||||
 | 
					        /// Set to 1 for "always", set to 0 for "never". 
 | 
				
			||||||
 | 
					        /// Everything else is a bit statistics, but e.g. when set to .5 the chances grow per day from [50%, 75%, 82.25%, ...]
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        public float changeChance;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -31,7 +31,8 @@ namespace RJW_Genes
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Adjusts the Body Type to match the given target gender 
 | 
					        /// Adjusts the Body Type to match the given target gender.
 | 
				
			||||||
 | 
					        /// This is only for "drawing" attributes of the pawn, the genitalia are untouched at this point. 
 | 
				
			||||||
        /// (for male and female only, baby,child and hulks don't change)
 | 
					        /// (for male and female only, baby,child and hulks don't change)
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="pawn"></param>
 | 
					        /// <param name="pawn"></param>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										276
									
								
								Source/Genes/Gender/Gene_GenderFluid.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,276 @@
 | 
				
			||||||
 | 
					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 Verse.AI;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace RJW_Genes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Once per day (or slightly different per configuration) checks if the pawn changes gender. 
 | 
				
			||||||
 | 
					     * At the triggered tick, there is a random chance to change gender. 
 | 
				
			||||||
 | 
					     * This will swap genitalia, appearance and breasts. 
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * For some situations, the pawn better not change genitalia, e.g. while having vaginal sex. This would throw errors.
 | 
				
			||||||
 | 
					     * For these cases a check is implemented, and if there was a block the change happens a bit later when "unblocked". 
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     * TODO: Keep pregnancies. 
 | 
				
			||||||
 | 
					     * The pregnancies remove their things on Tick at the end, which kills it for male pawns.
 | 
				
			||||||
 | 
					     * This seems to be an upstream RJW thing, but needs a bit of investigation.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public class Gene_GenderFluid : RJW_Gene
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //public const int CHANGE_INTERVAL_FALLBACK = 1000; // Test value for Quick Trials
 | 
				
			||||||
 | 
					        const int CHANGE_INTERVAL_FALLBACK = 60000; // 60k == 1 day
 | 
				
			||||||
 | 
					        const float SWITCH_CHANCE_FALLBACK = 0.25f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int change_interval;
 | 
				
			||||||
 | 
					        float switch_chance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        List<Hediff> storedBreasts = new List<Hediff>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private bool sexChangeWasBlocked = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Gene_GenderFluid() : base() {
 | 
				
			||||||
 | 
					            GenderFluidExtension genderFluidExt = GeneDefOf.rjw_genes_gender_fluid.GetModExtension<GenderFluidExtension>();
 | 
				
			||||||
 | 
					            change_interval = genderFluidExt?.changeInterval ?? CHANGE_INTERVAL_FALLBACK;
 | 
				
			||||||
 | 
					            switch_chance = genderFluidExt?.changeChance ?? SWITCH_CHANCE_FALLBACK;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public override void Tick()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            base.Tick();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Case 1: We had a blocked SexChange, now Pawn is free, apply sexchange a bit delayed.
 | 
				
			||||||
 | 
					            if (pawn.IsHashIntervalTick(1500) && sexChangeWasBlocked && !SexChangeBlocked(pawn)){
 | 
				
			||||||
 | 
					                ChangeSex();
 | 
				
			||||||
 | 
					                sexChangeWasBlocked = false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            // Case 2: Check every interval if the Chance triggers
 | 
				
			||||||
 | 
					            else if (pawn.IsHashIntervalTick(change_interval) && (new Random()).NextDouble() < switch_chance)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                // Case 2.A) SexChange was blocked, postpone it
 | 
				
			||||||
 | 
					                if (SexChangeBlocked(pawn))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    sexChangeWasBlocked |= true;
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                } 
 | 
				
			||||||
 | 
					                // Case 2.B) Nothing blocking, change the sex.
 | 
				
			||||||
 | 
					                else { ChangeSex();}
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void ChangeSex()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (rjw.Genital_Helper.is_futa(pawn))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // Handle Futa Pawns - Keep Genitalia as is, just change RW Gender
 | 
				
			||||||
 | 
					                pawn.gender = pawn.gender == Gender.Male? Gender.Female: Gender.Male;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            // Handle Non-Futas - Change Genitalia and Store breasts. 
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (pawn.gender == Gender.Female)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"genderfluid pawn {pawn} is changing from female to male");
 | 
				
			||||||
 | 
					                    SwitchToMale();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else if (pawn.gender == Gender.Male)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"genderfluid pawn {pawn} is changing from male to female");
 | 
				
			||||||
 | 
					                    SwitchToFemale();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            GenderUtility.RemoveAllSexChangeThoughts(pawn);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void SwitchToFemale()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Change Drawing 
 | 
				
			||||||
 | 
					            GenderUtility.AdjustBodyToTargetGender(pawn, Verse.Gender.Female);
 | 
				
			||||||
 | 
					            // Change Gender 
 | 
				
			||||||
 | 
					            pawn.gender = Verse.Gender.Female;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Switch Penisses to Vaginas
 | 
				
			||||||
 | 
					            var genitalsToRemove = pawn.GetGenitalsList().FindAll(g => Genital_Helper.is_penis(g) || Genital_Helper.is_vagina(g));
 | 
				
			||||||
 | 
					            foreach (var genital  in genitalsToRemove)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var genitaliaHediffDef = GenitaliaUtility.GetVaginaForGene(GenitaliaUtility.GetGenitaliaTypeGeneForPawn(pawn));
 | 
				
			||||||
 | 
					                float size = genital.Severity;
 | 
				
			||||||
 | 
					                pawn.health.RemoveHediff(genital);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var newVagina = HediffMaker.MakeHediff(genitaliaHediffDef, pawn, Genital_Helper.get_genitalsBPR(pawn));
 | 
				
			||||||
 | 
					                pawn.health.AddHediff(newVagina);
 | 
				
			||||||
 | 
					                newVagina.Severity = size;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SwitchBreasts();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void SwitchToMale()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Change Drawing 
 | 
				
			||||||
 | 
					            GenderUtility.AdjustBodyToTargetGender(pawn, Verse.Gender.Male);
 | 
				
			||||||
 | 
					            // Change Gender 
 | 
				
			||||||
 | 
					            pawn.gender = Verse.Gender.Male;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Switch Vaginas to Penisses
 | 
				
			||||||
 | 
					            var genitalsToRemove = pawn.GetGenitalsList().FindAll(g => Genital_Helper.is_penis(g) || Genital_Helper.is_vagina(g));
 | 
				
			||||||
 | 
					            foreach (var genital in genitalsToRemove)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var genitaliaHediffDef = GenitaliaUtility.GetPenisForGene(GenitaliaUtility.GetGenitaliaTypeGeneForPawn(pawn));
 | 
				
			||||||
 | 
					                float size = genital.Severity;
 | 
				
			||||||
 | 
					                pawn.health.RemoveHediff(genital);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var newPenis = HediffMaker.MakeHediff(genitaliaHediffDef, pawn, Genital_Helper.get_genitalsBPR(pawn));
 | 
				
			||||||
 | 
					                pawn.health.AddHediff(newPenis);
 | 
				
			||||||
 | 
					                newPenis.Severity = size;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SwitchBreasts();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            RemoveLicentiaVaginaHediffs();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void SwitchBreasts()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            List<Hediff> current_breasts  = pawn.GetBreastList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Stored_Breasts can be empty when the pawn first ever switches gender!
 | 
				
			||||||
 | 
					            if (storedBreasts.NullOrEmpty())
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                foreach (var breasts in current_breasts)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // Is Male, and does not have the "no breast gene"
 | 
				
			||||||
 | 
					                    if (pawn.gender == Gender.Male && !GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_no_breasts))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        storedBreasts.Add(CreateNewBreasts());
 | 
				
			||||||
 | 
					                    } 
 | 
				
			||||||
 | 
					                    else if (pawn.gender == Gender.Female && !GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_featureless_chest) )
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        storedBreasts.Add(CreateNewBreasts());
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach (var breast in current_breasts)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                pawn.health.RemoveHediff(breast);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            foreach (var breast in storedBreasts)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                pawn.health.AddHediff(breast);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            storedBreasts.Clear();
 | 
				
			||||||
 | 
					            storedBreasts.AddRange(current_breasts);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal Hediff CreateNewBreasts()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var correctGene = GenitaliaUtility.GetGenitaliaTypeGeneForPawn(pawn);
 | 
				
			||||||
 | 
					            var breastDef = GenitaliaUtility.GetBreastsForGene(correctGene);
 | 
				
			||||||
 | 
					            var partBPR = Genital_Helper.get_breastsBPR(pawn);
 | 
				
			||||||
 | 
					            var additional_breasts = HediffMaker.MakeHediff(breastDef, pawn,partBPR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var CompHediff = additional_breasts.TryGetComp<rjw.CompHediffBodyPart>();
 | 
				
			||||||
 | 
					            if (CompHediff != null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                CompHediff.initComp(pawn);
 | 
				
			||||||
 | 
					                CompHediff.updatesize();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return additional_breasts;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Checks the pawn if it has any of the vagina-related hediffs (e.g. stretched) and removes them.
 | 
				
			||||||
 | 
					        /// Anal Soreness, Stretching etc. remains. 
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        private void RemoveLicentiaVaginaHediffs()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (ModsConfig.IsActive("LustLicentia.RJWLabs")){
 | 
				
			||||||
 | 
					                    Hediff cumflation = pawn.health.hediffSet.GetFirstHediffOfDef(LicentiaLabs.Licentia.HediffDefs.Cumflation);
 | 
				
			||||||
 | 
					                    if (cumflation != null)
 | 
				
			||||||
 | 
					                        pawn.health.RemoveHediff(cumflation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    Hediff stretched = pawn.health.hediffSet.GetFirstHediffOfDef(LicentiaLabs.Licentia.HediffDefs.Stretched);
 | 
				
			||||||
 | 
					                    if (stretched != null && stretched.Part != Genital_Helper.get_anusBPR(pawn))
 | 
				
			||||||
 | 
					                        pawn.health.RemoveHediff(stretched);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    Hediff torn = pawn.health.hediffSet.GetFirstHediffOfDef(LicentiaLabs.Licentia.HediffDefs.StretchTear);
 | 
				
			||||||
 | 
					                    if (torn != null && torn.Part != Genital_Helper.get_anusBPR(pawn))
 | 
				
			||||||
 | 
					                        pawn.health.RemoveHediff(torn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    Hediff prolapsed = pawn.health.hediffSet.GetFirstHediffOfDef(LicentiaLabs.Licentia.HediffDefs.Prolapse);
 | 
				
			||||||
 | 
					                    if (prolapsed != null && prolapsed.Part != Genital_Helper.get_anusBPR(pawn))
 | 
				
			||||||
 | 
					                        pawn.health.RemoveHediff(prolapsed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    Hediff extremeProlapsed = pawn.health.hediffSet.GetFirstHediffOfDef(LicentiaLabs.Licentia.HediffDefs.ExtremeProlapse);
 | 
				
			||||||
 | 
					                    if (extremeProlapsed != null && extremeProlapsed.Part != Genital_Helper.get_anusBPR(pawn))
 | 
				
			||||||
 | 
					                        pawn.health.RemoveHediff(extremeProlapsed);
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            //TODO: Don't make this an "catch all" Exception!
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // To be expected for people without Licentia Labs, do nothing.
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// There are some actions that block sex change, 
 | 
				
			||||||
 | 
					        /// being drafted or having sex. 
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="pawn">The pawn that want to sexchange.</param>
 | 
				
			||||||
 | 
					        /// <returns>False if the SexChange is applicable, True if there needs to be a wait timer.</returns>
 | 
				
			||||||
 | 
					        internal bool SexChangeBlocked(Pawn pawn)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // DEVNOTE: This list might extend on new cases, thus the explicit method.
 | 
				
			||||||
 | 
					            return pawn == null
 | 
				
			||||||
 | 
					                || pawn.health.Dead
 | 
				
			||||||
 | 
					                || (pawn.jobs.curDriver is JobDriver_Masturbate)
 | 
				
			||||||
 | 
					                || (pawn.jobs.curDriver is JobDriver_Sex)
 | 
				
			||||||
 | 
					                || (pawn.jobs.curDriver is JobDriver_SexBaseReciever)
 | 
				
			||||||
 | 
					                || (pawn.jobs.curDriver is JobDriver_SexBaseInitiator)
 | 
				
			||||||
 | 
					                || (pawn.jobs.curDriver is JobDriver_JoinInBed)
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                || (pawn.jobs.curDriver is JobDriver_SexQuick)
 | 
				
			||||||
 | 
					                || (pawn.jobs.curDriver is JobDriver_SexBaseRecieverQuickie)
 | 
				
			||||||
 | 
					                || (pawn.jobs.curDriver is JobDriver_SexOnSpot)
 | 
				
			||||||
 | 
					                || (pawn.jobs.curDriver is JobDriver_SexOnSpotReciever)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                || (pawn.jobs.curDriver is JobDriver_Knotted)
 | 
				
			||||||
 | 
					                || (pawn.jobs.curDriver is JobDriver_Mate)
 | 
				
			||||||
 | 
					                || (pawn.jobs.curDriver is JobDriver_Mating)
 | 
				
			||||||
 | 
					                || (pawn.jobs.curDriver is JobDriver_Breeding)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                || (pawn.jobs.curDriver is JobDriver_Rape)
 | 
				
			||||||
 | 
					                || (pawn.jobs.curDriver is JobDriver_SexBaseRecieverRaped)
 | 
				
			||||||
 | 
					                || (pawn.jobs.curDriver is JobDriver_RandomRape)
 | 
				
			||||||
 | 
					                || (pawn.jobs.curDriver is JobDriver_RapeComfortPawn)
 | 
				
			||||||
 | 
					                || (pawn.jobs.curDriver is JobDriver_RapeEnemy)
 | 
				
			||||||
 | 
					                || pawn.jobs.curDriver is JobDriver_Lovin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // This is a heavy check, but this is necessary because sometimes the pawns go somewhere to have sex and then they start despite missing genitalia!
 | 
				
			||||||
 | 
					                || (pawn.jobs.curDriver is JobDriver_Goto)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                || pawn.Drafted;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										113
									
								
								Source/Genes/GenitaliaSize/Gene_EvergrowingGenitalia.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,113 @@
 | 
				
			||||||
 | 
					using Verse;
 | 
				
			||||||
 | 
					using Verse;
 | 
				
			||||||
 | 
					using RimWorld;
 | 
				
			||||||
 | 
					using rjw;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace RJW_Genes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class Gene_EvergrowingGenitalia : RJW_Gene
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// The age (in years) at which the Pawns Genes will take effect, resizing their genitalia. 
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        public const int RESIZING_AGE = 20;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //public const int GROWTH_INTERVAL = 1000; // Test value for Quick Trials
 | 
				
			||||||
 | 
					        public const int GROWTH_INTERVAL_FALLBACK = 60000; // 60k == 1 day
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public override void Tick()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            base.Tick();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int interval = ModExtensionHelper.GetTickIntervalFromModExtension(GeneDefOf.rjw_genes_evergrowth, GROWTH_INTERVAL_FALLBACK);
 | 
				
			||||||
 | 
					            if (pawn.IsHashIntervalTick(interval) 
 | 
				
			||||||
 | 
					                && this.pawn.Map != null 
 | 
				
			||||||
 | 
					                && pawn.ageTracker.AgeBiologicalYears >= RESIZING_AGE)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                GrowPenisses();
 | 
				
			||||||
 | 
					                GrowVaginas();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void GrowPenisses()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            List<Hediff> AllPenisses = Genital_Helper.get_AllPartsHediffList(pawn).FindAll(x => Genital_Helper.is_penis(x));
 | 
				
			||||||
 | 
					            foreach(Hediff penis in AllPenisses)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                CompHediffBodyPart CompHediff = penis.TryGetComp<rjw.CompHediffBodyPart>();
 | 
				
			||||||
 | 
					                if (penis.Severity < 1.00)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    penis.Severity = Math.Min(1.01f, penis.Severity + 0.05f);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    if (CompHediff != null)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        CompHediff.SizeOwner += 0.015f;
 | 
				
			||||||
 | 
					                        if (CompHediff.SizeOwner > 3.0f)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            // Add Mental Hediff 
 | 
				
			||||||
 | 
					                            HandleGenitaliaSizeThoughts(pawn);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Increase Fluid
 | 
				
			||||||
 | 
					                if (CompHediff != null)
 | 
				
			||||||
 | 
					                    CompHediff.FluidAmmount *= 1.05f;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void GrowVaginas()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            List<Hediff> AllVaginas = Genital_Helper.get_AllPartsHediffList(pawn).FindAll(x => Genital_Helper.is_vagina(x));
 | 
				
			||||||
 | 
					            foreach (Hediff vagina in AllVaginas)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                CompHediffBodyPart CompHediff = vagina.TryGetComp<rjw.CompHediffBodyPart>();
 | 
				
			||||||
 | 
					                if (vagina.Severity < 1.00)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    vagina.Severity = Math.Min(1.01f, vagina.Severity + 0.05f);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (CompHediff != null)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        CompHediff.SizeOwner += 0.015f;
 | 
				
			||||||
 | 
					                        if (CompHediff.SizeOwner > 3.0f)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            // Add Mental Hediff 
 | 
				
			||||||
 | 
					                            HandleGenitaliaSizeThoughts(pawn);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Increase Fluid
 | 
				
			||||||
 | 
					                if (CompHediff != null)
 | 
				
			||||||
 | 
					                    CompHediff.FluidAmmount *= 1.025f;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void HandleGenitaliaSizeThoughts(Pawn pawn)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Hediff hybridsThoughts = pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.rjw_genes_evergrowth_sideeffect);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (hybridsThoughts != null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                hybridsThoughts.Severity += 0.025f;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                hybridsThoughts = HediffMaker.MakeHediff(HediffDefOf.rjw_genes_evergrowth_sideeffect, pawn);
 | 
				
			||||||
 | 
					                hybridsThoughts.Severity = 0.1f;
 | 
				
			||||||
 | 
					                pawn.health.AddHediff(hybridsThoughts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (!xxx.is_nympho(pawn))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    pawn.story.traits.GainTrait(new Trait(xxx.nymphomaniac));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,5 @@
 | 
				
			||||||
using RimWorld;
 | 
					using RimWorld;
 | 
				
			||||||
 | 
					using rjw;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections;
 | 
					using System.Collections;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
| 
						 | 
					@ -30,9 +31,9 @@ namespace RJW_Genes
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="pawn">The pawn born, that maybe becomes a hive-xenotype.</param>
 | 
					        /// <param name="pawn">The pawn born, that maybe becomes a hive-xenotype.</param>
 | 
				
			||||||
        /// <param name="hasDroneParent">whether there was a drone parent involved</param>
 | 
					        /// <param name="hasDroneParent">whether there was a drone parent involved</param>
 | 
				
			||||||
        public static void ManageHiveBirth(Pawn pawn, bool hasDroneParent = false, XenotypeDef fallbackQueenDef = null, XenotypeDef fallbackDroneDef = null)
 | 
					        public static void ManageHiveBirth(Pawn pawn, bool hasDroneParent = false, Either<XenotypeDef, CustomXenotype> fallbackQueenDef = null, Either<XenotypeDef, CustomXenotype> fallbackDroneDef = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            XenotypeDef queenDef = TryFindParentQueenXenotype(pawn);
 | 
					            Either<XenotypeDef,CustomXenotype> queenDef = TryFindParentQueenXenotype(pawn);
 | 
				
			||||||
            if (queenDef == null) queenDef = fallbackQueenDef;
 | 
					            if (queenDef == null) queenDef = fallbackQueenDef;
 | 
				
			||||||
            HiveOffspringChanceDef hiveOffspringChanceDef = HiveUtility.LookupHiveInheritanceChances(queenDef);
 | 
					            HiveOffspringChanceDef hiveOffspringChanceDef = HiveUtility.LookupHiveInheritanceChances(queenDef);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,17 +50,15 @@ namespace RJW_Genes
 | 
				
			||||||
                // Case 2.a: New Queen born
 | 
					                // Case 2.a: New Queen born
 | 
				
			||||||
                if (roll < hiveOffspringChanceDef.queenChance)
 | 
					                if (roll < hiveOffspringChanceDef.queenChance)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    pawn.genes.SetXenotype(queenDef);
 | 
					                    MakeQueen(pawn, queenDef);
 | 
				
			||||||
                    if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"{pawn} born as a new queen with xenotype {queenDef.defName} ({hiveOffspringChanceDef.queenChance * 100}% chance,rolled {roll})");
 | 
					                    if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"Queen Chance: {hiveOffspringChanceDef.queenChance * 100}% chance,rolled { roll}");
 | 
				
			||||||
                    MakeQueenBornLetter(pawn);
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                // Case 2.b: New Drone born
 | 
					                // Case 2.b: New Drone born
 | 
				
			||||||
                else if (roll < hiveOffspringChanceDef.droneChance + hiveOffspringChanceDef.queenChance)
 | 
					                else if (roll < hiveOffspringChanceDef.droneChance + hiveOffspringChanceDef.queenChance)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    XenotypeDef droneDef = TryFindParentDroneXenotype(pawn);
 | 
					                    var droneDef = TryFindParentDroneXenotype(pawn); 
 | 
				
			||||||
                    if (droneDef == null) droneDef = fallbackDroneDef;
 | 
					                    MakeDrone(pawn,droneDef);
 | 
				
			||||||
                    pawn.genes.SetXenotype(droneDef);
 | 
					                    if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"Drone Chance ({(hiveOffspringChanceDef.droneChance + hiveOffspringChanceDef.queenChance) * 100}% chance,rolled {roll}))");
 | 
				
			||||||
                    if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"{pawn} born as a new drone with xenotype {droneDef.defName} ({(hiveOffspringChanceDef.droneChance + hiveOffspringChanceDef.queenChance) * 100}% chance,rolled {roll}))");
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                // Case 2.c: Worker
 | 
					                // Case 2.c: Worker
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
| 
						 | 
					@ -70,6 +69,52 @@ namespace RJW_Genes
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static void MakeQueen(Pawn pawnToBeQueen, Either<XenotypeDef,CustomXenotype> queenDef) {
 | 
				
			||||||
 | 
					            if (queenDef == null && pawnToBeQueen == null)
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            if (queenDef.isLeft) {
 | 
				
			||||||
 | 
					                var xenotype = queenDef.left;
 | 
				
			||||||
 | 
					                pawnToBeQueen.genes.SetXenotype(xenotype);
 | 
				
			||||||
 | 
					                if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"{pawnToBeQueen} born as a new queen with Xenotype {xenotype.defName}");
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                var customXenotype = queenDef.right;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                foreach (var gene in customXenotype.genes)
 | 
				
			||||||
 | 
					                    pawnToBeQueen.genes.AddGene(gene, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                pawnToBeQueen.genes.xenotypeName = customXenotype.name;
 | 
				
			||||||
 | 
					                pawnToBeQueen.genes.iconDef = customXenotype.iconDef;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"{pawnToBeQueen} born as a new queen with custom Xenotype {customXenotype.name}");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            MakeQueenBornLetter(pawnToBeQueen);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static void MakeDrone(Pawn pawnToBeDrone, Either<XenotypeDef, CustomXenotype> droneDef)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (droneDef == null && pawnToBeDrone == null)
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            if (droneDef.isLeft)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var xenotype = droneDef.left;
 | 
				
			||||||
 | 
					                pawnToBeDrone.genes.SetXenotype(xenotype);
 | 
				
			||||||
 | 
					                if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"{pawnToBeDrone} born as a new drone with Xenotype {xenotype.defName}");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var customXenotype = droneDef.right;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                foreach (var gene in customXenotype.genes)
 | 
				
			||||||
 | 
					                    pawnToBeDrone.genes.AddGene(gene, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                pawnToBeDrone.genes.xenotypeName = customXenotype.name;
 | 
				
			||||||
 | 
					                pawnToBeDrone.genes.iconDef = customXenotype.iconDef;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"{pawnToBeDrone} born as a new drone with custom Xenotype {customXenotype.name}");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Turns a given pawn into a worker, by looking up the relevant genes as per queen.
 | 
					        /// Turns a given pawn into a worker, by looking up the relevant genes as per queen.
 | 
				
			||||||
| 
						 | 
					@ -79,14 +124,19 @@ namespace RJW_Genes
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="pawnTobeWorker">The pawn for which the genes are added.</param>
 | 
					        /// <param name="pawnTobeWorker">The pawn for which the genes are added.</param>
 | 
				
			||||||
        /// <param name="queenDef">The xenotype of the queen, used for lookup.</param>
 | 
					        /// <param name="queenDef">The xenotype of the queen, used for lookup.</param>
 | 
				
			||||||
        private static void MakeWorker(Pawn pawnTobeWorker, XenotypeDef queenDef)
 | 
					        private static void MakeWorker(Pawn pawnTobeWorker, Either<XenotypeDef, CustomXenotype> queenDef)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (pawnTobeWorker == null)
 | 
					            if (pawnTobeWorker == null)
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var mappings = HiveUtility.GetQueenWorkerMappings();
 | 
					            var mappings = HiveUtility.GetQueenWorkerMappings();
 | 
				
			||||||
 | 
					            String queenDefName = HiveUtility.GetXenotypeDefName(queenDef);
 | 
				
			||||||
 | 
					            if (queenDef == null || mappings.NullOrEmpty())
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var genes = mappings.TryGetValue(queenDef, HiveUtility.LookupDefaultWorkerGenes());
 | 
					            var genes = mappings.TryGetValue(queenDefName, HiveUtility.LookupDefaultWorkerGenes());
 | 
				
			||||||
 | 
					            if (genes == null)
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (var gene in genes)
 | 
					            foreach (var gene in genes)
 | 
				
			||||||
                pawnTobeWorker.genes.AddGene(gene, false);
 | 
					                pawnTobeWorker.genes.AddGene(gene, false);
 | 
				
			||||||
| 
						 | 
					@ -101,7 +151,7 @@ namespace RJW_Genes
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="pawn">The pawn for whichs parent the xenotypes is looked up.</param>
 | 
					        /// <param name="pawn">The pawn for whichs parent the xenotypes is looked up.</param>
 | 
				
			||||||
        /// <returns>The Drone-Xenotype of a parent or null. If both are drones, mothers are preferred.</returns>
 | 
					        /// <returns>The Drone-Xenotype of a parent or null. If both are drones, mothers are preferred.</returns>
 | 
				
			||||||
        public static XenotypeDef TryFindParentDroneXenotype(Pawn pawn)
 | 
					        public static Either<XenotypeDef,CustomXenotype> TryFindParentDroneXenotype(Pawn pawn)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (pawn == null)
 | 
					            if (pawn == null)
 | 
				
			||||||
                return null;
 | 
					                return null;
 | 
				
			||||||
| 
						 | 
					@ -109,7 +159,7 @@ namespace RJW_Genes
 | 
				
			||||||
            List<DirectPawnRelation> parentRelations = pawn.relations.DirectRelations.FindAll(rel => rel.def.Equals(PawnRelationDefOf.Parent));
 | 
					            List<DirectPawnRelation> parentRelations = pawn.relations.DirectRelations.FindAll(rel => rel.def.Equals(PawnRelationDefOf.Parent));
 | 
				
			||||||
            foreach (DirectPawnRelation parent in parentRelations)
 | 
					            foreach (DirectPawnRelation parent in parentRelations)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                XenotypeDef xenotype = HiveUtility.TryGetDroneXenotype(parent.otherPawn);
 | 
					                var xenotype = HiveUtility.TryGetDroneXenotype(parent.otherPawn);
 | 
				
			||||||
                if (xenotype != null) return xenotype;
 | 
					                if (xenotype != null) return xenotype;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -120,10 +170,10 @@ namespace RJW_Genes
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (bornQueen == null) return;
 | 
					            if (bornQueen == null) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var letter= LetterMaker.MakeLetter(
 | 
					            var letter = LetterMaker.MakeLetter(
 | 
				
			||||||
                "New Queen", "A new Queen was born! Make sure to adress inheritance before the new queen reaches adolesence.", LetterDefOf.NeutralEvent, bornQueen
 | 
					                "rjw_genes_queenbirth_letter_label".Translate(),
 | 
				
			||||||
                );
 | 
					                string.Format("rjw_genes_queenbirth_letter_description".Translate(), xxx.get_pawnname(bornQueen)),
 | 
				
			||||||
            //letter.Start();
 | 
					                LetterDefOf.NeutralEvent, bornQueen);
 | 
				
			||||||
            Find.LetterStack.ReceiveLetter(letter); 
 | 
					            Find.LetterStack.ReceiveLetter(letter); 
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -134,7 +184,7 @@ namespace RJW_Genes
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="pawn">The pawn for whichs parent the xenotypes is looked up.</param>
 | 
					        /// <param name="pawn">The pawn for whichs parent the xenotypes is looked up.</param>
 | 
				
			||||||
        /// <returns>The Queen-Xenotype of a parent or null. If both are queens, mothers are preferred.</returns>
 | 
					        /// <returns>The Queen-Xenotype of a parent or null. If both are queens, mothers are preferred.</returns>
 | 
				
			||||||
        public static XenotypeDef TryFindParentQueenXenotype(Pawn pawn)
 | 
					        public static Either<XenotypeDef,CustomXenotype> TryFindParentQueenXenotype(Pawn pawn)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (pawn == null)
 | 
					            if (pawn == null)
 | 
				
			||||||
                return null;
 | 
					                return null;
 | 
				
			||||||
| 
						 | 
					@ -142,7 +192,7 @@ namespace RJW_Genes
 | 
				
			||||||
            List<DirectPawnRelation> parentRelations = pawn.relations.DirectRelations.FindAll(rel => rel.def.Equals(PawnRelationDefOf.Parent));
 | 
					            List<DirectPawnRelation> parentRelations = pawn.relations.DirectRelations.FindAll(rel => rel.def.Equals(PawnRelationDefOf.Parent));
 | 
				
			||||||
            foreach (var parent in parentRelations)
 | 
					            foreach (var parent in parentRelations)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                XenotypeDef xenotype = HiveUtility.TryGetQueenXenotype(parent.otherPawn);
 | 
					                var xenotype = HiveUtility.TryGetQueenXenotype(parent.otherPawn);
 | 
				
			||||||
                if (xenotype != null) return xenotype;
 | 
					                if (xenotype != null) return xenotype;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,6 +61,9 @@ namespace RJW_Genes
 | 
				
			||||||
        /// <returns>True if the pawn is on the home-map, False otherwise.</returns>
 | 
					        /// <returns>True if the pawn is on the home-map, False otherwise.</returns>
 | 
				
			||||||
        public static bool PawnIsOnHomeMap(Pawn pawn)
 | 
					        public static bool PawnIsOnHomeMap(Pawn pawn)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            if  (Find.Maps.NullOrEmpty() || !Find.Maps.Where(mapCandidate => mapCandidate.IsPlayerHome).Any()) { 
 | 
				
			||||||
 | 
					                return false; 
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            Map homeMap = Find.Maps.Where(mapCandidate => mapCandidate.IsPlayerHome).First();
 | 
					            Map homeMap = Find.Maps.Where(mapCandidate => mapCandidate.IsPlayerHome).First();
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
                homeMap != null && pawn != null
 | 
					                homeMap != null && pawn != null
 | 
				
			||||||
| 
						 | 
					@ -74,7 +77,7 @@ namespace RJW_Genes
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="pawn"></param>
 | 
					        /// <param name="pawn"></param>
 | 
				
			||||||
        /// <returns>A xenotype with a queen gene, or null.</returns>
 | 
					        /// <returns>A xenotype with a queen gene, or null.</returns>
 | 
				
			||||||
        public static XenotypeDef TryGetQueenXenotype(Pawn pawn)
 | 
					        public static Either<XenotypeDef,CustomXenotype> TryGetQueenXenotype(Pawn pawn)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (pawn == null)
 | 
					            if (pawn == null)
 | 
				
			||||||
                return null; 
 | 
					                return null; 
 | 
				
			||||||
| 
						 | 
					@ -84,8 +87,15 @@ namespace RJW_Genes
 | 
				
			||||||
                var potentialXenotype = pawn.genes.Xenotype;
 | 
					                var potentialXenotype = pawn.genes.Xenotype;
 | 
				
			||||||
                if (potentialXenotype != null && potentialXenotype.genes.Contains(GeneDefOf.rjw_genes_queen))
 | 
					                if (potentialXenotype != null && potentialXenotype.genes.Contains(GeneDefOf.rjw_genes_queen))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    return potentialXenotype;
 | 
					                    return new Either<XenotypeDef,CustomXenotype>(potentialXenotype);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var potentialCustomXenotype = pawn.genes.CustomXenotype;
 | 
				
			||||||
 | 
					                if (potentialCustomXenotype != null && potentialCustomXenotype.genes.Contains(GeneDefOf.rjw_genes_queen))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return new Either<XenotypeDef, CustomXenotype>(potentialCustomXenotype);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return null;
 | 
					            return null;
 | 
				
			||||||
| 
						 | 
					@ -98,7 +108,7 @@ namespace RJW_Genes
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="pawn"></param>
 | 
					        /// <param name="pawn"></param>
 | 
				
			||||||
        /// <returns>A xenotype with a drone gene, or null.</returns>
 | 
					        /// <returns>A xenotype with a drone gene, or null.</returns>
 | 
				
			||||||
        public static XenotypeDef TryGetDroneXenotype(Pawn pawn)
 | 
					        public static Either<XenotypeDef,CustomXenotype> TryGetDroneXenotype(Pawn pawn)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (pawn == null)
 | 
					            if (pawn == null)
 | 
				
			||||||
                return null;
 | 
					                return null;
 | 
				
			||||||
| 
						 | 
					@ -108,7 +118,13 @@ namespace RJW_Genes
 | 
				
			||||||
                var potentialXenotype = pawn.genes.Xenotype;
 | 
					                var potentialXenotype = pawn.genes.Xenotype;
 | 
				
			||||||
                if (potentialXenotype != null && potentialXenotype.genes.Contains(GeneDefOf.rjw_genes_drone))
 | 
					                if (potentialXenotype != null && potentialXenotype.genes.Contains(GeneDefOf.rjw_genes_drone))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    return potentialXenotype;
 | 
					                    return new Either<XenotypeDef,CustomXenotype>(potentialXenotype);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var potentialCustomXenotype = pawn.genes.CustomXenotype;
 | 
				
			||||||
 | 
					                if (potentialCustomXenotype != null && potentialCustomXenotype.genes.Contains(GeneDefOf.rjw_genes_drone))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return new Either<XenotypeDef, CustomXenotype>(potentialCustomXenotype);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -122,23 +138,35 @@ namespace RJW_Genes
 | 
				
			||||||
        /// Prints a bigger piece of information when debug printing is enabled. 
 | 
					        /// Prints a bigger piece of information when debug printing is enabled. 
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <returns>A mapping which Queen-Xenotypes should produce which worker genes.</returns>
 | 
					        /// <returns>A mapping which Queen-Xenotypes should produce which worker genes.</returns>
 | 
				
			||||||
 | 
					        public static Dictionary<String,List<GeneDef>> GetQueenWorkerMappings()
 | 
				
			||||||
        public static Dictionary<XenotypeDef,List<GeneDef>> GetQueenWorkerMappings()
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Dictionary<XenotypeDef,List<GeneDef>> dict = new Dictionary<XenotypeDef, List<GeneDef>>();
 | 
					 | 
				
			||||||
            IEnumerable<QueenWorkerMappingDef> mappingDefs = DefDatabase<QueenWorkerMappingDef>.AllDefs;
 | 
					            IEnumerable<QueenWorkerMappingDef> mappingDefs = DefDatabase<QueenWorkerMappingDef>.AllDefs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Dictionary<string, List<GeneDef>> results = new Dictionary<string, List<GeneDef>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Dev-Note: I first a nice lambda here, but I used nesting in favour of logging.
 | 
					            // Dev-Note: I first a nice lambda here, but I used nesting in favour of logging.
 | 
				
			||||||
            foreach (QueenWorkerMappingDef mappingDef in mappingDefs)
 | 
					            foreach (QueenWorkerMappingDef mappingDef in mappingDefs)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
               
 | 
					                // Option A) This is the default worker genes, expected, just ignore.
 | 
				
			||||||
                if (mappingDef.defName == "rjw_genes_default_worker_genes")
 | 
					                if (mappingDef.defName == "rjw_genes_default_worker_genes")
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    // Do nothing, there is no lookup but this entry is fine and should not log a warning. 
 | 
					                    // Do nothing, there is no lookup but this entry is fine and should not log a warning. 
 | 
				
			||||||
                    continue;
 | 
					                    continue;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                // Option B) The Xenotype is a "static" Xenotype, from a mod or something.
 | 
				
			||||||
                XenotypeDef queenDef = DefDatabase<XenotypeDef>.GetNamed(mappingDef.queenXenotype);
 | 
					                XenotypeDef queenDef = DefDatabase<XenotypeDef>.GetNamed(mappingDef.queenXenotype);
 | 
				
			||||||
 | 
					                string defName = null;
 | 
				
			||||||
                if (queenDef != null)
 | 
					                if (queenDef != null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    defName = queenDef.defName;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else if (Current.Game != null && Current.Game.customXenotypeDatabase != null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // Option C) The Xenotype is a Custom Xenotype, created by the player
 | 
				
			||||||
 | 
					                    CustomXenotype customQueenDef = Current.Game.customXenotypeDatabase.customXenotypes.Find(f => f.name == mappingDef.defName);
 | 
				
			||||||
 | 
					                    defName = customQueenDef?.name;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (defName != null)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    List<GeneDef> workerGenes = new List<GeneDef>();
 | 
					                    List<GeneDef> workerGenes = new List<GeneDef>();
 | 
				
			||||||
                    foreach (string geneName in mappingDef.workerGenes)
 | 
					                    foreach (string geneName in mappingDef.workerGenes)
 | 
				
			||||||
| 
						 | 
					@ -149,15 +177,17 @@ namespace RJW_Genes
 | 
				
			||||||
                        else if(RJW_Genes_Settings.rjw_genes_detailed_debug)
 | 
					                        else if(RJW_Genes_Settings.rjw_genes_detailed_debug)
 | 
				
			||||||
                            ModLog.Warning($"Could not look up Gene {geneName} for {mappingDef.queenXenotype}.");
 | 
					                            ModLog.Warning($"Could not look up Gene {geneName} for {mappingDef.queenXenotype}.");
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    dict.Add(queenDef, workerGenes);
 | 
					                    results.Add(defName, workerGenes);
 | 
				
			||||||
                }
 | 
					                    continue;
 | 
				
			||||||
                else {
 | 
					 | 
				
			||||||
                    if (RJW_Genes_Settings.rjw_genes_detailed_debug) 
 | 
					 | 
				
			||||||
                        ModLog.Warning($"Did not find a matching xenotype for {mappingDef.queenXenotype}! Defaulting to rjw_genes_default_worker_genes.");
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Option D) Fallback, unknown
 | 
				
			||||||
 | 
					                if (RJW_Genes_Settings.rjw_genes_detailed_debug) 
 | 
				
			||||||
 | 
					                    ModLog.Warning($"Did not find a matching xenotype for {mappingDef.queenXenotype}! Defaulting to rjw_genes_default_worker_genes.");
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return dict;
 | 
					            return results;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					@ -203,6 +233,16 @@ namespace RJW_Genes
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static String GetXenotypeDefName(Either<XenotypeDef, CustomXenotype> def)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (def == null)
 | 
				
			||||||
 | 
					                return null;
 | 
				
			||||||
 | 
					            else if (def.isLeft)
 | 
				
			||||||
 | 
					                return def.left.defName;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                return def.right.name;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static HiveOffspringChanceDef LookupDefaultHiveInheritanceChances()
 | 
					        public static HiveOffspringChanceDef LookupDefaultHiveInheritanceChances()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            IEnumerable<HiveOffspringChanceDef> offspringChanceDefs = DefDatabase<HiveOffspringChanceDef>.AllDefs;
 | 
					            IEnumerable<HiveOffspringChanceDef> offspringChanceDefs = DefDatabase<HiveOffspringChanceDef>.AllDefs;
 | 
				
			||||||
| 
						 | 
					@ -217,11 +257,16 @@ namespace RJW_Genes
 | 
				
			||||||
            return defaultChance;
 | 
					            return defaultChance;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static HiveOffspringChanceDef LookupHiveInheritanceChances(XenotypeDef queenDef)
 | 
					        public static HiveOffspringChanceDef LookupHiveInheritanceChances(Either<XenotypeDef, CustomXenotype> queenDef)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            if (queenDef == null)
 | 
				
			||||||
 | 
					                return LookupDefaultHiveInheritanceChances();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            String queenDefName = queenDef.isLeft ? queenDef.left.defName : queenDef.right.name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            IEnumerable<HiveOffspringChanceDef> offspringChanceDefs = DefDatabase<HiveOffspringChanceDef>.AllDefs;
 | 
					            IEnumerable<HiveOffspringChanceDef> offspringChanceDefs = DefDatabase<HiveOffspringChanceDef>.AllDefs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return offspringChanceDefs.FirstOrFallback(t => t.queenXenotype == queenDef.defName, LookupDefaultHiveInheritanceChances());
 | 
					            return offspringChanceDefs.FirstOrFallback(t => t.queenXenotype == queenDefName, LookupDefaultHiveInheritanceChances());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,8 +34,8 @@ namespace RJW_Genes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Pawn pawn = (Pawn)__result;
 | 
					            Pawn pawn = (Pawn)__result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            XenotypeDef queenDef = HiveBirthLogic.TryFindParentQueenXenotype(pawn) ?? TryFindParentQueenXenotypeFromEgg(__instance);
 | 
					            Either<XenotypeDef,CustomXenotype> queenDef = HiveBirthLogic.TryFindParentQueenXenotype(pawn) ?? TryFindParentQueenXenotypeFromEgg(__instance);
 | 
				
			||||||
            XenotypeDef droneDef = HiveBirthLogic.TryFindParentDroneXenotype(pawn) ?? TryFindParentDroneXenotypeFromEgg(__instance);
 | 
					            Either<XenotypeDef, CustomXenotype> droneDef = HiveBirthLogic.TryFindParentDroneXenotype(pawn) ?? TryFindParentDroneXenotypeFromEgg(__instance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            bool hasQueenParent = queenDef != null;
 | 
					            bool hasQueenParent = queenDef != null;
 | 
				
			||||||
            bool hasDroneParent = droneDef != null;
 | 
					            bool hasDroneParent = droneDef != null;
 | 
				
			||||||
| 
						 | 
					@ -47,6 +47,15 @@ namespace RJW_Genes
 | 
				
			||||||
            } else
 | 
					            } else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"Ignoring Postfix Hediff_InsectEgg::ProcessHumanLikeInsectEgg - No Queen Parent - No Action.");
 | 
					                if (RJW_Genes_Settings.rjw_genes_detailed_debug) ModLog.Message($"Ignoring Postfix Hediff_InsectEgg::ProcessHumanLikeInsectEgg - No Queen Parent - No Action.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Extra Debug for #56
 | 
				
			||||||
 | 
					                if (RJW_Genes_Settings.rjw_genes_detailed_debug)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    ModLog.Message($"Implanter was: ({__instance.implanter.genes.xenotypeName}|{__instance.implanter.genes.Xenotype}), Fertilizer was: ({__instance.father.genes.xenotypeName}|{__instance.father.genes.Xenotype})");
 | 
				
			||||||
 | 
					                    ModLog.Message($"Implanter Xenotype From helper: {HiveUtility.TryGetQueenXenotype(__instance.implanter)} and has Queen {__instance.implanter.genes.HasGene(GeneDefOf.rjw_genes_queen)}");
 | 
				
			||||||
 | 
					                    ModLog.Message($"Father Xenotype From helper: {HiveUtility.TryGetDroneXenotype(__instance.implanter)} and has Drone {__instance.father.genes.HasGene(GeneDefOf.rjw_genes_drone)}");
 | 
				
			||||||
 | 
					                    CustomXenotype custom = __instance.implanter.genes.CustomXenotype;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,9 +68,9 @@ namespace RJW_Genes
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="egg">An Egg for which queens are looked up for</param>
 | 
					        /// <param name="egg">An Egg for which queens are looked up for</param>
 | 
				
			||||||
        /// <returns>The relevant xenotypedef of a queen, or null.</returns>
 | 
					        /// <returns>The relevant xenotypedef of a queen, or null.</returns>
 | 
				
			||||||
        public static XenotypeDef TryFindParentQueenXenotypeFromEgg(Hediff_InsectEgg egg)
 | 
					        public static Either<XenotypeDef, CustomXenotype> TryFindParentQueenXenotypeFromEgg(Hediff_InsectEgg egg)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            XenotypeDef queenDef = null;
 | 
					            Either<XenotypeDef, CustomXenotype> queenDef = null;
 | 
				
			||||||
            if (egg == null)
 | 
					            if (egg == null)
 | 
				
			||||||
                return null;
 | 
					                return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -85,9 +94,9 @@ namespace RJW_Genes
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="egg">An Egg for which drones are looked up for</param>
 | 
					        /// <param name="egg">An Egg for which drones are looked up for</param>
 | 
				
			||||||
        /// <returns>The relevant xenotypedef of a drone, or null.</returns>
 | 
					        /// <returns>The relevant xenotypedef of a drone, or null.</returns>
 | 
				
			||||||
        public static XenotypeDef TryFindParentDroneXenotypeFromEgg(Hediff_InsectEgg egg)
 | 
					        public static Either<XenotypeDef, CustomXenotype> TryFindParentDroneXenotypeFromEgg(Hediff_InsectEgg egg)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            XenotypeDef droneDef = null;
 | 
					            Either<XenotypeDef, CustomXenotype> droneDef = null;
 | 
				
			||||||
            if (egg == null)
 | 
					            if (egg == null)
 | 
				
			||||||
                return null;
 | 
					                return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										16
									
								
								Source/Genes/Life_Force/Defs/LifeForceEmpathExtension.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,16 @@
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using Verse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace RJW_Genes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class LifeForceEmpathExtension : DefModExtension
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public float aheagoIncrement;
 | 
				
			||||||
 | 
					        public float satisfactionIncrement;
 | 
				
			||||||
 | 
					        public float frustratedDecrement;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -85,7 +85,7 @@ namespace RJW_Genes
 | 
				
			||||||
                if(colonyJoiners.Contains(pawn))
 | 
					                if(colonyJoiners.Contains(pawn))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    RecruitUtility.Recruit(pawn, Faction.OfPlayer);
 | 
					                    RecruitUtility.Recruit(pawn, Faction.OfPlayer);
 | 
				
			||||||
                    Find.LetterStack.ReceiveLetter("Guest Joins", string.Format("{0} enjoys it here and has decided to stay", xxx.get_pawnname(pawn)), LetterDefOf.PositiveEvent, pawn, null, null, null, null);
 | 
					                    Find.LetterStack.ReceiveLetter("rjw_genes_succubus_joins_letter_label".Translate(), string.Format("rjw_genes_succubus_joins_letter_description".Translate(), xxx.get_pawnname(pawn)), LetterDefOf.PositiveEvent, pawn, null, null, null, null);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										118
									
								
								Source/Genes/Life_Force/Genes/Gene_LifeForce_Empath.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,118 @@
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using Verse;
 | 
				
			||||||
 | 
					using RimWorld;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace RJW_Genes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class Gene_LifeForce_Empath : Gene
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const int EMPATH_DISTANCE_FALLBACK = 25;
 | 
				
			||||||
 | 
					        const int TICK_INTERVAL_FALLBACK = 60000 / 48;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const float AHEAGO_FALLBACK = 0.02f, SATISFIED_FALLBACK = 0.01f, FRUSTRATED_FALLBACK = -0.01f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int empathDistance = 25;
 | 
				
			||||||
 | 
					        int tickInterval = 60000 / 48 ; // 60k = 1 day, we want 0.5h which is 1/48th of 1 day. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        float aheagoIncrement = 0.02f;
 | 
				
			||||||
 | 
					        float satisfiedIncrement = 0.01f;
 | 
				
			||||||
 | 
					        float frustratedDecrement = -0.01f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Gene_LifeForce_Empath() : base()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SetValuesFromExtension();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void SetValuesFromExtension()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            LifeForceEmpathExtension empathExt = GeneDefOf.rjw_genes_lifeforce_empath.GetModExtension<LifeForceEmpathExtension>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            tickInterval =  ModExtensionHelper.GetTickIntervalFromModExtension(GeneDefOf.rjw_genes_lifeforce_empath, TICK_INTERVAL_FALLBACK);
 | 
				
			||||||
 | 
					            empathDistance = ModExtensionHelper.GetTickIntervalFromModExtension(GeneDefOf.rjw_genes_lifeforce_empath, EMPATH_DISTANCE_FALLBACK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            aheagoIncrement = empathExt?.aheagoIncrement ?? AHEAGO_FALLBACK;
 | 
				
			||||||
 | 
					            satisfiedIncrement = empathExt?.satisfactionIncrement ?? SATISFIED_FALLBACK;
 | 
				
			||||||
 | 
					            frustratedDecrement = empathExt?.frustratedDecrement ?? FRUSTRATED_FALLBACK;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public override void Tick()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            base.Tick();
 | 
				
			||||||
 | 
					            if (this.pawn.IsHashIntervalTick(tickInterval) && this.pawn.Map != null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                foreach (Pawn pawn in this.AffectedPawns(this.pawn.Position, this.pawn.Map))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    this.FarmLifeForce(pawn);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                        
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Creates an IEnumerable of all pawns which are closeby and in lineofsight, self and other pawns with lifeforce gene are skipped (to prevent loops).
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="pos">The position of the empath on the map</param>
 | 
				
			||||||
 | 
					        /// <param name="map">The map the empath is on</param>
 | 
				
			||||||
 | 
					        /// <returns>A list of all pawns that are close enough for the empath to connect.</returns>
 | 
				
			||||||
 | 
					        private IEnumerable<Pawn> AffectedPawns(IntVec3 pos, Map map)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            foreach (Pawn pawn in map.mapPawns.AllPawns)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // Return for trivial errors
 | 
				
			||||||
 | 
					                if (pawn == null || this.pawn == null || pawn == this.pawn)
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					                // Check for position-existance
 | 
				
			||||||
 | 
					                if (pawn.Position == null || pos == null || pawn.Map == null)
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					                // Do nothing if pawn is carried 
 | 
				
			||||||
 | 
					                if (pawn.CarriedBy != null)
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					                // Do nothing if Pawn is Baby or Child (#25)
 | 
				
			||||||
 | 
					                if (!pawn.ageTracker.Adult)
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					                // Do nothing for pawns that also have lifeforce
 | 
				
			||||||
 | 
					                if (GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_lifeforce))
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Actual Logic: 
 | 
				
			||||||
 | 
					                // Pawn qualifies in right distance and needs line of sight. 
 | 
				
			||||||
 | 
					                if (pos.DistanceTo(pawn.Position) < empathDistance && GenSight.LineOfSight(pos, pawn.Position, pawn.Map))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    yield return pawn;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            yield break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Adjust the empaths lifeforce depending on the farmed pawns sexneed. 
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="farmedPawn">The pawn affecting the empath, increasing or decreasing his lifeforce. </param>
 | 
				
			||||||
 | 
					        private void FarmLifeForce(Pawn farmedPawn)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Short rename to make rest more obvious.
 | 
				
			||||||
 | 
					            Pawn empath = pawn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (farmedPawn == null)
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var sexneed = farmedPawn.needs.TryGetNeed<rjw.Need_Sex>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Shortwire: do nothing on no sexneed.
 | 
				
			||||||
 | 
					            if (sexneed == null)
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (sexneed.CurLevel >= sexneed.thresh_ahegao())
 | 
				
			||||||
 | 
					                GeneUtility.OffsetLifeForce(GeneUtility.GetLifeForceGene(empath), aheagoIncrement);
 | 
				
			||||||
 | 
					            else if (sexneed.CurLevel >= sexneed.thresh_satisfied())
 | 
				
			||||||
 | 
					                GeneUtility.OffsetLifeForce(GeneUtility.GetLifeForceGene(empath), satisfiedIncrement);
 | 
				
			||||||
 | 
					            else if (sexneed.CurLevel <= sexneed.thresh_frustrated())
 | 
				
			||||||
 | 
					                GeneUtility.OffsetLifeForce(GeneUtility.GetLifeForceGene(empath), frustratedDecrement);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										28
									
								
								Source/Genes/Special/Defs/HormonalSalivaExtension.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,28 @@
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using Verse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace RJW_Genes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class HormonalSalivaExtension : DefModExtension
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// How much the genitalia will growth per interaction.
 | 
				
			||||||
 | 
					        /// This is applied "flat", so if you have penis 0.5 and growthRate 0.05 it goes to 0.55, 0.60, 0.65 etc. 
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        public float sizeIncrement;
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Upper Limit for the body size - default should be 2-3
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        public float maxBodySize;
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// How much more cum the pawn will make.
 | 
				
			||||||
 | 
					        /// This is applied as multiplication, so if you have cum 20 and multiplier 1.1 you will have 22,24,27 etc. 
 | 
				
			||||||
 | 
					        /// This leads to exponential growth, so try to keep it kinda low. 
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        public float cumMultiplier;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -11,8 +11,8 @@ namespace RJW_Genes
 | 
				
			||||||
        // This means that adding +.25 equals 1.5h of Libido. 
 | 
					        // This means that adding +.25 equals 1.5h of Libido. 
 | 
				
			||||||
        // Tick Speed is hence set to 0.5h 
 | 
					        // Tick Speed is hence set to 0.5h 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const int APHRODISIAC_DISTANCE = 25;
 | 
					        const int APHRODISIAC_DISTANCE_FALLBACK = 25;
 | 
				
			||||||
        const int TICK_INTERVAL = 60000 / 48 ; // 60k = 1 day, we want 0.5h which is 1/48th of 1 day. 
 | 
					        const int TICK_INTERVAL_FALLBACK = 60000 / 48 ; // 60k = 1 day, we want 0.5h which is 1/48th of 1 day. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const float SEXFREQ_THRESHOLD = 0.5f;
 | 
					        const float SEXFREQ_THRESHOLD = 0.5f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,7 +20,10 @@ namespace RJW_Genes
 | 
				
			||||||
        public override void Tick()
 | 
					        public override void Tick()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            base.Tick();
 | 
					            base.Tick();
 | 
				
			||||||
            if (this.pawn.IsHashIntervalTick(TICK_INTERVAL) && this.pawn.Map != null)
 | 
					
 | 
				
			||||||
 | 
					            int tickInterval = ModExtensionHelper.GetTickIntervalFromModExtension(GeneDefOf.rjw_genes_aphrodisiac_pheromones, TICK_INTERVAL_FALLBACK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (this.pawn.IsHashIntervalTick(tickInterval) && this.pawn.Map != null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // Only spread pheromones if sexdrive above 1
 | 
					                // Only spread pheromones if sexdrive above 1
 | 
				
			||||||
                float sexfrequency = this.pawn.GetStatValue(StatDef.Named("SexFrequency"));
 | 
					                float sexfrequency = this.pawn.GetStatValue(StatDef.Named("SexFrequency"));
 | 
				
			||||||
| 
						 | 
					@ -57,7 +60,8 @@ namespace RJW_Genes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // Actual Logic: 
 | 
					                // Actual Logic: 
 | 
				
			||||||
                // Pawn qualifies in right distance and needs line of sight. 
 | 
					                // Pawn qualifies in right distance and needs line of sight. 
 | 
				
			||||||
                if (pos.DistanceTo(pawn.Position) < APHRODISIAC_DISTANCE && GenSight.LineOfSight(pos, pawn.Position, pawn.Map))
 | 
					                int effectDistance = ModExtensionHelper.GetDistanceFromModExtension(GeneDefOf.rjw_genes_aphrodisiac_pheromones, APHRODISIAC_DISTANCE_FALLBACK);
 | 
				
			||||||
 | 
					                if (pos.DistanceTo(pawn.Position) < effectDistance && GenSight.LineOfSight(pos, pawn.Position, pawn.Map))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    yield return pawn;
 | 
					                    yield return pawn;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
							
								
								
									
										76
									
								
								Source/Genes/Special/Patches/Patch_HormonalSaliva.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,76 @@
 | 
				
			||||||
 | 
					using HarmonyLib;
 | 
				
			||||||
 | 
					using rjw;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using Verse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace RJW_Genes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    [HarmonyPatch(typeof(SexUtility), "Aftersex")]
 | 
				
			||||||
 | 
					    public class Patch_HormonalSaliva
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // TODO: Reduce to 0.02 after debug. 
 | 
				
			||||||
 | 
					        const float SIZE_INCREMENT_FALLBACK = 0.02f;
 | 
				
			||||||
 | 
					        const float MAX_BODY_SIZE_FALLBACK = 2.5f;
 | 
				
			||||||
 | 
					        const float CUM_MULTIPLIER_FALLBACK = 1.05f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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 (GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_hormonal_saliva) && (props.sexType == xxx.rjwSextype.Oral || props.sexType == xxx.rjwSextype.Sixtynine || props.sexType == xxx.rjwSextype.Fellatio))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                GrowPenisses(partner);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (GeneUtility.HasGeneNullCheck(partner, GeneDefOf.rjw_genes_hormonal_saliva) && (props.sexType == xxx.rjwSextype.Oral || props.sexType == xxx.rjwSextype.Sixtynine || props.sexType == xxx.rjwSextype.Fellatio))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                GrowPenisses(pawn);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static void GrowPenisses(Pawn pawn)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            HormonalSalivaExtension salivaExt = GeneDefOf.rjw_genes_hormonal_saliva.GetModExtension<HormonalSalivaExtension>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            float size_increment = salivaExt?.sizeIncrement ?? SIZE_INCREMENT_FALLBACK;
 | 
				
			||||||
 | 
					            float maximum_body_size = salivaExt?.maxBodySize ?? MAX_BODY_SIZE_FALLBACK;
 | 
				
			||||||
 | 
					            float cum_multiplier = salivaExt?.cumMultiplier ?? CUM_MULTIPLIER_FALLBACK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            List<Hediff> AllPenisses = Genital_Helper.get_AllPartsHediffList(pawn).FindAll(x => Genital_Helper.is_penis(x));
 | 
				
			||||||
 | 
					            foreach (Hediff penis in AllPenisses)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                CompHediffBodyPart CompHediff = penis.TryGetComp<rjw.CompHediffBodyPart>();
 | 
				
			||||||
 | 
					                if (penis.Severity < 1.00)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    penis.Severity = Math.Min(1.01f, penis.Severity + size_increment);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (CompHediff != null && CompHediff.SizeOwner <= maximum_body_size)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        CompHediff.SizeOwner += size_increment;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Increase Fluid
 | 
				
			||||||
 | 
					                if (CompHediff != null)
 | 
				
			||||||
 | 
					                    CompHediff.FluidAmmount *= cum_multiplier;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,8 @@ namespace RJW_Genes
 | 
				
			||||||
        public static readonly HediffDef rjw_genes_orgasm_rush_hediff;
 | 
					        public static readonly HediffDef rjw_genes_orgasm_rush_hediff;
 | 
				
			||||||
        public static readonly HediffDef rjw_genes_fertilin_craving;
 | 
					        public static readonly HediffDef rjw_genes_fertilin_craving;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static readonly HediffDef rjw_genes_evergrowth_sideeffect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static readonly HediffDef rjw_genes_orgasmic_mytosis_hediff;
 | 
					        public static readonly HediffDef rjw_genes_orgasmic_mytosis_hediff;
 | 
				
			||||||
        public static readonly HediffDef rjw_genes_mytosis_shock_hediff;
 | 
					        public static readonly HediffDef rjw_genes_mytosis_shock_hediff;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,5 @@
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using Verse;
 | 
					using Verse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,9 +15,8 @@ namespace RJW_Genes
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                ModLog.Message($"{HiveUtility.getQueenXenotypes().EnumerableCount()} Queen-Xenotypes ({string.Join(",", HiveUtility.getQueenXenotypes().Select(t => t.defName))})");
 | 
					                ModLog.Message($"{HiveUtility.getQueenXenotypes().EnumerableCount()} Queen-Xenotypes ({string.Join(",", HiveUtility.getQueenXenotypes().Select(t => t.defName))})");
 | 
				
			||||||
                ModLog.Message($"{HiveUtility.getDroneXenotypes().EnumerableCount()} Drone-Xenotypes ({string.Join(",", HiveUtility.getDroneXenotypes().Select(t => t.defName))})");
 | 
					                ModLog.Message($"{HiveUtility.getDroneXenotypes().EnumerableCount()} Drone-Xenotypes ({string.Join(",", HiveUtility.getDroneXenotypes().Select(t => t.defName))})");
 | 
				
			||||||
                ModLog.Message($"Found {HiveUtility.GetQueenWorkerMappings().Count} Queen-Worker Mappings  ({string.Join(",", HiveUtility.GetQueenWorkerMappings().Keys.Select(t => t.defName))} + Default) ");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                ModLog.Message($"Found {HiveUtility.GetQueenWorkerMappings().Count} Queen-Worker Mappings  ({string.Join(",", HiveUtility.GetQueenWorkerMappings().Keys.Select(t => t))} + Default) ");
 | 
				
			||||||
                IEnumerable<HiveOffspringChanceDef> offspringChanceDefs = DefDatabase<HiveOffspringChanceDef>.AllDefs;
 | 
					                IEnumerable<HiveOffspringChanceDef> offspringChanceDefs = DefDatabase<HiveOffspringChanceDef>.AllDefs;
 | 
				
			||||||
                IEnumerable<HiveOffspringChanceDef> faultOffspringDefs = offspringChanceDefs.Where(t => t.queenChance + t.workerChance + t.workerChance > 1.02 || t.queenChance + t.workerChance + t.workerChance < 0.98 );
 | 
					                IEnumerable<HiveOffspringChanceDef> faultOffspringDefs = offspringChanceDefs.Where(t => t.queenChance + t.workerChance + t.workerChance > 1.02 || t.queenChance + t.workerChance + t.workerChance < 0.98 );
 | 
				
			||||||
                ModLog.Message($"Found {offspringChanceDefs.Count()} OffspringChanceDefs, of which {faultOffspringDefs.Count()} had faulty chances ({string.Join(",", faultOffspringDefs.Select(t => t.defName))})");
 | 
					                ModLog.Message($"Found {offspringChanceDefs.Count()} OffspringChanceDefs, of which {faultOffspringDefs.Count()} had faulty chances ({string.Join(",", faultOffspringDefs.Select(t => t.defName))})");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,11 +39,18 @@
 | 
				
			||||||
    <Compile Include="Animal_Inheritance\Settings\RJW_BGSSettings.cs" />
 | 
					    <Compile Include="Animal_Inheritance\Settings\RJW_BGSSettings.cs" />
 | 
				
			||||||
    <Compile Include="Animal_Inheritance\Settings\RJW_BGSSettingsController.cs" />
 | 
					    <Compile Include="Animal_Inheritance\Settings\RJW_BGSSettingsController.cs" />
 | 
				
			||||||
    <Compile Include="Animal_Inheritance\Defs\BestialityGeneInheritanceDef.cs" />
 | 
					    <Compile Include="Animal_Inheritance\Defs\BestialityGeneInheritanceDef.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Common\Defs\DistanceExtension.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Common\Defs\ModExtensionHelper.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Common\Either.cs" />
 | 
				
			||||||
    <Compile Include="Common\ModLog.cs" />
 | 
					    <Compile Include="Common\ModLog.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Common\Defs\TickIntervalExtension.cs" />
 | 
				
			||||||
    <Compile Include="GeneDefOf.cs" />
 | 
					    <Compile Include="GeneDefOf.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Breeding\Gene_MechBreeder.cs" />
 | 
					    <Compile Include="Genes\Breeding\Gene_MechBreeder.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Breeding\PatchMechBirth.cs" />
 | 
					    <Compile Include="Genes\Breeding\PatchMechBirth.cs" />
 | 
				
			||||||
    <Compile Include="Genes\ExtraGenitalia\Gene_UdderBreasts.cs" />
 | 
					    <Compile Include="Genes\ExtraGenitalia\Gene_UdderBreasts.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Genes\Gender\Defs\GenderFluidExtension.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Genes\Gender\Gene_GenderFluid.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Genes\GenitaliaSize\Gene_EvergrowingGenitalia.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Hive\Defs\HiveOffspringChanceDef.cs" />
 | 
					    <Compile Include="Genes\Hive\Defs\HiveOffspringChanceDef.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Hive\Genes\Gene_FerventOvipositor.cs" />
 | 
					    <Compile Include="Genes\Hive\Genes\Gene_FerventOvipositor.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Hive\Genes\Gene_InsectIncubator.cs" />
 | 
					    <Compile Include="Genes\Hive\Genes\Gene_InsectIncubator.cs" />
 | 
				
			||||||
| 
						 | 
					@ -110,6 +117,8 @@
 | 
				
			||||||
    <Compile Include="Genes\Hive\Thoughts\ThoughtWorker_QueenPresent_Social.cs" />
 | 
					    <Compile Include="Genes\Hive\Thoughts\ThoughtWorker_QueenPresent_Social.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Hive\Thoughts\ThoughtWorker_RivalQueen_Social.cs" />
 | 
					    <Compile Include="Genes\Hive\Thoughts\ThoughtWorker_RivalQueen_Social.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Life_Force\Abilities\AbilityUtility.cs" />
 | 
					    <Compile Include="Genes\Life_Force\Abilities\AbilityUtility.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Genes\Life_Force\Defs\LifeForceEmpathExtension.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Genes\Life_Force\Genes\Gene_LifeForce_Empath.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Life_Force\UI\Alert_LowFertilin.cs" />
 | 
					    <Compile Include="Genes\Life_Force\UI\Alert_LowFertilin.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Life_Force\Abilities\CompAbilityEffect_CasterIsNaked.cs" />
 | 
					    <Compile Include="Genes\Life_Force\Abilities\CompAbilityEffect_CasterIsNaked.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Life_Force\Abilities\CompProperties_CasterIsNaked.cs" />
 | 
					    <Compile Include="Genes\Life_Force\Abilities\CompProperties_CasterIsNaked.cs" />
 | 
				
			||||||
| 
						 | 
					@ -139,9 +148,11 @@
 | 
				
			||||||
    <Compile Include="Genes\Life_Force\JobGivers\JobGiver_GetLifeForce.cs" />
 | 
					    <Compile Include="Genes\Life_Force\JobGivers\JobGiver_GetLifeForce.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Life_Force\ThinkNodes\ThinkNode_NewFlirtTarget.cs" />
 | 
					    <Compile Include="Genes\Life_Force\ThinkNodes\ThinkNode_NewFlirtTarget.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Patch_AddNotifyOnGeneration.cs" />
 | 
					    <Compile Include="Genes\Patch_AddNotifyOnGeneration.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Special\AgeTransferExtension.cs" />
 | 
					    <Compile Include="Genes\Special\Defs\AgeTransferExtension.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Special\Patch_AgeDrain.cs" />
 | 
					    <Compile Include="Genes\Special\Defs\HormonalSalivaExtension.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Special\Patch_OrgasmMytosis.cs" />
 | 
					    <Compile Include="Genes\Special\Patches\Patch_AgeDrain.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Genes\Special\Patches\Patch_HormonalSaliva.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Genes\Special\Patches\Patch_OrgasmMytosis.cs" />
 | 
				
			||||||
    <Compile Include="Interactions\SuccubusTailjob\CompAbility_SexInteractionRequirements.cs" />
 | 
					    <Compile Include="Interactions\SuccubusTailjob\CompAbility_SexInteractionRequirements.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Life_Force\Abilities\CompAbilityEffect_PussyHeal.cs" />
 | 
					    <Compile Include="Genes\Life_Force\Abilities\CompAbilityEffect_PussyHeal.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Life_Force\Abilities\CompProperties_AbilityLifeForceCost.cs" />
 | 
					    <Compile Include="Genes\Life_Force\Abilities\CompProperties_AbilityLifeForceCost.cs" />
 | 
				
			||||||
| 
						 | 
					@ -156,10 +167,10 @@
 | 
				
			||||||
    <Compile Include="Genes\Life_Force\Genes\Gene_LifeForce.cs" />
 | 
					    <Compile Include="Genes\Life_Force\Genes\Gene_LifeForce.cs" />
 | 
				
			||||||
    <Compile Include="Genes\RJW_Gene.cs" />
 | 
					    <Compile Include="Genes\RJW_Gene.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Genitalia\GenitaliaUtility.cs" />
 | 
					    <Compile Include="Genes\Genitalia\GenitaliaUtility.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Special\Gene_Aphrodisiac_Pheromones.cs" />
 | 
					    <Compile Include="Genes\Special\Genes\Gene_Aphrodisiac_Pheromones.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Life_Force\Patches\Patch_SatisfyPersonal_LifeForceGain.cs" />
 | 
					    <Compile Include="Genes\Life_Force\Patches\Patch_SatisfyPersonal_LifeForceGain.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Special\Patch_OrgasmRush.cs" />
 | 
					    <Compile Include="Genes\Special\Patches\Patch_OrgasmRush.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Special\Patch_Youth_Fountain.cs" />
 | 
					    <Compile Include="Genes\Special\Patches\Patch_Youth_Fountain.cs" />
 | 
				
			||||||
    <Compile Include="HarmonyInit.cs" />
 | 
					    <Compile Include="HarmonyInit.cs" />
 | 
				
			||||||
    <Compile Include="HediffDefOf.cs" />
 | 
					    <Compile Include="HediffDefOf.cs" />
 | 
				
			||||||
    <Compile Include="Interactions\SuccubusTailjob\CustomSexInteraction_Helper.cs" />
 | 
					    <Compile Include="Interactions\SuccubusTailjob\CustomSexInteraction_Helper.cs" />
 | 
				
			||||||
| 
						 | 
					@ -199,6 +210,7 @@
 | 
				
			||||||
    </Reference>
 | 
					    </Reference>
 | 
				
			||||||
    <Reference Include="RJWSexperience">
 | 
					    <Reference Include="RJWSexperience">
 | 
				
			||||||
      <HintPath>..\..\RJW-Sexperience-1.1.4.0\1.4\Assemblies\RJWSexperience.dll</HintPath>
 | 
					      <HintPath>..\..\RJW-Sexperience-1.1.4.0\1.4\Assemblies\RJWSexperience.dll</HintPath>
 | 
				
			||||||
 | 
					      <Private>False</Private>
 | 
				
			||||||
    </Reference>
 | 
					    </Reference>
 | 
				
			||||||
    <Reference Include="System" />
 | 
					    <Reference Include="System" />
 | 
				
			||||||
    <Reference Include="UnityEngine">
 | 
					    <Reference Include="UnityEngine">
 | 
				
			||||||
| 
						 | 
					@ -216,6 +228,8 @@
 | 
				
			||||||
      <Private>False</Private>
 | 
					      <Private>False</Private>
 | 
				
			||||||
    </Reference>
 | 
					    </Reference>
 | 
				
			||||||
  </ItemGroup>
 | 
					  </ItemGroup>
 | 
				
			||||||
  <ItemGroup />
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <Folder Include="Genes\Gender\Patches\" />
 | 
				
			||||||
 | 
					  </ItemGroup>
 | 
				
			||||||
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 | 
					  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 | 
				
			||||||
</Project>
 | 
					</Project>
 | 
				
			||||||