succubi are back

This commit is contained in:
Jaaldabaoth 2024-05-26 23:41:32 +02:00
parent 701168f642
commit 0617ea4995
124 changed files with 3894 additions and 12 deletions

Binary file not shown.

View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<AbilityDef ParentName="AbilityTouchBase">
<defName>rjw_genes_ability_cockeater</defName>
<label>Eat Cock</label>
<description>Eat the cock of another pawn, restoring fertilin based on the size of the cock.</description>
<iconPath>Genes/Icons/cockeater</iconPath>
<stunTargetWhileCasting>true</stunTargetWhileCasting>
<displayGizmoWhileUndrafted>true</displayGizmoWhileUndrafted>
<disableGizmoWhileUndrafted>false</disableGizmoWhileUndrafted>
<warmupMote>Mote_CoagulateStencil</warmupMote>
<warmupEffecter>Coagulate</warmupEffecter>
<warmupStartSound>Coagulate_Cast</warmupStartSound>
<jobDef>CastAbilityOnThingMelee</jobDef>
<displayOrder>402</displayOrder>
<verbProperties>
<verbClass>Verb_CastAbilityTouch</verbClass>
<drawAimPie>false</drawAimPie>
<range>-1</range>
<warmupTime>10</warmupTime>
<targetParams>
<canTargetAnimals>true</canTargetAnimals>
<canTargetSelf>false</canTargetSelf>
<canTargetBuildings>false</canTargetBuildings>
<canTargetMechs>false</canTargetMechs>
<canTargetBloodfeeders>true</canTargetBloodfeeders>
</targetParams>
</verbProperties>
<comps>
<li Class="RJW_Genes.CompProperties_AbilityCockEater"/> <!-- namespace needs to be changed when copied to another mod-->
</comps>
</AbilityDef>
</Defs>

View file

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<AbilityDef>
<defName>rjw_genes_ability_naked_prowess</defName>
<label>naked prowess</label>
<description>Enhance the strength and resilience of your naked body with fertilin.</description>
<iconPath>Genes/Icons/rjw_naked_prowess</iconPath>
<warmupMoteSocialSymbol>Things/Mote/Heart</warmupMoteSocialSymbol>
<jobDef>CastAbilityOnThing</jobDef>
<targetRequired>False</targetRequired>
<canUseAoeToGetTargets>False</canUseAoeToGetTargets>
<stunTargetWhileCasting>True</stunTargetWhileCasting>
<statBases>
<Ability_Duration>126</Ability_Duration>
<Ability_EffectRadius>0</Ability_EffectRadius>
</statBases>
<verbProperties>
<verbClass>Verb_CastAbility</verbClass>
<warmupTime>2</warmupTime>
<range>0</range>
<drawAimPie>False</drawAimPie>
<requireLineOfSight>False</requireLineOfSight>
<targetParams>
<canTargetSelf>true</canTargetSelf>
<canTargetPawns>false</canTargetPawns>
<canTargetBuildings>false</canTargetBuildings>
<canTargetAnimals>false</canTargetAnimals>
<canTargetHumans>false</canTargetHumans>
<canTargetMechs>false</canTargetMechs>
</targetParams>
</verbProperties>
<comps>
<li Class="CompProperties_AbilityGiveHediff">
<compClass>CompAbilityEffect_GiveHediff</compClass>
<hediffDef>rjw_genes_naked_prowess</hediffDef>
<onlyApplyToSelf>True</onlyApplyToSelf>
<replaceExisting>true</replaceExisting>
</li>
<li Class="RJW_Genes.CompProperties_CasterIsNaked"/>
<li Class="RJW_Genes.CompProperties_AbilityLifeForceCost">
<fertilinCost>0.15</fertilinCost>
</li>
</comps>
</AbilityDef>
</Defs>

View file

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<AbilityDef ParentName="AbilityTouchBase">
<defName>rjw_genes_ability_paralysingkiss</defName>
<label>paralysing kiss</label>
<description>Paralyse someone briefly with a kiss.</description>
<iconPath>Genes/Icons/rjw_genes_lips</iconPath>
<stunTargetWhileCasting>true</stunTargetWhileCasting>
<displayGizmoWhileUndrafted>true</displayGizmoWhileUndrafted>
<disableGizmoWhileUndrafted>false</disableGizmoWhileUndrafted>
<statBases>
<Ability_Duration>5</Ability_Duration>
</statBases>
<warmupMote>Mote_CoagulateStencil</warmupMote>
<warmupEffecter>Coagulate</warmupEffecter>
<warmupStartSound>Coagulate_Cast</warmupStartSound>
<displayOrder>402</displayOrder>
<verbProperties>
<verbClass>Verb_CastAbilityTouch</verbClass>
<drawAimPie>false</drawAimPie>
<range>-1</range>
<warmupTime>1</warmupTime>
<targetParams>
<canTargetAnimals>true</canTargetAnimals>
<canTargetSelf>false</canTargetSelf>
<canTargetBuildings>false</canTargetBuildings>
<canTargetMechs>false</canTargetMechs>
<canTargetBloodfeeders>true</canTargetBloodfeeders>
</targetParams>
</verbProperties>
<comps>
<li Class = "CompProperties_AbilityEffectWithDuration">
<compClass>CompAbilityEffect_Stun</compClass>
<goodwillImpact>-15</goodwillImpact>
</li>
<li Class="CompProperties_AbilityFleckOnTarget">
<fleckDef>rjw_genes_lips</fleckDef> <!--Will change to kiss when I have a good icon/fleck for it-->
</li>
<li Class="RJW_Genes.CompProperties_AbilityLifeForceCost">
<fertilinCost>0.1</fertilinCost>
</li>
</comps>
</AbilityDef>
</Defs>

View file

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<AbilityDef ParentName="AbilityTouchBase">
<defName>rjw_genes_ability_pussyheal</defName>
<label>SexHeal</label>
<description>Rape another pawn, so you can heal them with your vagina's special healing power.</description>
<iconPath>Things/Mote/Heart</iconPath>
<stunTargetWhileCasting>false</stunTargetWhileCasting>
<displayGizmoWhileUndrafted>true</displayGizmoWhileUndrafted>
<disableGizmoWhileUndrafted>false</disableGizmoWhileUndrafted>
<warmupMote>Mote_CoagulateStencil</warmupMote>
<warmupEffecter>Coagulate</warmupEffecter>
<warmupStartSound>Coagulate_Cast</warmupStartSound>
<jobDef>rjw_genes_lifeforce_healpussy</jobDef>
<displayOrder>401</displayOrder>
<verbProperties>
<verbClass>Verb_CastAbilityTouch</verbClass>
<drawAimPie>false</drawAimPie>
<range>-1</range>
<warmupTime>0</warmupTime>
<targetParams>
<canTargetAnimals>true</canTargetAnimals>
<canTargetSelf>false</canTargetSelf>
<canTargetBuildings>false</canTargetBuildings>
<canTargetMechs>false</canTargetMechs>
<canTargetBloodfeeders>true</canTargetBloodfeeders>
</targetParams>
</verbProperties>
<comps>
<li Class="RJW_Genes.CompProperties_AbilityLifeForceCost">
<fertilinCost>0.3</fertilinCost>
</li>
<li Class="RJW_Genes.CompProperties_AbilityPussyHeal">
<tendQualityRange>0.4~0.8</tendQualityRange>
</li>
<li Class="RJW_Genes.CompProperties_SexInteractionRequirements">
<tags>
<!-- <li>Consensual</li> -->
<li>Rape</li>
</tags>
<dominantRequirement>
<families>
<li>Vagina</li>
</families>
</dominantRequirement>
</li>
</comps>
</AbilityDef>
</Defs>

View file

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<AbilityDef>
<defName>rjw_genes_ability_seduce</defName>
<label>seduce</label>
<description>Seduce the target to approach the caster.</description>
<iconPath>Genes/Icons/seduce</iconPath>
<writeCombatLog>True</writeCombatLog>
<stunTargetWhileCasting>true</stunTargetWhileCasting>
<displayGizmoWhileUndrafted>true</displayGizmoWhileUndrafted>
<disableGizmoWhileUndrafted>false</disableGizmoWhileUndrafted>
<statBases>
<Ability_Duration>10</Ability_Duration>
</statBases>
<warmupMote>Mote_CoagulateStencil</warmupMote>
<warmupEffecter>Coagulate</warmupEffecter>
<warmupStartSound>Coagulate_Cast</warmupStartSound>
<verbProperties>
<verbClass>Verb_CastAbility</verbClass>
<range>10</range>
<warmupTime>1</warmupTime>
<targetParams>
<canTargetAnimals>false</canTargetAnimals>
<canTargetSelf>false</canTargetSelf>
<canTargetBuildings>false</canTargetBuildings>
<canTargetMechs>false</canTargetMechs>
<canTargetBloodfeeders>true</canTargetBloodfeeders>
</targetParams>
</verbProperties>
<comps>
<li Class = "RJW_Genes.CompProperties_Seduce">
<compClass>RJW_Genes.CompAbilityEffect_Seduce</compClass>
<destination>Caster</destination>
</li>
<li Class="CompProperties_AbilityFleckOnTarget">
<fleckDef>Heart</fleckDef>
</li>
<li Class="RJW_Genes.CompProperties_AbilityLifeForceCost">
<fertilinCost>0.20</fertilinCost>
</li>
</comps>
</AbilityDef>
</Defs>

View file

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<DutyDef>
<defName>rjw_genes_flirt</defName>
<thinkNode Class="ThinkNode_Priority">
<subNodes>
<!-- first fulfill needs -->
<li Class="ThinkNode_Tagger">
<tagToGive>SatisfyingNeeds</tagToGive>
<subNodes>
<li Class="ThinkNode_PrioritySorter">
<subNodes>
<li Class="JobGiver_GetFood"/>
<li Class="JobGiver_GetRest"/>
<li Class="JobGiver_SatisfyChemicalNeed"/>
<li Class="JobGiver_SatifyChemicalDependency" MayRequire="Ludeon.RimWorld.Biotech" />
</subNodes>
</li>
</subNodes>
</li>
<!-- switch target randomly or when target is unreachable/sleeping (similar to insults) -->
<li Class="RJW_Genes.ThinkNode_ConditionalCannotInteract">
<subNodes>
<li Class="RJW_Genes.ThinkNode_NewFlirtTarget" />
</subNodes>
</li>
<li Class="ThinkNode_ConditionalRandom">
<chance>0.05</chance>
<subNodes>
<li Class="RJW_Genes.ThinkNode_NewFlirtTarget" />
</subNodes>
</li>
<!--Go to target pawn-->
<li Class="JobGiver_AIFollowEscortee" />
<li Class="rjw.ThinkNode_ConditionalSexChecks">
<subNodes>
<!--If sexneed is low do rape or masturbate (like a nymph)-->
<li Class="rjw.ThinkNode_ConditionalFrustrated">
<subNodes>
<li Class="rjw.JobGiver_RandomRape" />
<li Class="rjw.JobGiver_Masturbate"/> <!--Won't work if fap everywhere is disabled-->
</subNodes>
</li>
<!--Will sometimes try and hookup with target pawn-->
<li Class="ThinkNode_ConditionalRandom">
<chance>0.1</chance>
<subNodes>
<li Class="RJW_Genes.JobGiver_TryQuickieWith" />
</subNodes>
</li>
</subNodes>
</li>
<!--Flirt with target pawn, decreasing their sexneed. Flirt has no custom text yet-->
<li Class="RJW_Genes.JobGiver_Flirt" />
<!--Just wander around if you can't flirt with anyone-->
<li Class="JobGiver_WanderAnywhere"/>
</subNodes>
</thinkNode>
</DutyDef>
</Defs>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<FleckDef ParentName="FleckBase_Thrown">
<defName>rjw_genes_lips</defName>
<graphicData>
<texPath>Genes/Icons/rjw_genes_lips</texPath>
</graphicData>
<altitudeLayer>MetaOverlays</altitudeLayer>
<fadeInTime>0.08</fadeInTime>
<solidTime>1.4</solidTime>
<fadeOutTime>1.5</fadeOutTime>
</FleckDef>
</Defs>

View file

@ -37,6 +37,12 @@
<displayPriorityInXenotype>15</displayPriorityInXenotype>
</GeneCategoryDef>
<GeneCategoryDef>
<defName>rjw_genes_fertilin</defName>
<label>Fertilin</label>
<displayPriorityInXenotype>14</displayPriorityInXenotype>
</GeneCategoryDef>
<GeneCategoryDef>
<defName>rjw_genes_breeding</defName>
<label>Breeding</label>

View file

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<GeneDef Name="rjw_genes_wings" Abstract="True">
<displayCategory>Miscellaneous</displayCategory>
<randomChosen>true</randomChosen>
<exclusionTags>
<li>Wing</li>
</exclusionTags>
</GeneDef>
<GeneDef ParentName="rjw_genes_wings">
<defName>rjw_genes_succubus_wings</defName>
<label>succubus wings</label>
<description>Carriers of this gene grow succubus wings.</description>
<iconPath>Genes/Icons/Succubus_Wings</iconPath>
<iconColor>(0.75, 0.75, 0.75)</iconColor>
<displayOrderInCategory>1000</displayOrderInCategory>
<abilities>
<li>rjw_genes_ability_flight</li>
</abilities>
<descriptionHyperlinks>
<AbilityDef>rjw_genes_ability_flight</AbilityDef>
</descriptionHyperlinks>
<biostatCpx>1</biostatCpx>
<biostatMet>-1</biostatMet>
<selectionWeight>0</selectionWeight>
<renderNodeProperties>
<li>
<workerClass>PawnRenderNodeWorker_AttachmentBody</workerClass>
<texPath>Things/Pawn/Humanlike/BodyAttachments/RJW_Genes_Succubus_Wings</texPath>
<drawSize>1.5</drawSize>
<parentTagDef>Body</parentTagDef>
<colorType>Skin</colorType>
<drawData>
<defaultData>
<layer>-2</layer>
</defaultData>
<scaleOffsetByBodySize>true</scaleOffsetByBodySize>
<dataNorth>
<layer>90</layer>
</dataNorth>
</drawData>
</li>
</renderNodeProperties>
<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="GeneTailBase">
<defName>rjw_genes_succubus_tail</defName>
<label>succubus tail</label>
<description>Carriers of this gene grow a slender tail ending with a heart that can act as a dexterous fifth limb.</description>
<iconPath>Genes/Icons/Succubus_Tail</iconPath>
<iconColor>(1, 0, 0)</iconColor>
<displayOrderInCategory>1000</displayOrderInCategory>
<capMods>
<li>
<capacity>Manipulation</capacity>
<offset>0.05</offset>
</li>
</capMods>
<biostatCpx>1</biostatCpx>
<biostatMet>-1</biostatMet>
<selectionWeight>0</selectionWeight>
<renderNodeProperties>
<li>
<workerClass>PawnRenderNodeWorker_AttachmentBody</workerClass>
<texPath>Things/Pawn/Humanlike/BodyAttachments/RJW_Genes_Succubus_Tail</texPath>
<overrideMeshSize>(1.5, 1.5)</overrideMeshSize>
<parentTagDef>Body</parentTagDef>
<colorType>Skin</colorType>
<rotDrawMode>Fresh, Rotting</rotDrawMode>
<drawData>
<scaleOffsetByBodySize>true</scaleOffsetByBodySize>
<defaultData>
<layer>-2</layer>
</defaultData>
<dataNorth>
<offset>(0, 0, -0.15)</offset>
<layer>90</layer>
</dataNorth>
<dataSouth>
<offset>(-0, 0, -0.15)</offset>
</dataSouth>
<dataEast>
<offset>(-0.2, 0, -0.15)</offset>
</dataEast>
<dataWest>
<offset>(0.2, 0, -0.15)</offset>
</dataWest>
</drawData>
</li>
</renderNodeProperties>
<randomChosen>true</randomChosen>
<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>

View file

@ -0,0 +1,237 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<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>
<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>
<geneClass>RJW_Genes.Gene_LifeForce</geneClass>
<resourceGizmoType>RJW_Genes.GeneGizmo_ResourceLifeForce</resourceGizmoType>
<resourceLabel>fertilin</resourceLabel>
<resourceGizmoThresholds>
<li>0.25</li>
<li>0.5</li>
<li>0.75</li>
</resourceGizmoThresholds>
<showGizmoOnWorldView>true</showGizmoOnWorldView>
<showGizmoWhenDrafted>true</showGizmoWhenDrafted>
<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>
<selectionWeight>0</selectionWeight>
<displayOrderInCategory>-2</displayOrderInCategory>
<minAgeActive>18</minAgeActive>
<customEffectDescriptions>
<li>Gives fertilin supply.</li>
</customEffectDescriptions>
<symbolPack>
<prefixSymbols>
<li><symbol>fert</symbol></li>
</prefixSymbols>
</symbolPack>
<resourceLossPerDay>0.025</resourceLossPerDay>
<biostatCpx>1</biostatCpx>
<biostatMet>1</biostatMet>
</GeneDef>
<GeneDef ParentName="LifeForceBase">
<defName>rjw_genes_lifeforce_drain</defName>
<label>fertilin drain</label>
<labelShortAdj>draining</labelShortAdj>
<description>Carriers lose an additional 7.5 fertilin per day from biological entropy.</description>
<resourceLabel>fertilin</resourceLabel>
<geneClass>RJW_Genes.Gene_LifeForceDrain</geneClass>
<iconPath>Genes/Icons/FertilinDrainAlt</iconPath>
<prerequisite>rjw_genes_lifeforce</prerequisite>
<resourceLossPerDay>0.075</resourceLossPerDay>
<minAgeActive>18</minAgeActive>
<displayOrderInCategory>-1</displayOrderInCategory>
<biostatCpx>1</biostatCpx>
<biostatMet>6</biostatMet>
</GeneDef>
<GeneDef ParentName="LifeForceBase">
<defName>rjw_genes_pussyhealing</defName>
<label>Pussy Healer</label>
<labelShortAdj>pussyhealer</labelShortAdj>
<description>Carriers of this gene are able use vaginal sex to tend to other's wounds.</description>
<iconPath>Genes/Icons/Healpussy</iconPath>
<prerequisite>rjw_genes_lifeforce</prerequisite>
<displayOrderInCategory>9</displayOrderInCategory>
<abilities>
<li>rjw_genes_ability_pussyheal</li>
</abilities>
<descriptionHyperlinks>
<AbilityDef>rjw_genes_ability_pussyheal</AbilityDef>
</descriptionHyperlinks>
<biostatCpx>1</biostatCpx>
<biostatMet>-1</biostatMet>
<symbolPack>
<suffixSymbols>
<li><symbol>life</symbol></li>
<li><symbol>pussy</symbol></li>
<li><symbol>heal</symbol></li>
</suffixSymbols>
</symbolPack>
</GeneDef>
<GeneDef ParentName="LifeForceBase">
<defName>rjw_genes_cockeater</defName>
<label>Cockeater</label>
<labelShortAdj>cockeater</labelShortAdj>
<description>Carriers of this gene are able eat cocks to restore their fertilin supply. Cocks are consumed during that process.</description>
<iconPath>Genes/Icons/cockeater</iconPath>
<prerequisite>rjw_genes_lifeforce</prerequisite>
<displayOrderInCategory>11</displayOrderInCategory>
<abilities>
<li>rjw_genes_ability_cockeater</li>
</abilities>
<descriptionHyperlinks>
<AbilityDef>rjw_genes_ability_cockeater</AbilityDef>
</descriptionHyperlinks>
<biostatCpx>1</biostatCpx>
<biostatMet>-1</biostatMet>
<symbolPack>
<suffixSymbols>
<li><symbol>life</symbol></li>
<li><symbol>cock</symbol></li>
<li><symbol>eat</symbol></li>
</suffixSymbols>
</symbolPack>
</GeneDef>
<GeneDef ParentName="LifeForceBase">
<defName>rjw_genes_paralysingkiss</defName>
<label>paralysing kiss</label>
<labelShortAdj>paralysing kiss</labelShortAdj>
<description>Carriers of this gene are able to briefly stun an enemy with a kiss.</description>
<iconPath>Genes/Icons/Paralysing_Kiss</iconPath>
<prerequisite>rjw_genes_lifeforce</prerequisite>
<displayOrderInCategory>12</displayOrderInCategory>
<abilities>
<li>rjw_genes_ability_paralysingkiss</li>
</abilities>
<descriptionHyperlinks>
<AbilityDef>rjw_genes_ability_paralysingkiss</AbilityDef>
</descriptionHyperlinks>
<biostatCpx>1</biostatCpx>
<biostatMet>-1</biostatMet>
<symbolPack>
<suffixSymbols>
<li><symbol>stun</symbol></li>
<li><symbol>kiss</symbol></li>
</suffixSymbols>
</symbolPack>
</GeneDef>
<GeneDef ParentName="LifeForceBase">
<defName>rjw_genes_seduce</defName>
<label>seduction</label>
<labelShortAdj>seduction</labelShortAdj>
<description>Carriers of this gene are able to seduce a pawn into having sex with them.</description>
<iconPath>Genes/Icons/seduce</iconPath>
<prerequisite>rjw_genes_lifeforce</prerequisite>
<displayOrderInCategory>13</displayOrderInCategory>
<abilities>
<li>rjw_genes_ability_seduce</li>
</abilities>
<descriptionHyperlinks>
<AbilityDef>rjw_genes_ability_seduce</AbilityDef>
</descriptionHyperlinks>
<biostatCpx>1</biostatCpx>
<biostatMet>-1</biostatMet>
<symbolPack>
<suffixSymbols>
<li><symbol>stun</symbol></li>
<li><symbol>kiss</symbol></li>
</suffixSymbols>
</symbolPack>
</GeneDef>
<GeneDef ParentName="LifeForceBase">
<defName>rjw_genes_naked_prowess</defName>
<label>naked prowess</label>
<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>
<prerequisite>rjw_genes_lifeforce</prerequisite>
<displayOrderInCategory>14</displayOrderInCategory>
<abilities>
<li>rjw_genes_ability_naked_prowess</li>
</abilities>
<descriptionHyperlinks>
<AbilityDef>rjw_genes_ability_naked_prowess</AbilityDef>
</descriptionHyperlinks>
<biostatCpx>1</biostatCpx>
<biostatMet>-1</biostatMet>
</GeneDef>
<GeneDef ParentName="LifeForceBase">
<defName>rjw_genes_cum_eater</defName>
<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>
<iconPath>Genes/Icons/cumeater</iconPath>
<prerequisite>rjw_genes_lifeforce</prerequisite>
<displayOrderInCategory>1</displayOrderInCategory>
<biostatCpx>1</biostatCpx>
</GeneDef>
<GeneDef ParentName="LifeForceBase">
<defName>rjw_genes_fertilin_absorber</defName>
<label>Fertilin Absorber</label>
<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>
<prerequisite>rjw_genes_lifeforce</prerequisite>
<displayOrderInCategory>2</displayOrderInCategory>
<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>
<li Class="RJW_Genes.LifeForceEmpathExtension">
<aheagoIncrement>0.02</aheagoIncrement>
<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>
</modExtensions>
</GeneDef>
<GeneDef ParentName="LifeForceBase">
<defName>rjw_genes_drainer</defName>
<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>
<iconPath>Genes/Icons/Vitality_Drainer</iconPath>
<prerequisite>rjw_genes_lifeforce</prerequisite>
<displayOrderInCategory>4</displayOrderInCategory>
<biostatCpx>1</biostatCpx>
<biostatMet>-1</biostatMet>
</GeneDef>
</Defs>

View file

@ -0,0 +1,144 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<XenotypeDef>
<defName>rjw_genes_succubus</defName>
<label>Succubus</label>
<description>Succubi are strongly enhanced xenohumans. These overnaturally beautiful creatures strive parasitically on the Fertilin found in semen.</description>
<descriptionShort>Succubi are beautiful and extremely hungry Xenohumans. They strive on having sex and extracting their victims life-force through this. </descriptionShort>
<iconPath>Genes/Icons/Xenotypes/Xenotype-Succubus</iconPath>
<soundDefOnImplant>PawnBecameSanguophage</soundDefOnImplant>
<generateWithXenogermReplicatingHediffChance>0.5</generateWithXenogermReplicatingHediffChance>
<xenogermReplicatingDurationLeftDaysRange>0.1~140</xenogermReplicatingDurationLeftDaysRange>
<combatPowerFactor>1</combatPowerFactor>
<displayPriority>-1000</displayPriority>
<factionlessGenerationWeight>0.005</factionlessGenerationWeight>
<inheritable>false</inheritable>
<doubleXenotypeChances>
<Pigskin>0.02</Pigskin>
<Impid>0.02</Impid>
<Yttakin>0.02</Yttakin>
<Neanderthal>0.02</Neanderthal>
<Waster>0.02</Waster>
<Dirtmole>0.02</Dirtmole>
</doubleXenotypeChances>
<genes>
<li>rjw_genes_bisexual</li>
<li>rjw_genes_hypersexual</li>
<li>rjw_genes_female_only</li>
<li>rjw_genes_lifeforce</li>
<li>rjw_genes_lifeforce_drain</li>
<li>rjw_genes_demonic_genitalia</li>
<li>rjw_genes_cum_eater</li>
<li>rjw_genes_fertilin_absorber</li>
<li>rjw_genes_paralysingkiss</li>
<li>rjw_genes_seduce</li>
<li MayRequire="rjw.sexperience">AptitudeRemarkable_Sex</li>
<li MayRequire="Sl4vP0weR.DominantGene">DominantGene</li>
<li MayRequire="LustLicentia.RJWLabs">rjw_genes_elasticity</li>
<li>rjw_genes_succubus_wings</li>
<li>rjw_genes_succubus_tail</li>
<li>rjw_genes_aphrodisiac_pheromones</li>
<li>Beauty_Pretty</li>
<li>MoveSpeed_Quick</li>
<li>AptitudeStrong_Social</li>
<li>Ears_Pointed</li>
<li>Headbone_MiniHorns</li>
<li>Skin_Purple</li>
</genes>
</XenotypeDef>
<XenotypeDef>
<defName>rjw_genes_incubus</defName>
<label>Incubus</label>
<description>Incubi are strongly enhanced xenohumans. These overnaturally beautiful creatures strive parasitically on the Fertilin found in semen.</description>
<descriptionShort>Incubi are beautiful and extremely hungry Xenohumans. They strive on having sex and extracting their victims life-force through this. </descriptionShort>
<iconPath>Genes/Icons/Xenotypes/Xenotype-Incubus</iconPath>
<soundDefOnImplant>PawnBecameSanguophage</soundDefOnImplant>
<generateWithXenogermReplicatingHediffChance>0.5</generateWithXenogermReplicatingHediffChance>
<xenogermReplicatingDurationLeftDaysRange>0.1~140</xenogermReplicatingDurationLeftDaysRange>
<combatPowerFactor>1</combatPowerFactor>
<displayPriority>-1000</displayPriority>
<factionlessGenerationWeight>0.005</factionlessGenerationWeight>
<inheritable>false</inheritable>
<doubleXenotypeChances>
<Pigskin>0.02</Pigskin>
<Impid>0.02</Impid>
<Yttakin>0.02</Yttakin>
<Neanderthal>0.02</Neanderthal>
<Waster>0.02</Waster>
<Dirtmole>0.02</Dirtmole>
</doubleXenotypeChances>
<genes>
<li>rjw_genes_hypersexual</li>
<li>rjw_genes_male_only</li>
<li>rjw_genes_lifeforce</li>
<li>rjw_genes_lifeforce_drain</li>
<li>rjw_genes_drainer</li>
<li>rjw_genes_demonic_genitalia</li>
<li MayRequire="rjw.sexperience">AptitudeRemarkable_Sex</li>
<li MayRequire="Sl4vP0weR.DominantGene">DominantGene</li>
<li>rjw_genes_seduce</li>
<li>rjw_genes_succubus_wings</li>
<li>rjw_genes_succubus_tail</li>
<li>rjw_genes_aphrodisiac_pheromones</li>
<li>Beauty_Pretty</li>
<li>MoveSpeed_Quick</li>
<li>Robust</li>
<li>UVSensitivity_Intense</li>
<li>AptitudeStrong_Intellectual</li>
<li>Ears_Pointed</li>
<li>Headbone_CenterHorn</li>
<li>Skin_InkBlack</li>
</genes>
</XenotypeDef>
<XenotypeDef>
<defName>rjw_genes_cumazone</defName>
<label>Cumazone</label>
<description>Cumazone are a female only xenotype that excel at meele combat. Originally created as bodyguards for glitterworld amazon communities, they spred to other systems by mere strength and providing for some fetishes. They can use Fertilin to enhance their skin to overpower any combatant in meele. Their only source for Fertilin is biting of male genitalia - so be sure to have a steady supply of victim males or prepare to raid unsuspecting men of the rim.</description>
<descriptionShort>Female only, strong meele fighters, that use Fertilin from bitten-off cocks for powerful buffs.</descriptionShort>
<iconPath>Genes/Icons/Xenotypes/Xenotype-Cumazon</iconPath>
<generateWithXenogermReplicatingHediffChance>0.5</generateWithXenogermReplicatingHediffChance>
<xenogermReplicatingDurationLeftDaysRange>0.1~140</xenogermReplicatingDurationLeftDaysRange>
<combatPowerFactor>2.5</combatPowerFactor>
<displayPriority>-1000</displayPriority>
<factionlessGenerationWeight>0.01</factionlessGenerationWeight>
<inheritable>false</inheritable>
<genes>
<li>WoundHealing_Fast</li>
<li>NakedSpeed</li>
<li>Aggression_Aggressive</li>
<li>MeleeDamage_Strong</li>
<li>KillThirst</li>
<li>Robust</li>
<li>Pain_Reduced</li>
<li>Beauty_Ugly</li>
<li>Hair_BaldOnly</li>
<li>Hair_ShortOnly</li>
<li>Brow_Heavy</li>
<li>Body_Hulk</li>
<li>AptitudeStrong_Shooting</li>
<li>AptitudeRemarkable_Melee</li>
<li>AptitudePoor_Crafting</li>
<li>AptitudePoor_Artistic</li>
<li>Unstoppable</li>
<li>rjw_genes_rapist</li>
<li>rjw_genes_female_only</li>
<li>rjw_genes_lifeforce</li>
<li>rjw_genes_lifeforce_drain</li>
<li>rjw_genes_pussyhealing</li>
<li>rjw_genes_cockeater</li>
<li>rjw_genes_naked_prowess</li>
<li>rjw_genes_orgasm_rush</li>
</genes>
</XenotypeDef>
</Defs>

View file

@ -0,0 +1,166 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<HediffDef>
<defName>rjw_genes_fertilin_lost</defName>
<hediffClass>Hediff_HemogenCraving</hediffClass>
<label>lost fertilin</label>
<description>Percentage of fertilin lost.</description>
<defaultLabelColor>(1,1,1)</defaultLabelColor>
<maxSeverity>1</maxSeverity>
<comps>
<li Class="HediffCompProperties_SeverityPerDay">
<severityPerDay>-0.5</severityPerDay>
</li>
</comps>
<stages>
<li>
<becomeVisible>true</becomeVisible>
</li>
</stages>
</HediffDef>
<HediffDef>
<defName>rjw_genes_succubus_drained</defName>
<hediffClass>HediffWithComps</hediffClass>
<label>Drained</label>
<description>The vitality of this pawn has been drained. Cannot be drained again until fully recovered.</description>
<defaultLabelColor>(1,0,0.5)</defaultLabelColor>
<maxSeverity>1.0</maxSeverity>
<initialSeverity>1.0</initialSeverity>
<comps>
<li Class="HediffCompProperties_SeverityPerDay">
<severityPerDay>-0.25</severityPerDay>
</li>
</comps>
<stages>
<li>
<label>minor</label>
<capMods>
<li>
<capacity>Consciousness</capacity>
<offset>-0.1</offset>
</li>
</capMods>
<restFallFactorOffset>0.1</restFallFactorOffset>
<statOffsets>
<WorkSpeedGlobal>-0.1</WorkSpeedGlobal>
</statOffsets>
</li>
<li>
<minSeverity>0.5</minSeverity>
<label>moderate</label>
<capMods>
<li>
<capacity>Consciousness</capacity>
<offset>-0.2</offset>
</li>
</capMods>
<hungerRateFactorOffset>0.05</hungerRateFactorOffset>
<restFallFactorOffset>0.20</restFallFactorOffset>
<statOffsets>
<WorkSpeedGlobal>-0.1</WorkSpeedGlobal>
</statOffsets>
</li>
<li>
<minSeverity>0.8</minSeverity>
<label>severe</label>
<capMods>
<li>
<capacity>Consciousness</capacity>
<offset>-0.3</offset>
</li>
</capMods>
<statOffsets>
<WorkSpeedGlobal>-0.2</WorkSpeedGlobal>
</statOffsets>
<vomitMtbDays>0.4</vomitMtbDays>
<hungerRateFactorOffset>0.1</hungerRateFactorOffset>
<restFallFactorOffset>0.35</restFallFactorOffset>
</li>
</stages>
</HediffDef>
<HediffDef>
<defName>rjw_genes_fertilin_craving</defName>
<label>fertilin craving</label>
<hediffClass>Hediff_HemogenCraving</hediffClass>
<description>weakened due to running out of fertilin.</description>
<defaultLabelColor>(1,0,0.5)</defaultLabelColor>
<maxSeverity>1.0</maxSeverity>
<initialSeverity>0.01</initialSeverity>
<stages>
<li>
<label>minor</label>
<painOffset>0.05</painOffset>
<capMods>
<li>
<capacity>Consciousness</capacity>
<setMax>0.9</setMax>
</li>
</capMods>
</li>
<li>
<label>moderate</label>
<minSeverity>0.35</minSeverity>
<painOffset>0.1</painOffset>
<capMods>
<li>
<capacity>Consciousness</capacity>
<setMax>0.8</setMax>
</li>
</capMods>
</li>
<li>
<label>major</label>
<minSeverity>0.7</minSeverity>
<painOffset>0.15</painOffset>
<capMods>
<li>
<capacity>Consciousness</capacity>
<setMax>0.5</setMax>
</li>
</capMods>
</li>
</stages>
<comps>
<li Class="RJW_Genes.HediffCompProperties_SeverityFromFertilin">
<severityPerHourEmpty>0.05</severityPerHourEmpty>
<severityPerHourHemogen>-0.1</severityPerHourHemogen>
</li>
</comps>
</HediffDef>
<HediffDef ParentName="RoleStatBuff">
<defName>rjw_genes_naked_prowess</defName>
<label>naked prowss</label>
<description>Driven by fertilin, this person has greatly increased strength and resilience.</description>
<hediffClass>HediffWithComps</hediffClass>
<stages>
<li>
<!--Maybe a bit to much, but they are supposed to be strong-->
<statOffsets>
<ArmorRating_Sharp>0.5</ArmorRating_Sharp>
<ArmorRating_Blunt>0.5</ArmorRating_Blunt>
<ArmorRating_Heat>0.5</ArmorRating_Heat>
<!-- <Insulation_Cold>10</Insulation_Cold>
<Insulation_Heat>10</Insulation_Heat> -->
</statOffsets>
<statFactors>
<IncomingDamageFactor>0.5</IncomingDamageFactor>
<MeleeDamageFactor>1.5</MeleeDamageFactor>
</statFactors>
</li>
</stages>
<comps>
<li Class="HediffCompProperties_Disappears">
<showRemainingTime>True</showRemainingTime>
<disappearsAfterTicks>5000</disappearsAfterTicks> <!-- 2 hours -->
</li>
<li Class="HediffCompProperties_DisappearsOnDeath"/>
<!--TODO: Make hediff disappear if pawn is nolonger naked-->
</comps>
<isBad>false</isBad>
</HediffDef>
</Defs>

View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<!--Chitchat reduced copy-->
<InteractionDef>
<defName>rjw_genes_flirt</defName>
<label>flirt</label>
<symbol>Things/Mote/SpeechSymbols/Chitchat</symbol>
<logRulesInitiator>
<rulesStrings>
<li>r_logentry->[INITIATOR_nameDef] and [RECIPIENT_nameDef] [talkedabout] [TalkTopicLight].</li>
<li>r_logentry->[INITIATOR_nameDef] [talkedabout] [TalkTopicLight] with [RECIPIENT_nameDef].</li>
<li>r_logentry(p=0.8)->[INITIATOR_nameDef] [commentedabout] [TalkTopicLight] to [RECIPIENT_nameDef].</li>
<li>talkedabout(p=4)->chatted about</li>
<li>talkedabout->shared a word about</li>
<li>talkedabout->spoke about</li>
<li>talkedabout->gabbed about</li>
<li>talkedabout->talked about</li>
<li>talkedabout->joked about</li>
<li>talkedabout->quipped about</li>
<li>commentedabout->said something about</li>
<li>commentedabout->said a word about</li>
<li>commentedabout->made a comment about</li>
<li>commentedabout->commented about</li>
<li>commentedabout->told a joke about</li>
</rulesStrings>
</logRulesInitiator>
</InteractionDef>
</Defs>

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<JobDef>
<defName>rjw_genes_lifeforce_randomrape</defName>
<driverClass>rjw.JobDriver_RandomRape</driverClass>
<reportString>Raping</reportString>
<casualInterruptible>false</casualInterruptible>
</JobDef>
<JobDef>
<defName>rjw_genes_lifeforce_healpussy</defName>
<driverClass>RJW_Genes.JobDriver_CastAbilityAfterSex</driverClass>
<reportString>Tending someones wounds with sex.</reportString>
<casualInterruptible>false</casualInterruptible>
</JobDef>
<JobDef>
<defName>rjw_genes_lifeforce_seduced</defName>
<driverClass>RJW_Genes.JobDriver_Seduced</driverClass>
<reportString>Seduced.</reportString>
<casualInterruptible>false</casualInterruptible>
<playerInterruptible>false</playerInterruptible>
</JobDef>
<JobDef>
<defName>rjw_genes_flirt</defName>
<driverClass>RJW_Genes.JobDriver_Flirt</driverClass>
<reportString>Seduced.</reportString>
<casualInterruptible>false</casualInterruptible>
</JobDef>
</Defs>

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<JobDef>
<defName>sex_on_spot</defName>
<driverClass>RJW_Genes.JobDriver_SexOnSpot</driverClass>
<reportString>Making love on the spot.</reportString>
<casualInterruptible>false</casualInterruptible>
</JobDef>
<JobDef>
<defName>sex_on_spot_reciever</defName>
<driverClass>RJW_Genes.JobDriver_SexOnSpotReciever</driverClass>
<reportString>lovin'.</reportString>
<casualInterruptible>false</casualInterruptible>
</JobDef>
</Defs>

View file

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<MentalBreakDef>
<defName>rjw_genes_lifeforce_randomrape</defName>
<mentalState>rjw_genes_lifeforce_randomrape</mentalState>
<baseCommonality>1.5</baseCommonality>
<intensity>Extreme</intensity>
<workerClass>RJW_Genes.LifeForceMentalBreakWorker</workerClass>
</MentalBreakDef>
<MentalStateDef ParentName="BaseMentalState">
<defName>rjw_genes_lifeforce_randomrape</defName>
<stateClass>RJW_Genes.LifeForceMentalState</stateClass>
<workerClass>RJW_Genes.LifeForceMentalStateWorker</workerClass>
<label>random rape</label>
<category>Malicious</category>
<prisonersCanDo>true</prisonersCanDo>
<colonistsOnly>false</colonistsOnly>
<minTicksBeforeRecovery>30000</minTicksBeforeRecovery>
<recoveryMtbDays>0.8</recoveryMtbDays>
<maxTicksBeforeRecovery>80000</maxTicksBeforeRecovery>
<nameColor>(0.5, 0.9, 0.5)</nameColor>
<beginLetterLabel>random rape</beginLetterLabel>
<beginLetter>{0} has run out of lifeforce and is looking to obtain some.</beginLetter>
<beginLetterDef>ThreatSmall</beginLetterDef>
<recoveryMessage>{0} is no longer raping randomly.</recoveryMessage>
<baseInspectLine>Mental state: Random Rape</baseInspectLine>
<recoverFromSleep>true</recoverFromSleep>
</MentalStateDef>
</Defs>

View file

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<!--If below low try get some, if critical also consider rape, also a chance to do bestiality
First try and obtain by normal sex, then try to eat gathercum (sexperience)
If these fail try rape and a small chance for bestiality
-->
<ThinkTreeDef>
<defName>SuccubusGetLifeForce</defName>
<insertTag>Humanlike_PostMain</insertTag>
<insertPriority>14</insertPriority>
<thinkRoot Class="ThinkNode_Priority">
<subNodes>
<li Class="RJW_Genes.ThinkNode_ConditionalLowLifeForce">
<subNodes>
<li Class="rjw.ThinkNode_ConditionalSexChecks">
<subNodes>
<li Class="JobGiver_DoLovin"/>
<li Class="rjw.JobGiver_JoininBed"/>
<li Class="rjw.JobGiver_ComfortPrisonerRape" />
<li Class="RJW_Genes.JobGiver_GetLifeForce"/>
<li Class="rjw.ThinkNode_ConditionalCanRapeCP">
<subNodes>
<li Class="RJW_Genes.ThinkNode_ConditionalCritcalLifeForce">
<subNodes>
<!--Maybe make a custom chance per hour to determine if pawn would consider rape-->
<li Class="ThinkNode_ChancePerHour_Constant">
<mtbHours>8</mtbHours>
<subNodes>
<li Class="rjw.JobGiver_RandomRape" />
</subNodes>
</li>
<li Class="rjw.ThinkNode_ConditionalBestiality">
<subNodes>
<li Class="rjw.ThinkNode_ChancePerHour_Bestiality">
<subNodes>
<li Class="rjw.JobGiver_Bestiality" />
</subNodes>
</li>
</subNodes>
</li>
</subNodes>
</li>
</subNodes>
</li>
</subNodes>
</li>
</subNodes>
</li>
</subNodes>
</thinkRoot>
</ThinkTreeDef>
</Defs>

View file

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<ThoughtDef>
<defName>rjw_genes_cock_eaten</defName>
<thoughtClass>Thought_Memory</thoughtClass>
<durationDays>30.0</durationDays>
<stackLimit>100</stackLimit>
<stackedEffectMultiplier>0.4</stackedEffectMultiplier>
<stages>
<li>
<label>cock eaten</label>
<description>My cock was eaten directly of my body, I am devestated. This is not what good head feels like. </description>
<baseMoodEffect>-30</baseMoodEffect>
</li>
</stages>
</ThoughtDef>
<ThoughtDef>
<defName>rjw_genes_seduced</defName>
<thoughtClass>Thought_Memory</thoughtClass>
<durationDays>10.0</durationDays>
<stackLimit>100</stackLimit>
<stackedEffectMultiplier>0.4</stackedEffectMultiplier>
<stages>
<li>
<label>seduced</label>
<description>I was seduced into having sex. I regret what happened.</description>
<baseMoodEffect>-10</baseMoodEffect>
</li>
</stages>
</ThoughtDef>
<ThoughtDef>
<defName>rjw_genes_critical_fertilin</defName>
<workerClass>ThoughtWorker_Hediff</workerClass>
<hediff>rjw_genes_fertilin_craving</hediff>
<stages>
<li>
<label>fertilin craving</label>
<description>My bones ache. I really need fertilin.</description>
<baseMoodEffect>-25</baseMoodEffect>
</li>
<li>
<label>fertilin craving</label>
<description>This hurts bad and I can't stop thinking about sex. I would do anything for some cum.</description>
<baseMoodEffect>-40</baseMoodEffect>
</li>
<li>
<label>fertilin craving</label>
<description>Can't think. Sex. Sex. Must. Have. Cum.</description>
<baseMoodEffect>-55</baseMoodEffect>
</li>
</stages>
</ThoughtDef>
</Defs>

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View file

@ -95,8 +95,29 @@ namespace RJW_Genes
public static readonly GeneDef rjw_genes_sexual_mytosis;
public static readonly GeneDef rjw_genes_hormonal_saliva;
// Cosmetic
public static readonly GeneDef rjw_genes_succubus_tail;
public static readonly GeneDef rjw_genes_succubus_wings;
}
//life force
public static readonly GeneDef rjw_genes_lifeforce;
public static readonly GeneDef rjw_genes_pussyhealing;
public static readonly GeneDef rjw_genes_lifeforce_drain;
public static readonly GeneDef rjw_genes_cum_eater;
public static readonly GeneDef rjw_genes_fertilin_absorber;
public static readonly GeneDef rjw_genes_drainer;
public static readonly GeneDef rjw_genes_seduce;
public static readonly GeneDef rjw_genes_paralysingkiss;
public static readonly GeneDef rjw_genes_cockeater;
public static readonly GeneDef rjw_genes_lifeforce_empath;
//Other Defs
public static readonly XenotypeDef rjw_genes_succubus;
public static readonly DutyDef rjw_genes_flirt;
public static readonly MentalBreakDef rjw_genes_lifeforce_randomrape;
}
}

View file

@ -6,13 +6,77 @@ namespace RJW_Genes
{
public class GeneUtility
{
public static float MaxEggSizeMul(Pawn pawn)
//Split function so I can offsetlifeforce from gene without needing to look for the gene agian (for the constant drain tick)
public static Gene_LifeForce GetLifeForceGene(Pawn pawn)
{
float MaxEggSize = 1;
return MaxEggSize;
Pawn_GeneTracker genes = pawn.genes;
Gene_LifeForce gene_LifeForce = genes.GetFirstGeneOfType<Gene_LifeForce>();
return gene_LifeForce;
}
public static void OffsetLifeForce(IGeneResourceDrain drain, float offset)
{
if (drain.Resource != null && drain.Resource.Active)
{
float old_value = drain.Resource.Value;
drain.Resource.Value += offset;
PostOffSetLifeForce(drain, old_value);
}
}
public static void PostOffSetLifeForce(IGeneResourceDrain drain, float old_value)
{
if (drain.Resource != null && drain.Resource.Active)
{
if (old_value > 0.2f && drain.Resource.Value <= 0.2f)
{
//TODO: Mood debuff
}
else if (old_value > 0f && drain.Resource.Value <= 0f)
{
Pawn pawn = drain.Pawn;
if (!drain.Pawn.health.hediffSet.HasHediff(HediffDefOf.rjw_genes_fertilin_craving))
{
drain.Pawn.health.AddHediff(HediffDefOf.rjw_genes_fertilin_craving);
}
}
}
}
public static bool HasLowLifeForce(Pawn pawn)
{
if (HasLifeForce(pawn))
{
Gene_LifeForce gene = pawn.genes.GetFirstGeneOfType<Gene_LifeForce>();
if (gene == null || !gene.Active)
return false;
if (gene.Resource.Value < gene.targetValue)
{
return true;
}
}
return false;
}
public static bool HasCriticalLifeForce(Pawn pawn)
{
if (HasLifeForce(pawn))
{
Gene_LifeForce gene = pawn.genes.GetFirstGeneOfType<Gene_LifeForce>();
if (gene == null || !gene.Active)
return false;
if (gene.Resource.Value < gene.MinLevelForAlert)
{
return true;
}
}
return false;
}
public static List<Gene_GenitaliaResizingGene> GetGenitaliaResizingGenes(Pawn pawn)
{
var ResizingGenes = new List<Gene_GenitaliaResizingGene>();
@ -44,13 +108,19 @@ namespace RJW_Genes
return pawn.genes.HasGene(genedef);
}
public static bool HasLifeForce(Pawn pawn) { return HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_lifeforce); }
public static bool IsMechbreeder(Pawn pawn) { return HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_mechbreeder); }
public static bool IsYouthFountain(Pawn pawn) { return HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_youth_fountain); }
public static bool IsAgeDrainer(Pawn pawn) { return HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_sex_age_drain); }
public static bool IsElastic(Pawn pawn) { return HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_elasticity); }
public static bool IsCumflationImmune(Pawn pawn) { return HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_cumflation_immunity); }
public static bool IsGenerousDonor(Pawn pawn) { return HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_generous_donor); }
public static bool IsPussyHealer(Pawn pawn) { return HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_pussyhealing); }
public static bool IsUnbreakable(Pawn pawn) { return HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_unbreakable); }
public static bool HasParalysingKiss(Pawn pawn) { return HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_paralysingkiss); }
public static bool HasSeduce(Pawn pawn) { return HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_seduce); }
public static bool IsSexualDrainer(Pawn pawn) { return HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_drainer); }
public static bool IsCumEater(Pawn pawn) { return HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_cum_eater); }
}
}

View file

@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse.Sound;
using Verse;
using RimWorld;
using rjw;
using rjw.Modules.Interactions.Helpers;
using rjw.Modules.Interactions.Enums;
namespace RJW_Genes
{
public class AbilityUtility
{
public static void PussyHeal(SexProps props)
{
if (InteractionHelper.GetWithExtension(props.dictionaryKey).DominantHasFamily(GenitalFamily.Vagina) || InteractionHelper.GetWithExtension(props.dictionaryKey).SubmissiveHasFamily(GenitalFamily.Vagina))
{
Pawn pawn = props.pawn;
Pawn partner = props.partner;
FloatRange tendQualityRange;
tendQualityRange.min = 0.4f;
tendQualityRange.max = 0.8f;
if (GeneUtility.IsPussyHealer(pawn))
{
Heal(partner, tendQualityRange);
}
if (GeneUtility.IsPussyHealer(partner))
{
Heal(pawn, tendQualityRange);
}
}
}
public static bool Heal(Pawn pawn, FloatRange tendQualityRange)
{
bool any_wound_tended = false;
List<Hediff> hediffs = pawn.health.hediffSet.hediffs;
for (int i = hediffs.Count - 1; i >= 0; i--)
{
if ((hediffs[i] is Hediff_Injury || hediffs[i] is Hediff_MissingPart) && hediffs[i].TendableNow(false))
{
hediffs[i].Tended(tendQualityRange.RandomInRange, tendQualityRange.TrueMax, 1);
any_wound_tended = true;
}
}
return any_wound_tended;
}
public static float LifeForceCost(Ability ability)
{
if (ability.comps != null)
{
using (List<AbilityComp>.Enumerator enumerator = ability.comps.GetEnumerator())
{
while (enumerator.MoveNext())
{
CompAbilityEffect_LifeForceCost compAbilityEffect_HemogenCost;
if ((compAbilityEffect_HemogenCost = (enumerator.Current as CompAbilityEffect_LifeForceCost)) != null)
{
return compAbilityEffect_HemogenCost.Props.fertilinCost;
}
}
}
}
return 0f;
}
}
}

View file

@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using Verse.AI;
using rjw;
namespace RJW_Genes
{
//Summary//
//Returns invalid if a pawn is not naked
//Summary//
public class CompAbilityEffect_CasterIsNaked : CompAbilityEffect_WithDest
{
private new CompProperties_CasterIsNaked Props
{
get
{
return (CompProperties_CasterIsNaked)this.props;
}
}
public override bool GizmoDisabled(out string reason)
{
Pawn pawn = this.CasterPawn;
if (pawn != null)
{
//Copied from ThoughtWorker_NudistNude.CurrentStateInternal
List<Apparel> wornApparel = pawn.apparel.WornApparel;
for (int i = 0; i < wornApparel.Count; i++)
{
Apparel apparel = wornApparel[i];
if (apparel.def.apparel.countsAsClothingForNudity)
{
for (int j = 0; j < apparel.def.apparel.bodyPartGroups.Count; j++)
{
if (apparel.def.apparel.bodyPartGroups[j] == BodyPartGroupDefOf.Torso)
{
reason = pawn.Name + " is not naked";
return true;
}
if (apparel.def.apparel.bodyPartGroups[j] == BodyPartGroupDefOf.Legs)
{
reason = pawn.Name + " is not naked";
return true;
}
}
}
}
}
reason = null;
return false;
}
}
}

View file

@ -0,0 +1,121 @@
using Verse;
using RimWorld;
using rjw;
namespace RJW_Genes
{
/// <summary>
/// The CockEater Ability bites off the first found non-artifical cock of an target pawn.
/// It will restore {MINIMUM_LIFEFORCE_GAIN} multiplied by up to 2-times the Cock-Size.
/// Consuming a "towering" cock will give 2*{MINIMUM_LIFEFORCE_GAIN}, resulting in default 0.5f LifeForce.
/// This number is reduced for consuming animals by Settings.
///
/// Balancing note: With the Cock-Eaters a drain of 0.08 is normal per day. This means 1 average cock should hold for 3-4 days of fertilin-fuel and half a day for an animal.
/// </summary>
public class CompAbilityEffect_CockEater : CompAbilityEffect
{
private new CompProperties_AbilityCockEater Props
{
get
{
return (CompProperties_AbilityCockEater)this.props;
}
}
public const float MINIMUM_LIFEFORCE_GAIN = 0.25f;
public override void Apply(LocalTargetInfo target, LocalTargetInfo dest)
{
base.Apply(target, dest);
Pawn CockBiter = this.parent.pawn;
Pawn CockBittenPawn = target.Pawn;
if (CockBittenPawn == null)
{
return;
}
var partBPR = Genital_Helper.get_genitalsBPR(CockBittenPawn);
var parts = Genital_Helper.get_PartsHediffList(CockBittenPawn, partBPR);
if (!parts.NullOrEmpty())
{
foreach (Hediff part in parts)
{
if (GenitaliaChanger.IsArtificial(part))
continue;
if (Genital_Helper.is_penis(part))
{
float gained_lifeforce = MINIMUM_LIFEFORCE_GAIN * (1 + part.Severity);
if (CockBittenPawn.IsAnimal())
{
gained_lifeforce *= RJW_Genes_Settings.rjw_genes_fertilin_from_animals_factor;
}
// Increase LifeForce for Biter
GeneUtility.OffsetLifeForce(GeneUtility.GetLifeForceGene(CockBiter), gained_lifeforce);
// Handle Damage for Bitten
CockBittenPawn.TakeDamage(new DamageInfo(DamageDefOf.Bite, 99999f, 999f, hitPart: Genital_Helper.get_genitalsBPR(CockBittenPawn)));
//CockBittenPawn.health.RemoveHediff(part);
CockBittenPawn.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.rjw_genes_cock_eaten, CockBittenPawn, null);
//Only one penis at the time
break;
}
}
}
}
/// <summary>
/// For validity, there are a few checks:
/// 1. Target has Penis
/// 2. Target is either Colonist / Prisoner
/// 3. If the Target is an enemy, it must be downed.
/// </summary>
public override bool Valid(LocalTargetInfo target, bool throwMessages = false)
{
Pawn CockBiteTarget = target.Pawn;
if (CockBiteTarget != null)
{
bool CockBiteTargetIsColonistOrPrisoner = CockBiteTarget.Faction == this.parent.pawn.Faction || CockBiteTarget.IsPrisonerOfColony;
bool CockBiteTargetIsHostile = CockBiteTarget.HostileTo(this.parent.pawn);
bool CockBiteTargetIsDowned = CockBiteTarget.Downed;
if (!CockBiteTargetIsColonistOrPrisoner && !(CockBiteTargetIsHostile && CockBiteTargetIsDowned))
{
if (throwMessages)
{
if(CockBiteTargetIsHostile && !CockBiteTargetIsDowned)
{
Messages.Message(CockBiteTarget.Name + " is hostile, but not downed.", CockBiteTarget, MessageTypeDefOf.RejectInput, false);
}
else if (!CockBiteTargetIsColonistOrPrisoner)
{
Messages.Message(CockBiteTarget.Name + " is not a part of the colony or hostile.", CockBiteTarget, MessageTypeDefOf.RejectInput, false);
}
}
return false;
}
if (!Genital_Helper.has_penis_fertile(CockBiteTarget))
{
if (throwMessages)
{
Messages.Message(CockBiteTarget.Name + " has no penis", CockBiteTarget, MessageTypeDefOf.RejectInput, false);
}
return false;
}
}
return base.Valid(target, throwMessages);
}
public override bool GizmoDisabled(out string reason)
{
Pawn_GeneTracker genes = this.parent.pawn.genes;
Gene_LifeForce gene_LifeForce = (genes != null) ? genes.GetFirstGeneOfType<Gene_LifeForce>() : null;
if (gene_LifeForce == null)
{
reason = "AbilityDisabledNoFertilinGene".Translate(this.parent.pawn);
return true;
}
reason = null;
return false;
}
}
}

View file

@ -0,0 +1,107 @@
using Verse;
using Verse.AI;
using RimWorld;
namespace RJW_Genes
{
public class CompAbilityEffect_LifeForceCost : CompAbilityEffect
{
public new CompProperties_AbilityLifeForceCost Props
{
get
{
return (CompProperties_AbilityLifeForceCost)this.props;
}
}
private bool HasEnoughFertilin
{
get
{
Pawn_GeneTracker genes = this.parent.pawn.genes;
Gene_LifeForce gene_lifeforce = (genes != null) ? genes.GetFirstGeneOfType < Gene_LifeForce>() : null;
return gene_lifeforce != null && gene_lifeforce.Value >= this.Props.fertilinCost;
}
}
public override void Apply(LocalTargetInfo target, LocalTargetInfo dest)
{
base.Apply(target, dest);
GeneUtility.OffsetLifeForce(GeneUtility.GetLifeForceGene(this.parent.pawn), -this.Props.fertilinCost);
}
public override bool GizmoDisabled(out string reason)
{
Pawn_GeneTracker genes = this.parent.pawn.genes;
Gene_LifeForce gene_LifeForce = (genes != null) ? genes.GetFirstGeneOfType<Gene_LifeForce>() : null;
if (gene_LifeForce == null)
{
reason = "AbilityDisabledNoFertilinGene".Translate(this.parent.pawn);
return true;
}
if (gene_LifeForce.Value < this.Props.fertilinCost)
{
reason = "AbilityDisabledNoFertilin".Translate(this.parent.pawn);
return true;
}
float num = this.TotalLifeForceCostOfQueuedAbilities();
float num2 = this.Props.fertilinCost + num;
if (this.Props.fertilinCost > 1E-45f && num2 > gene_LifeForce.Value)
{
reason = "AbilityDisabledNoFertilin".Translate(this.parent.pawn);
return true;
}
reason = null;
return false;
}
public override bool AICanTargetNow(LocalTargetInfo target)
{
return this.HasEnoughFertilin;
}
private float TotalLifeForceCostOfQueuedAbilities()
{
Pawn_JobTracker jobs = this.parent.pawn.jobs;
object obj;
if (jobs == null)
{
obj = null;
}
else
{
Job curJob = jobs.curJob;
obj = ((curJob != null) ? curJob.verbToUse : null);
}
Verb_CastAbility verb_CastAbility = obj as Verb_CastAbility;
float num;
if (verb_CastAbility == null)
{
num = 0f;
}
else
{
Ability ability = verb_CastAbility.ability;
num = ((ability != null) ? AbilityUtility.LifeForceCost(ability) : 0f);
}
float num2 = num;
if (this.parent.pawn.jobs != null)
{
for (int i = 0; i < this.parent.pawn.jobs.jobQueue.Count; i++)
{
Verb_CastAbility verb_CastAbility2;
if ((verb_CastAbility2 = (this.parent.pawn.jobs.jobQueue[i].job.verbToUse as Verb_CastAbility)) != null)
{
float num3 = num2;
Ability ability2 = verb_CastAbility2.ability;
num2 = num3 + ((ability2 != null) ? AbilityUtility.LifeForceCost(ability2) : 0f);
}
}
}
return num2;
}
}
}

View file

@ -0,0 +1,95 @@
using System.Collections.Generic;
using Verse;
using RimWorld;
using rjw;
namespace RJW_Genes
{
public class CompAbilityEffect_PussyHeal : CompAbilityEffect
{
private new CompProperties_AbilityPussyHeal Props
{
get
{
return (CompProperties_AbilityPussyHeal)this.props;
}
}
public override void Apply(LocalTargetInfo target, LocalTargetInfo dest)
{
base.Apply(target, dest);
Pawn pawn = target.Pawn;
if (pawn == null)
{
return;
}
bool any_wound_tended = AbilityUtility.Heal(pawn, this.Props.tendQualityRange);
if (any_wound_tended)
{
MoteMaker.ThrowText(pawn.DrawPos, pawn.Map, "Sex tended wounds", 3.65f);
}
}
//Not yet implemented, but the heal should also trigger after normal sex
public void AfterSex(Pawn pawn, Pawn target)
{
List<Hediff> hediffs = target.health.hediffSet.hediffs;
for (int i = 0; i < hediffs.Count; i++)
{
if ((hediffs[i] is Hediff_Injury || hediffs[i] is Hediff_MissingPart) && hediffs[i].TendableNow(false))
{
//target.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.Pussy_Healed, pawn, null);
break;
}
}
//InteractionHelper.GetWithExtension(dictionaryKey).DominantHasTag("CanBePenetrated")
}
public override bool Valid(LocalTargetInfo target, bool throwMessages = false)
{
Pawn pawn = target.Pawn;
if (pawn != null)
{
//to be replaced with severel checks to make it clear why target is unable to have sex
if (!CasualSex_Helper.CanHaveSex(pawn))
{
if (throwMessages)
{
Messages.Message(pawn.Name + " is unable to have sex", pawn, MessageTypeDefOf.RejectInput, false);
}
return false;
}
else if (pawn.IsAnimal() && !RJWSettings.bestiality_enabled)
{
if (throwMessages)
{
Messages.Message("bestiality is disabled", pawn, MessageTypeDefOf.RejectInput, false);
}
return false;
}
//TODO: Only make pawns targetable that have tendable wounds
}
return base.Valid(target, throwMessages);
}
public override bool GizmoDisabled(out string reason)
{
reason = null;
if (!Genital_Helper.has_vagina(this.parent.pawn))
{
reason = this.parent.pawn.Name + " has no vagina to use.";
return true;
}
else if (!RJWSettings.rape_enabled)
{
reason = "Rape is disabled";
return true;
}
return false;
}
}
}

View file

@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using Verse.AI;
using rjw;
namespace RJW_Genes
{
public class CompAbilityEffect_Seduce : CompAbilityEffect_WithDest
{
private new CompProperties_Seduce Props
{
get
{
return (CompProperties_Seduce)this.props;
}
}
public override void Apply(LocalTargetInfo target, LocalTargetInfo dest)
{
base.Apply(target, dest);
Pawn pawn = target.Thing as Pawn;
Pawn pawn2 = this.parent.pawn;
if (pawn != null && pawn2 != null && !pawn.Downed)
{
Job job = JobMaker.MakeJob(JobDefOf.rjw_genes_lifeforce_seduced, pawn2);
job.mote = MoteMaker.MakeThoughtBubble(pawn, this.parent.def.iconPath, true);
pawn.jobs.StopAll(false, true);
pawn.jobs.StartJob(job, JobCondition.InterruptForced, null, false, true, null, null, false, false, null, false, true);
}
}
public override bool Valid(LocalTargetInfo target, bool throwMessages = false)
{
Pawn pawn = target.Pawn;
if (pawn != null)
{
if (!xxx.can_be_fucked(pawn))
{
if (throwMessages)
{
Messages.Message(pawn.Name + " is unable to have sex", pawn, MessageTypeDefOf.RejectInput, false);
}
return false;
}
else if (pawn.IsAnimal() && !RJWSettings.bestiality_enabled)
{
if (throwMessages)
{
Messages.Message("bestiality is disabled", pawn, MessageTypeDefOf.RejectInput, false);
}
return false;
}
else if (GeneUtility.HasSeduce(pawn))
{
if (throwMessages)
{
Messages.Message(pawn.Name + " cannot be seduced, as they also have the Seduce-Ability", pawn, MessageTypeDefOf.RejectInput, false);
}
return false;
}
else if (pawn.Downed)
{
if (throwMessages)
{
Messages.Message(pawn.Name + " is unable to move", pawn, MessageTypeDefOf.RejectInput, false);
}
return false;
}
}
return base.Valid(target, throwMessages);
}
public override bool GizmoDisabled(out string reason)
{
reason = null;
if (!RJWSettings.rape_enabled)
{
reason = "Rape is disabled";
return true;
}
return false;
}
}
}

View file

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
namespace RJW_Genes
{
public class CompProperties_AbilityCockEater : CompProperties_AbilityEffect
{
public CompProperties_AbilityCockEater()
{
this.compClass = typeof(CompAbilityEffect_CockEater);
}
}
}

View file

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using Verse;
using RimWorld;
namespace RJW_Genes
{
// Token: 0x02000F65 RID: 3941
public class CompProperties_AbilityLifeForceCost : CompProperties_AbilityEffect
{
// Token: 0x06005D16 RID: 23830 RVA: 0x001FA73F File Offset: 0x001F893F
public CompProperties_AbilityLifeForceCost()
{
this.compClass = typeof(CompAbilityEffect_LifeForceCost);
}
// Token: 0x06005D17 RID: 23831 RVA: 0x001FA757 File Offset: 0x001F8957
public override IEnumerable<string> ExtraStatSummary()
{
yield return "AbilityFertilinCost" + ": " + Mathf.RoundToInt(this.fertilinCost * 100f);
yield break;
}
// Token: 0x040038CD RID: 14541
public float fertilinCost;
}
}

View file

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
namespace RJW_Genes
{
public class CompProperties_AbilityPussyHeal : CompProperties_AbilityEffect
{
public CompProperties_AbilityPussyHeal()
{
this.compClass = typeof(CompAbilityEffect_PussyHeal);
}
public FloatRange tendQualityRange;
}
}

View file

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
namespace RJW_Genes
{
public class CompProperties_CasterIsNaked : CompProperties_EffectWithDest
{
public CompProperties_CasterIsNaked()
{
this.compClass = typeof(CompAbilityEffect_CasterIsNaked);
}
}
}

View file

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
namespace RJW_Genes
{
public class CompProperties_Seduce : CompProperties_EffectWithDest
{
public CompProperties_Seduce()
{
this.compClass = typeof(CompAbilityEffect_Seduce);
}
public StatDef durationMultiplier;
}
}

View 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;
}
}

View file

@ -0,0 +1,140 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using Verse;
using RimWorld;
using rjw;
namespace RJW_Genes
{
public class Gene_LifeForce : Gene_Resource, IGeneResourceDrain
{
//Gene should only be active if sex is allowed for this pawn
public override bool Active
{
get
{
if (this.Overridden)
{
return false;
}
Pawn pawn = this.pawn;
return ((pawn != null) ? pawn.ageTracker : null) == null ||
((float)this.pawn.ageTracker.AgeBiologicalYears >= this.def.minAgeActive);
}
}
public override void ExposeData()
{
base.ExposeData();
Scribe_Values.Look<bool>(ref this.StoredCumAllowed, "StoredCumAllowed", true, false);
}
public bool ShouldConsumeLifeForceNow()
{
return this.Value < this.targetValue;
}
//Same as Gene_Hemogen
public override IEnumerable<Gizmo> GetGizmos()
{
foreach (Gizmo gizmo in base.GetGizmos())
{
yield return gizmo;
}
yield break;
}
//every tick it decreases fertilin value and everyday if fertilin is below alert minimum there a ~50 chance for mental break
public override void Tick()
{
base.Tick();
if (this.CanOffset && this.Resource != null)
{
GeneUtility.OffsetLifeForce(this, -this.ResourceLossPerDay / 60000f);
}
}
public bool StoredCumAllowed = true;
public Gene_Resource Resource
{
get
{
return this;
}
}
public Pawn Pawn
{
get
{
return this.pawn;
}
}
public bool CanOffset
{
get
{
return this.pawn.Spawned && this.Active;
}
}
public float ResourceLossPerDay
{
get
{
return this.def.resourceLossPerDay;
}
}
public string DisplayLabel
{
get
{
return this.def.resourceLabel;
}
}
public override float InitialResourceMax
{
get
{
return 1f;
}
}
public override float MinLevelForAlert
{
get
{
return 0.2f;
}
}
public override float MaxLevelOffset
{
get
{
return base.MaxLevelOffset;
}
}
protected override Color BarColor
{
get
{
return Color.grey;
}
}
protected override Color BarHighlightColor
{
get
{
return Color.white;
}
}
}
}

View file

@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using Verse;
using RimWorld;
namespace RJW_Genes
{
public class Gene_LifeForceDrain : Gene, IGeneResourceDrain
{
public Gene_Resource Resource
{
get
{
if (this.cachedLifeForceGene == null || !this.cachedLifeForceGene.Active)
{
this.cachedLifeForceGene = this.pawn.genes.GetFirstGeneOfType<Gene_LifeForce>();
}
return this.cachedLifeForceGene;
}
}
public bool CanOffset
{
get
{
return this.Active && this.Resource != null && this.Resource.Active;
}
}
public float ResourceLossPerDay
{
get
{
return this.def.resourceLossPerDay;
}
}
public Pawn Pawn
{
get
{
return this.pawn;
}
}
public string DisplayLabel
{
get
{
return this.Label + " (" + "Gene".Translate() + ")";
}
}
public override void Tick()
{
base.Tick();
if (this.CanOffset && this.Resource != null)
{
GeneUtility.OffsetLifeForce(this, -this.ResourceLossPerDay / 60000);
}
}
[Unsaved(false)]
private Gene_LifeForce cachedLifeForceGene;
private const float MinAgeForDrain = 3f;
}
}

View 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;
public 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);
}
}
}

View file

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
namespace RJW_Genes
{
public class HediffCompProperties_SeverityFromFertilin : HediffCompProperties
{
public HediffCompProperties_SeverityFromFertilin()
{
this.compClass = typeof(HediffComp_SeverityFromFertilin);
}
// Token: 0x04001162 RID: 4450
public float severityPerHourEmpty;
// Token: 0x04001163 RID: 4451
public float severityPerHourHemogen;
}
}

View file

@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
namespace RJW_Genes
{
public class HediffComp_SeverityFromFertilin : HediffComp
{
public HediffCompProperties_SeverityFromFertilin Props
{
get
{
return (HediffCompProperties_SeverityFromFertilin)this.props;
}
}
public override bool CompShouldRemove
{
get
{
Pawn_GeneTracker genes = base.Pawn.genes;
return ((genes != null) ? genes.GetFirstGeneOfType<Gene_LifeForce>() : null) == null;
}
}
private Gene_LifeForce LifeForce
{
get
{
if (this.cachedLifeForceGene == null)
{
this.cachedLifeForceGene = base.Pawn.genes.GetFirstGeneOfType<Gene_LifeForce>();
}
return this.cachedLifeForceGene;
}
}
public override void CompPostTick(ref float severityAdjustment)
{
base.CompPostTick(ref severityAdjustment);
severityAdjustment += ((this.LifeForce.Value > 0f) ? this.Props.severityPerHourHemogen : this.Props.severityPerHourEmpty) / 2500f;
this.MentalBreak();
}
public void MentalBreak()
{
if (cachedLifeForceGene.Resource.Value <= cachedLifeForceGene.Resource.MinLevelForAlert && this.Pawn.IsHashIntervalTick(2500) && Rand.Chance(0.03f)) //~50% chance each day for mental break
{
if (this.Pawn.genes.HasGene(GeneDefOf.rjw_genes_cum_eater)
|| this.Pawn.genes.HasGene(GeneDefOf.rjw_genes_fertilin_absorber) || this.Pawn.genes.HasGene(GeneDefOf.rjw_genes_drainer))
{
//TODO: use mentalstatedef instead of mentalbreakdef
MentalBreakDef randomrape = GeneDefOf.rjw_genes_lifeforce_randomrape;
if (ModsConfig.BiotechActive &&
this.Pawn.Spawned && !this.Pawn.InMentalState && !this.Pawn.Downed &&
randomrape.Worker.BreakCanOccur(this.Pawn))
{
randomrape.Worker.TryStart(this.Pawn, "MentalBreakNoFertilin".Translate(), false);
}
}
}
}
private Gene_LifeForce cachedLifeForceGene;
}
}

View file

@ -0,0 +1,24 @@
using RimWorld;
using Verse;
namespace RJW_Genes
{
/// <summary>
/// This class checks for pawns with LifeForce and Cumeater Gene to add Fertilin when eating cum (the Item from RJW-Sexperience).
/// </summary>
public class IngestionOutcomeDoer_LifeForceOffset : IngestionOutcomeDoer
{
public const float DEFAULT_FERTILIN_PER_UNIT = 1f;
public float FertilinPerUnit = 1f;
protected override void DoIngestionOutcomeSpecial(Pawn pawn, Thing ingested, int ingestedCount)
{
if (GeneUtility.HasLifeForce(pawn) && GeneUtility.IsCumEater(pawn))
{
float num = ingestedCount * this.FertilinPerUnit / 100;
GeneUtility.OffsetLifeForce(GeneUtility.GetLifeForceGene(pawn), num);
}
}
}
}

View file

@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RimWorld;
using Verse;
using Verse.AI;
using rjw;
namespace RJW_Genes
{
public class JobDriver_CastAbilityAfterSex : JobDriver_SexBaseInitiator
{
//Summary//
//Similar to jobdriver rape, but it cast an ability after sex and tries to limit what kind of sexinteractions are allowed.
protected override IEnumerable<Toil> MakeNewToils()
{
base.setup_ticks();
//this.FailOnDespawnedOrNull(TargetIndex.A);
//this.FailOnCannotTouch(TargetIndex.B, PathEndMode.OnCell);
this.FailOnDespawnedNullOrForbidden(this.iTarget);
//this.FailOn(() => !target.health.capacities.CanBeAwake);
JobDef PartnerJob = xxx.gettin_raped;
yield return Toils_Goto.Goto(TargetIndex.A, PathEndMode.OnCell);
yield return new Toil
{
defaultCompleteMode = ToilCompleteMode.Instant,
socialMode = RandomSocialMode.Off,
initAction = delegate ()
{
Job newJob = JobMaker.MakeJob(PartnerJob, this.pawn, this.Partner);
this.Partner.jobs.StartJob(newJob, JobCondition.InterruptForced, null, false, true, null, null, false, false, null, false, true);
}
};
Toil toil = new Toil();
toil.defaultCompleteMode = ToilCompleteMode.Never;
toil.socialMode = RandomSocialMode.Off;
toil.defaultDuration = this.duration;
toil.handlingFacing = true;
toil.FailOn(() => this.Partner.CurJob.def != PartnerJob);
toil.initAction = delegate ()
{
this.Partner.pather.StopDead();
this.Partner.jobs.curDriver.asleep = false;
//Tries to find CompProperties_SexInteractionRequirements and if it finds it it will try and generate sexprops based on the sexpropsrequirements.
foreach (AbilityComp comp in this.job.ability.comps)
{
if (comp.props is CompProperties_SexInteractionRequirements)
{
CompProperties_SexInteractionRequirements sexpropsreq = comp.props as CompProperties_SexInteractionRequirements;
this.Sexprops = CustomSexInteraction_Helper.GenerateSexProps(this.pawn, this.Partner, sexpropsreq);
}
}
this.Start();
this.Sexprops.usedCondom = (CondomUtility.TryUseCondom(this.pawn) || CondomUtility.TryUseCondom(this.Partner));
};
toil.AddPreTickAction(delegate
{
if (this.pawn.IsHashIntervalTick(this.ticks_between_hearts))
{
this.ThrowMetaIconF(this.pawn.Position, this.pawn.Map, FleckDefOf.Heart);
}
this.SexTick(this.pawn, this.Partner, true, true);
SexUtility.reduce_rest(this.Partner, 1f);
SexUtility.reduce_rest(this.pawn, 1f);
if (this.ticks_left <= 0)
{
this.ReadyForNextToil();
}
});
toil.AddFinishAction(delegate
{
this.End();
});
yield return toil;
yield return new Toil
{
initAction = delegate ()
{
SexUtility.ProcessSex(this.Sexprops);
},
defaultCompleteMode = ToilCompleteMode.Instant
};
yield return Toils_Combat.CastVerb(TargetIndex.A, TargetIndex.B, false);
yield break;
}
}
}

View file

@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using Verse.AI;
using RimWorld;
using rjw;
namespace RJW_Genes
{
public class JobDriver_Flirt : JobDriver
{
private Pawn Target
{
get
{
return (Pawn)((Thing)this.pawn.CurJob.GetTarget(TargetIndex.A));
}
}
public override bool TryMakePreToilReservations(bool errorOnFailed)
{
return true;
}
//Some wait toils to induce delay
protected override IEnumerable<Toil> MakeNewToils()
{
this.FailOnDespawnedOrNull(TargetIndex.A);
yield return Toils_Interpersonal.GotoInteractablePosition(TargetIndex.A);
yield return Toils_General.Wait(300, TargetIndex.A);
yield return Toils_Interpersonal.WaitToBeAbleToInteract(this.pawn);
Toil toil = Toils_Interpersonal.GotoInteractablePosition(TargetIndex.A);
toil.socialMode = RandomSocialMode.Off;
yield return toil;
yield return this.InteractToil();
Toil toil1 = Toils_General.Wait(300, TargetIndex.A);
toil1.socialMode = RandomSocialMode.Off;
yield return toil1;
yield break;
}
private Toil InteractToil()
{
return Toils_General.Do(delegate
{
if (this.pawn.interactions.TryInteractWith(this.Target, ThoughtDefOf.rjw_genes_flirt))
{
Need_Sex need_Sex = this.Target.needs.TryGetNeed<Need_Sex>();
need_Sex.CurLevel += -0.01f;
}
});
}
private const TargetIndex TargetInd = TargetIndex.A;
}
}

View file

@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RimWorld;
using Verse;
using Verse.AI;
using rjw;
using rjw.Modules.Interactions.Enums;
using rjw.Modules.Interactions.Helpers;
using rjw.Modules.Interactions.Objects;
using rjw.Modules.Interactions.Contexts;
using rjw.Modules.Interactions.Implementation;
namespace RJW_Genes
{
public class JobDriver_Seduced : JobDriver
{
//Summary//
//Makes a pawn move to seducing pawn and then tries to rape them.
protected override IEnumerable<Toil> MakeNewToils()
{
this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
this.FailOn(() => !this.pawn.CanReserve(TargetA, xxx.max_rapists_per_prisoner, 0, null, false));
this.FailOn(() => this.pawn.IsFighting());
this.FailOn(() => this.pawn.Drafted);
Pawn partner = this.job.GetTarget(TargetIndex.A).Pawn;
yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch);
yield return new Toil
{
defaultCompleteMode = ToilCompleteMode.Instant,
socialMode = RandomSocialMode.Off,
initAction = delegate ()
{
if(partner != null)
{
partner.drafter.Drafted = false;
this.pawn.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.rjw_genes_seduced, partner, null);
Job newJob = JobMaker.MakeJob(JobDefOf.sex_on_spot, pawn);
partner.jobs.StartJob(newJob, JobCondition.InterruptForced, null, false, true, null, null, false, false, null, false, true);
}
}
};
yield break;
}
public override bool TryMakePreToilReservations(bool errorOnFailed)
{
return this.pawn.Reserve(TargetA, this.job, xxx.max_rapists_per_prisoner, 0, null, errorOnFailed);
}
}
}

Some files were not shown because too many files have changed in this diff Show more