1.0.2.0
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<Manifest>
|
||||
<identifier>RJW Sexperience</identifier>
|
||||
<version>1.0.1.11b</version>
|
||||
<version>1.0.2.0</version>
|
||||
<dependencies>
|
||||
</dependencies>
|
||||
<incompatibleWith />
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
|
||||
<Defs>
|
||||
<JobDef>
|
||||
<defName>CleanSelfwithBucket</defName>
|
||||
<driverClass>RJWSexperience.JobDriver_CleanSelfWithBucket</driverClass>
|
||||
<reportString>collecting cum</reportString>
|
||||
<casualInterruptible>true</casualInterruptible>
|
||||
</JobDef>
|
||||
</Defs>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
|
||||
<Defs>
|
||||
<KeyBindingDef ParentName="GameKeyBinding">
|
||||
<defName>OpenSexStatistics</defName>
|
||||
<label>sexperience: open sex history</label>
|
||||
</KeyBindingDef>
|
||||
</Defs>
|
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Defs>
|
||||
<RecipeDef>
|
||||
<defName>Surgery_RestoreHymen</defName>
|
||||
<label>hymenoplasty</label>
|
||||
<description>Disguises as virgin.</description>
|
||||
<workerClass>RJWSexperience.Recipe_HymenSurgery</workerClass>
|
||||
<jobString>restoring hymen</jobString>
|
||||
<effectWorking>Surgery</effectWorking>
|
||||
<soundWorking>Recipe_Surgery</soundWorking>
|
||||
<workSpeedStat>MedicalOperationSpeed</workSpeedStat>
|
||||
<workSkill>Medicine</workSkill>
|
||||
<workSkillLearnFactor>0.2</workSkillLearnFactor>
|
||||
<workAmount>400</workAmount>
|
||||
<anesthetize>false</anesthetize>
|
||||
<recipeUsers>
|
||||
<li>Human</li>
|
||||
</recipeUsers>
|
||||
<surgerySuccessChanceFactor>100</surgerySuccessChanceFactor>
|
||||
<ingredients>
|
||||
<li>
|
||||
<filter>
|
||||
<categories>
|
||||
<li>Medicine</li>
|
||||
</categories>
|
||||
</filter>
|
||||
<count>1</count>
|
||||
</li>
|
||||
</ingredients>
|
||||
<fixedIngredientFilter>
|
||||
<categories>
|
||||
<li>Medicine</li>
|
||||
</categories>
|
||||
</fixedIngredientFilter>
|
||||
</RecipeDef>
|
||||
|
||||
|
||||
</Defs>
|
|
@ -4,7 +4,14 @@
|
|||
<RecordDef>
|
||||
<defName>NumofEatenCum</defName>
|
||||
<label>swallowed cum</label>
|
||||
<description>The number of times that i swalloed cum.</description>
|
||||
<description>The number of times that i swallowed cum.</description>
|
||||
<type>Int</type>
|
||||
</RecordDef>
|
||||
|
||||
<RecordDef>
|
||||
<defName>AmountofEatenCum</defName>
|
||||
<label>swallowed cum(mL)</label>
|
||||
<description>The amount of cum that i swallowed.</description>
|
||||
<type>Int</type>
|
||||
</RecordDef>
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
</RecordDef>
|
||||
|
||||
<RecordDef>
|
||||
<defName>HadnjobCount</defName>
|
||||
<defName>HandjobCount</defName>
|
||||
<label>handjobs</label>
|
||||
<description>The number of times of handjob.</description>
|
||||
<type>Int</type>
|
||||
|
|
|
@ -1,102 +1,47 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Defs>
|
||||
<ThingDef Name ="GatheredCum" ParentName="OrganicProductBase">
|
||||
<defName>GatheredCum</defName>
|
||||
<label>cum</label>
|
||||
<description>Gathered cum.</description>
|
||||
<thingCategories>
|
||||
<li>AnimalProductRaw</li>
|
||||
</thingCategories>
|
||||
<graphicData>
|
||||
<texPath>Things/Item/GatheredCum</texPath>
|
||||
<drawSize>1</drawSize>
|
||||
<graphicClass>Graphic_StackCount</graphicClass>
|
||||
</graphicData>
|
||||
<socialPropernessMatters>true</socialPropernessMatters>
|
||||
<statBases>
|
||||
<MarketValue>0.1</MarketValue>
|
||||
<Mass>0.1</Mass>
|
||||
<Nutrition>0.01</Nutrition>
|
||||
<Beauty>-5</Beauty>
|
||||
<Cleanliness>-1</Cleanliness>
|
||||
<FoodPoisonChanceFixedHuman>0.00</FoodPoisonChanceFixedHuman>
|
||||
<DeteriorationRate>60</DeteriorationRate>
|
||||
<Flammability>0.1</Flammability>
|
||||
</statBases>
|
||||
<ingestible>
|
||||
<foodType>Fluid, AnimalProduct</foodType>
|
||||
<preferability>DesperateOnlyForHumanlikes</preferability>
|
||||
<tasteThought>AteCum</tasteThought>
|
||||
<specialThoughtAsIngredient>AteCum</specialThoughtAsIngredient>
|
||||
<optimalityOffsetHumanlikes>-10</optimalityOffsetHumanlikes>
|
||||
<optimalityOffsetFeedingAnimals>-10</optimalityOffsetFeedingAnimals>
|
||||
<outcomeDoers>
|
||||
<li Class="IngestionOutcomeDoer_GiveHediff">
|
||||
<hediffDef>CumTolerance</hediffDef>
|
||||
<severity>0.032</severity>
|
||||
<divideByBodySize>true</divideByBodySize>
|
||||
</li>
|
||||
<li Class="IngestionOutcomeDoer_OffsetPsyfocus">
|
||||
<offset>0.05</offset>
|
||||
</li>
|
||||
</outcomeDoers>
|
||||
</ingestible>
|
||||
<comps>
|
||||
<li Class="CompProperties_Drug">
|
||||
<chemical>Cum</chemical>
|
||||
<addictiveness>0.050</addictiveness>
|
||||
<minToleranceToAddict>0.8</minToleranceToAddict>
|
||||
<existingAddictionSeverityOffset>0.1</existingAddictionSeverityOffset>
|
||||
<needLevelOffset>1</needLevelOffset>
|
||||
<listOrder>30</listOrder>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
|
||||
<ThingDef ParentName="PlantFoodRawBase">
|
||||
<defName>UsedCondom</defName>
|
||||
<label>Used Condom</label>
|
||||
<description>A condom filled with sperm. MMMM So good and tasty!</description>
|
||||
<ThingDef Name="GatheredCum" ParentName="OrganicProductBase">
|
||||
<defName>GatheredCum</defName>
|
||||
<label>cum</label>
|
||||
<description>Gathered cum.</description>
|
||||
<thingCategories>
|
||||
<li>AnimalProductRaw</li>
|
||||
</thingCategories>
|
||||
<graphicData>
|
||||
<texPath>Things/Item/UsedCondom</texPath>
|
||||
<texPath>Things/Item/GatheredCum</texPath>
|
||||
<drawSize>1</drawSize>
|
||||
<graphicClass>Graphic_StackCount</graphicClass>
|
||||
</graphicData>
|
||||
<stackLimit>50</stackLimit>
|
||||
<useHitPoints>true</useHitPoints>
|
||||
<selectable>true</selectable>
|
||||
<generateCommonality>0.0</generateCommonality>
|
||||
<techLevel>Industrial</techLevel>
|
||||
<socialPropernessMatters>true</socialPropernessMatters>
|
||||
<statBases>
|
||||
<Beauty>-10</Beauty>
|
||||
<MarketValue>1</MarketValue>
|
||||
<Mass>0.05</Mass>
|
||||
<Nutrition>0.05</Nutrition>
|
||||
<MarketValue>0.1</MarketValue>
|
||||
<Mass>0.1</Mass>
|
||||
<Nutrition>0.01</Nutrition>
|
||||
<Beauty>-5</Beauty>
|
||||
<Cleanliness>-1</Cleanliness>
|
||||
<FoodPoisonChanceFixedHuman>0.00</FoodPoisonChanceFixedHuman>
|
||||
<DeteriorationRate>60</DeteriorationRate>
|
||||
<Flammability>0.1</Flammability>
|
||||
</statBases>
|
||||
<ingestible>
|
||||
<foodType>Fluid, AnimalProduct</foodType>
|
||||
<preferability>DesperateOnlyForHumanlikes</preferability>
|
||||
<tasteThought>AteCum</tasteThought>
|
||||
<specialThoughtAsIngredient>AteCum</specialThoughtAsIngredient>
|
||||
<outcomeDoers>
|
||||
<li Class="IngestionOutcomeDoer_GiveHediff">
|
||||
<hediffDef>CumTolerance</hediffDef>
|
||||
<severity>0.032</severity>
|
||||
<divideByBodySize>true</divideByBodySize>
|
||||
</li>
|
||||
<li Class="IngestionOutcomeDoer_OffsetPsyfocus">
|
||||
<offset>0.05</offset>
|
||||
</li>
|
||||
</outcomeDoers>
|
||||
<tasteThought>AteCum</tasteThought>
|
||||
<specialThoughtAsIngredient>AteCum</specialThoughtAsIngredient>
|
||||
<optimalityOffsetHumanlikes>-10</optimalityOffsetHumanlikes>
|
||||
<optimalityOffsetFeedingAnimals>-10</optimalityOffsetFeedingAnimals>
|
||||
<outcomeDoers>
|
||||
<li Class="IngestionOutcomeDoer_GiveHediff">
|
||||
<hediffDef>CumTolerance</hediffDef>
|
||||
<severity>0.032</severity>
|
||||
<divideByBodySize>true</divideByBodySize>
|
||||
</li>
|
||||
<li Class="IngestionOutcomeDoer_OffsetPsyfocus">
|
||||
<offset>0.05</offset>
|
||||
</li>
|
||||
<li Class="RJWSexperience.CumOutcomeDoers"/>
|
||||
</outcomeDoers>
|
||||
</ingestible>
|
||||
<altitudeLayer>Item</altitudeLayer>
|
||||
<tickerType>Never</tickerType>
|
||||
<tradeTags>
|
||||
<li>Exotic</li>
|
||||
</tradeTags>
|
||||
<tradeability>Sellable</tradeability>
|
||||
<thingCategories>
|
||||
<li>AnimalProductRaw</li>
|
||||
</thingCategories>
|
||||
<comps>
|
||||
<li Class="CompProperties_Drug">
|
||||
<chemical>Cum</chemical>
|
||||
|
@ -109,6 +54,7 @@
|
|||
</comps>
|
||||
</ThingDef>
|
||||
|
||||
|
||||
<ChemicalDef>
|
||||
<defName>Cum</defName>
|
||||
<label>cum</label>
|
||||
|
|
|
@ -7,17 +7,57 @@
|
|||
<commonalityFemale>0.0</commonalityFemale>
|
||||
<degreeDatas>
|
||||
<li>
|
||||
<label>virgin</label>
|
||||
<description>[PAWN_nameDef] has no experience.</description>
|
||||
<labelMale>BUGGED! MALE CANNOT HAS THIS TRAIT</labelMale>
|
||||
<labelFemale>damaged virgin</labelFemale>
|
||||
<description>[PAWN_nameDef] never experienced. However, her hymen had damaged for some reason.</description>
|
||||
<degree>-1</degree>
|
||||
<marketValueFactorOffset>0.05</marketValueFactorOffset>
|
||||
<statOffsets>
|
||||
<SexFrequency>0.1</SexFrequency>
|
||||
<SexFrequency>0.2</SexFrequency>
|
||||
</statOffsets>
|
||||
<skillGains>
|
||||
<li>
|
||||
<key>Sex</key>
|
||||
<value>-4</value>
|
||||
</li>
|
||||
</skillGains>
|
||||
<skillGains>
|
||||
<li>
|
||||
<key>Sex</key>
|
||||
<value>-4</value>
|
||||
</li>
|
||||
</skillGains>
|
||||
</li>
|
||||
<li>
|
||||
<label>virgin</label>
|
||||
<description>[PAWN_nameDef] never experienced.</description>
|
||||
<degree>0</degree>
|
||||
<statOffsets>
|
||||
<SexFrequency>0.2</SexFrequency>
|
||||
</statOffsets>
|
||||
<skillGains>
|
||||
<li>
|
||||
<key>Sex</key>
|
||||
<value>-4</value>
|
||||
</li>
|
||||
</skillGains>
|
||||
</li>
|
||||
<li>
|
||||
<labelMale>BUGGED! MALE CANNOT HAS THIS TRAIT</labelMale>
|
||||
<labelFemale>virgin?</labelFemale>
|
||||
<description>[PAWN_nameDef] looks experienced. But the hymen is still threre.</description>
|
||||
<marketValueFactorOffset>0.10</marketValueFactorOffset>
|
||||
<degree>1</degree>
|
||||
</li>
|
||||
<li>
|
||||
<labelMale>BUGGED! MALE CANNOT HAS THIS TRAIT</labelMale>
|
||||
<labelFemale>virgin</labelFemale>
|
||||
<description>[PAWN_nameDef] never experienced.</description>
|
||||
<degree>2</degree>
|
||||
<statOffsets>
|
||||
<SexFrequency>0.2</SexFrequency>
|
||||
</statOffsets>
|
||||
<skillGains>
|
||||
<li>
|
||||
<key>Sex</key>
|
||||
<value>-4</value>
|
||||
</li>
|
||||
</skillGains>
|
||||
<marketValueFactorOffset>0.20</marketValueFactorOffset>
|
||||
</li>
|
||||
</degreeDatas>
|
||||
</TraitDef>
|
||||
|
|
|
@ -13,6 +13,48 @@
|
|||
<RSShouldCanFuck>capable of sex is required</RSShouldCanFuck>
|
||||
<RSTotalGatheredCum>Total gathered cum: </RSTotalGatheredCum>
|
||||
<RS_LostVirgin>{1} took {0}'s virginity.</RS_LostVirgin>
|
||||
<RS_FloatMenu_CleanSelf>Gather cums on body</RS_FloatMenu_CleanSelf>
|
||||
<RS_Best_Sextype>Best sextype</RS_Best_Sextype>
|
||||
<RS_Recent_Sextype>Recent sextype</RS_Recent_Sextype>
|
||||
<RS_Sex_Partners>Sex partners</RS_Sex_Partners>
|
||||
<RS_Cum_Swallowed>Cum swallowed</RS_Cum_Swallowed>
|
||||
<RS_Selected_Partner>Selected Partner's Info</RS_Selected_Partner>
|
||||
<RS_Sex_Info>{0}: {1} times</RS_Sex_Info>
|
||||
<RS_SAT_AVG>Avg: {0}</RS_SAT_AVG>
|
||||
<RS_Sex_Count>Sex count: </RS_Sex_Count>
|
||||
<RS_Orgasms>Orgasms: </RS_Orgasms>
|
||||
<RS_Recent_Sex_Partner>Recent Sex Partner</RS_Recent_Sex_Partner>
|
||||
<RS_Recent_Sex_Partner_ToolTip>A recent sex partner.</RS_Recent_Sex_Partner_ToolTip>
|
||||
<RS_First_Sex_Partner>First Sex Partner</RS_First_Sex_Partner>
|
||||
<RS_First_Sex_Partner_ToolTip>The first sex partner.</RS_First_Sex_Partner_ToolTip>
|
||||
<RS_Most_Sex_Partner>Most Sex Partner</RS_Most_Sex_Partner>
|
||||
<RS_Most_Sex_Partner_ToolTip>The most sex partner.</RS_Most_Sex_Partner_ToolTip>
|
||||
<RS_Best_Sex_Partner>Best Sex Partner</RS_Best_Sex_Partner>
|
||||
<RS_Best_Sex_Partner_ToolTip>The partner who had most satisfying sex.</RS_Best_Sex_Partner_ToolTip>
|
||||
<RS_VirginsTaken>Taken virgins</RS_VirginsTaken>
|
||||
<RS_VirginsTaken_ToolTip>The number of partners who i taken first.</RS_VirginsTaken_ToolTip>
|
||||
<RS_TotalSexHad>Total sex had</RS_TotalSexHad>
|
||||
<RS_TotalSexHad_ToolTip>Total number of sex.</RS_TotalSexHad_ToolTip>
|
||||
<RS_Raped>Raped: </RS_Raped>
|
||||
<RS_RapedMe>Raped me: </RS_RapedMe>
|
||||
<RS_Sex_History>Sex History</RS_Sex_History>
|
||||
<RS_Statistics>Sex Statistics</RS_Statistics>
|
||||
<RS_PartnerList>Partner List</RS_PartnerList>
|
||||
<RS_Sexuality>Sexuality</RS_Sexuality>
|
||||
<RS_BeenRaped>Had been raped</RS_BeenRaped>
|
||||
<RS_RapedSomeone>Raped someone</RS_RapedSomeone>
|
||||
<RS_PreferRace>Prefer Race</RS_PreferRace>
|
||||
<RS_Bestiality>Bestiality</RS_Bestiality>
|
||||
<RS_Interspecies>Interspecies</RS_Interspecies>
|
||||
<RS_Normal>Normal</RS_Normal>
|
||||
<RS_Necrophile>Necrophile</RS_Necrophile>
|
||||
<RS_GatherCum>Gather cum</RS_GatherCum>
|
||||
<RS_SexSkill>Sex skill</RS_SexSkill>
|
||||
<RS_CumAddiction>Cum addiction</RS_CumAddiction>
|
||||
<RS_CumAddiction_Tooltip>Addicted to cum.</RS_CumAddiction_Tooltip>
|
||||
<RS_CumAddictiveness>Cum addictiveness</RS_CumAddictiveness>
|
||||
<RS_CumAddictiveness_Tooltip>More likely to get addicted to cum.</RS_CumAddictiveness_Tooltip>
|
||||
<RS_NumofTimes>times</RS_NumofTimes>
|
||||
|
||||
<RSOption_1_Label>Enable record randomizer</RSOption_1_Label>
|
||||
<RSOption_1_Desc>Randomize pawn's sex records.</RSOption_1_Desc>
|
||||
|
@ -37,4 +79,40 @@
|
|||
<RSOption_11_Label></RSOption_11_Label>
|
||||
<RSOption_11_Desc> </RSOption_11_Desc>
|
||||
|
||||
<Vaginal>Vaginal</Vaginal>
|
||||
<Anal>Anal</Anal>
|
||||
<Oral>Oral</Oral>
|
||||
<Masturbation>Masturbation</Masturbation>
|
||||
<DoublePenetration>Double penetration</DoublePenetration>
|
||||
<Boobjob>Boobjob</Boobjob>
|
||||
<Handjob>Handjob</Handjob>
|
||||
<Footjob>Footjob</Footjob>
|
||||
<Fingering>Fingering</Fingering>
|
||||
<Scissoring>Scissoring</Scissoring>
|
||||
<MutualMasturbation>Mutual masturbation</MutualMasturbation>
|
||||
<Fisting>Fisting</Fisting>
|
||||
<MechImplant>Mech implant</MechImplant>
|
||||
<Rimming>Rimming</Rimming>
|
||||
<Fellatio>Fellatio</Fellatio>
|
||||
<Cunnilingus>Cunnilingus</Cunnilingus>
|
||||
<Sixtynine>Sixtynine</Sixtynine>
|
||||
|
||||
<None>None</None>
|
||||
<Asexual>Asexual</Asexual>
|
||||
<Pansexual>Pansexual</Pansexual>
|
||||
<Heterosexual>Hetero</Heterosexual>
|
||||
<MostlyHeterosexual>Mostly hetero</MostlyHeterosexual>
|
||||
<LeaningHeterosexual>Bisexual, leaning hetero</LeaningHeterosexual>
|
||||
<Bisexual>Bisexual</Bisexual>
|
||||
<LeaningHomosexual>Bisexual, leaning gay</LeaningHomosexual>
|
||||
<MostlyHomosexual>Mostly gay</MostlyHomosexual>
|
||||
<Homosexual>Gay</Homosexual>
|
||||
|
||||
|
||||
|
||||
<Lust>lust</Lust>
|
||||
<Unknown>unknown</Unknown>
|
||||
<Virgin>virgin</Virgin>
|
||||
<Incest>incest</Incest>
|
||||
|
||||
</LanguageData>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LanguageData>
|
||||
<Bastard.label>사생아</Bastard.label>
|
||||
<Bastard.labelFemale>사생아</Bastard.labelFemale>
|
||||
</LanguageData>
|
|
@ -11,6 +11,8 @@
|
|||
<RSNotHuman>사람이 아님</RSNotHuman>
|
||||
<RSNotAnimal>동물이 아님</RSNotAnimal>
|
||||
<RSShouldCanFuck>성관계가 가능해야 합니다.</RSShouldCanFuck>
|
||||
<RSTotalGatheredCum>수집한 정액 양: </RSTotalGatheredCum>
|
||||
<RS_LostVirgin>{1}이(가) {0}의 아다를 뗐습니다.</RS_LostVirgin>
|
||||
|
||||
<RSOption_1_Label>기록 생성기 활성화</RSOption_1_Label>
|
||||
<RSOption_1_Desc>폰의 섹스기록을 무작위로 생성합니다.</RSOption_1_Desc>
|
||||
|
@ -28,4 +30,8 @@
|
|||
<RSOption_7_Desc>활성화할 경우 노예는 강간당한 경험을 가집니다.</RSOption_7_Desc>
|
||||
<RSOption_8_Label>음란함 한계</RSOption_8_Label>
|
||||
<RSOption_8_Desc>음란함의 한계치를 설정합니다. 음란함의 절대값이 이 값에 가까워지거나 클수록, 음란함이 적게 변합니다.</RSOption_8_Desc>
|
||||
<RSOption_9_Label>섹스가능 최소나이</RSOption_9_Label>
|
||||
<RSOption_9_Desc>섹스 가능한 최소나이를 설정합니다. 이 값은 RJW의 최소 나이 설정과 관계가 없고 기록을 생성하는데만 사용됩니다.</RSOption_9_Desc>
|
||||
<RSOption_10_Label>동정 비율</RSOption_10_Label>
|
||||
<RSOption_10_Desc>나이 상관없이 동정일 확률을 설정합니다.</RSOption_10_Desc>
|
||||
</LanguageData>
|
|
@ -0,0 +1,75 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<Patch>
|
||||
|
||||
<Operation Class="PatchOperationConditional">
|
||||
<xpath>Defs/ThingDef[defName="UsedCondom"]/ingestible/outcomeDoers</xpath>
|
||||
<nomatch Class="PatchOperationAdd">
|
||||
<xpath>Defs/ThingDef[defName="UsedCondom"]/ingestible</xpath>
|
||||
<value>
|
||||
<outcomeDoers>
|
||||
<li Class="IngestionOutcomeDoer_GiveHediff">
|
||||
<hediffDef>CumTolerance</hediffDef>
|
||||
<severity>0.032</severity>
|
||||
<divideByBodySize>true</divideByBodySize>
|
||||
</li>
|
||||
<li Class="IngestionOutcomeDoer_OffsetPsyfocus">
|
||||
<offset>0.05</offset>
|
||||
</li>
|
||||
<li Class="RJWSexperience.CumOutcomeDoers">
|
||||
<unitAmount>5.2</unitAmount>
|
||||
</li>
|
||||
</outcomeDoers>
|
||||
</value>
|
||||
</nomatch>
|
||||
<match Class="PatchOperationAdd">
|
||||
<xpath>Defs/ThingDef[defName="UsedCondom"]/ingestible/outcomeDoers</xpath>
|
||||
<value>
|
||||
<li Class="IngestionOutcomeDoer_GiveHediff">
|
||||
<hediffDef>CumTolerance</hediffDef>
|
||||
<severity>0.032</severity>
|
||||
<divideByBodySize>true</divideByBodySize>
|
||||
</li>
|
||||
<li Class="IngestionOutcomeDoer_OffsetPsyfocus">
|
||||
<offset>0.05</offset>
|
||||
</li>
|
||||
<li Class="RJWSexperience.CumOutcomeDoers">
|
||||
<unitAmount>5.2</unitAmount>
|
||||
</li>
|
||||
</value>
|
||||
</match>
|
||||
</Operation>
|
||||
|
||||
<Operation Class="PatchOperationConditional">
|
||||
<xpath>Defs/ThingDef[defName="UsedCondom"]/comps</xpath>
|
||||
<nomatch Class="PatchOperationAdd">
|
||||
<xpath>Defs/ThingDef[defName="UsedCondom"]</xpath>
|
||||
<value>
|
||||
<comps>
|
||||
<li Class="CompProperties_Drug">
|
||||
<chemical>Cum</chemical>
|
||||
<addictiveness>0.050</addictiveness>
|
||||
<minToleranceToAddict>0.8</minToleranceToAddict>
|
||||
<existingAddictionSeverityOffset>0.1</existingAddictionSeverityOffset>
|
||||
<needLevelOffset>1</needLevelOffset>
|
||||
<listOrder>30</listOrder>
|
||||
</li>
|
||||
</comps>
|
||||
</value>
|
||||
</nomatch>
|
||||
<match Class="PatchOperationAdd">
|
||||
<xpath>Defs/ThingDef[defName="UsedCondom"]/comps</xpath>
|
||||
<value>
|
||||
<li Class="CompProperties_Drug">
|
||||
<chemical>Cum</chemical>
|
||||
<addictiveness>0.050</addictiveness>
|
||||
<minToleranceToAddict>0.8</minToleranceToAddict>
|
||||
<existingAddictionSeverityOffset>0.1</existingAddictionSeverityOffset>
|
||||
<needLevelOffset>1</needLevelOffset>
|
||||
<listOrder>30</listOrder>
|
||||
</li>
|
||||
</value>
|
||||
</match>
|
||||
</Operation>
|
||||
|
||||
</Patch>
|
|
@ -19,16 +19,21 @@ namespace RJWSexperience.Ideology
|
|||
public const string Incestous = "[Incestuos]";
|
||||
public const string BeenRaped = "[BeenRaped]";
|
||||
public const string Rape = "[Rape]";
|
||||
public const string Spouse = "[Spouse]";
|
||||
public const string NotSpouse = "[NotSpouse]";
|
||||
|
||||
public static string Gender(Pawn pawn) => "[" + pawn.gender + "]";
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class PreceptComp_SelfTookThoughtTagged : PreceptComp_SelfTookMemoryThought
|
||||
{
|
||||
public string tag;
|
||||
public bool exclusive = false;
|
||||
public RecordDef recordDef;
|
||||
public float? recordoffset;
|
||||
//public RecordDef recordDef;
|
||||
//public float? recordoffset;
|
||||
|
||||
public PreceptComp_SelfTookThoughtTagged() { }
|
||||
|
||||
|
@ -41,28 +46,28 @@ namespace RJWSexperience.Ideology
|
|||
if (tags.ContainAll(tag.Replace(" ","").Split(',')) ^ exclusive)
|
||||
{
|
||||
TookThought(ev, precept, canApplySelfTookThoughts);
|
||||
if (ev.args.TryGetArg(HistoryEventArgsNames.Doer, out Pawn pawn))
|
||||
{
|
||||
AdjustRecord(pawn);
|
||||
}
|
||||
//if (ev.args.TryGetArg(HistoryEventArgsNames.Doer, out Pawn pawn))
|
||||
//{
|
||||
// AdjustRecord(pawn);
|
||||
//}
|
||||
}
|
||||
}
|
||||
else if (exclusive)
|
||||
{
|
||||
TookThought(ev, precept, canApplySelfTookThoughts);
|
||||
if (ev.args.TryGetArg(HistoryEventArgsNames.Doer, out Pawn pawn))
|
||||
{
|
||||
AdjustRecord(pawn);
|
||||
}
|
||||
//if (ev.args.TryGetArg(HistoryEventArgsNames.Doer, out Pawn pawn))
|
||||
//{
|
||||
// AdjustRecord(pawn);
|
||||
//}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TookThought(ev, precept, canApplySelfTookThoughts);
|
||||
if (ev.args.TryGetArg(HistoryEventArgsNames.Doer, out Pawn pawn))
|
||||
{
|
||||
AdjustRecord(pawn);
|
||||
}
|
||||
//if (ev.args.TryGetArg(HistoryEventArgsNames.Doer, out Pawn pawn))
|
||||
//{
|
||||
// AdjustRecord(pawn);
|
||||
//}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -99,13 +104,13 @@ namespace RJWSexperience.Ideology
|
|||
}
|
||||
|
||||
|
||||
protected void AdjustRecord(Pawn pawn)
|
||||
{
|
||||
if (recordDef != null)
|
||||
{
|
||||
pawn.records.AddTo(recordDef, recordoffset ?? 1f);
|
||||
}
|
||||
}
|
||||
//protected void AdjustRecord(Pawn pawn)
|
||||
//{
|
||||
// if (recordDef != null)
|
||||
// {
|
||||
// pawn.records.AddTo(recordDef, recordoffset ?? 1f);
|
||||
// }
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
|
||||
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
public class PreceptDef_RequirementExtended : PreceptDef
|
||||
{
|
||||
public List<MemeDef> requiredAllMemes = new List<MemeDef>();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -59,8 +59,8 @@ namespace RJWSexperience.Ideology
|
|||
|
||||
public static float BestialityByPrecept(Ideo ideo)
|
||||
{
|
||||
if (ideo.HasPrecept(VariousDefOf.Bestiality_Honorable)) return 0.3f;
|
||||
else if (ideo.HasPrecept(VariousDefOf.Bestiality_OnlyVenerated)) return 0.6f;
|
||||
if (ideo.HasPrecept(VariousDefOf.Bestiality_Honorable)) return 0.5f;
|
||||
else if (ideo.HasPrecept(VariousDefOf.Bestiality_OnlyVenerated)) return 0.65f;
|
||||
else if (ideo.HasPrecept(VariousDefOf.Bestiality_Acceptable)) return 0.75f;
|
||||
else if (ideo.HasPrecept(VariousDefOf.Bestiality_Disapproved)) return 1.0f;
|
||||
else return 5f;
|
||||
|
@ -78,13 +78,30 @@ namespace RJWSexperience.Ideology
|
|||
|
||||
public static float RapeByPrecept(Ideo ideo)
|
||||
{
|
||||
if (ideo.HasPrecept(VariousDefOf.Rape_Honorable)) return 0.25f;
|
||||
else if (ideo.HasPrecept(VariousDefOf.Rape_Acceptable)) return 0.5f;
|
||||
if (ideo.HasPrecept(VariousDefOf.Rape_Honorable)) return 0.5f;
|
||||
else if (ideo.HasPrecept(VariousDefOf.Rape_Acceptable)) return 0.75f;
|
||||
else if (ideo.HasPrecept(VariousDefOf.Rape_Disapproved)) return 1.0f;
|
||||
else return 3f;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(ThinkNode_ChancePerHour_Necro), "MtbHours")]
|
||||
public static class RJW_Patch_ThinkNode_ChancePerHour_Necro
|
||||
{
|
||||
public static void Postfix(Pawn pawn, ref float __result)
|
||||
{
|
||||
Ideo ideo = pawn.Ideo;
|
||||
if (ideo != null) __result *= NecroByPrecept(ideo); // ideo is null if don't have dlc
|
||||
}
|
||||
|
||||
public static float NecroByPrecept(Ideo ideo)
|
||||
{
|
||||
if (ideo.HasPrecept(VariousDefOf.Necrophilia_Approved)) return 0.5f;
|
||||
else if (ideo.HasPrecept(VariousDefOf.Necrophilia_Acceptable)) return 0.75f;
|
||||
else if (ideo.HasPrecept(VariousDefOf.Necrophilia_Disapproved)) return 1.0f;
|
||||
else return 8f;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(xxx), "is_rapist")]
|
||||
public static class RJW_Patch_is_rapist
|
||||
|
@ -371,6 +388,19 @@ namespace RJWSexperience.Ideology
|
|||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(PawnDesignations_Comfort), "UpdateCanDesignateComfort")]
|
||||
public static class RJW_PatchUpdateCanDesignateComfort
|
||||
{
|
||||
public static void Postfix(Pawn pawn, ref bool __result)
|
||||
{
|
||||
if (pawn.IsSubmissive())
|
||||
{
|
||||
SaveStorage.DataStore.GetPawnData(pawn).CanDesignateComfort = true;
|
||||
__result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(Hediff_BasePregnancy), "PostBirth")]
|
||||
public static class RJW_Patch_PostBirth
|
||||
{
|
||||
|
|
|
@ -55,5 +55,36 @@ namespace RJWSexperience.Ideology
|
|||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(IdeoFoundation), "CanAdd")]
|
||||
public static class Rimworld_Patch_IdeoFoundation
|
||||
{
|
||||
public static void Postfix(PreceptDef precept, bool checkDuplicates, ref IdeoFoundation __instance, ref AcceptanceReport __result)
|
||||
{
|
||||
if (precept is PreceptDef_RequirementExtended)
|
||||
{
|
||||
PreceptDef_RequirementExtended def = precept as PreceptDef_RequirementExtended;
|
||||
if (!def.requiredAllMemes.NullOrEmpty())
|
||||
{
|
||||
for (int i=0; i< def.requiredAllMemes.Count; i++)
|
||||
{
|
||||
if (!__instance.ideo.memes.Contains(def.requiredAllMemes[i]))
|
||||
{
|
||||
List<string> report = new List<string>();
|
||||
foreach (MemeDef meme in def.requiredAllMemes) report.Add(meme.LabelCap);
|
||||
|
||||
__result = new AcceptanceReport("RequiresMeme".Translate() + ": " + report.ToCommaList());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Verse;
|
||||
using Verse.AI;
|
||||
using Verse.AI.Group;
|
||||
using RimWorld;
|
||||
using rjw;
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
public class JobGiver_GangbangConsensual : ThinkNode_JobGiver
|
||||
{
|
||||
protected override Job TryGiveJob(Pawn pawn)
|
||||
{
|
||||
if (pawn.Drafted) return null;
|
||||
DutyDef dutyDef = null;
|
||||
PawnDuty duty = null;
|
||||
if (pawn.mindState != null)
|
||||
{
|
||||
duty = pawn.mindState.duty;
|
||||
dutyDef = duty.def;
|
||||
}
|
||||
else return null;
|
||||
|
||||
if (dutyDef == DutyDefOf.TravelOrLeave || !xxx.can_fuck(pawn))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Pawn target = duty.focusSecond.Pawn;
|
||||
|
||||
if (!pawn.CanReach(target, PathEndMode.ClosestTouch, Danger.None)) return null;
|
||||
|
||||
return JobMaker.MakeJob(VariousDefOf.Gangbang, target);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class JobDriver_Gangbang : JobDriver_SexBaseInitiator
|
||||
{
|
||||
public override bool TryMakePreToilReservations(bool errorOnFailed)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override IEnumerable<Toil> MakeNewToils()
|
||||
{
|
||||
//ModLog.Message("" + this.GetType().ToString() + "::MakeNewToils() called");
|
||||
setup_ticks();
|
||||
|
||||
this.FailOnDespawnedNullOrForbidden(iTarget);
|
||||
this.FailOn(() => Partner == null);
|
||||
this.FailOn(() => pawn.Drafted);
|
||||
this.FailOn(() => Partner.Drafted);
|
||||
yield return Toils_Goto.GotoThing(iTarget, PathEndMode.OnCell);
|
||||
|
||||
Toil StartPartnerJob = new Toil();
|
||||
StartPartnerJob.defaultCompleteMode = ToilCompleteMode.Instant;
|
||||
StartPartnerJob.socialMode = RandomSocialMode.Off;
|
||||
StartPartnerJob.initAction = delegate
|
||||
{
|
||||
|
||||
var dri = Partner.jobs.curDriver as JobDriver_SexBaseRecieverRaped;
|
||||
if (dri == null)
|
||||
{
|
||||
Job gettin_loved = JobMaker.MakeJob(VariousDefOf.GettinGangbang, pawn, Bed);
|
||||
Partner.jobs.StartJob(gettin_loved, JobCondition.InterruptForced);
|
||||
}
|
||||
};
|
||||
yield return StartPartnerJob;
|
||||
|
||||
Toil SexToil = new Toil();
|
||||
SexToil.defaultCompleteMode = ToilCompleteMode.Never;
|
||||
SexToil.defaultDuration = duration;
|
||||
SexToil.handlingFacing = true;
|
||||
SexToil.FailOn(() => Partner.CurJob.def != VariousDefOf.GettinGangbang);
|
||||
SexToil.initAction = delegate
|
||||
{
|
||||
Start();
|
||||
Sexprops.usedCondom = CondomUtility.TryUseCondom(pawn) || CondomUtility.TryUseCondom(Partner);
|
||||
};
|
||||
SexToil.AddPreTickAction(delegate
|
||||
{
|
||||
SexTick(pawn, Partner);
|
||||
SexUtility.reduce_rest(Partner, 1);
|
||||
SexUtility.reduce_rest(pawn, 2);
|
||||
if (ticks_left <= 0)
|
||||
ReadyForNextToil();
|
||||
});
|
||||
SexToil.AddFinishAction(delegate
|
||||
{
|
||||
End();
|
||||
});
|
||||
yield return SexToil;
|
||||
|
||||
yield return new Toil
|
||||
{
|
||||
initAction = delegate
|
||||
{
|
||||
// Trying to add some interactions and social logs
|
||||
SexUtility.ProcessSex(Sexprops);
|
||||
},
|
||||
defaultCompleteMode = ToilCompleteMode.Instant
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class JobDriver_GangbangReceiver : JobDriver_SexBaseRecieverLoved
|
||||
{
|
||||
protected override IEnumerable<Toil> MakeNewToils()
|
||||
{
|
||||
setup_ticks();
|
||||
parteners.Add(Partner);// add job starter, so this wont fail, before Initiator starts his job
|
||||
|
||||
Toil get_banged = new Toil();
|
||||
get_banged.defaultCompleteMode = ToilCompleteMode.Never;
|
||||
get_banged.handlingFacing = true;
|
||||
get_banged.initAction = delegate
|
||||
{
|
||||
pawn.pather.StopDead();
|
||||
pawn.jobs.curDriver.asleep = false;
|
||||
};
|
||||
get_banged.tickAction = delegate
|
||||
{
|
||||
if ((parteners.Count > 0) && (pawn.IsHashIntervalTick(ticks_between_hearts / parteners.Count)))
|
||||
if (pawn.IsHashIntervalTick(ticks_between_hearts))
|
||||
ThrowMetaIconF(pawn.Position, pawn.Map, FleckDefOf.Heart);
|
||||
};
|
||||
get_banged.AddEndCondition(new Func<JobCondition>(() =>
|
||||
{
|
||||
if (parteners.Count <= 0)
|
||||
{
|
||||
return JobCondition.Succeeded;
|
||||
}
|
||||
return JobCondition.Ongoing;
|
||||
}));
|
||||
get_banged.AddFinishAction(delegate
|
||||
{
|
||||
if (xxx.is_human(pawn))
|
||||
pawn.Drawer.renderer.graphics.ResolveApparelGraphics();
|
||||
GlobalTextureAtlasManager.TryMarkPawnFrameSetDirty(pawn);
|
||||
|
||||
if (Bed != null && pawn.Downed)
|
||||
{
|
||||
Job tobed = JobMaker.MakeJob(JobDefOf.Rescue, pawn, Bed);
|
||||
tobed.count = 1;
|
||||
Partner.jobs.jobQueue.EnqueueFirst(tobed);
|
||||
//Log.Message(xxx.get_pawnname(Initiator) + ": job tobed:" + tobed);
|
||||
}
|
||||
else if (pawn.HostileTo(Partner))
|
||||
pawn.health.AddHediff(xxx.submitting);
|
||||
});
|
||||
get_banged.socialMode = RandomSocialMode.Off;
|
||||
yield return get_banged;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -26,7 +26,7 @@ namespace RJWSexperience.Ideology
|
|||
}
|
||||
else return null;
|
||||
|
||||
if (dutyDef == DutyDefOf.TravelOrLeave || !xxx.can_rape(pawn, true))
|
||||
if (dutyDef == DutyDefOf.TravelOrLeave || !xxx.can_fuck(pawn))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
@ -57,7 +57,6 @@ namespace RJWSexperience.Ideology
|
|||
var PartnerJob = xxx.gettin_raped;
|
||||
|
||||
this.FailOnDespawnedNullOrForbidden(iTarget);
|
||||
//this.FailOn(() => (!Partner.health.capacities.CanBeAwake) || (!comfort_prisoners.is_designated(Partner)));//this is wrong
|
||||
this.FailOn(() => Partner == null);
|
||||
this.FailOn(() => pawn.Drafted);
|
||||
this.FailOn(() => Partner.Drafted);
|
||||
|
|
|
@ -14,11 +14,11 @@ namespace RJWSexperience.Ideology
|
|||
{
|
||||
public LordJob_Ritual_Gangbang() { }
|
||||
|
||||
public LordJob_Ritual_Gangbang(TargetInfo selectedTarget, Precept_Ritual ritual, RitualObligation obligation, List<RitualStage> allStages, RitualRoleAssignments assignments, Pawn organizer = null) : base(selectedTarget, ritual, obligation, allStages, assignments, organizer)
|
||||
public LordJob_Ritual_Gangbang(string targetID ,TargetInfo selectedTarget, Precept_Ritual ritual, RitualObligation obligation, List<RitualStage> allStages, RitualRoleAssignments assignments, Pawn organizer = null) : base(selectedTarget, ritual, obligation, allStages, assignments, organizer)
|
||||
{
|
||||
foreach (RitualRole ritualRole in assignments.AllRolesForReading)
|
||||
{
|
||||
if (ritualRole != null && ritualRole.id.Contains("victim"))
|
||||
if (ritualRole != null && ritualRole.id.Contains(targetID))
|
||||
{
|
||||
Pawn item = assignments.FirstAssignedPawn(ritualRole);
|
||||
pawnsDeathIgnored.Add(item);
|
||||
|
|
|
@ -23,17 +23,27 @@ namespace RJWSexperience.Ideology
|
|||
{
|
||||
WorkGiver_Warden_TakeToBed.TryTakePrisonerToBed(pawn, warden);
|
||||
pawn.guest.WaitInsteadOfEscapingFor(1250);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected override LordJob CreateLordJob(TargetInfo target, Pawn organizer, Precept_Ritual ritual, RitualObligation obligation, RitualRoleAssignments assignments)
|
||||
{
|
||||
return new LordJob_Ritual_Gangbang(target, ritual, obligation, def.stages, assignments, organizer);
|
||||
return new LordJob_Ritual_Gangbang("victim", target, ritual, obligation, def.stages, assignments, organizer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class RitualBehaviorWorker_Gangbang_Consensual : RitualBehaviorWorker
|
||||
{
|
||||
public RitualBehaviorWorker_Gangbang_Consensual() { }
|
||||
|
||||
public RitualBehaviorWorker_Gangbang_Consensual(RitualBehaviorDef def) : base(def) { }
|
||||
|
||||
protected override LordJob CreateLordJob(TargetInfo target, Pawn organizer, Precept_Ritual ritual, RitualObligation obligation, RitualRoleAssignments assignments)
|
||||
{
|
||||
return new LordJob_Ritual_Gangbang("initiator", target, ritual, obligation, def.stages, assignments, organizer);
|
||||
}
|
||||
}
|
||||
|
||||
public class RitualStage_InteractWithVictim : RitualStage
|
||||
{
|
||||
public override TargetInfo GetSecondFocus(LordJob_Ritual ritual)
|
||||
|
@ -49,5 +59,11 @@ namespace RJWSexperience.Ideology
|
|||
return ritual.assignments.AssignedPawns("victim").FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
public class RitualStage_InteractWithInitiator : RitualStage
|
||||
{
|
||||
public override TargetInfo GetSecondFocus(LordJob_Ritual ritual)
|
||||
{
|
||||
return ritual.assignments.AssignedPawns("initiator").FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HarmonyLib;
|
||||
using rjw;
|
||||
using RJWSexperience;
|
||||
using Verse;
|
||||
using RimWorld;
|
||||
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
[HarmonyPatch(typeof(RJWUtility), "ThrowVirginHIstoryEvent")]
|
||||
public static class Sexperience_Patch_ThrowVirginHIstoryEvent
|
||||
{
|
||||
public static void Postfix(Pawn pawn, Pawn partner, SexProps props, int degree)
|
||||
{
|
||||
string tag = "";
|
||||
if (props.isRape)
|
||||
{
|
||||
if (pawn == props.pawn && props.isRapist) tag += HETag.Rape;
|
||||
else tag += HETag.BeenRaped;
|
||||
}
|
||||
if (!pawn.relations.DirectRelationExists(PawnRelationDefOf.Spouse, partner))
|
||||
{
|
||||
tag += HETag.NotSpouse;
|
||||
}
|
||||
|
||||
|
||||
if (pawn.gender == Gender.Male)
|
||||
{
|
||||
if (degree > 1) Find.HistoryEventsManager.RecordEvent(VariousDefOf.Virgin_TakenM.TaggedEvent(pawn, tag + HETag.Gender(pawn), partner));
|
||||
Find.HistoryEventsManager.RecordEvent(VariousDefOf.Virgin_TookM.TaggedEvent(partner, tag + HETag.Gender(pawn), pawn));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (degree > 1) Find.HistoryEventsManager.RecordEvent(VariousDefOf.Virgin_TakenF.TaggedEvent(pawn, tag + HETag.Gender(pawn), partner));
|
||||
Find.HistoryEventsManager.RecordEvent(VariousDefOf.Virgin_TookF.TaggedEvent(partner, tag + HETag.Gender(pawn), pawn));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(Utility), "IsIncest")]
|
||||
public static class Sexperience_Patch_IsIncest
|
||||
{
|
||||
public static bool Prefix(Pawn pawn, Pawn otherpawn, ref bool __result)
|
||||
{
|
||||
__result = IsIncest(pawn, otherpawn);
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsIncest(Pawn pawn, Pawn partner)
|
||||
{
|
||||
IEnumerable<PawnRelationDef> relations = pawn.GetRelations(partner);
|
||||
Ideo ideo = pawn.Ideo;
|
||||
bool wide = false;
|
||||
if (ideo != null) wide = ideo.HasPrecept(VariousDefOf.Incestuos_Disapproved_CloseOnly);
|
||||
if (!relations.EnumerableNullOrEmpty()) foreach (PawnRelationDef relation in relations)
|
||||
{
|
||||
if (wide)
|
||||
{
|
||||
if (relation.incestOpinionOffset < 0) return true;
|
||||
}
|
||||
else if (relation.familyByBloodRelation) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -10,25 +10,9 @@ using UnityEngine;
|
|||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
public static class Utility
|
||||
public static class IdeoUtility
|
||||
{
|
||||
|
||||
public static bool IsIncest(this Pawn pawn, Pawn partner)
|
||||
{
|
||||
IEnumerable<PawnRelationDef> relations = pawn.GetRelations(partner);
|
||||
Ideo ideo = pawn.Ideo;
|
||||
bool wide = false;
|
||||
if (ideo != null) wide = ideo.HasPrecept(VariousDefOf.Incestuos_Disapproved_CloseOnly);
|
||||
if (!relations.EnumerableNullOrEmpty()) foreach (PawnRelationDef relation in relations)
|
||||
{
|
||||
if (wide)
|
||||
{
|
||||
if (relation.incestOpinionOffset < 0) return true;
|
||||
}
|
||||
else if (relation.familyByBloodRelation) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsSubmissive(this Pawn pawn)
|
||||
{
|
||||
|
|
|
@ -95,9 +95,12 @@
|
|||
<ItemGroup>
|
||||
<Compile Include="Ideology\GoodwillSituationWorker_MemeCompatibility.cs" />
|
||||
<Compile Include="Harmony.cs" />
|
||||
<Compile Include="Ideology\PreceptDef_RequirementExtended.cs" />
|
||||
<Compile Include="Ideology\Rituals\JobGiver_GangbangConsensual.cs" />
|
||||
<Compile Include="Ideology\Rituals\LordJob_Rituals.cs" />
|
||||
<Compile Include="Ideology\RJW_Patch_Ideo.cs" />
|
||||
<Compile Include="Ideology\PreceptComp_SelftTookThoughtExtended.cs" />
|
||||
<Compile Include="Ideology\Sexperience_Patch.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Ideology\Rimworld_Patch.cs" />
|
||||
<Compile Include="Ideology\Rituals\JobGiver_DrugOrgy.cs" />
|
||||
|
|
|
@ -11,6 +11,8 @@ namespace RJWSexperience.Ideology
|
|||
public static class VariousDefOf
|
||||
{
|
||||
public static readonly JobDef RapeVictim = DefDatabase<JobDef>.GetNamed("RapeVictim");
|
||||
public static readonly JobDef Gangbang = DefDatabase<JobDef>.GetNamed("Gangbang");
|
||||
public static readonly JobDef GettinGangbang = DefDatabase<JobDef>.GetNamed("GettinGangbang");
|
||||
public static readonly JobDef DrugSex = DefDatabase<JobDef>.GetNamed("DrugSex");
|
||||
public static readonly JobDef GettinDrugSex = DefDatabase<JobDef>.GetNamed("GettinDrugSex");
|
||||
public static readonly JobDef DrugMasturbate = DefDatabase<JobDef>.GetNamed("DrugMasturbate");
|
||||
|
@ -34,6 +36,10 @@ namespace RJWSexperience.Ideology
|
|||
[MayRequireIdeology] public static readonly HistoryEventDef PromiscuousSex = DefDatabase<HistoryEventDef>.GetNamed("PromiscuousSex");
|
||||
[MayRequireIdeology] public static readonly HistoryEventDef Incestuos_Marriage = DefDatabase<HistoryEventDef>.GetNamed("Incestuos_Marriage");
|
||||
[MayRequireIdeology] public static readonly HistoryEventDef SexWithCorpse = DefDatabase<HistoryEventDef>.GetNamed("SexWithCorpse");
|
||||
[MayRequireIdeology] public static readonly HistoryEventDef Virgin_TakenF = DefDatabase<HistoryEventDef>.GetNamed("Virgin_TakenF");
|
||||
[MayRequireIdeology] public static readonly HistoryEventDef Virgin_TakenM = DefDatabase<HistoryEventDef>.GetNamed("Virgin_TakenM");
|
||||
[MayRequireIdeology] public static readonly HistoryEventDef Virgin_TookF = DefDatabase<HistoryEventDef>.GetNamed("Virgin_TookF");
|
||||
[MayRequireIdeology] public static readonly HistoryEventDef Virgin_TookM = DefDatabase<HistoryEventDef>.GetNamed("Virgin_TookM");
|
||||
[MayRequireIdeology] public static readonly PreceptDef Bestiality_Abhorrent = DefDatabase<PreceptDef>.GetNamed("Bestiality_Abhorrent");
|
||||
[MayRequireIdeology] public static readonly PreceptDef Bestiality_Horrible = DefDatabase<PreceptDef>.GetNamed("Bestiality_Horrible");
|
||||
[MayRequireIdeology] public static readonly PreceptDef Bestiality_Disapproved = DefDatabase<PreceptDef>.GetNamed("Bestiality_Disapproved");
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using Verse;
|
||||
using RimWorld;
|
||||
using rjw;
|
||||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
|
@ -43,7 +44,11 @@ namespace RJWSexperience
|
|||
int num = (int)storedcum;
|
||||
|
||||
cum.stackCount = num;
|
||||
if (cum.stackCount > 0) GenPlace.TryPlaceThing(cum, PositionHeld, Map, ThingPlaceMode.Direct, out Thing res);
|
||||
if (cum.stackCount > 0)
|
||||
{
|
||||
if (!GenPlace.TryPlaceThing(cum, PositionHeld, Map, ThingPlaceMode.Direct, out Thing res))
|
||||
FilthMaker.TryMakeFilth(PositionHeld, Map, VariousDefOf.FilthCum, num);
|
||||
}
|
||||
storedcum -= num;
|
||||
}
|
||||
|
|
@ -36,6 +36,8 @@ namespace RJWSexperience
|
|||
public static float MinSexablePercent = MinSexablePercentDefault;
|
||||
public static float VirginRatio = VirginRatioDefault;
|
||||
|
||||
public static bool SelectionLocked = false;
|
||||
|
||||
public static void ResettoDefault()
|
||||
{
|
||||
MaxLustDeviation = MaxInitialLustDefault;
|
||||
|
@ -62,6 +64,7 @@ namespace RJWSexperience
|
|||
Scribe_Values.Look(ref LustLimit, "LustLimit", LustLimit, true);
|
||||
Scribe_Values.Look(ref MinSexablePercent, "MinSexablePercent", MinSexablePercent, true);
|
||||
Scribe_Values.Look(ref VirginRatio, "VirginRatio", VirginRatio, true);
|
||||
Scribe_Values.Look(ref SelectionLocked, "SelectionLocked", SelectionLocked, true);
|
||||
base.ExposeData();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,25 @@ namespace RJWSexperience
|
|||
{
|
||||
public static class DebugToolsSexperience
|
||||
{
|
||||
[DebugAction("RJW Sexperience", "Reset pawn's record", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.PlayingOnMap)]
|
||||
private static void ResetRecords(Pawn p)
|
||||
{
|
||||
Trait virgin = p.story?.traits?.GetTrait(VariousDefOf.Virgin);
|
||||
if (virgin != null) p.story.traits.RemoveTrait(virgin);
|
||||
p.ResetRecord(true);
|
||||
p.ResetRecord(false);
|
||||
MoteMaker.ThrowText(p.TrueCenter(), p.Map, "Records resetted!");
|
||||
}
|
||||
|
||||
[DebugAction("RJW Sexperience", "Reset pawn's record(virgin)", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.PlayingOnMap)]
|
||||
private static void ResetRecordsZero(Pawn p)
|
||||
{
|
||||
p.ResetRecord(true);
|
||||
p.AddVirginTrait();
|
||||
MoteMaker.ThrowText(p.TrueCenter(), p.Map, "Records resetted!\nVirginified!");
|
||||
}
|
||||
|
||||
|
||||
[DebugAction("RJW Sexperience", "Reset lust", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.PlayingOnMap)]
|
||||
private static void ResetLust(Pawn p)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using rjw;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
|
||||
|
||||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
public class CumOutcomeDoers : IngestionOutcomeDoer
|
||||
{
|
||||
public float unitAmount = 1.0f;
|
||||
|
||||
protected override void DoIngestionOutcomeSpecial(Pawn pawn, Thing ingested)
|
||||
{
|
||||
pawn.AteCum(ingested.stackCount * unitAmount);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
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 RJWSexperience
|
||||
{
|
||||
public class JobGiver_UseBucket : ThinkNode_JobGiver
|
||||
{
|
||||
protected override Job TryGiveJob(Pawn pawn)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class JobDriver_CleanSelfWithBucket : JobDriver
|
||||
{
|
||||
const int UNITTIME = 240;//ticks - 120 = 2 real seconds, 3 in-game minutes
|
||||
protected float progress = 0;
|
||||
protected float severitycache = 1;
|
||||
protected Hediff hediffcache;
|
||||
protected float CleaningTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return severitycache * UNITTIME;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected Building_CumBucket Bucket => TargetB.Thing as Building_CumBucket;
|
||||
|
||||
public override bool TryMakePreToilReservations(bool errorOnFailed)
|
||||
{
|
||||
return pawn.Reserve(pawn, job, 1, -1, null, errorOnFailed);
|
||||
}
|
||||
|
||||
protected override IEnumerable<Toil> MakeNewToils()
|
||||
{
|
||||
|
||||
this.FailOn(delegate
|
||||
{
|
||||
List<Hediff> hediffs = pawn.health.hediffSet.hediffs;
|
||||
return !hediffs.Exists(x => x.def == RJW_SemenoOverlayHediffDefOf.Hediff_Bukkake);
|
||||
});
|
||||
yield return Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch);
|
||||
Toil cleaning = new Toil();
|
||||
cleaning.initAction = CleaningInit;
|
||||
cleaning.tickAction = CleaningTick;
|
||||
cleaning.AddFinishAction(Finish);
|
||||
cleaning.defaultCompleteMode = ToilCompleteMode.Never;
|
||||
cleaning.WithProgressBar(TargetIndex.A, () => progress/CleaningTime);
|
||||
|
||||
yield return cleaning;
|
||||
yield break;
|
||||
}
|
||||
|
||||
protected void CleaningInit()
|
||||
{
|
||||
hediffcache = pawn.health.hediffSet.hediffs.Find(x => (x.def == RJW_SemenoOverlayHediffDefOf.Hediff_Semen || x.def == RJW_SemenoOverlayHediffDefOf.Hediff_InsectSpunk));
|
||||
if (hediffcache == null)
|
||||
{
|
||||
pawn.jobs.EndCurrentJob(JobCondition.Succeeded);
|
||||
}
|
||||
else
|
||||
{
|
||||
progress = 0;
|
||||
severitycache = hediffcache.Severity;
|
||||
}
|
||||
}
|
||||
|
||||
protected void CleaningTick()
|
||||
{
|
||||
progress += 1;
|
||||
if (progress > CleaningTime)
|
||||
{
|
||||
Cleaned();
|
||||
}
|
||||
}
|
||||
|
||||
protected void Cleaned()
|
||||
{
|
||||
if (hediffcache != null)
|
||||
{
|
||||
float cumamount = hediffcache.Severity * 10;
|
||||
hediffcache.Severity = 0;
|
||||
Bucket.AddCum(cumamount);
|
||||
}
|
||||
CleaningInit();
|
||||
}
|
||||
|
||||
protected void Finish()
|
||||
{
|
||||
if (pawn.CurJobDef == JobDefOf.Wait_MaintainPosture)
|
||||
{
|
||||
pawn.jobs.EndCurrentJob(JobCondition.InterruptForced);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -5,7 +5,8 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using Verse;
|
||||
using RimWorld;
|
||||
|
||||
using rjw;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
|
@ -14,7 +15,9 @@ namespace RJWSexperience
|
|||
public static string LustStatFactor(string value) => "LustStatFactor".Translate(value);
|
||||
public static string SlaveStatFactor(string value) => "SlaveStatFactor".Translate(value);
|
||||
public static string MemeStatFactor(string value) => "MemeStatFactor".Translate(value);
|
||||
public static string RS_LostVirgin(string pawn, string partner) => "RS_LostVirgin".Translate(pawn,partner);
|
||||
public static string RS_LostVirgin(string pawn, string partner) => "RS_LostVirgin".Translate(pawn.Colorize(Color.yellow),partner.Colorize(Color.yellow));
|
||||
public static string RS_Sex_Info(string sextype, string sexcount) => "RS_Sex_Info".Translate(sextype, sexcount);
|
||||
public static string RS_SAT_AVG(string avgsat) => "RS_SAT_AVG".Translate(avgsat);
|
||||
|
||||
public static readonly string Mod_Title = "RS_Mod_Title".Translate();
|
||||
public static readonly string SlaveStatFactorDefault = "SlaveStatFactorDefault".Translate();
|
||||
|
@ -24,6 +27,50 @@ namespace RJWSexperience
|
|||
public static readonly string RSNotAnimal = "RSNotAnimal".Translate();
|
||||
public static readonly string RSShouldCanFuck = "RSShouldCanFuck".Translate();
|
||||
public static readonly string RSTotalGatheredCum = "RSTotalGatheredCum".Translate();
|
||||
public static readonly string RS_FloatMenu_CleanSelf = "RS_FloatMenu_CleanSelf".Translate();
|
||||
public static readonly string RS_Best_Sextype = "RS_Best_Sextype".Translate();
|
||||
public static readonly string RS_Recent_Sextype = "RS_Recent_Sextype".Translate();
|
||||
public static readonly string RS_Sex_Partners = "RS_Sex_Partners".Translate();
|
||||
public static readonly string RS_Cum_Swallowed = "RS_Cum_Swallowed".Translate();
|
||||
public static readonly string RS_Selected_Partner = "RS_Selected_Partner".Translate();
|
||||
public static readonly string RS_Sex_Count = "RS_Sex_Count".Translate();
|
||||
public static readonly string RS_Orgasms = "RS_Orgasms".Translate();
|
||||
public static readonly string RS_Recent_Sex_Partner = "RS_Recent_Sex_Partner".Translate();
|
||||
public static readonly string RS_First_Sex_Partner = "RS_First_Sex_Partner".Translate();
|
||||
public static readonly string RS_Most_Sex_Partner = "RS_Most_Sex_Partner".Translate();
|
||||
public static readonly string RS_Best_Sex_Partner = "RS_Best_Sex_Partner".Translate();
|
||||
public static readonly string RS_VirginsTaken = "RS_VirginsTaken".Translate();
|
||||
public static readonly string RS_TotalSexHad = "RS_TotalSexHad".Translate();
|
||||
public static readonly string RS_Recent_Sex_Partner_ToolTip = "RS_Recent_Sex_Partner_ToolTip".Translate();
|
||||
public static readonly string RS_First_Sex_Partner_ToolTip = "RS_First_Sex_Partner_ToolTip".Translate();
|
||||
public static readonly string RS_Most_Sex_Partner_ToolTip = "RS_Most_Sex_Partner_ToolTip".Translate();
|
||||
public static readonly string RS_Best_Sex_Partner_ToolTip = "RS_Best_Sex_Partner_ToolTip".Translate();
|
||||
public static readonly string RS_VirginsTaken_ToolTip = "RS_VirginsTaken_ToolTip".Translate();
|
||||
public static readonly string RS_TotalSexHad_ToolTip = "RS_TotalSexHad_ToolTip".Translate();
|
||||
public static readonly string RS_Raped = "RS_Raped".Translate();
|
||||
public static readonly string RS_RapedMe = "RS_RapedMe".Translate();
|
||||
public static readonly string RS_Sex_History = "RS_Sex_History".Translate();
|
||||
public static readonly string RS_Statistics = "RS_Statistics".Translate();
|
||||
public static readonly string RS_PartnerList = "RS_PartnerList".Translate();
|
||||
public static readonly string RS_Sexuality = "RS_Sexuality".Translate();
|
||||
public static readonly string RS_BeenRaped = "RS_BeenRaped".Translate();
|
||||
public static readonly string RS_RapedSomeone = "RS_RapedSomeone".Translate();
|
||||
public static readonly string RS_PreferRace = "RS_PreferRace".Translate();
|
||||
public static readonly string Lust = "Lust".Translate();
|
||||
public static readonly string Unknown = "Unknown".Translate();
|
||||
public static readonly string Incest = "Incest".Translate();
|
||||
public static readonly string None = "None".Translate();
|
||||
public static readonly string RS_Bestiality = "RS_Bestiality".Translate();
|
||||
public static readonly string RS_Interspecies = "RS_Interspecies".Translate();
|
||||
public static readonly string RS_Normal = "RS_Normal".Translate();
|
||||
public static readonly string RS_Necrophile = "RS_Necrophile".Translate();
|
||||
public static readonly string RS_GatherCum = "RS_GatherCum".Translate();
|
||||
public static readonly string RS_SexSkill = "RS_SexSkill".Translate();
|
||||
public static readonly string RS_CumAddiction = "RS_CumAddiction".Translate();
|
||||
public static readonly string RS_CumAddiction_Tooltip = "RS_CumAddiction_Tooltip".Translate();
|
||||
public static readonly string RS_CumAddictiveness = "RS_CumAddictiveness".Translate();
|
||||
public static readonly string RS_CumAddictiveness_Tooltip = "RS_CumAddictiveness_Tooltip".Translate();
|
||||
public static readonly string RS_NumofTimes = "RS_NumofTimes".Translate();
|
||||
|
||||
|
||||
public static readonly string Option_1_Label = "RSOption_1_Label".Translate();
|
||||
|
@ -49,5 +96,46 @@ namespace RJWSexperience
|
|||
public static readonly string Option_11_Label = "RSOption_11_Label".Translate();
|
||||
public static readonly string Option_11_Desc = "RSOption_11_Desc".Translate();
|
||||
|
||||
|
||||
public static readonly string[] Sextype =
|
||||
{
|
||||
((xxx.rjwSextype)0).ToString().Translate(),
|
||||
((xxx.rjwSextype)1).ToString().Translate(),
|
||||
((xxx.rjwSextype)2).ToString().Translate(),
|
||||
((xxx.rjwSextype)3).ToString().Translate(),
|
||||
((xxx.rjwSextype)4).ToString().Translate(),
|
||||
((xxx.rjwSextype)5).ToString().Translate(),
|
||||
((xxx.rjwSextype)6).ToString().Translate(),
|
||||
((xxx.rjwSextype)7).ToString().Translate(),
|
||||
((xxx.rjwSextype)8).ToString().Translate(),
|
||||
((xxx.rjwSextype)9).ToString().Translate(),
|
||||
((xxx.rjwSextype)10).ToString().Translate(),
|
||||
((xxx.rjwSextype)11).ToString().Translate(),
|
||||
((xxx.rjwSextype)12).ToString().Translate(),
|
||||
((xxx.rjwSextype)13).ToString().Translate(),
|
||||
((xxx.rjwSextype)14).ToString().Translate(),
|
||||
((xxx.rjwSextype)15).ToString().Translate(),
|
||||
((xxx.rjwSextype)16).ToString().Translate(),
|
||||
((xxx.rjwSextype)17).ToString().Translate(),
|
||||
((xxx.rjwSextype)18).ToString().Translate(),
|
||||
((xxx.rjwSextype)19).ToString().Translate(),
|
||||
((xxx.rjwSextype)20).ToString().Translate()
|
||||
};
|
||||
|
||||
public static readonly string[] Sexuality =
|
||||
{
|
||||
((Orientation)0).ToString().Translate(),
|
||||
((Orientation)1).ToString().Translate(),
|
||||
((Orientation)2).ToString().Translate(),
|
||||
((Orientation)3).ToString().Translate(),
|
||||
((Orientation)4).ToString().Translate(),
|
||||
((Orientation)5).ToString().Translate(),
|
||||
((Orientation)6).ToString().Translate(),
|
||||
((Orientation)7).ToString().Translate(),
|
||||
((Orientation)8).ToString().Translate(),
|
||||
((Orientation)9).ToString().Translate(),
|
||||
((Orientation)10).ToString().Translate()
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Verse;
|
||||
using HarmonyLib;
|
||||
|
||||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
[StaticConstructorOnStartup]
|
||||
public static class DefInjection
|
||||
{
|
||||
static DefInjection()
|
||||
{
|
||||
InjectRaces();
|
||||
}
|
||||
|
||||
private static void InjectRaces()
|
||||
{
|
||||
List<ThingDef> PawnDefs = DefDatabase<ThingDef>.AllDefs.Where(x => x.race != null).ToList();
|
||||
InjectComp(PawnDefs);
|
||||
}
|
||||
|
||||
private static void InjectComp(List<ThingDef> PawnDefs)
|
||||
{
|
||||
CompProperties comp = new CompProperties(typeof(SexPartnerHistory));
|
||||
if (!PawnDefs.NullOrEmpty()) foreach(ThingDef def in PawnDefs)
|
||||
{
|
||||
def.comps.Add(comp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
using HarmonyLib;
|
||||
using rjw;
|
||||
using RJWSexperience.UI;
|
||||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
[HarmonyPatch(typeof(Pawn),"GetGizmos")]
|
||||
public class Pawn_GetGizmos
|
||||
{
|
||||
public static void Postfix(ref IEnumerable<Gizmo> __result, Pawn __instance)
|
||||
{
|
||||
|
||||
List<Gizmo> gizmoList = __result.ToList();
|
||||
|
||||
AddHistoryGizmo(__instance, ref gizmoList);
|
||||
|
||||
|
||||
__result = gizmoList;
|
||||
}
|
||||
|
||||
private static void AddHistoryGizmo(Pawn pawn, ref List<Gizmo> gizmos)
|
||||
{
|
||||
SexPartnerHistory history = pawn.GetPartnerHistory();
|
||||
if (history != null) gizmos.Add(CreateHIstoryGizmo(pawn,history));
|
||||
}
|
||||
|
||||
private static Gizmo CreateHIstoryGizmo(Pawn pawn, SexPartnerHistory history)
|
||||
{
|
||||
Gizmo gizmo = new Command_Action
|
||||
{
|
||||
defaultLabel = Keyed.RS_Sex_History,
|
||||
icon = HistoryUtility.HistoryIcon,
|
||||
defaultIconColor = HistoryUtility.HistoryColor,
|
||||
hotKey = VariousDefOf.OpenSexStatistics,
|
||||
action = delegate
|
||||
{
|
||||
SexStatusWindow.ToggleWindow(pawn, history);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return gizmo;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,207 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HarmonyLib;
|
||||
using rjw;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
using Verse.AI;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
|
||||
|
||||
|
||||
[HarmonyPatch(typeof(JobDriver_Sex), "Orgasm")]
|
||||
public static class RJW_Patch_Orgasm
|
||||
{
|
||||
public static void Postfix(JobDriver_Sex __instance)
|
||||
{
|
||||
if (__instance.Sexprops.sexType != xxx.rjwSextype.Masturbation && !(__instance is JobDriver_Masturbate))
|
||||
{
|
||||
if (__instance.Sexprops.isRape)
|
||||
{
|
||||
__instance.pawn?.skills?.Learn(VariousDefOf.SexSkill, 0.05f, true);
|
||||
}
|
||||
{
|
||||
__instance.pawn?.skills?.Learn(VariousDefOf.SexSkill, 0.35f, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(WhoringHelper), "WhoreAbilityAdjustmentMin")]
|
||||
public static class RJW_Patch_WhoreAbilityAdjustmentMin
|
||||
{
|
||||
public static void Postfix(Pawn whore, ref float __result)
|
||||
{
|
||||
__result *= whore.GetSexStat();
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(WhoringHelper), "WhoreAbilityAdjustmentMax")]
|
||||
public static class RJW_Patch_WhoreAbilityAdjustmentMax
|
||||
{
|
||||
public static void Postfix(Pawn whore, ref float __result)
|
||||
{
|
||||
__result *= whore.GetSexStat();
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(SexUtility), "SatisfyPersonal")]
|
||||
public static class RJW_Patch_SatisfyPersonal
|
||||
{
|
||||
private const float base_sat_per_fuck = 0.4f;
|
||||
|
||||
public static void Prefix(SexProps props, ref float satisfaction)
|
||||
{
|
||||
Pawn pawn = props.pawn;
|
||||
Pawn partner = props.partner;
|
||||
satisfaction = Mathf.Max(base_sat_per_fuck, satisfaction * partner.GetSexStat());
|
||||
}
|
||||
|
||||
public static void Postfix(SexProps props, ref float satisfaction)
|
||||
{
|
||||
Pawn pawn = props.pawn;
|
||||
Pawn partner = props.partner;
|
||||
float? lust = pawn.records?.GetValue(VariousDefOf.Lust);
|
||||
xxx.rjwSextype sextype = props.sexType;
|
||||
if (lust != null)
|
||||
{
|
||||
if (sextype != xxx.rjwSextype.Masturbation || partner != null) pawn.records.AddTo(VariousDefOf.Lust, Mathf.Clamp((satisfaction - base_sat_per_fuck) * RJWUtility.LustIncrementFactor(lust ?? 0), -0.5f, 0.5f)); // If the sex is satisfactory, lust grows up. Declines at the opposite.
|
||||
else pawn.records.AddTo(VariousDefOf.Lust, Mathf.Clamp(satisfaction * satisfaction * RJWUtility.LustIncrementFactor(lust ?? 0), 0, 0.5f)); // Masturbation always increases lust.
|
||||
}
|
||||
|
||||
if (sextype == xxx.rjwSextype.Masturbation || partner == null)
|
||||
{
|
||||
Building_CumBucket cumbucket = (Building_CumBucket)pawn.GetAdjacentBuilding<Building_CumBucket>();
|
||||
if (cumbucket != null)
|
||||
{
|
||||
cumbucket.AddCum(pawn.GetCumVolume());
|
||||
}
|
||||
}
|
||||
|
||||
RJWUtility.UpdateSatisfactionHIstory(pawn, partner, props, satisfaction);
|
||||
pawn.records?.Increment(VariousDefOf.OrgasmCount);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(SexUtility), "TransferNutrition")]
|
||||
public static class RJW_Patch_TransferNutrition
|
||||
{
|
||||
public static void Postfix(SexProps props)
|
||||
{
|
||||
Pawn pawn = props.pawn;
|
||||
Pawn partner = props.partner;
|
||||
xxx.rjwSextype sextype = props.sexType;
|
||||
Pawn giver = null;
|
||||
Pawn receiver = null;
|
||||
|
||||
if (Genital_Helper.has_penis_fertile(pawn))
|
||||
{
|
||||
giver = pawn;
|
||||
receiver = partner;
|
||||
}
|
||||
else if (Genital_Helper.has_penis_fertile(partner))
|
||||
{
|
||||
giver = partner;
|
||||
receiver = pawn;
|
||||
}
|
||||
|
||||
if (receiver != null && (
|
||||
sextype == xxx.rjwSextype.Oral ||
|
||||
sextype == xxx.rjwSextype.Fellatio ||
|
||||
sextype == xxx.rjwSextype.Sixtynine))
|
||||
{
|
||||
receiver.AteCum(giver.GetCumVolume(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(Nymph_Generator), "set_skills")]
|
||||
public static class RJW_Patch_Nymph_set_skills
|
||||
{
|
||||
public static void Postfix(Pawn pawn)
|
||||
{
|
||||
SkillRecord sexskill = pawn.skills.GetSkill(VariousDefOf.SexSkill);
|
||||
if (sexskill != null)
|
||||
{
|
||||
sexskill.passion = Passion.Major;
|
||||
sexskill.Level = (int)Utility.RandGaussianLike(7f, 20.99f);
|
||||
sexskill.xpSinceLastLevel = sexskill.XpRequiredForLevelUp * Rand.Range(0.10f, 0.90f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(AfterSexUtility), "UpdateRecords")]
|
||||
public static class RJW_Patch_UpdateRecords
|
||||
{
|
||||
public static void Postfix(SexProps props)
|
||||
{
|
||||
RJWUtility.UpdateSextypeRecords(props);
|
||||
RJWUtility.UpdatePartnerHistory(props.pawn, props.partner, props);
|
||||
RJWUtility.UpdatePartnerHistory(props.partner, props.pawn, props);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(JobDriver_SexBaseInitiator), "Start")]
|
||||
public static class RJW_Patch_LogSextype
|
||||
{
|
||||
public static void Postfix(JobDriver_SexBaseInitiator __instance)
|
||||
{
|
||||
if (__instance.Partner != null)
|
||||
{
|
||||
__instance.pawn.PoptheCherry(__instance.Partner, __instance.Sexprops);
|
||||
__instance.Partner.PoptheCherry(__instance.pawn, __instance.Sexprops);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[HarmonyPatch(typeof(WorkGiver_CleanSelf), "JobOnThing")]
|
||||
public static class RJW_Patch_CleanSelf_JobOnThing
|
||||
{
|
||||
public static bool Prefix(Pawn pawn, Thing t, bool forced, ref Job __result)
|
||||
{
|
||||
Building_CumBucket bucket = pawn.GetAdjacentBuilding<Building_CumBucket>();
|
||||
if (bucket == null) bucket = pawn.FindClosestBucket();
|
||||
if (bucket != null)
|
||||
{
|
||||
__result = JobMaker.MakeJob(VariousDefOf.CleanSelfwithBucket, null, bucket, bucket.Position);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(JobGiver_Masturbate), "TryGiveJob")]
|
||||
public static class RJW_Patch_Masturabte_TryGiveJob
|
||||
{
|
||||
public static void Postfix(Pawn pawn, ref Job __result)
|
||||
{
|
||||
if (RJWPreferenceSettings.FapEverywhere && __result != null)
|
||||
{
|
||||
Building_CumBucket bucket = pawn.FindClosestBucket();
|
||||
if (bucket != null)
|
||||
{
|
||||
__result.Clear();
|
||||
__result = JobMaker.MakeJob(xxx.Masturbate, null, null, bucket.RandomAdjacentCell8Way());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HarmonyLib;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
using rjw;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
|
||||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
[HarmonyPatch(typeof(PawnGenerator), "GeneratePawn", new Type[] { typeof(PawnGenerationRequest) })]
|
||||
public static class Rimworld_Patch_GeneratePawn
|
||||
{
|
||||
public static void Postfix(PawnGenerationRequest request, ref Pawn __result)
|
||||
{
|
||||
if (Configurations.EnableRecordRandomizer && __result != null && !request.Newborn && xxx.is_human(__result))
|
||||
{
|
||||
int avgsex = -500;
|
||||
bool isvirgin = Rand.Chance(Configurations.VirginRatio);
|
||||
int totalsex = 0;
|
||||
int totalbirth = 0;
|
||||
int deviation = (int)Configurations.MaxSexCountDeviation;
|
||||
if (__result.story != null)
|
||||
{
|
||||
float lust;
|
||||
if (xxx.is_nympho(__result)) lust = __result.RecordRandomizer(VariousDefOf.Lust, Configurations.AvgLust, Configurations.MaxLustDeviation, 0);
|
||||
else lust = __result.RecordRandomizer(VariousDefOf.Lust, Configurations.AvgLust, Configurations.MaxLustDeviation, float.MinValue);
|
||||
|
||||
int sexableage = 0;
|
||||
int minsexage = (int)(__result.RaceProps.lifeExpectancy * Configurations.MinSexablePercent);
|
||||
if (__result.ageTracker.AgeBiologicalYears > minsexage)
|
||||
{
|
||||
sexableage = __result.ageTracker.AgeBiologicalYears - minsexage;
|
||||
avgsex = (int)(sexableage * Configurations.SexPerYear * __result.LustFactor());
|
||||
}
|
||||
|
||||
|
||||
if (__result.relations != null && __result.gender == Gender.Female)
|
||||
{
|
||||
totalbirth += __result.relations.ChildrenCount;
|
||||
totalsex += totalbirth;
|
||||
__result.records?.AddTo(xxx.CountOfSexWithHumanlikes, totalbirth);
|
||||
__result.records?.SetTo(xxx.CountOfBirthHuman, totalbirth);
|
||||
if (totalbirth > 0) isvirgin = false;
|
||||
}
|
||||
if (!isvirgin)
|
||||
{
|
||||
if (xxx.is_rapist(__result))
|
||||
{
|
||||
if (xxx.is_zoophile(__result))
|
||||
{
|
||||
if (__result.Has(Quirk.ChitinLover)) totalsex += __result.RecordRandomizer(xxx.CountOfRapedInsects, avgsex, deviation);
|
||||
else totalsex += __result.RecordRandomizer(xxx.CountOfRapedAnimals, avgsex, deviation);
|
||||
}
|
||||
else totalsex += __result.RecordRandomizer(xxx.CountOfRapedHumanlikes, avgsex, deviation);
|
||||
avgsex /= 8;
|
||||
}
|
||||
|
||||
if (xxx.is_zoophile(__result))
|
||||
{
|
||||
if (__result.Has(Quirk.ChitinLover)) totalsex += __result.RecordRandomizer(xxx.CountOfRapedInsects, avgsex, deviation);
|
||||
else totalsex += __result.RecordRandomizer(xxx.CountOfSexWithAnimals, avgsex, deviation);
|
||||
avgsex /= 10;
|
||||
}
|
||||
else if (xxx.is_necrophiliac(__result))
|
||||
{
|
||||
totalsex += __result.RecordRandomizer(xxx.CountOfSexWithCorpse, avgsex, deviation);
|
||||
avgsex /= 4;
|
||||
}
|
||||
|
||||
if (__result.IsSlave)
|
||||
{
|
||||
totalsex += __result.RecordRandomizer(xxx.CountOfBeenRapedByAnimals, Rand.Range(-50, 10), Rand.Range(0, 10) * sexableage);
|
||||
totalsex += __result.RecordRandomizer(xxx.CountOfBeenRapedByHumanlikes, 0, Rand.Range(0, 100) * sexableage);
|
||||
}
|
||||
|
||||
|
||||
totalsex += __result.RecordRandomizer(xxx.CountOfSexWithHumanlikes, avgsex, deviation);
|
||||
|
||||
if (totalsex > 0) __result.records.AddTo(VariousDefOf.SexPartnerCount, Math.Max(1, Rand.Range(0, totalsex/7)));
|
||||
}
|
||||
}
|
||||
__result.records?.SetTo(xxx.CountOfSex, totalsex);
|
||||
RJWUtility.GenerateSextypeRecords(__result, totalsex);
|
||||
}
|
||||
if (__result.story?.traits != null)
|
||||
{
|
||||
if (__result.IsVirgin())
|
||||
{
|
||||
int degree = 0;
|
||||
if (__result.gender == Gender.Female) degree = 2;
|
||||
Trait virgin = new Trait(VariousDefOf.Virgin, degree ,true);
|
||||
__result.story.traits.GainTrait(virgin);
|
||||
}
|
||||
else if (__result.gender == Gender.Female && Rand.Chance(0.05f))
|
||||
{
|
||||
Trait virgin = new Trait(VariousDefOf.Virgin, 1, true);
|
||||
__result.story.traits.GainTrait(virgin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
[HarmonyPatch(typeof(FloatMenuMakerMap), "AddHumanlikeOrders")]
|
||||
public class HumanlikeOrder_Patch
|
||||
{
|
||||
public static void Postfix(Vector3 clickPos, Pawn pawn, List<FloatMenuOption> opts)
|
||||
{
|
||||
var targets = GenUI.TargetsAt(clickPos, TargetingParameters.ForBuilding());
|
||||
|
||||
if (pawn.health.hediffSet.HasHediff(RJW_SemenoOverlayHediffDefOf.Hediff_Bukkake))
|
||||
foreach (LocalTargetInfo t in targets)
|
||||
{
|
||||
Building building = t.Thing as Building;
|
||||
if (building != null)
|
||||
{
|
||||
if (building is Building_CumBucket)
|
||||
{
|
||||
opts.AddDistinct(MakeMenu(pawn, building));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static FloatMenuOption MakeMenu(Pawn pawn, LocalTargetInfo target)
|
||||
{
|
||||
FloatMenuOption option = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(Keyed.RS_FloatMenu_CleanSelf, delegate ()
|
||||
{
|
||||
pawn.jobs.TryTakeOrderedJob(new Verse.AI.Job(VariousDefOf.CleanSelfwithBucket, null, target, target.Cell));
|
||||
}, MenuOptionPriority.Low), pawn, target);
|
||||
|
||||
return option;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -63,6 +63,12 @@
|
|||
<HintPath>..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.IMGUIModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextCoreModule">
|
||||
<HintPath>..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.TextCoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextRenderingModule">
|
||||
<HintPath>..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.TextRenderingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.UI.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
|
@ -77,20 +83,31 @@
|
|||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Buildings.cs" />
|
||||
<Compile Include="Building_Cumbucket.cs" />
|
||||
<Compile Include="Configurations.cs" />
|
||||
<Compile Include="DebugAction.cs" />
|
||||
<Compile Include="Harmony.cs" />
|
||||
<Compile Include="SexHistory.cs" />
|
||||
<Compile Include="IngestionOutcomeDoers.cs" />
|
||||
<Compile Include="JobDrivers.cs" />
|
||||
<Compile Include="Patches\DefInjection.cs" />
|
||||
<Compile Include="Patches\GetGizmos.cs" />
|
||||
<Compile Include="Recipe_HymenSurgery.cs" />
|
||||
<Compile Include="RJWUtility.cs" />
|
||||
<Compile Include="SexHistory\HistoryUtility.cs" />
|
||||
<Compile Include="SexHistory\SexHistory.cs" />
|
||||
<Compile Include="PawnRelationWorkers.cs" />
|
||||
<Compile Include="Keyed.cs" />
|
||||
<Compile Include="Rimworld_Patch.cs" />
|
||||
<Compile Include="RJW_Patch.cs" />
|
||||
<Compile Include="Patches\Rimworld_Patch.cs" />
|
||||
<Compile Include="Patches\RJW_Patch.cs" />
|
||||
<Compile Include="StatParts.cs" />
|
||||
<Compile Include="Thought_Opinionbased.cs" />
|
||||
<Compile Include="Thought_Recordbased.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="UI\RJWUIUtility.cs" />
|
||||
<Compile Include="UI\SexStatus.cs" />
|
||||
<Compile Include="Utility.cs" />
|
||||
<Compile Include="VariousDefOf.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
|
@ -0,0 +1,409 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using rjw;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
using Verse.AI;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
public static class RJWUtility
|
||||
{
|
||||
public static float GetSexStat(this Pawn pawn)
|
||||
{
|
||||
if (xxx.is_human(pawn) && !pawn.Dead)
|
||||
{
|
||||
return pawn.GetStatValue(xxx.sex_stat);
|
||||
}
|
||||
else return 1.0f;
|
||||
}
|
||||
|
||||
public static float LustIncrementFactor(float lust)
|
||||
{
|
||||
return Mathf.Exp(-Mathf.Pow(lust / Configurations.LustLimit, 2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the pawn is virgin, return true.
|
||||
/// </summary>
|
||||
public static bool IsVirgin(this Pawn pawn)
|
||||
{
|
||||
if (pawn.records.GetValue(VariousDefOf.VaginalSexCount) == 0) return true;
|
||||
return false;
|
||||
}
|
||||
public static bool HasHymen(this Pawn pawn)
|
||||
{
|
||||
Trait virgin = pawn.story?.traits?.GetTrait(VariousDefOf.Virgin);
|
||||
if (virgin != null)
|
||||
{
|
||||
if (virgin.Degree > 0) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If pawn is virgin, lose his/her virginity.
|
||||
/// </summary>
|
||||
public static void PoptheCherry(this Pawn pawn, Pawn partner, SexProps props)
|
||||
{
|
||||
if (props != null && props.sexType == xxx.rjwSextype.Vaginal)
|
||||
{
|
||||
if (pawn.IsVirgin())
|
||||
{
|
||||
SexPartnerHistory history = pawn.GetPartnerHistory();
|
||||
if (history != null)
|
||||
{
|
||||
history.RecordFirst(partner, props);
|
||||
}
|
||||
if (RemoveVirginTrait(pawn, partner, props))
|
||||
{
|
||||
Messages.Message(Keyed.RS_LostVirgin(pawn.LabelShort, partner.LabelShort), MessageTypeDefOf.NeutralEvent, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveVirginTrait(pawn, partner, props);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool RemoveVirginTrait(Pawn pawn, Pawn partner, SexProps props)
|
||||
{
|
||||
int degree;
|
||||
Trait virgin = pawn.story?.traits?.GetTrait(VariousDefOf.Virgin);
|
||||
if (virgin != null)
|
||||
{
|
||||
degree = virgin.Degree;
|
||||
if (pawn.gender == Gender.Female && degree > 0)
|
||||
{
|
||||
FilthMaker.TryMakeFilth(pawn.Position, pawn.Map, ThingDefOf.Filth_Blood, pawn.LabelShort, 1, FilthSourceFlags.Pawn);
|
||||
}
|
||||
ThrowVirginHIstoryEvent(pawn, partner, props, degree);
|
||||
pawn.story.traits.RemoveTrait(virgin);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// For ideo patch
|
||||
/// </summary>
|
||||
public static void ThrowVirginHIstoryEvent(Pawn pawn, Pawn partner, SexProps props, int degree)
|
||||
{
|
||||
//for non-ideo
|
||||
if (partner.Ideo == null)
|
||||
{
|
||||
partner.needs?.mood?.thoughts?.memories.TryGainMemory(xxx.took_virginity, pawn);
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdateSextypeRecords(SexProps props)
|
||||
{
|
||||
xxx.rjwSextype sextype = props.sexType;
|
||||
Pawn pawn = props.pawn;
|
||||
Pawn partner = props.partner;
|
||||
Pawn receiver = props.reciever;
|
||||
Pawn giver = props.giver;
|
||||
|
||||
if (partner != null)
|
||||
{
|
||||
|
||||
switch (sextype)
|
||||
{
|
||||
case xxx.rjwSextype.Vaginal:
|
||||
case xxx.rjwSextype.Scissoring:
|
||||
IncreaseSameRecords(pawn, partner, VariousDefOf.VaginalSexCount);
|
||||
break;
|
||||
case xxx.rjwSextype.Anal:
|
||||
IncreaseSameRecords(pawn, partner, VariousDefOf.AnalSexCount);
|
||||
break;
|
||||
case xxx.rjwSextype.Oral:
|
||||
case xxx.rjwSextype.Fellatio:
|
||||
if (Genital_Helper.has_penis_fertile(giver) || Genital_Helper.has_penis_infertile(giver))
|
||||
{
|
||||
IncreaseRecords(giver, receiver, VariousDefOf.OralSexCount, VariousDefOf.BlowjobCount);
|
||||
}
|
||||
else if (Genital_Helper.has_penis_infertile(receiver) || Genital_Helper.has_penis_infertile(receiver))
|
||||
{
|
||||
IncreaseRecords(giver, receiver, VariousDefOf.BlowjobCount, VariousDefOf.OralSexCount);
|
||||
}
|
||||
break;
|
||||
case xxx.rjwSextype.Sixtynine:
|
||||
IncreaseSameRecords(pawn, partner, VariousDefOf.OralSexCount);
|
||||
RecordDef recordpawn, recordpartner;
|
||||
if (Genital_Helper.has_penis_fertile(pawn) || Genital_Helper.has_penis_infertile(pawn))
|
||||
{
|
||||
recordpartner = VariousDefOf.BlowjobCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
recordpartner = VariousDefOf.CunnilingusCount;
|
||||
}
|
||||
|
||||
if (Genital_Helper.has_penis_fertile(partner) || Genital_Helper.has_penis_infertile(partner))
|
||||
{
|
||||
recordpawn = VariousDefOf.BlowjobCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
recordpawn = VariousDefOf.CunnilingusCount;
|
||||
}
|
||||
IncreaseRecords(pawn, partner, recordpawn, recordpartner);
|
||||
break;
|
||||
case xxx.rjwSextype.Cunnilingus:
|
||||
if (Genital_Helper.has_vagina(giver))
|
||||
{
|
||||
IncreaseRecords(giver, receiver, VariousDefOf.OralSexCount, VariousDefOf.CunnilingusCount);
|
||||
}
|
||||
else if (Genital_Helper.has_vagina(receiver))
|
||||
{
|
||||
IncreaseRecords(giver, receiver, VariousDefOf.CunnilingusCount, VariousDefOf.OralSexCount);
|
||||
}
|
||||
break;
|
||||
case xxx.rjwSextype.Masturbation:
|
||||
break;
|
||||
case xxx.rjwSextype.Handjob:
|
||||
if (Genital_Helper.has_penis_fertile(giver) || Genital_Helper.has_penis_infertile(giver))
|
||||
{
|
||||
IncreaseRecords(giver, receiver, VariousDefOf.GenitalCaressCount, VariousDefOf.HandjobCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
IncreaseRecords(giver, receiver, VariousDefOf.HandjobCount, VariousDefOf.GenitalCaressCount);
|
||||
}
|
||||
break;
|
||||
case xxx.rjwSextype.Fingering:
|
||||
case xxx.rjwSextype.Fisting:
|
||||
if (Genital_Helper.has_vagina(giver))
|
||||
{
|
||||
IncreaseRecords(giver, receiver, VariousDefOf.GenitalCaressCount, VariousDefOf.FingeringCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
IncreaseRecords(giver, receiver, VariousDefOf.FingeringCount, VariousDefOf.GenitalCaressCount);
|
||||
}
|
||||
break;
|
||||
case xxx.rjwSextype.Footjob:
|
||||
IncreaseSameRecords(pawn, partner, VariousDefOf.FootjobCount);
|
||||
break;
|
||||
default:
|
||||
IncreaseSameRecords(pawn, partner, VariousDefOf.MiscSexualBehaviorCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdatePartnerHistory(Pawn pawn, Pawn partner, SexProps props)
|
||||
{
|
||||
if (partner != null)
|
||||
{
|
||||
SexPartnerHistory pawnshistory = pawn.TryGetComp<SexPartnerHistory>();
|
||||
pawnshistory?.RecordHistory(partner, props);
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdateSatisfactionHIstory(Pawn pawn, Pawn partner, SexProps props, float satisfaction)
|
||||
{
|
||||
if (partner != null)
|
||||
{
|
||||
SexPartnerHistory pawnshistory = pawn.TryGetComp<SexPartnerHistory>();
|
||||
pawnshistory?.RecordSatisfactionHistory(partner, props, satisfaction);
|
||||
}
|
||||
}
|
||||
|
||||
public static void IncreaseSameRecords(Pawn pawn, Pawn partner, RecordDef record)
|
||||
{
|
||||
pawn.records?.AddTo(record, 1);
|
||||
partner.records?.AddTo(record, 1);
|
||||
}
|
||||
|
||||
public static void IncreaseRecords(Pawn pawn, Pawn partner, RecordDef recordforpawn, RecordDef recordforpartner)
|
||||
{
|
||||
pawn.records?.AddTo(recordforpawn, 1);
|
||||
partner.records?.AddTo(recordforpartner, 1);
|
||||
}
|
||||
|
||||
public static void GenerateSextypeRecords(Pawn pawn, int totalsex)
|
||||
{
|
||||
float totalweight =
|
||||
RJWPreferenceSettings.vaginal +
|
||||
RJWPreferenceSettings.anal +
|
||||
RJWPreferenceSettings.fellatio +
|
||||
RJWPreferenceSettings.cunnilingus +
|
||||
RJWPreferenceSettings.rimming +
|
||||
RJWPreferenceSettings.double_penetration +
|
||||
RJWPreferenceSettings.breastjob +
|
||||
RJWPreferenceSettings.handjob +
|
||||
RJWPreferenceSettings.mutual_masturbation +
|
||||
RJWPreferenceSettings.fingering +
|
||||
RJWPreferenceSettings.footjob +
|
||||
RJWPreferenceSettings.scissoring +
|
||||
RJWPreferenceSettings.fisting +
|
||||
RJWPreferenceSettings.sixtynine;
|
||||
Gender prefer = pawn.PreferGender();
|
||||
int sex = (int)(totalsex * RJWPreferenceSettings.vaginal / totalweight);
|
||||
totalsex -= sex;
|
||||
pawn.records.AddTo(VariousDefOf.VaginalSexCount, sex);
|
||||
|
||||
sex = (int)(totalsex * RJWPreferenceSettings.anal / totalweight);
|
||||
totalsex -= sex;
|
||||
pawn.records.AddTo(VariousDefOf.AnalSexCount, sex);
|
||||
|
||||
sex = (int)(totalsex * RJWPreferenceSettings.fellatio / totalweight);
|
||||
totalsex -= sex;
|
||||
if (prefer == Gender.Male) pawn.records.AddTo(VariousDefOf.BlowjobCount, sex);
|
||||
else pawn.records.AddTo(VariousDefOf.OralSexCount, sex);
|
||||
|
||||
sex = (int)(totalsex * RJWPreferenceSettings.cunnilingus / totalweight);
|
||||
totalsex -= sex;
|
||||
if (prefer == Gender.Male) pawn.records.AddTo(VariousDefOf.OralSexCount, sex);
|
||||
else pawn.records.AddTo(VariousDefOf.CunnilingusCount, sex);
|
||||
|
||||
sex = (int)(totalsex * RJWPreferenceSettings.rimming / totalweight);
|
||||
totalsex -= sex;
|
||||
pawn.records.AddTo(VariousDefOf.MiscSexualBehaviorCount, sex);
|
||||
|
||||
sex = (int)(totalsex * RJWPreferenceSettings.double_penetration / totalweight) / 2;
|
||||
totalsex -= sex;
|
||||
totalsex -= sex;
|
||||
pawn.records.AddTo(VariousDefOf.VaginalSexCount, sex);
|
||||
pawn.records.AddTo(VariousDefOf.AnalSexCount, sex);
|
||||
|
||||
sex = (int)(totalsex * RJWPreferenceSettings.breastjob / totalweight);
|
||||
totalsex -= sex;
|
||||
pawn.records.AddTo(VariousDefOf.MiscSexualBehaviorCount, sex);
|
||||
|
||||
sex = (int)(totalsex * RJWPreferenceSettings.handjob / totalweight);
|
||||
totalsex -= sex;
|
||||
if (prefer == Gender.Male) pawn.records.AddTo(VariousDefOf.HandjobCount, sex);
|
||||
else pawn.records.AddTo(VariousDefOf.GenitalCaressCount, sex);
|
||||
|
||||
sex = (int)(totalsex * RJWPreferenceSettings.fingering / totalweight);
|
||||
totalsex -= sex;
|
||||
if (prefer == Gender.Female) pawn.records.AddTo(VariousDefOf.FingeringCount, sex);
|
||||
else pawn.records.AddTo(VariousDefOf.GenitalCaressCount, sex);
|
||||
|
||||
sex = (int)(totalsex * RJWPreferenceSettings.mutual_masturbation / totalweight);
|
||||
totalsex -= sex;
|
||||
if (prefer == Gender.Male) pawn.records.AddTo(VariousDefOf.HandjobCount, sex);
|
||||
else pawn.records.AddTo(VariousDefOf.FingeringCount, sex);
|
||||
pawn.records.AddTo(VariousDefOf.GenitalCaressCount, sex);
|
||||
|
||||
sex = (int)(totalsex * RJWPreferenceSettings.footjob / totalweight);
|
||||
totalsex -= sex;
|
||||
pawn.records.AddTo(VariousDefOf.FootjobCount, sex);
|
||||
|
||||
sex = (int)(totalsex * RJWPreferenceSettings.scissoring / totalweight);
|
||||
totalsex -= sex;
|
||||
pawn.records.AddTo(VariousDefOf.MiscSexualBehaviorCount, sex);
|
||||
|
||||
sex = (int)(totalsex * RJWPreferenceSettings.fisting / totalweight);
|
||||
totalsex -= sex;
|
||||
pawn.records.AddTo(VariousDefOf.MiscSexualBehaviorCount, sex);
|
||||
|
||||
pawn.records.AddTo(VariousDefOf.OralSexCount, totalsex);
|
||||
if (prefer == Gender.Male) pawn.records.AddTo(VariousDefOf.BlowjobCount, totalsex);
|
||||
else pawn.records.AddTo(VariousDefOf.CunnilingusCount, totalsex);
|
||||
|
||||
}
|
||||
|
||||
public static Gender PreferGender(this Pawn pawn)
|
||||
{
|
||||
if (pawn.gender == Gender.Male)
|
||||
{
|
||||
if (xxx.is_homosexual(pawn)) return Gender.Male;
|
||||
else return Gender.Female;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (xxx.is_homosexual(pawn)) return Gender.Female;
|
||||
else return Gender.Male;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool GetRapist(this SexProps props, out Pawn rapist)
|
||||
{
|
||||
if (!props.isRape)
|
||||
{
|
||||
rapist = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
rapist = props.pawn;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool IsBestiality(this SexProps props)
|
||||
{
|
||||
if (props.partner != null)
|
||||
{
|
||||
return props.pawn.IsAnimal() ^ props.partner.IsAnimal();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Building_CumBucket FindClosestBucket(this Pawn pawn)
|
||||
{
|
||||
List<Building> buckets = pawn.Map.listerBuildings.allBuildingsColonist.FindAll(x => x is Building_CumBucket);
|
||||
Dictionary<Building, float> targets = new Dictionary<Building, float>();
|
||||
if (!buckets.NullOrEmpty()) for (int i = 0; i < buckets.Count; i++)
|
||||
{
|
||||
if (pawn.CanReach(buckets[i], PathEndMode.ClosestTouch, Danger.None))
|
||||
{
|
||||
targets.Add(buckets[i], pawn.Position.DistanceTo(buckets[i].Position));
|
||||
}
|
||||
}
|
||||
if (!targets.NullOrEmpty())
|
||||
{
|
||||
return (Building_CumBucket)targets.MinBy(x => x.Value).Key;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void AteCum(this Pawn pawn, float amount, bool doDrugEffect = false)
|
||||
{
|
||||
pawn.records.AddTo(VariousDefOf.NumofEatenCum, 1);
|
||||
pawn.records.AddTo(VariousDefOf.AmountofEatenCum, amount);
|
||||
if (doDrugEffect) pawn.CumDrugEffect();
|
||||
}
|
||||
|
||||
public static void CumDrugEffect(this Pawn pawn)
|
||||
{
|
||||
Need need = pawn.needs?.TryGetNeed(VariousDefOf.Chemical_Cum);
|
||||
if (need != null) need.CurLevel += VariousDefOf.CumneedLevelOffset;
|
||||
Hediff addictive = HediffMaker.MakeHediff(VariousDefOf.CumTolerance, pawn);
|
||||
addictive.Severity = 0.032f;
|
||||
pawn.health.AddHediff(addictive);
|
||||
Hediff addiction = pawn.health.hediffSet.GetFirstHediffOfDef(VariousDefOf.CumAddiction);
|
||||
if (addiction != null) addiction.Severity += VariousDefOf.CumexistingAddictionSeverityOffset;
|
||||
|
||||
pawn.needs?.mood?.thoughts?.memories?.TryGainMemoryFast(VariousDefOf.AteCum);
|
||||
}
|
||||
|
||||
public static void AddVirginTrait(this Pawn pawn)
|
||||
{
|
||||
if (pawn.story?.traits != null)
|
||||
{
|
||||
if (pawn.IsVirgin())
|
||||
{
|
||||
int degree = 0;
|
||||
if (pawn.gender == Gender.Female) degree = 2;
|
||||
Trait virgin = new Trait(VariousDefOf.Virgin, degree, true);
|
||||
pawn.story.traits.GainTrait(virgin);
|
||||
}
|
||||
else if (pawn.gender == Gender.Female && Rand.Chance(0.05f))
|
||||
{
|
||||
Trait virgin = new Trait(VariousDefOf.Virgin, 1, true);
|
||||
pawn.story.traits.GainTrait(virgin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,305 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HarmonyLib;
|
||||
using rjw;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
public static class RJWUtility
|
||||
{
|
||||
public static float GetSexStat(this Pawn pawn)
|
||||
{
|
||||
if (xxx.is_human(pawn) && !pawn.Dead)
|
||||
{
|
||||
return pawn.GetStatValue(xxx.sex_stat);
|
||||
}
|
||||
else return 1.0f;
|
||||
}
|
||||
|
||||
public static float LustIncrementFactor(float lust)
|
||||
{
|
||||
return Mathf.Exp(-Mathf.Pow(lust / Configurations.LustLimit, 2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the pawn is virgin, return true.
|
||||
/// </summary>
|
||||
public static bool IsVirgin(this Pawn pawn)
|
||||
{
|
||||
if (pawn.records.GetValue(xxx.CountOfSex) == 0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If pawn is virgin, lose his/her virginity.
|
||||
/// </summary>
|
||||
public static void PoptheCherry(this Pawn pawn, Pawn partner, bool violent)
|
||||
{
|
||||
if (pawn.IsVirgin())
|
||||
{
|
||||
Messages.Message(Keyed.RS_LostVirgin(pawn.LabelShort, partner.LabelShort), MessageTypeDefOf.NeutralEvent, true);
|
||||
RemoveVirginTrait(pawn);
|
||||
FilthMaker.TryMakeFilth(pawn.Position, pawn.Map, ThingDefOf.Filth_Blood, 1, FilthSourceFlags.Pawn);
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveVirginTrait(Pawn pawn)
|
||||
{
|
||||
Trait virgin = pawn.story?.traits?.GetTrait(VariousDefOf.Virgin);
|
||||
if (virgin != null)
|
||||
{
|
||||
pawn.story.traits.RemoveTrait(virgin);
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdateSextypeRecords(SexProps props)
|
||||
{
|
||||
xxx.rjwSextype sextype = props.sexType;
|
||||
Pawn pawn = props.pawn;
|
||||
Pawn partner = props.partner;
|
||||
Pawn receiver = props.reciever;
|
||||
Pawn giver = props.giver;
|
||||
|
||||
if (partner != null)
|
||||
{
|
||||
|
||||
switch (sextype)
|
||||
{
|
||||
case xxx.rjwSextype.Vaginal:
|
||||
case xxx.rjwSextype.Scissoring:
|
||||
IncreaseSameRecords(pawn, partner, VariousDefOf.VaginalSexCount);
|
||||
break;
|
||||
case xxx.rjwSextype.Anal:
|
||||
IncreaseSameRecords(pawn, partner, VariousDefOf.AnalSexCount);
|
||||
break;
|
||||
case xxx.rjwSextype.Oral:
|
||||
case xxx.rjwSextype.Fellatio:
|
||||
if (Genital_Helper.has_penis_fertile(giver) || Genital_Helper.has_penis_infertile(giver))
|
||||
{
|
||||
IncreaseRecords(giver, receiver, VariousDefOf.OralSexCount, VariousDefOf.BlowjobCount);
|
||||
}
|
||||
else if (Genital_Helper.has_penis_infertile(receiver) || Genital_Helper.has_penis_infertile(receiver))
|
||||
{
|
||||
IncreaseRecords(giver, receiver, VariousDefOf.BlowjobCount, VariousDefOf.OralSexCount);
|
||||
}
|
||||
break;
|
||||
case xxx.rjwSextype.Sixtynine:
|
||||
IncreaseSameRecords(pawn, partner, VariousDefOf.OralSexCount);
|
||||
RecordDef recordpawn, recordpartner;
|
||||
if (Genital_Helper.has_penis_fertile(pawn) || Genital_Helper.has_penis_infertile(pawn))
|
||||
{
|
||||
recordpartner = VariousDefOf.BlowjobCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
recordpartner = VariousDefOf.CunnilingusCount;
|
||||
}
|
||||
|
||||
if (Genital_Helper.has_penis_fertile(partner) || Genital_Helper.has_penis_infertile(partner))
|
||||
{
|
||||
recordpawn = VariousDefOf.BlowjobCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
recordpawn = VariousDefOf.CunnilingusCount;
|
||||
}
|
||||
IncreaseRecords(pawn, partner, recordpawn, recordpartner);
|
||||
break;
|
||||
case xxx.rjwSextype.Cunnilingus:
|
||||
if (Genital_Helper.has_vagina(giver))
|
||||
{
|
||||
IncreaseRecords(giver, receiver, VariousDefOf.OralSexCount, VariousDefOf.CunnilingusCount);
|
||||
}
|
||||
else if (Genital_Helper.has_vagina(receiver))
|
||||
{
|
||||
IncreaseRecords(giver, receiver, VariousDefOf.CunnilingusCount, VariousDefOf.OralSexCount);
|
||||
}
|
||||
break;
|
||||
case xxx.rjwSextype.Masturbation:
|
||||
break;
|
||||
case xxx.rjwSextype.Handjob:
|
||||
if (Genital_Helper.has_penis_fertile(giver) || Genital_Helper.has_penis_infertile(giver))
|
||||
{
|
||||
IncreaseRecords(giver, receiver, VariousDefOf.GenitalCaressCount, VariousDefOf.HadnjobCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
IncreaseRecords(giver, receiver, VariousDefOf.HadnjobCount, VariousDefOf.GenitalCaressCount);
|
||||
}
|
||||
break;
|
||||
case xxx.rjwSextype.Fingering:
|
||||
case xxx.rjwSextype.Fisting:
|
||||
if (Genital_Helper.has_vagina(giver))
|
||||
{
|
||||
IncreaseRecords(giver, receiver, VariousDefOf.GenitalCaressCount, VariousDefOf.FingeringCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
IncreaseRecords(giver, receiver, VariousDefOf.FingeringCount, VariousDefOf.GenitalCaressCount);
|
||||
}
|
||||
break;
|
||||
case xxx.rjwSextype.Footjob:
|
||||
IncreaseSameRecords(pawn, partner, VariousDefOf.FootjobCount);
|
||||
break;
|
||||
default:
|
||||
IncreaseSameRecords(pawn, partner, VariousDefOf.MiscSexualBehaviorCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdatePartnerHistory(Pawn pawn, Pawn partner, SexProps props, float satisfaction)
|
||||
{
|
||||
SexPartnerHistory pawnshistory = pawn.GetComp<SexPartnerHistory>();
|
||||
pawnshistory.RecordHistory(partner, props);
|
||||
}
|
||||
|
||||
public static void IncreaseSameRecords(Pawn pawn, Pawn partner, RecordDef record)
|
||||
{
|
||||
pawn.records?.AddTo(record, 1);
|
||||
partner.records?.AddTo(record, 1);
|
||||
}
|
||||
|
||||
public static void IncreaseRecords(Pawn pawn, Pawn partner, RecordDef recordforpawn, RecordDef recordforpartner)
|
||||
{
|
||||
pawn.records?.AddTo(recordforpawn, 1);
|
||||
partner.records?.AddTo(recordforpartner, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
[HarmonyPatch(typeof(JobDriver_Sex), "Orgasm")]
|
||||
public static class RJW_Patch_Orgasm
|
||||
{
|
||||
public static void Postfix(JobDriver_Sex __instance)
|
||||
{
|
||||
if (__instance.Sexprops.sexType != xxx.rjwSextype.Masturbation && !(__instance is JobDriver_Masturbate))
|
||||
{
|
||||
if (__instance.Sexprops.isRape)
|
||||
{
|
||||
__instance.pawn?.skills?.Learn(VariousDefOf.SexSkill, 0.05f, true);
|
||||
}
|
||||
{
|
||||
__instance.pawn?.skills?.Learn(VariousDefOf.SexSkill, 0.35f, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(WhoringHelper), "WhoreAbilityAdjustmentMin")]
|
||||
public static class RJW_Patch_WhoreAbilityAdjustmentMin
|
||||
{
|
||||
public static void Postfix(Pawn whore, ref float __result)
|
||||
{
|
||||
__result *= whore.GetSexStat();
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(WhoringHelper), "WhoreAbilityAdjustmentMax")]
|
||||
public static class RJW_Patch_WhoreAbilityAdjustmentMax
|
||||
{
|
||||
public static void Postfix(Pawn whore, ref float __result)
|
||||
{
|
||||
__result *= whore.GetSexStat();
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(SexUtility), "SatisfyPersonal")]
|
||||
public static class RJW_Patch_SatisfyPersonal
|
||||
{
|
||||
private const float base_sat_per_fuck = 0.4f;
|
||||
|
||||
public static void Prefix(SexProps props, ref float satisfaction)
|
||||
{
|
||||
Pawn pawn = props.pawn;
|
||||
Pawn partner = props.partner;
|
||||
satisfaction = Mathf.Max(base_sat_per_fuck, satisfaction * partner.GetSexStat());
|
||||
}
|
||||
|
||||
public static void Postfix(SexProps props, float satisfaction)
|
||||
{
|
||||
Pawn pawn = props.pawn;
|
||||
Pawn partner = props.partner;
|
||||
float? lust = pawn.records?.GetValue(VariousDefOf.Lust);
|
||||
xxx.rjwSextype sextype = props.sexType;
|
||||
if (lust != null)
|
||||
{
|
||||
if (sextype != xxx.rjwSextype.Masturbation || partner != null) pawn.records.AddTo(VariousDefOf.Lust, Mathf.Clamp((satisfaction - base_sat_per_fuck) * RJWUtility.LustIncrementFactor(lust ?? 0), -0.5f, 0.5f)); // If the sex is satisfactory, lust grows up. Declines at the opposite.
|
||||
else pawn.records.AddTo(VariousDefOf.Lust, Mathf.Clamp(satisfaction * satisfaction * RJWUtility.LustIncrementFactor(lust ?? 0), 0, 0.5f)); // Masturbation always increases lust.
|
||||
}
|
||||
|
||||
if (sextype == xxx.rjwSextype.Masturbation || partner == null)
|
||||
{
|
||||
Building_CumBucket cumbucket = (Building_CumBucket)pawn.GetAdjacentBuilding<Building_CumBucket>();
|
||||
if (cumbucket != null)
|
||||
{
|
||||
cumbucket.AddCum(pawn.GetCumVolume());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(SexUtility), "TransferNutrition")]
|
||||
public static class RJW_Patch_TransferNutrition
|
||||
{
|
||||
public static void Postfix(SexProps props)
|
||||
{
|
||||
Pawn pawn = props.pawn;
|
||||
Pawn partner = props.partner;
|
||||
xxx.rjwSextype sextype = props.sexType;
|
||||
Pawn receiver = null;
|
||||
|
||||
if (Genital_Helper.has_penis_fertile(pawn)) receiver = partner;
|
||||
else if (Genital_Helper.has_penis_fertile(partner)) receiver = pawn;
|
||||
|
||||
if (receiver != null && (
|
||||
sextype == xxx.rjwSextype.Oral ||
|
||||
sextype == xxx.rjwSextype.Fellatio ||
|
||||
sextype == xxx.rjwSextype.Sixtynine))
|
||||
{
|
||||
receiver.CumDrugEffect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(Nymph_Generator), "set_skills")]
|
||||
public static class RJW_Patch_Nymph_set_skills
|
||||
{
|
||||
public static void Postfix(Pawn pawn)
|
||||
{
|
||||
SkillRecord sexskill = pawn.skills.GetSkill(VariousDefOf.SexSkill);
|
||||
if (sexskill != null)
|
||||
{
|
||||
sexskill.passion = Passion.Major;
|
||||
sexskill.Level = (int)Utility.RandGaussianLike(7f, 20.99f);
|
||||
sexskill.xpSinceLastLevel = sexskill.XpRequiredForLevelUp * Rand.Range(0.10f, 0.90f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(AfterSexUtility), "UpdateRecords")]
|
||||
public static class RJW_Patch_UpdateRecords
|
||||
{
|
||||
public static void Postfix(SexProps props)
|
||||
{
|
||||
RJWUtility.UpdateSextypeRecords(props);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -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 rjw;
|
||||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
public class Recipe_HymenSurgery : Recipe_Surgery
|
||||
{
|
||||
public override IEnumerable<BodyPartRecord> GetPartsToApplyOn(Pawn pawn, RecipeDef recipe)
|
||||
{
|
||||
|
||||
if (pawn.gender != Gender.Female)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
BodyPartRecord part = Genital_Helper.get_genitalsBPR(pawn);
|
||||
if (part != null)
|
||||
{
|
||||
List<Hediff> hediffs = Genital_Helper.get_PartsHediffList(pawn, part);
|
||||
if (Genital_Helper.has_vagina(pawn, hediffs) && !pawn.HasHymen())
|
||||
{
|
||||
yield return part;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List<Thing> ingredients, Bill bill)
|
||||
{
|
||||
if (billDoer != null)
|
||||
{
|
||||
TaleRecorder.RecordTale(TaleDefOf.DidSurgery, new object[]
|
||||
{
|
||||
billDoer,
|
||||
pawn
|
||||
});
|
||||
SurgeryResult(pawn);
|
||||
}
|
||||
}
|
||||
|
||||
protected void SurgeryResult(Pawn pawn)
|
||||
{
|
||||
int degree = 1;
|
||||
if (pawn.IsVirgin()) degree = 2;
|
||||
Trait virgin = new Trait(VariousDefOf.Virgin, degree, true);
|
||||
pawn.story.traits.GainTrait(virgin);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HarmonyLib;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
using rjw;
|
||||
|
||||
|
||||
|
||||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
[HarmonyPatch(typeof(PawnGenerator), "GeneratePawn", new Type[] { typeof(PawnGenerationRequest) })]
|
||||
public static class Rimworld_Patch_GeneratePawn
|
||||
{
|
||||
public static void Postfix(PawnGenerationRequest request, ref Pawn __result)
|
||||
{
|
||||
if (__result != null && !request.Newborn && xxx.is_human(__result))
|
||||
{
|
||||
float avgsex = -500;
|
||||
bool isvirgin = Rand.Chance(Configurations.VirginRatio);
|
||||
int totalsex = 0;
|
||||
float totalbirth = 0;
|
||||
if (__result.story != null)
|
||||
{
|
||||
float lust;
|
||||
if (xxx.is_nympho(__result)) lust = __result.RecordRandomizer(VariousDefOf.Lust, Configurations.AvgLust, Configurations.MaxLustDeviation, 0);
|
||||
else lust = __result.RecordRandomizer(VariousDefOf.Lust, Configurations.AvgLust, Configurations.MaxLustDeviation, float.MinValue);
|
||||
|
||||
float sexableage = 0;
|
||||
float minsexage = __result.RaceProps.lifeExpectancy * Configurations.MinSexablePercent;
|
||||
if (__result.ageTracker.AgeBiologicalYears > minsexage)
|
||||
{
|
||||
sexableage = __result.ageTracker.AgeBiologicalYearsFloat - minsexage;
|
||||
avgsex = sexableage * Configurations.SexPerYear * __result.LustFactor();
|
||||
}
|
||||
|
||||
|
||||
if (__result.relations != null && __result.gender == Gender.Female)
|
||||
{
|
||||
totalbirth += __result.relations.ChildrenCount;
|
||||
totalsex += (int)totalbirth;
|
||||
__result.records?.AddTo(xxx.CountOfSexWithHumanlikes, totalbirth);
|
||||
__result.records?.SetTo(xxx.CountOfBirthHuman, totalbirth);
|
||||
if (totalbirth > 0) isvirgin = false;
|
||||
}
|
||||
if (!isvirgin)
|
||||
{
|
||||
if (xxx.is_rapist(__result))
|
||||
{
|
||||
if (xxx.is_zoophile(__result))
|
||||
{
|
||||
if (__result.Has(Quirk.ChitinLover)) totalsex += (int)__result.RecordRandomizer(xxx.CountOfRapedInsects, avgsex, Configurations.MaxSexCountDeviation);
|
||||
else totalsex += (int)__result.RecordRandomizer(xxx.CountOfRapedAnimals, avgsex, Configurations.MaxSexCountDeviation);
|
||||
}
|
||||
else totalsex += (int)__result.RecordRandomizer(xxx.CountOfRapedHumanlikes, avgsex, Configurations.MaxSexCountDeviation);
|
||||
avgsex /= 4;
|
||||
}
|
||||
|
||||
if (xxx.is_zoophile(__result))
|
||||
{
|
||||
if (__result.Has(Quirk.ChitinLover)) totalsex += (int)__result.RecordRandomizer(xxx.CountOfRapedInsects, avgsex, Configurations.MaxSexCountDeviation);
|
||||
else totalsex += (int)__result.RecordRandomizer(xxx.CountOfSexWithAnimals, avgsex, Configurations.MaxSexCountDeviation);
|
||||
avgsex /= 2;
|
||||
}
|
||||
else if (xxx.is_necrophiliac(__result))
|
||||
{
|
||||
totalsex += (int)__result.RecordRandomizer(xxx.CountOfSexWithCorpse, avgsex, Configurations.MaxSexCountDeviation);
|
||||
avgsex /= 2;
|
||||
}
|
||||
|
||||
if (__result.IsSlave)
|
||||
{
|
||||
totalsex += (int)__result.RecordRandomizer(xxx.CountOfBeenRapedByAnimals, Rand.Range(-50, 10), Rand.Range(0, 10) * sexableage);
|
||||
totalsex += (int)__result.RecordRandomizer(xxx.CountOfBeenRapedByHumanlikes, 0, Rand.Range(0, 100) * sexableage);
|
||||
}
|
||||
|
||||
|
||||
totalsex += (int)__result.RecordRandomizer(xxx.CountOfSexWithHumanlikes, avgsex, Configurations.MaxSexCountDeviation);
|
||||
}
|
||||
}
|
||||
__result.records?.SetTo(xxx.CountOfSex, totalsex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,284 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
using rjw;
|
||||
|
||||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
public class SexPartnerHistory : ThingComp
|
||||
{
|
||||
public SexPartnerHistory() { }
|
||||
|
||||
|
||||
//protected List<SexHistory> histories = new List<SexHistory>();
|
||||
protected Dictionary<string,SexHistory> histories = new Dictionary<string,SexHistory>();
|
||||
protected string first = "";
|
||||
protected bool dirty = true;
|
||||
protected string bestaffinity = "";
|
||||
protected float bestaffinitysat = 0;
|
||||
protected xxx.rjwSextype recentsex = xxx.rjwSextype.None;
|
||||
protected string recentpartner = "";
|
||||
protected int[] sextypecount = new int[20];
|
||||
protected float[] sextypesat = new float[20];
|
||||
|
||||
protected string mostpartnercache = "";
|
||||
protected xxx.rjwSextype mostsextypecache = xxx.rjwSextype.None;
|
||||
protected xxx.rjwSextype mostsatsextypecache = xxx.rjwSextype.None;
|
||||
|
||||
|
||||
public string FirstSexInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
Update();
|
||||
return
|
||||
"Partner: " + histories.TryGetValue(first)?.Label ?? "Unknown" +
|
||||
"";
|
||||
}
|
||||
}
|
||||
public string MostSexPartner
|
||||
{
|
||||
get
|
||||
{
|
||||
Update();
|
||||
return histories.TryGetValue(mostpartnercache)?.Label ?? "Unknown";
|
||||
}
|
||||
}
|
||||
public xxx.rjwSextype MostSextype
|
||||
{
|
||||
get
|
||||
{
|
||||
Update();
|
||||
return mostsextypecache;
|
||||
}
|
||||
}
|
||||
public xxx.rjwSextype MostSatisfiedSex
|
||||
{
|
||||
get
|
||||
{
|
||||
Update();
|
||||
return mostsatsextypecache;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override void PostExposeData()
|
||||
{
|
||||
Scribe_Collections.Look(ref histories, "histories", LookMode.Deep);
|
||||
Scribe_Values.Look(ref first, "first", "", true);
|
||||
Scribe_Values.Look(ref bestaffinity, "bestaffinity", "", true);
|
||||
Scribe_Values.Look(ref bestaffinitysat, "bestaffinitysat", bestaffinitysat, true);
|
||||
Scribe_Values.Look(ref recentsex, "recentsex", recentsex, true);
|
||||
Scribe_Values.Look(ref recentpartner, "recentpartner", recentpartner, true);
|
||||
Scribe_Values.Look(ref sextypecount, "sextypecount", sextypecount, true);
|
||||
Scribe_Values.Look(ref sextypesat, "sextypesat", sextypesat, true);
|
||||
base.PostExposeData();
|
||||
}
|
||||
|
||||
public void RecordHistory(Pawn partner, SexProps props)
|
||||
{
|
||||
TryAddHistory(partner);
|
||||
recentpartner = partner.ThingID;
|
||||
SexHistory history = histories[partner.ThingID];
|
||||
history?.RecordSex(props);
|
||||
recentsex = props.sexType;
|
||||
sextypecount[(int)props.sexType]++;
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public void RecordSatisfactionHistory(Pawn partner, SexProps props, float satisfaction)
|
||||
{
|
||||
TryAddHistory(partner);
|
||||
RecordFirst(partner, props);
|
||||
SexHistory history = histories[partner.ThingID];
|
||||
history?.RecordSatisfaction(props, satisfaction);
|
||||
sextypesat[(int)props.sexType] += satisfaction;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
protected bool TryAddHistory(Pawn partner)
|
||||
{
|
||||
if (!histories.ContainsKey(partner.ThingID))
|
||||
{
|
||||
histories.Add(partner.ThingID, new SexHistory(partner));
|
||||
Pawn pawn = parent as Pawn;
|
||||
if (pawn != null)
|
||||
{
|
||||
pawn.records.AddTo(VariousDefOf.SexPartnerCount, 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void RecordFirst(Pawn partner, SexProps props)
|
||||
{
|
||||
if (VirginCheck() && props.sexType == xxx.rjwSextype.Vaginal)
|
||||
{
|
||||
first = partner.ThingID;
|
||||
}
|
||||
}
|
||||
|
||||
protected void Update()
|
||||
{
|
||||
if (dirty)
|
||||
{
|
||||
UpdateStatistics();
|
||||
dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected void UpdateStatistics()
|
||||
{
|
||||
int max = 0;
|
||||
float maxf = 0;
|
||||
int maxindex = 0;
|
||||
string mostID = "Unknown";
|
||||
|
||||
foreach (KeyValuePair<string,SexHistory> element in histories)
|
||||
{
|
||||
SexHistory h = element.Value;
|
||||
|
||||
//find most sex partner
|
||||
if (max < h.TotalSexCount)
|
||||
{
|
||||
max = h.TotalSexCount;
|
||||
mostID = element.Key;
|
||||
}
|
||||
}
|
||||
|
||||
max = 0;
|
||||
for (int i=0; i < sextypecount.Length; i++)
|
||||
{
|
||||
float avgsat = sextypesat[i] / sextypecount[i];
|
||||
if (maxf < avgsat)
|
||||
{
|
||||
maxf = avgsat;
|
||||
maxindex = i;
|
||||
}
|
||||
}
|
||||
|
||||
mostsatsextypecache = (xxx.rjwSextype)maxindex;
|
||||
mostsextypecache = (xxx.rjwSextype)sextypecount.FirstIndexOf(x => x == sextypecount.Max());
|
||||
mostpartnercache = mostID;
|
||||
}
|
||||
|
||||
protected bool VirginCheck()
|
||||
{
|
||||
Pawn pawn = parent as Pawn;
|
||||
if (pawn != null)
|
||||
{
|
||||
if (pawn.IsVirgin()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class SexHistory : IExposable
|
||||
{
|
||||
protected Pawn partner;
|
||||
protected string namecache;
|
||||
protected int totalsexhad = 0;
|
||||
protected int raped = 0;
|
||||
protected int rapedme = 0;
|
||||
protected int orgasms = 0;
|
||||
protected xxx.rjwSextype bestsextype = xxx.rjwSextype.None;
|
||||
protected float bestsatisfaction = 0;
|
||||
|
||||
|
||||
|
||||
public string Label
|
||||
{
|
||||
get
|
||||
{
|
||||
if (partner != null)
|
||||
{
|
||||
namecache = partner.Label;
|
||||
return namecache;
|
||||
}
|
||||
else return namecache;
|
||||
}
|
||||
}
|
||||
public xxx.rjwSextype BestSextype
|
||||
{
|
||||
get
|
||||
{
|
||||
return bestsextype;
|
||||
}
|
||||
}
|
||||
public float BestSatisfaction
|
||||
{
|
||||
get
|
||||
{
|
||||
return bestsatisfaction;
|
||||
}
|
||||
}
|
||||
public int TotalSexCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return totalsexhad;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public SexHistory() { }
|
||||
|
||||
public SexHistory(Pawn pawn)
|
||||
{
|
||||
partner = pawn;
|
||||
namecache = pawn.Label;
|
||||
}
|
||||
|
||||
|
||||
public void ExposeData()
|
||||
{
|
||||
Scribe_References.Look(ref partner, "partner", true);
|
||||
Scribe_Values.Look(ref namecache, "namecache", namecache, true);
|
||||
Scribe_Values.Look(ref totalsexhad, "totalsexhad", totalsexhad, true);
|
||||
Scribe_Values.Look(ref raped, "raped", raped, true);
|
||||
Scribe_Values.Look(ref rapedme, "rapedme", rapedme, true);
|
||||
Scribe_Values.Look(ref orgasms, "orgasms", orgasms, true);
|
||||
Scribe_Values.Look(ref bestsextype, "bestsextype", bestsextype, true);
|
||||
Scribe_Values.Look(ref bestsatisfaction, "bestsatisfaction", bestsatisfaction, true);
|
||||
}
|
||||
|
||||
public void RecordSex(SexProps props)
|
||||
{
|
||||
totalsexhad++;
|
||||
if (props.isRape)
|
||||
{
|
||||
if (partner == props.giver)
|
||||
{
|
||||
rapedme++;
|
||||
}
|
||||
else if (partner == props.reciever)
|
||||
{
|
||||
raped++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RecordSatisfaction(SexProps props, float satisfaction)
|
||||
{
|
||||
if (satisfaction > bestsatisfaction)
|
||||
{
|
||||
orgasms++;
|
||||
bestsextype = props.sexType;
|
||||
bestsatisfaction = satisfaction;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
using rjw;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
[StaticConstructorOnStartup]
|
||||
public static class HistoryUtility
|
||||
{
|
||||
public static readonly Texture2D HistoryIcon = ContentFinder<Texture2D>.Get("UI/buttons/OpenStatsReport");
|
||||
public static readonly Texture2D UnknownPawn = ContentFinder<Texture2D>.Get("UI/Icon/UnknownPawn");
|
||||
public static readonly Texture2D FirstOverlay = ContentFinder<Texture2D>.Get("UI/Icon/FirstBG");
|
||||
public static readonly Texture2D Heart = ContentFinder<Texture2D>.Get("Things/Mote/Heart");
|
||||
public static readonly Texture2D Incest = ContentFinder<Texture2D>.Get("UI/Icon/Incest");
|
||||
public static readonly Texture2D Locked = ContentFinder<Texture2D>.Get("UI/Icon/RSLocked");
|
||||
public static readonly Texture2D Unlocked = ContentFinder<Texture2D>.Get("UI/Icon/RSUnlocked");
|
||||
public static Texture2D Slaanesh = SolidColorMaterials.NewSolidColorTexture(0.686f, 0.062f, 0.698f, 1.0f);
|
||||
public static Texture2D Khorne = SolidColorMaterials.NewSolidColorTexture(0.415f, 0.0f, 0.003f, 1.0f);
|
||||
public static Texture2D Tzeentch = SolidColorMaterials.NewSolidColorTexture(0.082f, 0.453f, 0.6f, 1.0f);
|
||||
public static Texture2D Nurgle = SolidColorMaterials.NewSolidColorTexture(0.6f, 0.83f, 0.35f, 1.0f);
|
||||
public static Texture2D Partners = SolidColorMaterials.NewSolidColorTexture(0.843f, 0.474f, 0.6f, 1.0f);
|
||||
public static Texture2D TotalSex = SolidColorMaterials.NewSolidColorTexture(0.878f, 0.674f, 0.411f, 1.0f);
|
||||
public static Texture2D Satisfaction = SolidColorMaterials.NewSolidColorTexture(0.325f, 0.815f, 0.729f,1.0f);
|
||||
public static readonly Color HistoryColor = new Color(0.9f,0.5f,0.5f);
|
||||
|
||||
public static readonly Texture2D[] SextypeColor = new Texture2D[]
|
||||
{
|
||||
Texture2D.linearGrayTexture, //None = 0,
|
||||
SolidColorMaterials.NewSolidColorTexture(0.900f, 0.500f, 0.500f, 1.0f), //Vaginal = 1,
|
||||
SolidColorMaterials.NewSolidColorTexture(0.529f, 0.313f, 0.113f, 1.0f), //Anal = 2,
|
||||
SolidColorMaterials.NewSolidColorTexture(0.529f, 0.113f, 0.305f, 1.0f), //Oral = 3,
|
||||
SolidColorMaterials.NewSolidColorTexture(0.000f, 0.819f, 0.219f, 1.0f), //Masturbation = 4,
|
||||
SolidColorMaterials.NewSolidColorTexture(0.000f, 0.560f, 0.090f, 1.0f), //DoublePenetration
|
||||
SolidColorMaterials.NewSolidColorTexture(0.839f, 0.850f, 0.505f, 1.0f), //Boobjob = 6,
|
||||
SolidColorMaterials.NewSolidColorTexture(0.858f, 0.886f, 0.113f, 1.0f), //Handjob = 7,
|
||||
SolidColorMaterials.NewSolidColorTexture(0.752f, 0.780f, 0.000f, 1.0f), //Footjob = 8,
|
||||
SolidColorMaterials.NewSolidColorTexture(0.484f, 0.500f, 0.241f, 1.0f), //Fingering = 9,
|
||||
SolidColorMaterials.NewSolidColorTexture(0.913f, 0.909f, 0.909f, 1.0f), //Scissoring = 10,
|
||||
SolidColorMaterials.NewSolidColorTexture(0.588f, 0.576f, 0.431f, 1.0f), //MutualMasturbation
|
||||
SolidColorMaterials.NewSolidColorTexture(0.741f, 0.000f, 0.682f, 1.0f), //Fisting = 12,
|
||||
SolidColorMaterials.NewSolidColorTexture(0.121f, 0.929f, 1.000f, 1.0f), //MechImplant = 13,
|
||||
SolidColorMaterials.NewSolidColorTexture(0.478f, 0.274f, 0.160f, 1.0f), //Rimming = 14,
|
||||
SolidColorMaterials.NewSolidColorTexture(0.819f, 0.301f, 0.552f, 1.0f), //Fellatio = 15,
|
||||
SolidColorMaterials.NewSolidColorTexture(0.819f, 0.301f, 0.552f, 1.0f), //Cunnilingus = 16,
|
||||
SolidColorMaterials.NewSolidColorTexture(0.529f, 0.113f, 0.305f, 1.0f), //Sixtynine = 17
|
||||
Texture2D.linearGrayTexture, //? = 18
|
||||
Texture2D.linearGrayTexture, //? = 19
|
||||
Texture2D.linearGrayTexture //? = 20
|
||||
};
|
||||
|
||||
public static readonly Texture2D[] PassionBG = new Texture2D[]
|
||||
{
|
||||
|
||||
Texture2D.blackTexture, //None = 0,
|
||||
SolidColorMaterials.NewSolidColorTexture(0.800f, 0.800f, 0.800f, 1.0f), //Minor = 1,
|
||||
SolidColorMaterials.NewSolidColorTexture(1.000f, 0.875f, 0.000f, 1.0f) //Major = 2,
|
||||
};
|
||||
|
||||
public static SexPartnerHistory GetPartnerHistory(this Pawn pawn)
|
||||
{
|
||||
return pawn.TryGetComp<SexPartnerHistory>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,638 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
using rjw;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
public class SexPartnerHistory : ThingComp
|
||||
{
|
||||
public SexPartnerHistory() { }
|
||||
public const int ARRLEN = 20;
|
||||
|
||||
//protected List<SexHistory> histories = new List<SexHistory>();
|
||||
protected Dictionary<string, SexHistory> histories = new Dictionary<string, SexHistory>();
|
||||
protected string first = "";
|
||||
protected bool dirty = true;
|
||||
protected xxx.rjwSextype recentsex = xxx.rjwSextype.None;
|
||||
protected float recentsat = 0;
|
||||
protected string recentpartner = "";
|
||||
protected int[] sextypecount = new int[ARRLEN];
|
||||
protected float[] sextypesat = new float[ARRLEN];
|
||||
protected int virginstaken = 0;
|
||||
protected int incestuous = 0;
|
||||
protected int bestiality = 0;
|
||||
protected int corpsefuck = 0;
|
||||
protected int interspecies = 0;
|
||||
|
||||
protected string mostpartnercache = "";
|
||||
protected xxx.rjwSextype mostsextypecache = xxx.rjwSextype.None;
|
||||
protected xxx.rjwSextype mostsatsextypecache = xxx.rjwSextype.None;
|
||||
protected xxx.rjwSextype bestsextypecache = xxx.rjwSextype.None;
|
||||
protected float bestsextypesatcache = 0;
|
||||
protected string bestpartnercache = "";
|
||||
protected int totalsexcache = 0;
|
||||
protected int totalrapedcache = 0;
|
||||
protected int totalbeenrapedcache = 0;
|
||||
protected ThingDef preferracecache = null;
|
||||
protected int preferracesexcountcache = 0;
|
||||
protected Pawn preferracepawncache = null;
|
||||
protected float avtsatcache = 0;
|
||||
|
||||
|
||||
private List<SexHistory> partnerlistcache;
|
||||
private List<int> sextypecountsave;
|
||||
private List<float> sextypesatsave;
|
||||
|
||||
|
||||
public SexHistory GetFirstPartnerHistory
|
||||
{
|
||||
get
|
||||
{
|
||||
Update();
|
||||
return histories.TryGetValue(first);
|
||||
}
|
||||
}
|
||||
public SexHistory GetMostPartnerHistory
|
||||
{
|
||||
get
|
||||
{
|
||||
Update();
|
||||
return histories.TryGetValue(mostpartnercache);
|
||||
}
|
||||
}
|
||||
public xxx.rjwSextype MostSextype
|
||||
{
|
||||
get
|
||||
{
|
||||
Update();
|
||||
return mostsextypecache;
|
||||
}
|
||||
}
|
||||
public xxx.rjwSextype MostSatisfiedSex
|
||||
{
|
||||
get
|
||||
{
|
||||
Update();
|
||||
return mostsatsextypecache;
|
||||
}
|
||||
}
|
||||
public SexHistory GetRecentPartnersHistory
|
||||
{
|
||||
get
|
||||
{
|
||||
return histories.TryGetValue(recentpartner);
|
||||
}
|
||||
}
|
||||
public SexHistory GetBestSexPartnerHistory
|
||||
{
|
||||
get
|
||||
{
|
||||
Update();
|
||||
SexHistory history = histories.TryGetValue(bestpartnercache);
|
||||
return history;
|
||||
}
|
||||
}
|
||||
public float TotalSexHad
|
||||
{
|
||||
get
|
||||
{
|
||||
Update();
|
||||
return totalsexcache;
|
||||
}
|
||||
}
|
||||
public int VirginsTaken
|
||||
{
|
||||
get
|
||||
{
|
||||
return virginstaken;
|
||||
}
|
||||
}
|
||||
public List<SexHistory> PartnerList
|
||||
{
|
||||
get
|
||||
{
|
||||
Update();
|
||||
return partnerlistcache;
|
||||
}
|
||||
}
|
||||
public int PartnerCount
|
||||
{
|
||||
get
|
||||
{
|
||||
if (histories == null) histories = new Dictionary<string, SexHistory>();
|
||||
return histories.Count;
|
||||
}
|
||||
}
|
||||
public int IncestuousCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return incestuous;
|
||||
}
|
||||
}
|
||||
public int RapedCount
|
||||
{
|
||||
get
|
||||
{
|
||||
Update();
|
||||
return totalrapedcache;
|
||||
}
|
||||
}
|
||||
public int BeenRapedCount
|
||||
{
|
||||
get
|
||||
{
|
||||
Update();
|
||||
return totalbeenrapedcache;
|
||||
}
|
||||
}
|
||||
public ThingDef PreferRace
|
||||
{
|
||||
get
|
||||
{
|
||||
Update();
|
||||
return preferracecache;
|
||||
}
|
||||
}
|
||||
public int PreferRaceSexCount
|
||||
{
|
||||
get
|
||||
{
|
||||
Update();
|
||||
return preferracesexcountcache;
|
||||
}
|
||||
}
|
||||
public int BestialityCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return bestiality;
|
||||
}
|
||||
}
|
||||
public int CorpseFuckCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return corpsefuck;
|
||||
}
|
||||
}
|
||||
public int InterspeciesCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return interspecies;
|
||||
}
|
||||
}
|
||||
public float AVGSat
|
||||
{
|
||||
get
|
||||
{
|
||||
Update();
|
||||
if (totalsexcache == 0) return 0;
|
||||
return sextypesat.Sum() / totalsexcache;
|
||||
}
|
||||
}
|
||||
public Texture GetPreferRaceIcon(Vector2 size)
|
||||
{
|
||||
Update();
|
||||
if (preferracepawncache != null) return PortraitsCache.Get(preferracepawncache, size, Rot4.South, default, 1, true, true, false, false);
|
||||
else return HistoryUtility.UnknownPawn;
|
||||
|
||||
}
|
||||
|
||||
public float GetBestSextype(out xxx.rjwSextype sextype)
|
||||
{
|
||||
if (dirty) Update();
|
||||
sextype = bestsextypecache;
|
||||
return bestsextypesatcache;
|
||||
}
|
||||
|
||||
public float GetRecentSextype(out xxx.rjwSextype sextype)
|
||||
{
|
||||
if (dirty) Update();
|
||||
sextype = recentsex;
|
||||
return recentsat;
|
||||
}
|
||||
|
||||
public SexHistory this[Pawn pawn]
|
||||
{
|
||||
get
|
||||
{
|
||||
return histories.TryGetValue(pawn.ThingID);
|
||||
}
|
||||
}
|
||||
|
||||
public float GetAVGSat(xxx.rjwSextype sextype)
|
||||
{
|
||||
int index = (int)sextype;
|
||||
return GetAVGSat(index);
|
||||
}
|
||||
|
||||
public float GetAVGSat(int index)
|
||||
{
|
||||
float res = sextypesat[index] / sextypecount[index];
|
||||
return float.IsNaN(res) ? 0f : res;
|
||||
}
|
||||
|
||||
public int GetSexCount(int index)
|
||||
{
|
||||
return sextypecount[index];
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override void PostExposeData()
|
||||
{
|
||||
if (Scribe.mode == LoadSaveMode.Saving)
|
||||
{
|
||||
sextypecountsave = sextypecount.ToList();
|
||||
sextypesatsave = sextypesat.ToList();
|
||||
}
|
||||
|
||||
Scribe_Collections.Look(ref histories, "histories", LookMode.Value, LookMode.Deep);
|
||||
Scribe_Values.Look(ref first, "first", "", true);
|
||||
Scribe_Values.Look(ref recentsex, "recentsex", recentsex, true);
|
||||
Scribe_Values.Look(ref recentsat, "recentsat", recentsat, true);
|
||||
Scribe_Values.Look(ref recentpartner, "recentpartner", recentpartner, true);
|
||||
Scribe_Values.Look(ref virginstaken, "virginstaken", virginstaken, true);
|
||||
Scribe_Values.Look(ref incestuous, "incestous", incestuous, true);
|
||||
Scribe_Values.Look(ref bestiality, "bestiality", bestiality, true);
|
||||
Scribe_Values.Look(ref corpsefuck, "corpsefuck", corpsefuck, true);
|
||||
Scribe_Values.Look(ref interspecies, "interspecies", interspecies, true);
|
||||
Scribe_Collections.Look(ref sextypecountsave, "sextypecountsave", LookMode.Value);
|
||||
Scribe_Collections.Look(ref sextypesatsave, "sextypesatsave", LookMode.Value);
|
||||
//Scribe_Values.Look(ref sextypecount, "sextypecount", new int[ARRLEN], true); // not work
|
||||
//Scribe_Values.Look(ref sextypesat, "sextypesat", new float[ARRLEN], true);
|
||||
if (Scribe.mode == LoadSaveMode.LoadingVars)
|
||||
{
|
||||
sextypecount = sextypecountsave?.ToArray() ?? new int[ARRLEN];
|
||||
sextypesat = sextypesatsave?.ToArray() ?? new float[ARRLEN];
|
||||
}
|
||||
|
||||
if (histories == null) histories = new Dictionary<string, SexHistory>();
|
||||
|
||||
base.PostExposeData();
|
||||
}
|
||||
|
||||
public void RecordHistory(Pawn partner, SexProps props)
|
||||
{
|
||||
Pawn pawn = parent as Pawn;
|
||||
TryAddHistory(partner);
|
||||
RecordFirst(partner, props);
|
||||
recentpartner = partner.ThingID;
|
||||
SexHistory history = histories[partner.ThingID];
|
||||
history?.RecordSex(props);
|
||||
recentsex = props.sexType;
|
||||
sextypecount[(int)props.sexType]++;
|
||||
if (partner.IsIncest(pawn)) incestuous++;
|
||||
if (partner.Dead) corpsefuck++;
|
||||
if (props.IsBestiality()) bestiality++;
|
||||
else if (pawn.def != partner.def) interspecies++;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public void RecordSatisfactionHistory(Pawn partner, SexProps props, float satisfaction)
|
||||
{
|
||||
TryAddHistory(partner);
|
||||
RecordFirst(partner, props);
|
||||
SexHistory history = histories[partner.ThingID];
|
||||
history?.RecordSatisfaction(props, satisfaction);
|
||||
recentsat = satisfaction;
|
||||
sextypesat[(int)props.sexType] += satisfaction;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
protected bool TryAddHistory(Pawn partner)
|
||||
{
|
||||
if (!histories.ContainsKey(partner.ThingID))
|
||||
{
|
||||
SexHistory newhistory = new SexHistory(partner,partner.IsIncest(parent as Pawn));
|
||||
histories.Add(partner.ThingID, newhistory);
|
||||
Pawn pawn = parent as Pawn;
|
||||
if (pawn != null)
|
||||
{
|
||||
pawn.records.AddTo(VariousDefOf.SexPartnerCount, 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void RecordFirst(Pawn partner, SexProps props)
|
||||
{
|
||||
if (VirginCheck() && props.sexType == xxx.rjwSextype.Vaginal)
|
||||
{
|
||||
TryAddHistory(partner);
|
||||
first = partner.ThingID;
|
||||
SexPartnerHistory history = partner.GetPartnerHistory();
|
||||
if (history != null)
|
||||
{
|
||||
history.TakeSomeonesVirgin(parent as Pawn);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void TakeSomeonesVirgin(Pawn partner)
|
||||
{
|
||||
TryAddHistory(partner);
|
||||
SexHistory history = histories[partner.ThingID];
|
||||
if (history != null) history.TookVirgin();
|
||||
virginstaken++;
|
||||
}
|
||||
|
||||
protected void Update()
|
||||
{
|
||||
if (dirty)
|
||||
{
|
||||
UpdateStatistics();
|
||||
UpdateBestSex();
|
||||
UpdatePartnerList();
|
||||
dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected void UpdateStatistics()
|
||||
{
|
||||
int max = 0;
|
||||
float maxsat = 0;
|
||||
float maxf = 0;
|
||||
int maxindex = 0;
|
||||
string mostID = Keyed.Unknown;
|
||||
string bestID = Keyed.Unknown;
|
||||
totalsexcache = 0;
|
||||
totalrapedcache = 0;
|
||||
totalbeenrapedcache = 0;
|
||||
Dictionary<ThingDef, int> racetotalsat = new Dictionary<ThingDef, int>();
|
||||
List<Pawn> allpartners = new List<Pawn>();
|
||||
|
||||
foreach (KeyValuePair<string,SexHistory> element in histories)
|
||||
{
|
||||
SexHistory h = element.Value;
|
||||
|
||||
//find most sex partner
|
||||
if (max < h.TotalSexCount)
|
||||
{
|
||||
max = h.TotalSexCount;
|
||||
mostID = element.Key;
|
||||
}
|
||||
if (maxsat < h.BestSatisfaction)
|
||||
{
|
||||
maxsat = h.BestSatisfaction;
|
||||
bestID = element.Key;
|
||||
}
|
||||
|
||||
if (h.Partner != null)
|
||||
{
|
||||
Pawn partner = h.Partner;
|
||||
allpartners.Add(partner);
|
||||
if (racetotalsat.ContainsKey(partner.def))
|
||||
{
|
||||
racetotalsat[partner.def] += h.TotalSexCount - h.RapedMe;
|
||||
}
|
||||
else
|
||||
{
|
||||
racetotalsat.Add(partner.def, h.TotalSexCount - h.RapedMe);
|
||||
}
|
||||
}
|
||||
|
||||
totalsexcache += h.TotalSexCount;
|
||||
totalrapedcache += h.Raped;
|
||||
totalbeenrapedcache += h.RapedMe;
|
||||
}
|
||||
|
||||
if (!racetotalsat.NullOrEmpty())
|
||||
{
|
||||
KeyValuePair<ThingDef, int> prefer = racetotalsat.MaxBy(x => x.Value);
|
||||
preferracecache = prefer.Key;
|
||||
preferracesexcountcache = prefer.Value;
|
||||
preferracepawncache = allpartners.FirstOrDefault(x => x.def == preferracecache);
|
||||
}
|
||||
|
||||
max = 0;
|
||||
for (int i=0; i < sextypecount.Length; i++)
|
||||
{
|
||||
float avgsat = sextypesat[i] / sextypecount[i];
|
||||
if (maxf < avgsat)
|
||||
{
|
||||
maxf = avgsat;
|
||||
maxindex = i;
|
||||
}
|
||||
}
|
||||
|
||||
mostsatsextypecache = (xxx.rjwSextype)maxindex;
|
||||
mostsextypecache = (xxx.rjwSextype)sextypecount.FirstIndexOf(x => x == sextypecount.Max());
|
||||
mostpartnercache = mostID;
|
||||
bestpartnercache = bestID;
|
||||
|
||||
racetotalsat.Clear();
|
||||
allpartners.Clear();
|
||||
}
|
||||
|
||||
protected void UpdateBestSex()
|
||||
{
|
||||
int bestindex = 0;
|
||||
float bestsat = 0;
|
||||
float avgsat;
|
||||
for(int i=0; i< sextypecount.Length; i++)
|
||||
{
|
||||
avgsat = sextypesat[i] / sextypecount[i];
|
||||
if (bestsat < avgsat)
|
||||
{
|
||||
bestindex = i;
|
||||
bestsat = avgsat;
|
||||
}
|
||||
}
|
||||
bestsextypecache = (xxx.rjwSextype)bestindex;
|
||||
bestsextypesatcache = bestsat;
|
||||
}
|
||||
|
||||
protected void UpdatePartnerList()
|
||||
{
|
||||
if (partnerlistcache == null) partnerlistcache = new List<SexHistory>();
|
||||
partnerlistcache.Clear();
|
||||
if (!histories.NullOrEmpty()) foreach (SexHistory history in histories.Values)
|
||||
{
|
||||
if (history != null) partnerlistcache.Add(history);
|
||||
}
|
||||
}
|
||||
|
||||
protected bool VirginCheck()
|
||||
{
|
||||
if (histories.TryGetValue(first) != null) return false;
|
||||
|
||||
Pawn pawn = parent as Pawn;
|
||||
if (pawn != null)
|
||||
{
|
||||
if (pawn.IsVirgin()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class SexHistory : IExposable
|
||||
{
|
||||
protected Pawn partner = null;
|
||||
protected string namecache;
|
||||
protected int totalsexhad = 0;
|
||||
protected int raped = 0;
|
||||
protected int rapedme = 0;
|
||||
protected int orgasms = 0;
|
||||
protected xxx.rjwSextype bestsextype = xxx.rjwSextype.None;
|
||||
protected float bestsatisfaction = 0;
|
||||
protected bool itookvirgin = false;
|
||||
protected bool incest = false;
|
||||
|
||||
public string Label
|
||||
{
|
||||
get
|
||||
{
|
||||
if (partner != null)
|
||||
{
|
||||
namecache = partner.Label;
|
||||
return namecache;
|
||||
}
|
||||
else return namecache;
|
||||
}
|
||||
}
|
||||
public xxx.rjwSextype BestSextype
|
||||
{
|
||||
get
|
||||
{
|
||||
return bestsextype;
|
||||
}
|
||||
}
|
||||
public float BestSatisfaction
|
||||
{
|
||||
get
|
||||
{
|
||||
return bestsatisfaction;
|
||||
}
|
||||
}
|
||||
public int TotalSexCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return totalsexhad;
|
||||
}
|
||||
}
|
||||
public Pawn Partner
|
||||
{
|
||||
get
|
||||
{
|
||||
return partner;
|
||||
}
|
||||
}
|
||||
public string RapeInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
string res = "";
|
||||
if (raped > 0) res += Keyed.RS_Raped + raped + " ";
|
||||
if (rapedme > 0) res += Keyed.RS_RapedMe + rapedme + " ";
|
||||
return res;
|
||||
}
|
||||
}
|
||||
public int OrgasmCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return orgasms;
|
||||
}
|
||||
}
|
||||
public bool IamFirst
|
||||
{
|
||||
get
|
||||
{
|
||||
return itookvirgin;
|
||||
}
|
||||
}
|
||||
public bool Incest
|
||||
{
|
||||
get
|
||||
{
|
||||
return incest;
|
||||
}
|
||||
}
|
||||
public int Raped
|
||||
{
|
||||
get
|
||||
{
|
||||
return raped;
|
||||
}
|
||||
}
|
||||
public int RapedMe
|
||||
{
|
||||
get
|
||||
{
|
||||
return rapedme;
|
||||
}
|
||||
}
|
||||
|
||||
public SexHistory() { }
|
||||
|
||||
public SexHistory(Pawn pawn, bool incest = false)
|
||||
{
|
||||
this.partner = pawn;
|
||||
this.namecache = pawn.Label;
|
||||
this.incest = incest;
|
||||
}
|
||||
|
||||
|
||||
public void ExposeData()
|
||||
{
|
||||
Scribe_References.Look(ref partner, "partner", true);
|
||||
Scribe_Values.Look(ref namecache, "namecache", namecache, true);
|
||||
Scribe_Values.Look(ref totalsexhad, "totalsexhad", totalsexhad, true);
|
||||
Scribe_Values.Look(ref raped, "raped", raped, true);
|
||||
Scribe_Values.Look(ref rapedme, "rapedme", rapedme, true);
|
||||
Scribe_Values.Look(ref orgasms, "orgasms", orgasms, true);
|
||||
Scribe_Values.Look(ref bestsextype, "bestsextype", bestsextype, true);
|
||||
Scribe_Values.Look(ref bestsatisfaction, "bestsatisfaction", bestsatisfaction, true);
|
||||
Scribe_Values.Look(ref itookvirgin, "itookvirgin", itookvirgin, true);
|
||||
Scribe_Values.Look(ref incest, "incest", incest, true);
|
||||
}
|
||||
|
||||
public void RecordSex(SexProps props)
|
||||
{
|
||||
totalsexhad++;
|
||||
if (props.isRape)
|
||||
{
|
||||
if (partner == props.giver)
|
||||
{
|
||||
rapedme++;
|
||||
}
|
||||
else if (partner == props.reciever)
|
||||
{
|
||||
raped++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RecordSatisfaction(SexProps props, float satisfaction)
|
||||
{
|
||||
if (satisfaction > bestsatisfaction)
|
||||
{
|
||||
orgasms++;
|
||||
bestsextype = props.sexType;
|
||||
bestsatisfaction = satisfaction;
|
||||
}
|
||||
}
|
||||
|
||||
public void TookVirgin()
|
||||
{
|
||||
itookvirgin = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Verse;
|
||||
using RimWorld;
|
||||
|
||||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
/// <summary>
|
||||
/// ThoughtDef using opinion
|
||||
/// </summary>
|
||||
public class ThoughtDef_Opinionbased : ThoughtDef
|
||||
{
|
||||
public List<float> minimumValueforStage = new List<float>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Thought class using record.
|
||||
/// </summary>
|
||||
public class Thought_Opinionbased : Thought_Memory
|
||||
{
|
||||
protected ThoughtDef_Opinionbased Def => (ThoughtDef_Opinionbased)def;
|
||||
protected List<float> minimumValueforStage => Def.minimumValueforStage;
|
||||
|
||||
public override int CurStageIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
float value = 0f;
|
||||
if (otherPawn != null) value = pawn.relations?.OpinionOf(otherPawn) ?? 0f;
|
||||
for (int i = minimumValueforStage.Count - 1; i > 0; i--)
|
||||
{
|
||||
if (minimumValueforStage[i] < value) return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -45,9 +45,6 @@ namespace RJWSexperience
|
|||
|
||||
public class Thought_AteCum : Thought_Recordbased
|
||||
{
|
||||
|
||||
protected int recordIncrement = 1;
|
||||
|
||||
public override int CurStageIndex
|
||||
{
|
||||
get
|
||||
|
@ -60,21 +57,13 @@ namespace RJWSexperience
|
|||
public override void ExposeData()
|
||||
{
|
||||
base.ExposeData();
|
||||
Scribe_Values.Look(ref recordIncrement, "recordIncrement", recordIncrement, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//There is no direct way to modify custom records via ingestion. So i increase it from thought.
|
||||
public override void ThoughtInterval()
|
||||
{
|
||||
base.ThoughtInterval();
|
||||
if (recordIncrement >= 1)
|
||||
{
|
||||
recordIncrement--;
|
||||
pawn.records.AddTo(VariousDefOf.NumofEatenCum, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override bool TryMergeWithExistingMemory(out bool showBubble)
|
||||
|
@ -97,13 +86,11 @@ namespace RJWSexperience
|
|||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
recordIncrement = 1;
|
||||
}
|
||||
|
||||
protected virtual void Merged()
|
||||
{
|
||||
age = 0;
|
||||
recordIncrement += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Verse;
|
||||
using RimWorld;
|
||||
using UnityEngine;
|
||||
using rjw;
|
||||
|
||||
|
||||
namespace RJWSexperience.UI
|
||||
{
|
||||
public static class RJWUIUtility
|
||||
{
|
||||
public const float FONTHEIGHT = 22f;
|
||||
public const float CARDHEIGHT = 110f;
|
||||
public const float LISTPAWNSIZE = 100f;
|
||||
public const float BASESAT = 0.40f;
|
||||
public const float ICONSIZE = 30f;
|
||||
|
||||
|
||||
public static void DrawQuirk(this Rect rect, Pawn pawn)
|
||||
{
|
||||
List<Quirk> quirks = Quirk.All.FindAll(x => pawn.Has(x));
|
||||
string quirkstr = quirks.Select(x => x.Key).ToCommaList();
|
||||
string tooltip = "";
|
||||
|
||||
Widgets.Label(rect, "Quirks".Translate() + quirkstr);
|
||||
|
||||
if (Mouse.IsOver(rect))
|
||||
{
|
||||
if (quirks.NullOrEmpty())
|
||||
{
|
||||
tooltip = "NoQuirks".Translate();
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
foreach (var q in quirks)
|
||||
{
|
||||
stringBuilder.AppendLine(q.Key.Colorize(Color.yellow));
|
||||
stringBuilder.AppendLine(q.LocaliztionKey.Translate(pawn.Named("pawn")).AdjustedFor(pawn).Resolve());
|
||||
stringBuilder.AppendLine("");
|
||||
}
|
||||
tooltip = stringBuilder.ToString().TrimEndNewlines();
|
||||
}
|
||||
Widgets.DrawHighlight(rect);
|
||||
}
|
||||
|
||||
TooltipHandler.TipRegion(rect, tooltip);
|
||||
}
|
||||
|
||||
public static void DrawSexuality(this Rect rect, CompRJW comp)
|
||||
{
|
||||
if (comp != null)
|
||||
{
|
||||
string sexuality = Keyed.Sexuality[(int)comp.orientation];
|
||||
Widgets.Label(rect, Keyed.RS_Sexuality + ": " + sexuality);
|
||||
Widgets.DrawHighlightIfMouseover(rect);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetRelationsString(this Pawn pawn, Pawn otherpawn)
|
||||
{
|
||||
if (otherpawn != null)
|
||||
{
|
||||
IEnumerable<PawnRelationDef> relations = pawn.GetRelations(otherpawn);
|
||||
if (!relations.EnumerableNullOrEmpty()) return relations.Select(x => x.GetGenderSpecificLabel(otherpawn)).ToCommaList().CapitalizeFirst();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static void DrawBorder(this Rect rect, Texture border, float thickness = 1f)
|
||||
{
|
||||
GUI.DrawTexture(new Rect(rect.x,rect.y,rect.width, thickness), border);
|
||||
GUI.DrawTexture(new Rect(rect.x+rect.width-thickness,rect.y, thickness, rect.height), border);
|
||||
GUI.DrawTexture(new Rect(rect.x,rect.y+rect.height - thickness,rect.width, thickness), border);
|
||||
GUI.DrawTexture(new Rect(rect.x, rect.y, thickness, rect.height), border);
|
||||
}
|
||||
|
||||
public static string GetStatExplanation(Pawn pawn, StatDef stat, float val)
|
||||
{
|
||||
return stat.description + "\n" +
|
||||
stat.Worker.GetExplanationFull(StatRequest.For(pawn), ToStringNumberSense.Undefined, val);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,608 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
using Verse.Sound;
|
||||
using RimWorld;
|
||||
using rjw;
|
||||
|
||||
|
||||
namespace RJWSexperience.UI
|
||||
{
|
||||
public class SexStatusWindow : Window
|
||||
{
|
||||
public const float FONTHEIGHT = RJWUIUtility.FONTHEIGHT;
|
||||
public const float CARDHEIGHT = RJWUIUtility.CARDHEIGHT;
|
||||
public const float LISTPAWNSIZE = RJWUIUtility.LISTPAWNSIZE;
|
||||
public const float BASESAT = RJWUIUtility.BASESAT;
|
||||
public const float ICONSIZE = RJWUIUtility.ICONSIZE;
|
||||
|
||||
public static readonly int[] Sextype =
|
||||
{
|
||||
(int)xxx.rjwSextype.Vaginal,
|
||||
(int)xxx.rjwSextype.Anal,
|
||||
(int)xxx.rjwSextype.Oral,
|
||||
(int)xxx.rjwSextype.Fellatio,
|
||||
(int)xxx.rjwSextype.Cunnilingus,
|
||||
(int)xxx.rjwSextype.DoublePenetration,
|
||||
(int)xxx.rjwSextype.Boobjob,
|
||||
(int)xxx.rjwSextype.Handjob,
|
||||
(int)xxx.rjwSextype.Footjob,
|
||||
(int)xxx.rjwSextype.Fingering,
|
||||
(int)xxx.rjwSextype.Scissoring,
|
||||
(int)xxx.rjwSextype.MutualMasturbation,
|
||||
(int)xxx.rjwSextype.Fisting,
|
||||
(int)xxx.rjwSextype.Rimming,
|
||||
(int)xxx.rjwSextype.Sixtynine
|
||||
};
|
||||
|
||||
|
||||
protected Pawn pawn;
|
||||
protected SexHistory selectedPawn;
|
||||
protected SexPartnerHistory history;
|
||||
protected CompRJW rjwcomp;
|
||||
|
||||
private static GUIStyleState fontstylestate = new GUIStyleState() { textColor = Color.white };
|
||||
private static GUIStyleState boxstylestate = GUI.skin.textArea.normal;
|
||||
private static GUIStyleState buttonstylestate = GUI.skin.button.normal;
|
||||
private static GUIStyle fontstylecenter = new GUIStyle() { alignment = TextAnchor.MiddleCenter, normal = fontstylestate };
|
||||
private static GUIStyle fontstyleright = new GUIStyle() { alignment = TextAnchor.MiddleRight, normal = fontstylestate };
|
||||
private static GUIStyle fontstyleleft = new GUIStyle() { alignment = TextAnchor.MiddleLeft, normal = fontstylestate };
|
||||
private static GUIStyle boxstyle = new GUIStyle(GUI.skin.textArea) { hover = boxstylestate, onHover = boxstylestate, onNormal = boxstylestate };
|
||||
private static GUIStyle buttonstyle = new GUIStyle(GUI.skin.button) { hover = buttonstylestate, onHover = buttonstylestate, onNormal = buttonstylestate };
|
||||
|
||||
private static Vector2 pos;
|
||||
private static Vector2 scroll;
|
||||
private static bool opened;
|
||||
|
||||
public SexStatusWindow(Pawn pawn, SexPartnerHistory history)
|
||||
{
|
||||
this.pawn = pawn;
|
||||
this.history = history;
|
||||
this.selectedPawn = null;
|
||||
this.rjwcomp = pawn.TryGetComp<CompRJW>();
|
||||
}
|
||||
|
||||
protected override void SetInitialSizeAndPosition()
|
||||
{
|
||||
Vector2 initialSize = InitialSize;
|
||||
if (!opened)
|
||||
{
|
||||
windowRect = new Rect((Verse.UI.screenWidth - initialSize.x) / 2f, ((float)Verse.UI.screenHeight - initialSize.y) / 2f, initialSize.x, initialSize.y);
|
||||
opened = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
windowRect = new Rect(pos, initialSize);
|
||||
}
|
||||
windowRect = windowRect.Rounded();
|
||||
|
||||
}
|
||||
|
||||
public override Vector2 InitialSize
|
||||
{
|
||||
get
|
||||
{
|
||||
float width = 900f;
|
||||
float height = 600f;
|
||||
soundClose = SoundDefOf.CommsWindow_Close;
|
||||
absorbInputAroundWindow = false;
|
||||
forcePause = false;
|
||||
preventCameraMotion = false;
|
||||
draggable = true;
|
||||
doCloseX = true;
|
||||
return new Vector2(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void DoWindowContents(Rect inRect)
|
||||
{
|
||||
pos = windowRect.position;
|
||||
if (!Configurations.SelectionLocked)
|
||||
{
|
||||
List<Pawn> selected = Find.Selector.SelectedPawns;
|
||||
if (selected.Count == 1)
|
||||
{
|
||||
Pawn p = selected.First();
|
||||
if (p != pawn)
|
||||
{
|
||||
SexPartnerHistory h = p.GetPartnerHistory();
|
||||
if (h != null) ChangePawn(p, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DrawSexStatus(inRect,history);
|
||||
}
|
||||
|
||||
public static void ToggleWindow(Pawn pawn, SexPartnerHistory history)
|
||||
{
|
||||
SexStatusWindow window = (SexStatusWindow)Find.WindowStack.Windows.FirstOrDefault(x => x.GetType() == typeof(SexStatusWindow));
|
||||
if (window != null)
|
||||
{
|
||||
if (window.pawn != pawn)
|
||||
{
|
||||
SoundDefOf.TabOpen.PlayOneShotOnCamera();
|
||||
window.ChangePawn(pawn, history);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Find.WindowStack.Add(new SexStatusWindow(pawn, history));
|
||||
}
|
||||
}
|
||||
|
||||
public void ChangePawn(Pawn pawn, SexPartnerHistory history)
|
||||
{
|
||||
List<Pawn> selected = Find.Selector.SelectedPawns;
|
||||
if (!selected.NullOrEmpty()) foreach(Pawn p in selected)
|
||||
{
|
||||
Find.Selector.Deselect(p);
|
||||
}
|
||||
this.pawn = pawn;
|
||||
this.history = history;
|
||||
this.selectedPawn = null;
|
||||
this.rjwcomp = pawn.TryGetComp<CompRJW>();
|
||||
if (!pawn.DestroyedOrNull() && Find.CurrentMap == pawn.Map) Find.Selector.Select(pawn);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Main contents
|
||||
/// </summary>
|
||||
protected void DrawSexStatus(Rect mainrect, SexPartnerHistory history)
|
||||
{
|
||||
float sectionwidth = mainrect.width / 3;
|
||||
|
||||
Rect leftRect = new Rect(mainrect.x, mainrect.y, sectionwidth, mainrect.height);
|
||||
Rect centerRect = new Rect(mainrect.x + sectionwidth, mainrect.y, sectionwidth, mainrect.height);
|
||||
Rect rightRect = new Rect(mainrect.x + sectionwidth * 2, mainrect.y, sectionwidth, mainrect.height);
|
||||
|
||||
if (history != null)
|
||||
{
|
||||
//Left section
|
||||
DrawBaseSexInfoLeft(leftRect.ContractedBy(4f));
|
||||
|
||||
//Center section
|
||||
DrawBaseSexInfoCenter(centerRect.ContractedBy(4f),history.parent as Pawn);
|
||||
|
||||
//Right section
|
||||
DrawBaseSexInfoRight(rightRect.ContractedBy(4f));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected void DrawInfoWithPortrait(Rect rect, SexHistory history, string tooltip = "")
|
||||
{
|
||||
Widgets.DrawMenuSection(rect);
|
||||
string str = tooltip;
|
||||
Rect portraitRect = new Rect(rect.x, rect.y, rect.height - FONTHEIGHT, rect.height - FONTHEIGHT);
|
||||
Rect nameRect = new Rect(rect.x + portraitRect.width, rect.y, rect.width - portraitRect.width, FONTHEIGHT);
|
||||
Rect sexinfoRect = new Rect(rect.x + portraitRect.width, rect.y + FONTHEIGHT, rect.width - portraitRect.width, FONTHEIGHT);
|
||||
Rect sexinfoRect2 = new Rect(rect.x + portraitRect.width, rect.y + FONTHEIGHT * 2, rect.width - portraitRect.width, FONTHEIGHT);
|
||||
Rect bestsexRect = new Rect(rect.x + 2f, rect.y + FONTHEIGHT * 3, rect.width - 4f, FONTHEIGHT - 2f);
|
||||
|
||||
if (history != null)
|
||||
{
|
||||
if (history.Incest) str += " - " + Keyed.Incest;
|
||||
Pawn partner = history.Partner;
|
||||
DrawPawn(portraitRect, history);
|
||||
Widgets.DrawHighlightIfMouseover(portraitRect);
|
||||
if (Widgets.ButtonInvisible(portraitRect))
|
||||
{
|
||||
SexPartnerHistory pawnhistory = partner?.GetPartnerHistory();
|
||||
if (pawnhistory != null)
|
||||
{
|
||||
ChangePawn(partner, pawnhistory);
|
||||
SoundDefOf.Click.PlayOneShotOnCamera();
|
||||
}
|
||||
else SoundDefOf.ClickReject.PlayOneShotOnCamera();
|
||||
}
|
||||
GUI.Label(nameRect, partner?.Name?.ToStringFull ?? history.Label.CapitalizeFirst(), fontstyleleft);
|
||||
GUI.Label(sexinfoRect, Keyed.RS_Sex_Count + history.TotalSexCount + " " + history.RapeInfo, fontstyleleft);
|
||||
GUI.Label(sexinfoRect2, Keyed.RS_Orgasms + history.OrgasmCount, fontstyleleft);
|
||||
GUI.Label(sexinfoRect2, pawn.GetRelationsString(partner) + " ", fontstyleright);
|
||||
float p = history.BestSatisfaction / BASESAT;
|
||||
FillableBarLabeled(bestsexRect,String.Format(Keyed.RS_Best_Sextype+": {0}", Keyed.Sextype[(int)history.BestSextype]), p / 2, HistoryUtility.SextypeColor[(int)history.BestSextype], Texture2D.blackTexture, null, String.Format("{0:P2}", p));
|
||||
|
||||
if (history.IamFirst) str += "\n" + Keyed.RS_LostVirgin(history.Label, pawn.LabelShort);
|
||||
|
||||
|
||||
TooltipHandler.TipRegion(rect, str);
|
||||
}
|
||||
else
|
||||
{
|
||||
Widgets.DrawTextureFitted(portraitRect, HistoryUtility.UnknownPawn, 1.0f);
|
||||
Widgets.Label(nameRect, Keyed.Unknown);
|
||||
Widgets.Label(sexinfoRect, Keyed.RS_Sex_Count + "?");
|
||||
Widgets.Label(sexinfoRect2, Keyed.RS_Orgasms+"?");
|
||||
FillableBarLabeled(bestsexRect,String.Format(Keyed .RS_Best_Sextype + ": {0}", Keyed.Sextype[(int)xxx.rjwSextype.None]), 0, Texture2D.linearGrayTexture, Texture2D.blackTexture);
|
||||
}
|
||||
}
|
||||
|
||||
protected void DrawSexInfoCard(Rect rect, SexHistory history, string label, string tooltip)
|
||||
{
|
||||
Rect labelRect = new Rect(rect.x, rect.y, rect.width, FONTHEIGHT);
|
||||
Rect infoRect = new Rect(rect.x, rect.y + FONTHEIGHT, rect.width, rect.height - FONTHEIGHT);
|
||||
GUI.Label(labelRect, label, fontstyleleft);
|
||||
DrawInfoWithPortrait(infoRect,history, tooltip);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Right section
|
||||
/// </summary>
|
||||
protected void DrawBaseSexInfoRight(Rect rect)
|
||||
{
|
||||
Listing_Standard listmain = new Listing_Standard();
|
||||
listmain.Begin(rect.ContractedBy(4f));
|
||||
DrawSexInfoCard(listmain.GetRect(CARDHEIGHT), history.GetRecentPartnersHistory, Keyed.RS_Recent_Sex_Partner, Keyed.RS_Recent_Sex_Partner_ToolTip);
|
||||
DrawSexInfoCard(listmain.GetRect(CARDHEIGHT), history.GetFirstPartnerHistory, Keyed.RS_First_Sex_Partner, Keyed.RS_First_Sex_Partner_ToolTip);
|
||||
DrawSexInfoCard(listmain.GetRect(CARDHEIGHT), history.GetMostPartnerHistory, Keyed.RS_Most_Sex_Partner, Keyed.RS_Most_Sex_Partner_ToolTip);
|
||||
DrawSexInfoCard(listmain.GetRect(CARDHEIGHT), history.GetBestSexPartnerHistory, Keyed.RS_Best_Sex_Partner, Keyed.RS_Best_Sex_Partner_ToolTip);
|
||||
GUI.Label(listmain.GetRect(FONTHEIGHT), Keyed.RS_PreferRace, fontstyleleft);
|
||||
DrawPreferRace(listmain.GetRect(66f+15f));
|
||||
listmain.GetRect(15f);
|
||||
|
||||
|
||||
listmain.End();
|
||||
}
|
||||
|
||||
protected void DrawPreferRace(Rect rect)
|
||||
{
|
||||
Widgets.DrawMenuSection(rect);
|
||||
Rect portraitRect = new Rect(rect.x, rect.y, rect.height-15f, rect.height-15f);
|
||||
Rect infoRect1 = new Rect(rect.x + portraitRect.width, rect.y, rect.width - portraitRect.width, FONTHEIGHT);
|
||||
Rect infoRect2 = new Rect(rect.x + portraitRect.width, rect.y + FONTHEIGHT, rect.width - portraitRect.width, FONTHEIGHT);
|
||||
Rect infoRect3 = new Rect(rect.x + portraitRect.width, rect.y + FONTHEIGHT*2, rect.width - portraitRect.width - 2f, FONTHEIGHT);
|
||||
|
||||
if (history.PreferRace != null)
|
||||
{
|
||||
Widgets.DrawTextureFitted(portraitRect, history.GetPreferRaceIcon(portraitRect.size), 1.0f);
|
||||
GUI.Label(infoRect1, history.PreferRace?.label.CapitalizeFirst() ?? Keyed.None, fontstyleleft);
|
||||
GUI.Label(infoRect2, Keyed.RS_Sex_Count + history.PreferRaceSexCount, fontstyleleft);
|
||||
if (history.PreferRace != pawn.def)
|
||||
{
|
||||
if (history.PreferRace.race.Animal ^ pawn.def.race.Animal)
|
||||
{
|
||||
GUI.Label(infoRect1, Keyed.RS_Bestiality + " ", fontstyleright);
|
||||
FillableBarLabeled(infoRect3, Keyed.RS_Sex_Info(Keyed.RS_Bestiality, history.BestialityCount.ToString()), history.BestialityCount/100f, Texture2D.linearGrayTexture, Texture2D.blackTexture);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.Label(infoRect1, Keyed.RS_Interspecies + " ", fontstyleright);
|
||||
FillableBarLabeled(infoRect3, Keyed.RS_Sex_Info(Keyed.RS_Interspecies, history.InterspeciesCount.ToString()), history.InterspeciesCount / 100f, Texture2D.linearGrayTexture, Texture2D.blackTexture);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.Label(infoRect1, Keyed.RS_Normal + " ", fontstyleright);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Widgets.DrawTextureFitted(portraitRect, HistoryUtility.UnknownPawn, 1.0f);
|
||||
GUI.Label(infoRect1, Keyed.None, fontstyleleft);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Center section
|
||||
/// </summary>
|
||||
protected void DrawBaseSexInfoCenter(Rect rect, Pawn pawn)
|
||||
{
|
||||
Rect portraitRect = new Rect(rect.x + rect.width / 4, rect.y, rect.width / 2, rect.width / 1.5f);
|
||||
Rect nameRect = new Rect(portraitRect.x, portraitRect.yMax - FONTHEIGHT * 2, portraitRect.width, FONTHEIGHT * 2);
|
||||
Rect infoRect = new Rect(rect.x, rect.y + portraitRect.height, rect.width, rect.height - portraitRect.height);
|
||||
Rect lockRect = new Rect(portraitRect.xMax - ICONSIZE, portraitRect.y, ICONSIZE, ICONSIZE);
|
||||
Rect tmp;
|
||||
|
||||
if (Mouse.IsOver(portraitRect))
|
||||
{
|
||||
Texture lockicon = Configurations.SelectionLocked ? HistoryUtility.Locked : HistoryUtility.Unlocked;
|
||||
Widgets.DrawTextureFitted(lockRect, lockicon, 1.0f);
|
||||
if (Widgets.ButtonInvisible(lockRect))
|
||||
{
|
||||
SoundDefOf.Click.PlayOneShotOnCamera();
|
||||
Configurations.SelectionLocked = !Configurations.SelectionLocked;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GUI.Box(portraitRect, "", boxstyle);
|
||||
Widgets.DrawTextureFitted(portraitRect, PortraitsCache.Get(pawn, portraitRect.size, Rot4.South, default, 1, true, true, false, false), 1.0f);
|
||||
Widgets.DrawHighlightIfMouseover(portraitRect);
|
||||
if (Widgets.ButtonInvisible(portraitRect))
|
||||
{
|
||||
SoundDefOf.Click.PlayOneShotOnCamera();
|
||||
selectedPawn = null;
|
||||
}
|
||||
|
||||
GUI.Box(nameRect, "", boxstyle);
|
||||
GUI.Label(nameRect.TopHalf(), pawn.Name?.ToStringFull ?? pawn.Label, fontstylecenter);
|
||||
if (pawn.story != null) GUI.Label(nameRect.BottomHalf(), pawn.ageTracker.AgeBiologicalYears + ", " + pawn.story.Title, fontstylecenter);
|
||||
else GUI.Label(nameRect.BottomHalf(), pawn.ageTracker.AgeBiologicalYears + ", " + pawn.def.label, fontstylecenter);
|
||||
|
||||
Listing_Standard listmain = new Listing_Standard();
|
||||
listmain.Begin(infoRect);
|
||||
listmain.Gap(20f);
|
||||
float p;
|
||||
|
||||
if (pawn.IsVirgin())
|
||||
{
|
||||
tmp = listmain.GetRect(FONTHEIGHT);
|
||||
GUI.color = Color.red;
|
||||
GUI.Box(tmp, "", boxstyle);
|
||||
GUI.color = Color.white;
|
||||
GUI.Label(tmp, "Virgin", fontstylecenter);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = history.TotalSexHad;
|
||||
FillableBarLabeled(listmain.GetRect(FONTHEIGHT), String.Format(Keyed.RS_TotalSexHad + ": {0:0} ({1:0})", p, pawn.records.GetValue(xxx.CountOfSex)), p / 100, HistoryUtility.TotalSex, Texture2D.blackTexture, null, Keyed.RS_SAT_AVG(String.Format("{0:P2}", history.AVGSat)));
|
||||
}
|
||||
listmain.Gap(1f);
|
||||
|
||||
|
||||
tmp = listmain.GetRect(FONTHEIGHT);
|
||||
p = pawn.records.GetValue(VariousDefOf.Lust);
|
||||
FillableBarLabeled(tmp, String.Format(Keyed.Lust +": {0:0.00}", p), Mathf.Clamp01(p.Normalization(-Configurations.LustLimit*3, Configurations.LustLimit*3)), HistoryUtility.Slaanesh, Texture2D.blackTexture, null, String.Format(xxx.sex_drive_stat.LabelCap.CapitalizeFirst() + ": {0:P2}", pawn.GetStatValue(xxx.sex_drive_stat)));
|
||||
listmain.Gap(1f);
|
||||
if (Mouse.IsOver(tmp))
|
||||
{
|
||||
TooltipHandler.TipRegion(tmp, RJWUIUtility.GetStatExplanation(pawn, xxx.sex_drive_stat, pawn.GetStatValue(xxx.sex_drive_stat)));
|
||||
}
|
||||
|
||||
p = history.GetBestSextype(out xxx.rjwSextype sextype) / BASESAT;
|
||||
FillableBarLabeled(listmain.GetRect(FONTHEIGHT),String.Format(Keyed.RS_Best_Sextype+": {0}", Keyed.Sextype[(int)sextype]), p / 2, HistoryUtility.SextypeColor[(int)sextype], Texture2D.blackTexture, null, Keyed.RS_SAT_AVG(String.Format("{0:P2}", p)));
|
||||
listmain.Gap(1f);
|
||||
|
||||
p = history.GetRecentSextype(out sextype) / BASESAT;
|
||||
FillableBarLabeled(listmain.GetRect(FONTHEIGHT),String.Format(Keyed.RS_Recent_Sextype+": {0}", Keyed.Sextype[(int)sextype]), p / 2, HistoryUtility.SextypeColor[(int)sextype], Texture2D.blackTexture, null, String.Format("{0:P2}", p));
|
||||
listmain.Gap(1f);
|
||||
|
||||
if (history.IncestuousCount < history.CorpseFuckCount)
|
||||
{
|
||||
p = history.CorpseFuckCount;
|
||||
FillableBarLabeled(listmain.GetRect(FONTHEIGHT), String.Format(Keyed.RS_Necrophile + ": {0}", p), p / 50, HistoryUtility.Nurgle, Texture2D.blackTexture);
|
||||
listmain.Gap(1f);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = history.IncestuousCount;
|
||||
FillableBarLabeled(listmain.GetRect(FONTHEIGHT), String.Format(Keyed.Incest + ": {0}", p), p / 50, HistoryUtility.Nurgle, Texture2D.blackTexture);
|
||||
listmain.Gap(1f);
|
||||
}
|
||||
|
||||
p = pawn.records.GetValue(VariousDefOf.AmountofEatenCum);
|
||||
FillableBarLabeled(listmain.GetRect(FONTHEIGHT), String.Format(Keyed.RS_Cum_Swallowed + ": {0:0.00} mL, {1} " + Keyed.RS_NumofTimes, p, pawn.records.GetValue(VariousDefOf.NumofEatenCum)), p / 1000, Texture2D.linearGrayTexture, Texture2D.blackTexture);
|
||||
listmain.Gap(1f);
|
||||
|
||||
Hediff addiction = pawn.health.hediffSet.GetFirstHediffOfDef(VariousDefOf.CumAddiction);
|
||||
if (addiction != null)
|
||||
{
|
||||
p = addiction.Severity;
|
||||
FillableBarLabeled(listmain.GetRect(FONTHEIGHT), String.Format(Keyed.RS_CumAddiction + ": {0:P2}", p), p, Texture2D.linearGrayTexture, Texture2D.blackTexture, Keyed.RS_CumAddiction_Tooltip);
|
||||
listmain.Gap(1f);
|
||||
}
|
||||
else if ((addiction = pawn.health.hediffSet.GetFirstHediffOfDef(VariousDefOf.CumTolerance)) != null)
|
||||
{
|
||||
p = addiction.Severity;
|
||||
FillableBarLabeled(listmain.GetRect(FONTHEIGHT), String.Format(Keyed.RS_CumAddictiveness + ": {0:P}", p), p, Texture2D.linearGrayTexture, Texture2D.blackTexture, Keyed.RS_CumAddictiveness_Tooltip);
|
||||
listmain.Gap(1f);
|
||||
}
|
||||
else
|
||||
{
|
||||
listmain.GetRect(FONTHEIGHT);
|
||||
listmain.Gap(1f);
|
||||
}
|
||||
|
||||
|
||||
//listmain.GetRect(FONTHEIGHT);
|
||||
//listmain.Gap(1f);
|
||||
|
||||
p = history.RapedCount;
|
||||
tmp = listmain.GetRect(FONTHEIGHT);
|
||||
if (p < history.BeenRapedCount)
|
||||
{
|
||||
p = history.BeenRapedCount;
|
||||
FillableBarLabeled(tmp, String.Format(Keyed.RS_BeenRaped + ": {0}", p), p / 50, Texture2D.grayTexture, Texture2D.blackTexture, null, String.Format(xxx.vulnerability_stat.LabelCap.CapitalizeFirst() + ": {0:P2}", pawn.GetStatValue(xxx.vulnerability_stat)));
|
||||
listmain.Gap(1f);
|
||||
}
|
||||
else
|
||||
{
|
||||
FillableBarLabeled(tmp, String.Format(Keyed.RS_RapedSomeone + ": {0}", p), p / 50, HistoryUtility.Khorne, Texture2D.blackTexture, null, String.Format(xxx.vulnerability_stat.LabelCap.CapitalizeFirst() + ": {0:P2}", pawn.GetStatValue(xxx.vulnerability_stat)));
|
||||
listmain.Gap(1f);
|
||||
}
|
||||
if (Mouse.IsOver(tmp))
|
||||
{
|
||||
TooltipHandler.TipRegion(tmp, RJWUIUtility.GetStatExplanation(pawn, xxx.vulnerability_stat, pawn.GetStatValue(xxx.vulnerability_stat)));
|
||||
}
|
||||
|
||||
|
||||
p = pawn.GetStatValue(xxx.sex_satisfaction);
|
||||
tmp = listmain.GetRect(FONTHEIGHT);
|
||||
FillableBarLabeled(tmp, String.Format(xxx.sex_satisfaction.LabelCap.CapitalizeFirst() + ": {0:P2}", p), p/2, HistoryUtility.Satisfaction, Texture2D.blackTexture);
|
||||
listmain.Gap(1f);
|
||||
if (Mouse.IsOver(tmp))
|
||||
{
|
||||
TooltipHandler.TipRegion(tmp, RJWUIUtility.GetStatExplanation(pawn, xxx.sex_satisfaction, pawn.GetStatValue(xxx.sex_satisfaction)));
|
||||
}
|
||||
|
||||
//p = pawn.GetStatValue(xxx.vulnerability_stat);
|
||||
//FillableBarLabeled(listmain.GetRect(FONTHEIGHT), String.Format(xxx.vulnerability_stat.LabelCap.CapitalizeFirst() + ": {0:P2}", p), p / 2, HistoryUtility.Khorne, Texture2D.blackTexture, xxx.vulnerability_stat.description);
|
||||
//listmain.Gap(1f);
|
||||
|
||||
SkillRecord skill = pawn.skills?.GetSkill(VariousDefOf.SexSkill);
|
||||
p = skill?.Level ?? 0;
|
||||
tmp = listmain.GetRect(FONTHEIGHT);
|
||||
FillableBarLabeled(tmp, String.Format(Keyed.RS_SexSkill + ": {0}, {1:P2}", p, skill?.xpSinceLastLevel/ skill?.XpRequiredForLevelUp), p / 20, HistoryUtility.Tzeentch, Texture2D.blackTexture, null, String.Format(xxx.sex_stat.LabelCap.CapitalizeFirst() + ": {0:P2}", pawn.GetStatValue(xxx.sex_stat)), HistoryUtility.PassionBG[(int)(skill?.passion ?? 0)]);
|
||||
if (Mouse.IsOver(tmp))
|
||||
{
|
||||
TooltipHandler.TipRegion(tmp, RJWUIUtility.GetStatExplanation(pawn, xxx.sex_stat, pawn.GetStatValue(xxx.sex_stat)));
|
||||
}
|
||||
|
||||
|
||||
listmain.Gap(1f);
|
||||
|
||||
if (selectedPawn != null) DrawSexInfoCard(listmain.GetRect(CARDHEIGHT), selectedPawn, Keyed.RS_Selected_Partner, Keyed.RS_Selected_Partner);
|
||||
else DrawExtraInfo(listmain.GetRect(CARDHEIGHT));
|
||||
|
||||
listmain.End();
|
||||
}
|
||||
|
||||
protected void DrawExtraInfo(Rect rect)
|
||||
{
|
||||
Widgets.DrawMenuSection(rect);
|
||||
Rect inRect = rect.ContractedBy(4f);
|
||||
Listing_Standard listmain = new Listing_Standard();
|
||||
listmain.Begin(inRect);
|
||||
listmain.Gap(4f);
|
||||
listmain.GetRect(FONTHEIGHT).DrawSexuality(rjwcomp);
|
||||
listmain.Gap(1f);
|
||||
listmain.GetRect(FONTHEIGHT).DrawQuirk(pawn);
|
||||
listmain.Gap(1f);
|
||||
|
||||
|
||||
|
||||
listmain.End();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Left section
|
||||
/// </summary>
|
||||
protected void DrawBaseSexInfoLeft(Rect rect)
|
||||
{
|
||||
|
||||
Listing_Standard listmain = new Listing_Standard();
|
||||
listmain.Begin(rect);
|
||||
float p;
|
||||
|
||||
//Sex statistics
|
||||
GUI.Label(listmain.GetRect(FONTHEIGHT), " " + Keyed.RS_Statistics, fontstyleleft);
|
||||
listmain.Gap(1f);
|
||||
for (int i = 0; i < Sextype.Length; i++)
|
||||
{
|
||||
int sexindex = Sextype[i];
|
||||
p = history.GetAVGSat(sexindex) / BASESAT;
|
||||
string label = Keyed.RS_Sex_Info(Keyed.Sextype[sexindex], history.GetSexCount(sexindex).ToString());
|
||||
FillableBarLabeled(listmain.GetRect(FONTHEIGHT),label, p / 2, HistoryUtility.SextypeColor[sexindex], Texture2D.blackTexture, null, Keyed.RS_SAT_AVG(String.Format("{0:P2}", p)));
|
||||
listmain.Gap(1f);
|
||||
}
|
||||
|
||||
p = history.PartnerCount;
|
||||
FillableBarLabeled(listmain.GetRect(FONTHEIGHT), String.Format(Keyed.RS_Sex_Partners + ": {0} ({1})", p, pawn.records.GetValue(VariousDefOf.SexPartnerCount)), p / 50, HistoryUtility.Partners, Texture2D.blackTexture);
|
||||
listmain.Gap(1f);
|
||||
|
||||
p = history.VirginsTaken;
|
||||
FillableBarLabeled(listmain.GetRect(FONTHEIGHT), String.Format(Keyed.RS_VirginsTaken + ": {0:0}", p), p / 100, HistoryUtility.Partners, Texture2D.blackTexture);
|
||||
listmain.Gap(1f);
|
||||
|
||||
//Partner list
|
||||
GUI.Label(listmain.GetRect(FONTHEIGHT)," "+Keyed.RS_PartnerList, fontstyleleft);
|
||||
listmain.Gap(1f);
|
||||
|
||||
Rect scrollRect = listmain.GetRect(CARDHEIGHT+1f);
|
||||
GUI.Box(scrollRect,"", buttonstyle);
|
||||
List<SexHistory> partnerList = history.PartnerList;
|
||||
Rect listRect = new Rect(scrollRect.x, scrollRect.y, LISTPAWNSIZE * partnerList.Count, scrollRect.height - 30f);
|
||||
Widgets.BeginScrollView(scrollRect, ref scroll, listRect);
|
||||
Widgets.ScrollHorizontal(scrollRect, ref scroll, listRect);
|
||||
DrawPartnerList(listRect, partnerList);
|
||||
Widgets.EndScrollView();
|
||||
|
||||
listmain.End();
|
||||
}
|
||||
|
||||
protected void DrawPartnerList(Rect rect, List<SexHistory> partnerList)
|
||||
{
|
||||
Rect pawnRect = new Rect(rect.x, rect.y, LISTPAWNSIZE, LISTPAWNSIZE);
|
||||
for (int i = 0; i < partnerList.Count; i++)
|
||||
{
|
||||
Rect labelRect = new Rect(pawnRect.x,pawnRect.yMax - FONTHEIGHT,pawnRect.width,FONTHEIGHT);
|
||||
|
||||
DrawPawn(pawnRect, partnerList[i]);
|
||||
Widgets.DrawHighlightIfMouseover(pawnRect);
|
||||
GUI.Label(labelRect, partnerList[i].Label, fontstylecenter);
|
||||
if (Widgets.ButtonInvisible(pawnRect))
|
||||
{
|
||||
selectedPawn = partnerList[i];
|
||||
SoundDefOf.Click.PlayOneShotOnCamera();
|
||||
}
|
||||
if (partnerList[i] == selectedPawn)
|
||||
{
|
||||
Widgets.DrawHighlightSelected(pawnRect);
|
||||
}
|
||||
|
||||
pawnRect.x += LISTPAWNSIZE;
|
||||
}
|
||||
}
|
||||
|
||||
protected void DrawPawn(Rect rect, SexHistory history)
|
||||
{
|
||||
if (history != null)
|
||||
{
|
||||
bool drawheart = false;
|
||||
Rect iconRect = new Rect(rect.x + rect.width * 3 / 4, rect.y, rect.width / 4, rect.height / 4);
|
||||
Texture img = HistoryUtility.UnknownPawn;
|
||||
if (history.Partner != null)
|
||||
{
|
||||
img = PortraitsCache.Get(history.Partner, rect.size, Rot4.South, default, 1, true, true, false, false);
|
||||
if (history.IamFirst)
|
||||
{
|
||||
GUI.color = HistoryUtility.HistoryColor;
|
||||
Widgets.DrawTextureFitted(rect, HistoryUtility.FirstOverlay, 1.0f);
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
|
||||
drawheart = LovePartnerRelationUtility.LovePartnerRelationExists(pawn, history.Partner);
|
||||
|
||||
}
|
||||
|
||||
if (history.Incest)
|
||||
{
|
||||
Widgets.DrawTextureFitted(iconRect, HistoryUtility.Incest, 1.0f);
|
||||
iconRect.x -= iconRect.width;
|
||||
}
|
||||
Widgets.DrawTextureFitted(rect, img, 1.0f);
|
||||
if (drawheart)
|
||||
{
|
||||
Widgets.DrawTextureFitted(iconRect, HistoryUtility.Heart,1.0f);
|
||||
iconRect.x -= iconRect.width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static void FillableBarLabeled(Rect rect, string label, float fillPercent, Texture2D filltexture, Texture2D bgtexture, string tooltip = null, string rightlabel = "", Texture2D border = null)
|
||||
{
|
||||
Widgets.FillableBar(rect, Math.Min(fillPercent, 1.0f), filltexture, bgtexture, true);
|
||||
GUI.Label(rect, " " + label.CapitalizeFirst(), fontstyleleft);
|
||||
GUI.Label(rect, rightlabel.CapitalizeFirst() + " ", fontstyleright);
|
||||
Widgets.DrawHighlightIfMouseover(rect);
|
||||
if (tooltip != null) TooltipHandler.TipRegion(rect, tooltip);
|
||||
if (border != null)
|
||||
{
|
||||
rect.DrawBorder(border,2f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -10,26 +10,23 @@ using UnityEngine;
|
|||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
|
||||
public static class Utility
|
||||
{
|
||||
public static System.Random random = new System.Random(Environment.TickCount);
|
||||
|
||||
//public static readonly Dictionary<xxx.rjwSextype, RecordDef> sextypeRecords = new Dictionary<xxx.rjwSextype, RecordDef> {
|
||||
// { xxx.rjwSextype.Vaginal, xxx.CountOfSex },
|
||||
// { xxx.rjwSextype.Vaginal, xxx.CountOfSex },
|
||||
// { xxx.rjwSextype.Vaginal, xxx.CountOfSex },
|
||||
// { xxx.rjwSextype.Vaginal, xxx.CountOfSex },
|
||||
// { xxx.rjwSextype.Vaginal, xxx.CountOfSex },
|
||||
// { xxx.rjwSextype.Vaginal, xxx.CountOfSex },
|
||||
// { xxx.rjwSextype.Vaginal, xxx.CountOfSex },
|
||||
// { xxx.rjwSextype.Vaginal, xxx.CountOfSex },
|
||||
// { xxx.rjwSextype.Vaginal, xxx.CountOfSex },
|
||||
// { xxx.rjwSextype.Vaginal, xxx.CountOfSex },
|
||||
// { xxx.rjwSextype.Vaginal, xxx.CountOfSex },
|
||||
// { xxx.rjwSextype.Vaginal, xxx.CountOfSex }
|
||||
//
|
||||
//
|
||||
//};
|
||||
public static bool IsIncest(this Pawn pawn, Pawn otherpawn)
|
||||
{
|
||||
if (otherpawn != null)
|
||||
{
|
||||
IEnumerable<PawnRelationDef> relations = pawn.GetRelations(otherpawn);
|
||||
if (!relations.EnumerableNullOrEmpty()) foreach (PawnRelationDef relation in relations)
|
||||
{
|
||||
if (relation.incestOpinionOffset < 0) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static float RandGaussianLike(float min, float max, int iterations = 3)
|
||||
{
|
||||
|
@ -59,6 +56,15 @@ namespace RJWSexperience
|
|||
return value;
|
||||
}
|
||||
|
||||
public static int RecordRandomizer(this Pawn pawn, RecordDef record, int avg, int dist, int min = 0, int max = int.MaxValue)
|
||||
{
|
||||
int value = (int)Mathf.Clamp(RandGaussianLike(avg - dist, avg + dist), min, max);
|
||||
int recordvalue = pawn.records.GetAsInt(record);
|
||||
pawn.records.AddTo(record, value - recordvalue);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static bool ContainAll(this string str, string[] tags)
|
||||
{
|
||||
string lstr = str.ToLower();
|
||||
|
@ -86,17 +92,17 @@ namespace RJWSexperience
|
|||
}
|
||||
|
||||
|
||||
public static Building GetAdjacentBuilding<T>(this Pawn pawn) where T : Building
|
||||
public static T GetAdjacentBuilding<T>(this Pawn pawn) where T : Building
|
||||
{
|
||||
|
||||
if (pawn.Spawned)
|
||||
{
|
||||
EdificeGrid edifice = pawn.Map.edificeGrid;
|
||||
if (edifice[pawn.Position] is T) return edifice[pawn.Position];
|
||||
if (edifice[pawn.Position] is T) return (T)edifice[pawn.Position];
|
||||
IEnumerable<IntVec3> adjcells = GenAdjFast.AdjacentCells8Way(pawn.Position);
|
||||
foreach(IntVec3 pos in adjcells)
|
||||
{
|
||||
if (edifice[pos] is T) return edifice[pos];
|
||||
if (edifice[pos] is T) return (T)edifice[pos];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -139,18 +145,6 @@ namespace RJWSexperience
|
|||
return res;
|
||||
}
|
||||
|
||||
public static void CumDrugEffect(this Pawn pawn)
|
||||
{
|
||||
Need need = pawn.needs?.TryGetNeed(VariousDefOf.Chemical_Cum);
|
||||
if (need != null) need.CurLevel += VariousDefOf.CumneedLevelOffset;
|
||||
Hediff addictive = HediffMaker.MakeHediff(VariousDefOf.CumTolerance, pawn);
|
||||
addictive.Severity = 0.032f;
|
||||
pawn.health.AddHediff(addictive);
|
||||
Hediff addiction = pawn.health.hediffSet.GetFirstHediffOfDef(VariousDefOf.CumAddiction);
|
||||
if (addiction != null) addiction.Severity += VariousDefOf.CumexistingAddictionSeverityOffset;
|
||||
|
||||
pawn.needs?.mood?.thoughts?.memories?.TryGainMemoryFast(VariousDefOf.AteCum);
|
||||
}
|
||||
|
||||
public static float Normalization(this float num, float min, float max)
|
||||
{
|
||||
|
@ -163,5 +157,134 @@ namespace RJWSexperience
|
|||
return num * (max - min) + min;
|
||||
}
|
||||
|
||||
public static void ResetRecord(this Pawn pawn, bool allzero)
|
||||
{
|
||||
if (!allzero)
|
||||
{
|
||||
if (Configurations.EnableRecordRandomizer && pawn != null && xxx.is_human(pawn))
|
||||
{
|
||||
int avgsex = -500;
|
||||
bool isvirgin = Rand.Chance(Configurations.VirginRatio);
|
||||
int totalsex = 0;
|
||||
int totalbirth = 0;
|
||||
int deviation = (int)Configurations.MaxSexCountDeviation;
|
||||
if (pawn.story != null)
|
||||
{
|
||||
float lust;
|
||||
if (xxx.is_nympho(pawn)) lust = pawn.RecordRandomizer(VariousDefOf.Lust, Configurations.AvgLust, Configurations.MaxLustDeviation, 0);
|
||||
else lust = pawn.RecordRandomizer(VariousDefOf.Lust, Configurations.AvgLust, Configurations.MaxLustDeviation, float.MinValue);
|
||||
|
||||
int sexableage = 0;
|
||||
int minsexage = (int)(pawn.RaceProps.lifeExpectancy * Configurations.MinSexablePercent);
|
||||
if (pawn.ageTracker.AgeBiologicalYears > minsexage)
|
||||
{
|
||||
sexableage = pawn.ageTracker.AgeBiologicalYears - minsexage;
|
||||
avgsex = (int)(sexableage * Configurations.SexPerYear * pawn.LustFactor());
|
||||
}
|
||||
|
||||
|
||||
if (pawn.relations != null && pawn.gender == Gender.Female)
|
||||
{
|
||||
totalbirth += pawn.relations.ChildrenCount;
|
||||
totalsex += totalbirth;
|
||||
pawn.records?.AddTo(xxx.CountOfSexWithHumanlikes, totalbirth);
|
||||
pawn.records?.SetTo(xxx.CountOfBirthHuman, totalbirth);
|
||||
if (totalbirth > 0) isvirgin = false;
|
||||
}
|
||||
if (!isvirgin)
|
||||
{
|
||||
if (xxx.is_rapist(pawn))
|
||||
{
|
||||
if (xxx.is_zoophile(pawn))
|
||||
{
|
||||
if (pawn.Has(Quirk.ChitinLover)) totalsex += pawn.RecordRandomizer(xxx.CountOfRapedInsects, avgsex, deviation);
|
||||
else totalsex += pawn.RecordRandomizer(xxx.CountOfRapedAnimals, avgsex, deviation);
|
||||
}
|
||||
else totalsex += pawn.RecordRandomizer(xxx.CountOfRapedHumanlikes, avgsex, deviation);
|
||||
avgsex /= 8;
|
||||
}
|
||||
|
||||
if (xxx.is_zoophile(pawn))
|
||||
{
|
||||
if (pawn.Has(Quirk.ChitinLover)) totalsex += pawn.RecordRandomizer(xxx.CountOfRapedInsects, avgsex, deviation);
|
||||
else totalsex += pawn.RecordRandomizer(xxx.CountOfSexWithAnimals, avgsex, deviation);
|
||||
avgsex /= 10;
|
||||
}
|
||||
else if (xxx.is_necrophiliac(pawn))
|
||||
{
|
||||
totalsex += pawn.RecordRandomizer(xxx.CountOfSexWithCorpse, avgsex, deviation);
|
||||
avgsex /= 4;
|
||||
}
|
||||
|
||||
if (pawn.IsSlave)
|
||||
{
|
||||
totalsex += pawn.RecordRandomizer(xxx.CountOfBeenRapedByAnimals, Rand.Range(-50, 10), Rand.Range(0, 10) * sexableage);
|
||||
totalsex += pawn.RecordRandomizer(xxx.CountOfBeenRapedByHumanlikes, 0, Rand.Range(0, 100) * sexableage);
|
||||
}
|
||||
|
||||
|
||||
totalsex += pawn.RecordRandomizer(xxx.CountOfSexWithHumanlikes, avgsex, deviation);
|
||||
|
||||
if (totalsex > 0) pawn.records.AddTo(VariousDefOf.SexPartnerCount, Math.Max(1, Rand.Range(0, totalsex / 7)));
|
||||
}
|
||||
}
|
||||
pawn.records?.SetTo(xxx.CountOfSex, totalsex);
|
||||
RJWUtility.GenerateSextypeRecords(pawn, totalsex);
|
||||
}
|
||||
if (pawn.story?.traits != null)
|
||||
{
|
||||
if (pawn.IsVirgin())
|
||||
{
|
||||
int degree = 0;
|
||||
if (pawn.gender == Gender.Female) degree = 2;
|
||||
Trait virgin = new Trait(VariousDefOf.Virgin, degree, true);
|
||||
pawn.story.traits.GainTrait(virgin);
|
||||
}
|
||||
else if (pawn.gender == Gender.Female && Rand.Chance(0.05f))
|
||||
{
|
||||
Trait virgin = new Trait(VariousDefOf.Virgin, 1, true);
|
||||
pawn.story.traits.GainTrait(virgin);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pawn.records.SetTo(VariousDefOf.Lust, 0);
|
||||
pawn.records.SetTo(VariousDefOf.NumofEatenCum, 0);
|
||||
pawn.records.SetTo(VariousDefOf.AmountofEatenCum, 0);
|
||||
pawn.records.SetTo(VariousDefOf.VaginalSexCount, 0);
|
||||
pawn.records.SetTo(VariousDefOf.AnalSexCount, 0);
|
||||
pawn.records.SetTo(VariousDefOf.OralSexCount, 0);
|
||||
pawn.records.SetTo(VariousDefOf.BlowjobCount, 0);
|
||||
pawn.records.SetTo(VariousDefOf.CunnilingusCount, 0);
|
||||
pawn.records.SetTo(VariousDefOf.GenitalCaressCount, 0);
|
||||
pawn.records.SetTo(VariousDefOf.HandjobCount, 0);
|
||||
pawn.records.SetTo(VariousDefOf.FingeringCount, 0);
|
||||
pawn.records.SetTo(VariousDefOf.FootjobCount, 0);
|
||||
pawn.records.SetTo(VariousDefOf.MiscSexualBehaviorCount, 0);
|
||||
pawn.records.SetTo(VariousDefOf.SexPartnerCount, 0);
|
||||
pawn.records.SetTo(VariousDefOf.OrgasmCount, 0);
|
||||
pawn.records.SetTo(xxx.CountOfBeenRapedByAnimals, 0);
|
||||
pawn.records.SetTo(xxx.CountOfBeenRapedByHumanlikes, 0);
|
||||
pawn.records.SetTo(xxx.CountOfBeenRapedByInsects, 0);
|
||||
pawn.records.SetTo(xxx.CountOfBeenRapedByOthers, 0);
|
||||
pawn.records.SetTo(xxx.CountOfBirthAnimal, 0);
|
||||
pawn.records.SetTo(xxx.CountOfBirthEgg, 0);
|
||||
pawn.records.SetTo(xxx.CountOfBirthHuman, 0);
|
||||
pawn.records.SetTo(xxx.CountOfFappin, 0);
|
||||
pawn.records.SetTo(xxx.CountOfRapedAnimals, 0);
|
||||
pawn.records.SetTo(xxx.CountOfRapedHumanlikes, 0);
|
||||
pawn.records.SetTo(xxx.CountOfRapedInsects, 0);
|
||||
pawn.records.SetTo(xxx.CountOfRapedOthers, 0);
|
||||
pawn.records.SetTo(xxx.CountOfSex, 0);
|
||||
pawn.records.SetTo(xxx.CountOfSexWithAnimals, 0);
|
||||
pawn.records.SetTo(xxx.CountOfSexWithCorpse, 0);
|
||||
pawn.records.SetTo(xxx.CountOfSexWithHumanlikes, 0);
|
||||
pawn.records.SetTo(xxx.CountOfSexWithInsects, 0);
|
||||
pawn.records.SetTo(xxx.CountOfSexWithOthers, 0);
|
||||
pawn.records.SetTo(xxx.CountOfWhore, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace RJWSexperience
|
|||
public static class VariousDefOf
|
||||
{
|
||||
public static readonly RecordDef NumofEatenCum = DefDatabase<RecordDef>.GetNamed("NumofEatenCum");
|
||||
public static readonly RecordDef AmountofEatenCum = DefDatabase<RecordDef>.GetNamed("AmountofEatenCum");
|
||||
public static readonly RecordDef Lust = DefDatabase<RecordDef>.GetNamed("Lust");
|
||||
public static readonly RecordDef VaginalSexCount = DefDatabase<RecordDef>.GetNamed("VaginalSexCount");
|
||||
public static readonly RecordDef AnalSexCount = DefDatabase<RecordDef>.GetNamed("AnalSexCount");
|
||||
|
@ -18,20 +19,27 @@ namespace RJWSexperience
|
|||
public static readonly RecordDef BlowjobCount = DefDatabase<RecordDef>.GetNamed("BlowjobCount");
|
||||
public static readonly RecordDef CunnilingusCount = DefDatabase<RecordDef>.GetNamed("CunnilingusCount");
|
||||
public static readonly RecordDef GenitalCaressCount = DefDatabase<RecordDef>.GetNamed("GenitalCaressCount");
|
||||
public static readonly RecordDef HadnjobCount = DefDatabase<RecordDef>.GetNamed("HadnjobCount");
|
||||
public static readonly RecordDef HandjobCount = DefDatabase<RecordDef>.GetNamed("HandjobCount");
|
||||
public static readonly RecordDef FingeringCount = DefDatabase<RecordDef>.GetNamed("FingeringCount");
|
||||
public static readonly RecordDef FootjobCount = DefDatabase<RecordDef>.GetNamed("FootjobCount");
|
||||
public static readonly RecordDef MiscSexualBehaviorCount = DefDatabase<RecordDef>.GetNamed("MiscSexualBehaviorCount");
|
||||
public static readonly RecordDef SexPartnerCount = DefDatabase<RecordDef>.GetNamed("SexPartnerCount");
|
||||
public static readonly RecordDef OrgasmCount = DefDatabase<RecordDef>.GetNamed("OrgasmCount");
|
||||
public static readonly SkillDef SexSkill = DefDatabase<SkillDef>.GetNamed("Sex");
|
||||
public static readonly ThoughtDef_Recordbased AteCum = DefDatabase<ThoughtDef_Recordbased>.GetNamed("AteCum");
|
||||
public static readonly PawnRelationDef Bastard = DefDatabase<PawnRelationDef>.GetNamed("Bastard");
|
||||
public static readonly ThingDef GatheredCum = DefDatabase<ThingDef>.GetNamed("GatheredCum");
|
||||
public static readonly ThingDef FilthCum = ThingDef.Named("FilthCum");
|
||||
public static readonly ThingDef FilthGirlcum = ThingDef.Named("FilthGirlCum");
|
||||
public static readonly HediffDef CumAddiction = DefDatabase<HediffDef>.GetNamed("CumAddiction");
|
||||
public static readonly HediffDef CumTolerance = DefDatabase<HediffDef>.GetNamed("CumTolerance");
|
||||
public static readonly ChemicalDef Cum = DefDatabase<ChemicalDef>.GetNamed("Cum");
|
||||
public static readonly NeedDef Chemical_Cum = DefDatabase<NeedDef>.GetNamed("Chemical_Cum");
|
||||
public static readonly TraitDef Virgin = DefDatabase<TraitDef>.GetNamed("Virgin");
|
||||
public static readonly JobDef CleanSelfwithBucket = DefDatabase<JobDef>.GetNamed("CleanSelfwithBucket");
|
||||
public static readonly PawnRelationDef relation_birthgiver = DefDatabase<PawnRelationDef>.GetNamed("RJW_Sire");
|
||||
public static readonly PawnRelationDef relation_spawn = DefDatabase<PawnRelationDef>.GetNamed("RJW_Pup");
|
||||
public static readonly KeyBindingDef OpenSexStatistics = DefDatabase<KeyBindingDef>.GetNamed("OpenSexStatistics");
|
||||
|
||||
public static float CumneedLevelOffset
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<Defs>
|
||||
|
||||
<DutyDef>
|
||||
<defName>Gangbang</defName>
|
||||
<defName>Gangbang_Rape</defName>
|
||||
<hook>HighPriority</hook>
|
||||
<socialModeMax>Off</socialModeMax>
|
||||
<thinkNode Class="ThinkNode_Priority">
|
||||
|
@ -25,6 +25,31 @@
|
|||
</subNodes>
|
||||
</thinkNode>
|
||||
</DutyDef>
|
||||
|
||||
<DutyDef>
|
||||
<defName>Gangbang_Consensual</defName>
|
||||
<hook>HighPriority</hook>
|
||||
<socialModeMax>Off</socialModeMax>
|
||||
<thinkNode Class="ThinkNode_Priority">
|
||||
<subNodes>
|
||||
<li Class="ThinkNode_ConditionalInGatheringArea">
|
||||
<subNodes>
|
||||
<li Class="ThinkNode_ConditionalRandom">
|
||||
<chance>0.25</chance>
|
||||
<subNodes>
|
||||
<li Class="RJWSexperience.Ideology.JobGiver_GangbangConsensual"/>
|
||||
</subNodes>
|
||||
</li>
|
||||
</subNodes>
|
||||
</li>
|
||||
|
||||
<li Class="JobGiver_WanderInGatheringArea">
|
||||
<locomotionUrgency>Jog</locomotionUrgency>
|
||||
<ticksBetweenWandersRange>50~250</ticksBetweenWandersRange>
|
||||
</li>
|
||||
</subNodes>
|
||||
</thinkNode>
|
||||
</DutyDef>
|
||||
|
||||
<DutyDef>
|
||||
<defName>FuckVictim</defName>
|
||||
|
|
|
@ -28,4 +28,20 @@
|
|||
<reportString>masturbatin'.</reportString>
|
||||
<casualInterruptible>false</casualInterruptible>
|
||||
</JobDef>
|
||||
|
||||
<JobDef>
|
||||
<defName>Gangbang</defName>
|
||||
<driverClass>RJWSexperience.Ideology.JobDriver_Gangbang</driverClass>
|
||||
<reportString>lovin'.</reportString>
|
||||
<casualInterruptible>false</casualInterruptible>
|
||||
</JobDef>
|
||||
|
||||
<JobDef>
|
||||
<defName>GettinGangbang</defName>
|
||||
<driverClass>RJWSexperience.Ideology.JobDriver_GangbangReceiver</driverClass>
|
||||
<reportString>gettin' gangbanged.</reportString>
|
||||
<checkOverrideOnDamage>Never</checkOverrideOnDamage>
|
||||
<casualInterruptible>false</casualInterruptible>
|
||||
</JobDef>
|
||||
|
||||
</Defs>
|
|
@ -25,8 +25,30 @@
|
|||
<li>Rapist</li>
|
||||
</requiredMemes>
|
||||
</PreceptDef>
|
||||
|
||||
|
||||
<PreceptDef>
|
||||
<defName>GangbangCeremony_Consensual</defName>
|
||||
<label>gangbang</label>
|
||||
<description>A ritualistic gangbang where a organizer being fucked. The audience will fuck the organizer.</description>
|
||||
<issue>Ritual</issue>
|
||||
<impact>Medium</impact>
|
||||
<iconPath>UI/Issues/Gangbang_Consensual</iconPath>
|
||||
<preceptClass>Precept_Ritual</preceptClass>
|
||||
<ritualPatternBase>Gangbang_Consensual</ritualPatternBase>
|
||||
<allowDuplicates>true</allowDuplicates>
|
||||
<countsTowardsPreceptLimit>false</countsTowardsPreceptLimit>
|
||||
<selectionWeight>1.0</selectionWeight>
|
||||
<displayOrderInImpact>100</displayOrderInImpact>
|
||||
<ignoreLimitsInEditMode>false</ignoreLimitsInEditMode>
|
||||
<receivesExpectationsQualityOffset>true</receivesExpectationsQualityOffset>
|
||||
<canGenerateAsSpecialPrecept>false</canGenerateAsSpecialPrecept>
|
||||
<allowStackingRitualObligationAlerts>true</allowStackingRitualObligationAlerts>
|
||||
<requiredMemes>
|
||||
<li>Lewd</li>
|
||||
</requiredMemes>
|
||||
</PreceptDef>
|
||||
|
||||
<RJWSexperience.Ideology.PreceptDef_RequirementExtended>
|
||||
<defName>AnimalGangbangCeremony</defName>
|
||||
<label>animal gangbang</label>
|
||||
<description>A ritualistic gangbang where animals rape a victim.</description>
|
||||
|
@ -43,12 +65,36 @@
|
|||
<receivesExpectationsQualityOffset>true</receivesExpectationsQualityOffset>
|
||||
<canGenerateAsSpecialPrecept>false</canGenerateAsSpecialPrecept>
|
||||
<allowStackingRitualObligationAlerts>true</allowStackingRitualObligationAlerts>
|
||||
<requiredAllMemes>
|
||||
<li>Rapist</li>
|
||||
<li>Zoophile</li>
|
||||
</requiredAllMemes>
|
||||
</RJWSexperience.Ideology.PreceptDef_RequirementExtended>
|
||||
|
||||
<PreceptDef>
|
||||
<defName>AnimalGangbangCeremony_Consensual</defName>
|
||||
<label>animal gangbang</label>
|
||||
<description>A ritualistic gangbang where animals fuck the organizer.</description>
|
||||
<issue>Ritual</issue>
|
||||
<impact>Medium</impact>
|
||||
<iconPath>UI/Commands/Breeding_Pawn_on</iconPath>
|
||||
<preceptClass>Precept_Ritual</preceptClass>
|
||||
<ritualPatternBase>GangbangByAnimal_Consensual</ritualPatternBase>
|
||||
<allowDuplicates>true</allowDuplicates>
|
||||
<countsTowardsPreceptLimit>false</countsTowardsPreceptLimit>
|
||||
<selectionWeight>1.0</selectionWeight>
|
||||
<displayOrderInImpact>100</displayOrderInImpact>
|
||||
<ignoreLimitsInEditMode>false</ignoreLimitsInEditMode>
|
||||
<receivesExpectationsQualityOffset>true</receivesExpectationsQualityOffset>
|
||||
<canGenerateAsSpecialPrecept>false</canGenerateAsSpecialPrecept>
|
||||
<allowStackingRitualObligationAlerts>true</allowStackingRitualObligationAlerts>
|
||||
<requiredMemes>
|
||||
<li>Zoophile</li>
|
||||
</requiredMemes>
|
||||
</PreceptDef>
|
||||
|
||||
|
||||
|
||||
<PreceptDef>
|
||||
<defName>DrugOrgyCeremony</defName>
|
||||
<label>drug orgy</label>
|
||||
|
|
|
@ -58,8 +58,6 @@
|
|||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>AnalSex</eventDef>
|
||||
<thought>Sex_Promiscuous</thought>
|
||||
<recordDef>Lust</recordDef>
|
||||
<recordoffset>2.0</recordoffset>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_KnowsMemoryThoughtTagged">
|
||||
<eventDef>AnalSex</eventDef>
|
||||
|
@ -68,8 +66,6 @@
|
|||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>OralSex</eventDef>
|
||||
<thought>Sex_Promiscuous</thought>
|
||||
<recordDef>Lust</recordDef>
|
||||
<recordoffset>2.0</recordoffset>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_KnowsMemoryThoughtTagged">
|
||||
<eventDef>OralSex</eventDef>
|
||||
|
@ -78,8 +74,6 @@
|
|||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>MiscSex</eventDef>
|
||||
<thought>Sex_Promiscuous</thought>
|
||||
<recordDef>Lust</recordDef>
|
||||
<recordoffset>2.0</recordoffset>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_KnowsMemoryThoughtTagged">
|
||||
<eventDef>MiscSex</eventDef>
|
||||
|
@ -88,8 +82,6 @@
|
|||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>PromiscuousSex</eventDef>
|
||||
<thought>Sex_Promiscuous</thought>
|
||||
<recordDef>Lust</recordDef>
|
||||
<recordoffset>3.0</recordoffset>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_KnowsMemoryThoughtTagged">
|
||||
<eventDef>PromiscuousSex</eventDef>
|
||||
|
@ -111,8 +103,6 @@
|
|||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>VaginalSex</eventDef>
|
||||
<thought>Sex_Promiscuous</thought>
|
||||
<recordDef>Lust</recordDef>
|
||||
<recordoffset>2.0</recordoffset>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_KnowsMemoryThoughtTagged">
|
||||
<eventDef>VaginalSex</eventDef>
|
||||
|
@ -121,8 +111,6 @@
|
|||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>OralSex</eventDef>
|
||||
<thought>Sex_Promiscuous</thought>
|
||||
<recordDef>Lust</recordDef>
|
||||
<recordoffset>2.0</recordoffset>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_KnowsMemoryThoughtTagged">
|
||||
<eventDef>OralSex</eventDef>
|
||||
|
@ -131,8 +119,6 @@
|
|||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>MiscSex</eventDef>
|
||||
<thought>Sex_Promiscuous</thought>
|
||||
<recordDef>Lust</recordDef>
|
||||
<recordoffset>2.0</recordoffset>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_KnowsMemoryThoughtTagged">
|
||||
<eventDef>MiscSex</eventDef>
|
||||
|
@ -141,8 +127,6 @@
|
|||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>PromiscuousSex</eventDef>
|
||||
<thought>Sex_Promiscuous</thought>
|
||||
<recordDef>Lust</recordDef>
|
||||
<recordoffset>3.0</recordoffset>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_KnowsMemoryThoughtTagged">
|
||||
<eventDef>PromiscuousSex</eventDef>
|
||||
|
@ -164,8 +148,6 @@
|
|||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>VaginalSex</eventDef>
|
||||
<thought>Sex_Promiscuous</thought>
|
||||
<recordDef>Lust</recordDef>
|
||||
<recordoffset>2.0</recordoffset>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_KnowsMemoryThoughtTagged">
|
||||
<eventDef>VaginalSex</eventDef>
|
||||
|
@ -174,8 +156,6 @@
|
|||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>AnalSex</eventDef>
|
||||
<thought>Sex_Promiscuous</thought>
|
||||
<recordDef>Lust</recordDef>
|
||||
<recordoffset>2.0</recordoffset>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_KnowsMemoryThoughtTagged">
|
||||
<eventDef>AnalSex</eventDef>
|
||||
|
@ -184,8 +164,6 @@
|
|||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>MiscSex</eventDef>
|
||||
<thought>Sex_Promiscuous</thought>
|
||||
<recordDef>Lust</recordDef>
|
||||
<recordoffset>2.0</recordoffset>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_KnowsMemoryThoughtTagged">
|
||||
<eventDef>MiscSex</eventDef>
|
||||
|
@ -194,8 +172,6 @@
|
|||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>PromiscuousSex</eventDef>
|
||||
<thought>Sex_Promiscuous</thought>
|
||||
<recordDef>Lust</recordDef>
|
||||
<recordoffset>3.0</recordoffset>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_KnowsMemoryThoughtTagged">
|
||||
<eventDef>PromiscuousSex</eventDef>
|
||||
|
|
|
@ -0,0 +1,342 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Defs>
|
||||
<!-- Issues -->
|
||||
<IssueDef>
|
||||
<defName>Virginity_Female</defName>
|
||||
<label>virginity of female</label>
|
||||
<iconPath>UI/Issues/Female</iconPath>
|
||||
</IssueDef>
|
||||
|
||||
<IssueDef>
|
||||
<defName>Virginity_Male</defName>
|
||||
<label>virginity of male</label>
|
||||
<iconPath>UI/Issues/Male</iconPath>
|
||||
</IssueDef>
|
||||
|
||||
<HistoryEventDef>
|
||||
<defName>Virgin_TakenF</defName>
|
||||
<label>virgin taken</label>
|
||||
</HistoryEventDef>
|
||||
|
||||
<HistoryEventDef>
|
||||
<defName>Virgin_TakenM</defName>
|
||||
<label>virgin taken</label>
|
||||
</HistoryEventDef>
|
||||
|
||||
<HistoryEventDef>
|
||||
<defName>Virgin_TookF</defName>
|
||||
<label>virgin took</label>
|
||||
</HistoryEventDef>
|
||||
|
||||
<HistoryEventDef>
|
||||
<defName>Virgin_TookM</defName>
|
||||
<label>virgin took</label>
|
||||
</HistoryEventDef>
|
||||
|
||||
<!-- Precepts -->
|
||||
|
||||
<PreceptDef>
|
||||
<defName>Virgin_UselessF</defName>
|
||||
<issue>Virginity_Female</issue>
|
||||
<label>useless</label>
|
||||
<description>Female's virginity is useless.</description>
|
||||
<impact>Medium</impact>
|
||||
<displayOrderInIssue>50</displayOrderInIssue>
|
||||
<displayOrderInImpact>1000</displayOrderInImpact>
|
||||
<defaultSelectionWeight>10</defaultSelectionWeight>
|
||||
</PreceptDef>
|
||||
|
||||
<PreceptDef>
|
||||
<defName>Virgin_UselessM</defName>
|
||||
<issue>Virginity_Male</issue>
|
||||
<label>useless</label>
|
||||
<description>Male's virginity is useless.</description>
|
||||
<impact>Low</impact>
|
||||
<displayOrderInIssue>50</displayOrderInIssue>
|
||||
<displayOrderInImpact>1000</displayOrderInImpact>
|
||||
<defaultSelectionWeight>80</defaultSelectionWeight>
|
||||
</PreceptDef>
|
||||
|
||||
<PreceptDef>
|
||||
<defName>Virgin_PreciousF</defName>
|
||||
<issue>Virginity_Female</issue>
|
||||
<label>precious</label>
|
||||
<description>Female's virginity is precious.</description>
|
||||
<impact>Medium</impact>
|
||||
<displayOrderInIssue>40</displayOrderInIssue>
|
||||
<displayOrderInImpact>1000</displayOrderInImpact>
|
||||
<defaultSelectionWeight>80</defaultSelectionWeight>
|
||||
<comps>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>Virgin_TakenF</eventDef>
|
||||
<thought>Virgin_Precious_Taken_Forcefully</thought>
|
||||
<tag>BeenRaped</tag>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>Virgin_TakenF</eventDef>
|
||||
<thought>Virgin_Precious_Taken</thought>
|
||||
<tag>BeenRaped</tag>
|
||||
<exclusive>true</exclusive>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>Virgin_TookF</eventDef>
|
||||
<thought>TookVirginity</thought>
|
||||
</li>
|
||||
</comps>
|
||||
</PreceptDef>
|
||||
|
||||
<PreceptDef>
|
||||
<defName>Virgin_PreciousM</defName>
|
||||
<issue>Virginity_Male</issue>
|
||||
<label>precious</label>
|
||||
<description>Male's virginity is precious.</description>
|
||||
<impact>Medium</impact>
|
||||
<displayOrderInIssue>40</displayOrderInIssue>
|
||||
<displayOrderInImpact>1000</displayOrderInImpact>
|
||||
<defaultSelectionWeight>1</defaultSelectionWeight>
|
||||
<comps>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>Virgin_TakenM</eventDef>
|
||||
<thought>Virgin_Precious_Taken_Forcefully</thought>
|
||||
<tag>BeenRaped</tag>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>Virgin_TakenM</eventDef>
|
||||
<thought>Virgin_Precious_Taken</thought>
|
||||
<tag>BeenRaped</tag>
|
||||
<exclusive>true</exclusive>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>Virgin_TookM</eventDef>
|
||||
<thought>TookVirginity</thought>
|
||||
</li>
|
||||
</comps>
|
||||
</PreceptDef>
|
||||
|
||||
<PreceptDef>
|
||||
<defName>Virgin_OnlyForSpouseF</defName>
|
||||
<issue>Virginity_Female</issue>
|
||||
<label>precious(strict)</label>
|
||||
<description>Losing virginity before marriage is evil.</description>
|
||||
<impact>Medium</impact>
|
||||
<displayOrderInIssue>40</displayOrderInIssue>
|
||||
<displayOrderInImpact>1000</displayOrderInImpact>
|
||||
<defaultSelectionWeight>80</defaultSelectionWeight>
|
||||
<requiredMemes>
|
||||
<li>MaleSupremacy</li>
|
||||
</requiredMemes>
|
||||
<conflictingMemes>
|
||||
<li>FemaleSupremacy</li>
|
||||
</conflictingMemes>
|
||||
<associatedMemes>
|
||||
<li>MaleSupremacy</li>
|
||||
</associatedMemes>
|
||||
<comps>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>Virgin_TakenF</eventDef>
|
||||
<thought>Virgin_Precious_Taken_Forcefully</thought>
|
||||
<tag>BeenRaped</tag>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>Virgin_TakenF</eventDef>
|
||||
<thought>Virgin_Precious_Taken</thought>
|
||||
<tag>BeenRaped</tag>
|
||||
<exclusive>true</exclusive>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_KnowsMemoryThoughtTagged">
|
||||
<eventDef>Virgin_TakenF</eventDef>
|
||||
<thought>Virgin_OnlyForSpouse_Know_Taken</thought>
|
||||
<tag>Female, NotSpouse</tag>
|
||||
</li>
|
||||
<li Class="PreceptComp_SelfTookMemoryThought">
|
||||
<eventDef>Virgin_TookF</eventDef>
|
||||
<thought>TookVirginity</thought>
|
||||
</li>
|
||||
</comps>
|
||||
</PreceptDef>
|
||||
|
||||
<PreceptDef>
|
||||
<defName>Virgin_OnlyForSpouseM</defName>
|
||||
<issue>Virginity_Male</issue>
|
||||
<label>precious(strict)</label>
|
||||
<description>Losing virginity before marriage is evil.</description>
|
||||
<impact>Medium</impact>
|
||||
<displayOrderInIssue>40</displayOrderInIssue>
|
||||
<displayOrderInImpact>1000</displayOrderInImpact>
|
||||
<defaultSelectionWeight>20</defaultSelectionWeight>
|
||||
<requiredMemes>
|
||||
<li>FemaleSupremacy</li>
|
||||
</requiredMemes>
|
||||
<conflictingMemes>
|
||||
<li>MaleSupremacy</li>
|
||||
</conflictingMemes>
|
||||
<associatedMemes>
|
||||
<li>FemaleSupremacy</li>
|
||||
</associatedMemes>
|
||||
<comps>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>Virgin_TakenM</eventDef>
|
||||
<thought>Virgin_Precious_Taken_Forcefully</thought>
|
||||
<tag>BeenRaped</tag>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>Virgin_TakenM</eventDef>
|
||||
<thought>Virgin_Precious_Taken</thought>
|
||||
<tag>BeenRaped</tag>
|
||||
<exclusive>true</exclusive>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_KnowsMemoryThoughtTagged">
|
||||
<eventDef>Virgin_TakenM</eventDef>
|
||||
<thought>Virgin_OnlyForSpouse_Know_Taken</thought>
|
||||
<tag>Male, NotSpouse</tag>
|
||||
</li>
|
||||
<li Class="PreceptComp_SelfTookMemoryThought">
|
||||
<eventDef>Virgin_TookM</eventDef>
|
||||
<thought>TookVirginity</thought>
|
||||
</li>
|
||||
</comps>
|
||||
</PreceptDef>
|
||||
|
||||
<PreceptDef>
|
||||
<defName>Virgin_ShamefulF</defName>
|
||||
<issue>Virginity_Female</issue>
|
||||
<label>shameful</label>
|
||||
<description>Remaining as virgin is shameful thing and being laughed at.</description>
|
||||
<impact>Medium</impact>
|
||||
<displayOrderInIssue>30</displayOrderInIssue>
|
||||
<displayOrderInImpact>1000</displayOrderInImpact>
|
||||
<defaultSelectionWeight>1</defaultSelectionWeight>
|
||||
<associatedMemes>
|
||||
<li>FemaleSupremacy</li>
|
||||
</associatedMemes>
|
||||
<comps>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>Virgin_TakenF</eventDef>
|
||||
<thought>Virgin_Shameful_Taken</thought>
|
||||
<tag>BeenRaped</tag>
|
||||
<exclusive>true</exclusive>
|
||||
</li>
|
||||
</comps>
|
||||
</PreceptDef>
|
||||
|
||||
<PreceptDef>
|
||||
<defName>Virgin_ShamefulM</defName>
|
||||
<issue>Virginity_Male</issue>
|
||||
<label>shameful</label>
|
||||
<description>Remaining as virgin is shameful thing and being laughed at.</description>
|
||||
<impact>Medium</impact>
|
||||
<displayOrderInIssue>30</displayOrderInIssue>
|
||||
<displayOrderInImpact>1000</displayOrderInImpact>
|
||||
<defaultSelectionWeight>40</defaultSelectionWeight>
|
||||
<associatedMemes>
|
||||
<li>MaleSupremacy</li>
|
||||
</associatedMemes>
|
||||
<comps>
|
||||
<li Class="RJWSexperience.Ideology.PreceptComp_SelfTookThoughtTagged">
|
||||
<eventDef>Virgin_TakenM</eventDef>
|
||||
<thought>Virgin_Shameful_Taken</thought>
|
||||
<tag>BeenRaped</tag>
|
||||
<exclusive>true</exclusive>
|
||||
</li>
|
||||
</comps>
|
||||
</PreceptDef>
|
||||
|
||||
<!-- Thoughts -->
|
||||
|
||||
<ThoughtDef>
|
||||
<defName>Virgin_Precious_Taken_Forcefully</defName>
|
||||
<thoughtClass>Thought_MemorySocial</thoughtClass>
|
||||
<durationDays>30</durationDays>
|
||||
<stackLimit>1</stackLimit>
|
||||
<stages>
|
||||
<li>
|
||||
<label>Lost virginity</label>
|
||||
<description>I lost my virginity forcefully.</description>
|
||||
<baseMoodEffect>-10</baseMoodEffect>
|
||||
<baseOpinionOffset>-200</baseOpinionOffset>
|
||||
</li>
|
||||
</stages>
|
||||
</ThoughtDef>
|
||||
|
||||
<RJWSexperience.ThoughtDef_Opinionbased>
|
||||
<defName>Virgin_Precious_Taken</defName>
|
||||
<thoughtClass>RJWSexperience.Thought_Opinionbased</thoughtClass>
|
||||
<durationDays>7</durationDays>
|
||||
<stackLimit>1</stackLimit>
|
||||
<minimumValueforStage>
|
||||
<li>-100</li>
|
||||
<li>-50</li>
|
||||
<li>0</li>
|
||||
<li>75</li>
|
||||
</minimumValueforStage>
|
||||
<stages>
|
||||
<li>
|
||||
<label>Lost virginity by {0}</label>
|
||||
<description>I am no longer virgin.</description>
|
||||
<baseMoodEffect>-5</baseMoodEffect>
|
||||
</li>
|
||||
<li>
|
||||
<label>Lost virginity by {0}</label>
|
||||
<description>I am no longer virgin.</description>
|
||||
<baseMoodEffect>-3</baseMoodEffect>
|
||||
</li>
|
||||
<li>
|
||||
<label>Lost virginity by {0}</label>
|
||||
<description>I am no longer virgin.</description>
|
||||
<baseMoodEffect>-1</baseMoodEffect>
|
||||
</li>
|
||||
<li>
|
||||
<label>Gave virginity to {0}</label>
|
||||
<description>I Gave my virginity to my love.</description>
|
||||
<baseMoodEffect>5</baseMoodEffect>
|
||||
</li>
|
||||
</stages>
|
||||
</RJWSexperience.ThoughtDef_Opinionbased>
|
||||
|
||||
<RJWSexperience.ThoughtDef_Opinionbased>
|
||||
<defName>Virgin_Shameful_Taken</defName>
|
||||
<thoughtClass>RJWSexperience.Thought_Opinionbased</thoughtClass>
|
||||
<durationDays>7</durationDays>
|
||||
<stackLimit>1</stackLimit>
|
||||
<minimumValueforStage>
|
||||
<li>-100</li>
|
||||
<li>0</li>
|
||||
<li>75</li>
|
||||
</minimumValueforStage>
|
||||
<stages>
|
||||
<li>
|
||||
<label>Lost virginity by {0}</label>
|
||||
<description>Finally!</description>
|
||||
<baseMoodEffect>5</baseMoodEffect>
|
||||
</li>
|
||||
<li>
|
||||
<label>Lost virginity by {0}</label>
|
||||
<description>Finally!</description>
|
||||
<baseMoodEffect>10</baseMoodEffect>
|
||||
</li>
|
||||
<li>
|
||||
<label>Lost virginity by {0}</label>
|
||||
<description>Finally!</description>
|
||||
<baseMoodEffect>20</baseMoodEffect>
|
||||
</li>
|
||||
</stages>
|
||||
</RJWSexperience.ThoughtDef_Opinionbased>
|
||||
|
||||
|
||||
<ThoughtDef>
|
||||
<defName>Virgin_OnlyForSpouse_Know_Taken</defName>
|
||||
<thoughtClass>Thought_MemorySocial</thoughtClass>
|
||||
<durationDays>30</durationDays>
|
||||
<stackLimit>100</stackLimit>
|
||||
<stackLimitForSameOtherPawn>3</stackLimitForSameOtherPawn>
|
||||
<nullifyingTraits>
|
||||
<li>Nymphomaniac</li>
|
||||
</nullifyingTraits>
|
||||
<stages>
|
||||
<li>
|
||||
<label>slut</label>
|
||||
<baseOpinionOffset>-30</baseOpinionOffset>
|
||||
</li>
|
||||
</stages>
|
||||
</ThoughtDef>
|
||||
</Defs>
|
|
@ -21,6 +21,17 @@
|
|||
<patternGroupTag/>
|
||||
</RitualPatternDef>
|
||||
|
||||
<RitualPatternDef ParentName="GangbangBase">
|
||||
<defName>Gangbang_Consensual</defName>
|
||||
<ritualBehavior>Gangbang_Consensual</ritualBehavior>
|
||||
<shortDescOverride>gangbang</shortDescOverride>
|
||||
<descOverride>A ritualistic gangbang. The organizer will give a speech to excite the crowd, then fucked by the crowd.</descOverride>
|
||||
<iconPathOverride>UI/Issues/Gangbang_Consensual</iconPathOverride>
|
||||
<ritualOnlyForIdeoMembers>false</ritualOnlyForIdeoMembers>
|
||||
<ritualOutcomeEffect>Gangbang_Consensual</ritualOutcomeEffect>
|
||||
<patternGroupTag/>
|
||||
</RitualPatternDef>
|
||||
|
||||
<RitualPatternDef ParentName="GangbangBase">
|
||||
<defName>GangbangByAnimal</defName>
|
||||
<ritualBehavior>GangbangByAnimal</ritualBehavior>
|
||||
|
@ -32,6 +43,17 @@
|
|||
<patternGroupTag/>
|
||||
</RitualPatternDef>
|
||||
|
||||
<RitualPatternDef ParentName="GangbangBase">
|
||||
<defName>GangbangByAnimal_Consensual</defName>
|
||||
<ritualBehavior>GangbangByAnimal_Consensual</ritualBehavior>
|
||||
<shortDescOverride>gangbang by animal</shortDescOverride>
|
||||
<descOverride>A ritualistic animal gangbang. The organizer will give a speech to excite the crowd, then animals begin fuck the organizer.</descOverride>
|
||||
<iconPathOverride>UI/Commands/Breeding_Pawn_on</iconPathOverride>
|
||||
<ritualOnlyForIdeoMembers>false</ritualOnlyForIdeoMembers>
|
||||
<ritualOutcomeEffect>BestialGangbang_Consensual</ritualOutcomeEffect>
|
||||
<patternGroupTag/>
|
||||
</RitualPatternDef>
|
||||
|
||||
<RitualPatternDef ParentName="CelebrationConsumable">
|
||||
<defName>DrugOrgy</defName>
|
||||
<shortDescOverride>drug orgy</shortDescOverride>
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
<Defs>
|
||||
|
||||
<RitualBehaviorDef Name="GangbangBehaviorBase" Abstract="True" ParentName="DateRitualBehavior">
|
||||
<preceptRequirements><li Class="PreceptRequirement_Altar"/></preceptRequirements>
|
||||
<preceptRequirements>
|
||||
<li Class="PreceptRequirement_Altar"/>
|
||||
</preceptRequirements>
|
||||
<durationTicks>7500</durationTicks>
|
||||
<roles Inherit="False">
|
||||
<li Class="RitualRoleTag">
|
||||
|
@ -84,7 +86,7 @@
|
|||
</roleBehaviors>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.RitualStage_InteractWithVictim">
|
||||
<defaultDuty>Gangbang</defaultDuty>
|
||||
<defaultDuty>Gangbang_Rape</defaultDuty>
|
||||
<essential>True</essential>
|
||||
<endTriggers>
|
||||
<li Class="StageEndTrigger_DurationPercentage">
|
||||
|
@ -102,7 +104,7 @@
|
|||
</roleBehaviors>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.RitualStage_InteractWithVictim">
|
||||
<defaultDuty>Gangbang</defaultDuty>
|
||||
<defaultDuty>Gangbang_Rape</defaultDuty>
|
||||
<endTriggers>
|
||||
<li Class="StageEndTrigger_DurationPercentage">
|
||||
<percentage>0.1</percentage>
|
||||
|
@ -122,6 +124,85 @@
|
|||
</stages>
|
||||
</RitualBehaviorDef>
|
||||
|
||||
<RitualBehaviorDef ParentName="GangbangBehaviorBase">
|
||||
<defName>Gangbang_Consensual</defName>
|
||||
<workerClass>RJWSexperience.Ideology.RitualBehaviorWorker_Gangbang_Consensual</workerClass>
|
||||
<stages Inherit="False">
|
||||
<li Class="RJWSexperience.Ideology.RitualStage_InteractWithInitiator">
|
||||
<defaultDuty>Spectate</defaultDuty>
|
||||
<endTriggers>
|
||||
<li Class="StageEndTrigger_RolesArrived">
|
||||
<roleIds>
|
||||
<li>initiator</li>
|
||||
</roleIds>
|
||||
</li>
|
||||
</endTriggers>
|
||||
<roleBehaviors>
|
||||
<li>
|
||||
<roleId>initiator</roleId>
|
||||
<dutyDef>ArriveToCell</dutyDef>
|
||||
</li>
|
||||
</roleBehaviors>
|
||||
</li>
|
||||
<li>
|
||||
<defaultDuty>Spectate</defaultDuty>
|
||||
<endTriggers>
|
||||
<li Class="StageEndTrigger_DurationPercentage">
|
||||
<percentage>0.1</percentage>
|
||||
</li>
|
||||
</endTriggers>
|
||||
<roleBehaviors>
|
||||
<li>
|
||||
<roleId>initiator</roleId>
|
||||
<dutyDef>SpeakOnCellFacingSpectators</dutyDef>
|
||||
<speakerInteraction>Speech_Gangbang</speakerInteraction>
|
||||
<customPositions>
|
||||
<li Class="RitualPosition_Lectern">
|
||||
<maxDistanceToFocus>5</maxDistanceToFocus>
|
||||
</li>
|
||||
<li Class="RitualPosition_OnInteractionCell" />
|
||||
</customPositions>
|
||||
</li>
|
||||
</roleBehaviors>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.RitualStage_InteractWithInitiator">
|
||||
<defaultDuty>Gangbang_Consensual</defaultDuty>
|
||||
<essential>True</essential>
|
||||
<endTriggers>
|
||||
<li Class="StageEndTrigger_DurationPercentage">
|
||||
<percentage>1.0</percentage>
|
||||
</li>
|
||||
</endTriggers>
|
||||
<roleBehaviors>
|
||||
<li>
|
||||
<roleId>initiator</roleId>
|
||||
<dutyDef>LayDownAwake</dutyDef>
|
||||
<customPositions>
|
||||
<li Class="RitualPosition_OnInteractionCell" />
|
||||
</customPositions>
|
||||
</li>
|
||||
</roleBehaviors>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.RitualStage_InteractWithInitiator">
|
||||
<defaultDuty>Spectate</defaultDuty>
|
||||
<endTriggers>
|
||||
<li Class="StageEndTrigger_DurationPercentage">
|
||||
<percentage>0.1</percentage>
|
||||
</li>
|
||||
</endTriggers>
|
||||
<roleBehaviors>
|
||||
<li>
|
||||
<roleId>initiator</roleId>
|
||||
<dutyDef>SpeakOnCellFacingSpectators</dutyDef>
|
||||
<speakerInteraction>Speech_Gangbang</speakerInteraction>
|
||||
<customPositions>
|
||||
<li Class="RitualPosition_OnInteractionCell" />
|
||||
</customPositions>
|
||||
</li>
|
||||
</roleBehaviors>
|
||||
</li>
|
||||
</stages>
|
||||
</RitualBehaviorDef>
|
||||
|
||||
|
||||
<RitualBehaviorDef ParentName="GangbangBehaviorBase">
|
||||
|
@ -228,7 +309,7 @@
|
|||
<roleBehaviors>
|
||||
<li>
|
||||
<roleId>animal</roleId>
|
||||
<dutyDef>Gangbang</dutyDef>
|
||||
<dutyDef>Gangbang_Rape</dutyDef>
|
||||
<customPositions>
|
||||
<li Class="RitualPosition_OnInteractionCell" />
|
||||
</customPositions>
|
||||
|
@ -263,7 +344,106 @@
|
|||
</li>
|
||||
</stages>
|
||||
</RitualBehaviorDef>
|
||||
|
||||
|
||||
<RitualBehaviorDef ParentName="GangbangBehaviorBase">
|
||||
<defName>GangbangByAnimal_Consensual</defName>
|
||||
<workerClass>RJWSexperience.Ideology.RitualBehaviorWorker_Gangbang_Consensual</workerClass>
|
||||
<roles>
|
||||
<li Class="RJWSexperience.Ideology.RitualRole_AnimalBreeder">
|
||||
<label>breeder</label>
|
||||
<id>animal</id>
|
||||
<maxCount>30</maxCount>
|
||||
<required>false</required>
|
||||
<missingDesc>a breedable animal</missingDesc>
|
||||
<countsAsParticipant>false</countsAsParticipant>
|
||||
</li>
|
||||
</roles>
|
||||
<stages Inherit="False">
|
||||
<li Class="RJWSexperience.Ideology.RitualStage_InteractWithInitiator">
|
||||
<defaultDuty>Spectate</defaultDuty>
|
||||
<endTriggers>
|
||||
<li Class="StageEndTrigger_RolesArrived">
|
||||
<roleIds>
|
||||
<li>initiator</li>
|
||||
</roleIds>
|
||||
</li>
|
||||
</endTriggers>
|
||||
<roleBehaviors>
|
||||
<li>
|
||||
<roleId>initiator</roleId>
|
||||
<dutyDef>ArriveToCell</dutyDef>
|
||||
</li>
|
||||
</roleBehaviors>
|
||||
</li>
|
||||
<li>
|
||||
<defaultDuty>Spectate</defaultDuty>
|
||||
<endTriggers>
|
||||
<li Class="StageEndTrigger_DurationPercentage">
|
||||
<percentage>0.1</percentage>
|
||||
</li>
|
||||
</endTriggers>
|
||||
<roleBehaviors>
|
||||
<li>
|
||||
<roleId>initiator</roleId>
|
||||
<dutyDef>SpeakOnCellFacingSpectators</dutyDef>
|
||||
<speakerInteraction>Speech_Zoophile</speakerInteraction>
|
||||
<customPositions>
|
||||
<li Class="RitualPosition_Lectern">
|
||||
<maxDistanceToFocus>5</maxDistanceToFocus>
|
||||
</li>
|
||||
<li Class="RitualPosition_OnInteractionCell" />
|
||||
</customPositions>
|
||||
</li>
|
||||
<li>
|
||||
<roleId>animal</roleId>
|
||||
<dutyDef>Spectate</dutyDef>
|
||||
</li>
|
||||
</roleBehaviors>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.RitualStage_InteractWithInitiator">
|
||||
<defaultDuty>Spectate</defaultDuty>
|
||||
<essential>True</essential>
|
||||
<endTriggers>
|
||||
<li Class="StageEndTrigger_DurationPercentage">
|
||||
<percentage>0.9</percentage>
|
||||
</li>
|
||||
</endTriggers>
|
||||
<roleBehaviors>
|
||||
<li>
|
||||
<roleId>animal</roleId>
|
||||
<dutyDef>Gangbang_Consensual</dutyDef>
|
||||
<customPositions>
|
||||
<li Class="RitualPosition_OnInteractionCell" />
|
||||
</customPositions>
|
||||
</li>
|
||||
<li>
|
||||
<roleId>initiator</roleId>
|
||||
<dutyDef>LayDownAwake</dutyDef>
|
||||
</li>
|
||||
</roleBehaviors>
|
||||
</li>
|
||||
<li>
|
||||
<defaultDuty>Spectate</defaultDuty>
|
||||
<endTriggers>
|
||||
<li Class="StageEndTrigger_DurationPercentage">
|
||||
<percentage>0.1</percentage>
|
||||
</li>
|
||||
</endTriggers>
|
||||
<roleBehaviors>
|
||||
<li>
|
||||
<roleId>initiator</roleId>
|
||||
<dutyDef>SpeakOnCellFacingSpectators</dutyDef>
|
||||
<speakerInteraction>Speech_Zoophile</speakerInteraction>
|
||||
<customPositions>
|
||||
<li Class="RitualPosition_OnInteractionCell" />
|
||||
</customPositions>
|
||||
</li>
|
||||
</roleBehaviors>
|
||||
</li>
|
||||
</stages>
|
||||
</RitualBehaviorDef>
|
||||
|
||||
<RitualBehaviorDef ParentName="DateRitualBehavior">
|
||||
<defName>DrugOrgy</defName>
|
||||
<durationTicks>7500</durationTicks>
|
||||
|
|
|
@ -32,31 +32,114 @@
|
|||
</li>
|
||||
<li Class="RJWSexperience.Ideology.RitualOutcomeComp_HediffBased">
|
||||
<label>victim broken</label>
|
||||
<qualityOffset>0.2</qualityOffset>
|
||||
<qualityOffset>0.15</qualityOffset>
|
||||
<hediffDef>FeelingBroken</hediffDef>
|
||||
<minSeverity>0.3</minSeverity>
|
||||
<roleId>victim</roleId>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.RitualOutcomeComp_HediffBased">
|
||||
<label>victim extremly broken</label>
|
||||
<qualityOffset>0.2</qualityOffset>
|
||||
<qualityOffset>0.15</qualityOffset>
|
||||
<hediffDef>FeelingBroken</hediffDef>
|
||||
<minSeverity>0.5</minSeverity>
|
||||
<roleId>victim</roleId>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.RitualOutcomeComp_HediffBased">
|
||||
<label>victim completely broken</label>
|
||||
<qualityOffset>0.4</qualityOffset>
|
||||
<qualityOffset>0.3</qualityOffset>
|
||||
<hediffDef>FeelingBroken</hediffDef>
|
||||
<minSeverity>0.9</minSeverity>
|
||||
<roleId>victim</roleId>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.RitualOutcomeComp_NeedBased">
|
||||
<label>statisfied participants</label>
|
||||
<qualityOffset>0.2</qualityOffset>
|
||||
<qualityOffset>0.4</qualityOffset>
|
||||
<needDef>Sex</needDef>
|
||||
<minAvgNeed>0.7</minAvgNeed>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.RitualOutcomeComp_NeedBased">
|
||||
<label>completly statisfied participants</label>
|
||||
<qualityOffset>0.4</qualityOffset>
|
||||
<needDef>Sex</needDef>
|
||||
<minAvgNeed>0.9</minAvgNeed>
|
||||
</li>
|
||||
</comps>
|
||||
<outcomeChances>
|
||||
<li>
|
||||
<label>Terrible</label>
|
||||
<chance>0.05</chance>
|
||||
<memory>TerribleGangbang</memory>
|
||||
<description>The {0} was terrible! The speech was stuttering and incoherent, and the victim was botched - everyone was waiting for it to end.</description>
|
||||
<positivityIndex>-2</positivityIndex>
|
||||
</li>
|
||||
<li>
|
||||
<label>Boring</label>
|
||||
<chance>0.10</chance>
|
||||
<memory>BoringGangbang</memory>
|
||||
<description>The {0} was boring. The speech was repetitive and the victim was noticeably flawed. It just didn't feel dignified.</description>
|
||||
<positivityIndex>-1</positivityIndex>
|
||||
</li>
|
||||
<li>
|
||||
<label>Satisfying</label>
|
||||
<chance>0.6</chance>
|
||||
<memory>FunGangbang</memory>
|
||||
<description>The {0} was satisfying. The speech felt meaningful, and the victim was precise and dignified.</description>
|
||||
<potentialExtraOutcomeDesc>There's a 5% chance that a random participant gets an inspiration.</potentialExtraOutcomeDesc>
|
||||
<positivityIndex>1</positivityIndex>
|
||||
</li>
|
||||
<li>
|
||||
<label>Spectacular</label>
|
||||
<chance>0.25</chance>
|
||||
<memory>UnforgettableGangbang</memory>
|
||||
<description>The {0} was spectacular! The speech brought everyone to the edge of a frenzy and the victim was like succubus.</description>
|
||||
<potentialExtraOutcomeDesc>There's a 10% chance that a random participant gets an inspiration.</potentialExtraOutcomeDesc>
|
||||
<positivityIndex>2</positivityIndex>
|
||||
</li>
|
||||
</outcomeChances>
|
||||
</RitualOutcomeEffectDef>
|
||||
|
||||
<RitualOutcomeEffectDef>
|
||||
<defName>Gangbang_Consensual</defName>
|
||||
<description>Depending on ritual quality, participants will get between {MINMOOD} and {MAXMOOD} mood for {MOODDAYS} days.</description>
|
||||
<workerClass>RitualOutcomeEffectWorker_Consumable</workerClass>
|
||||
<extraPredictedOutcomeDescriptions>
|
||||
<li>If the {0} is satisfying, one of the participants might gain an inspiration.</li>
|
||||
</extraPredictedOutcomeDescriptions>
|
||||
<comps>
|
||||
<li Class="RitualOutcomeComp_RolePresentNotSubstituted">
|
||||
<roleId>initiator</roleId>
|
||||
<label>moral guide present</label>
|
||||
<qualityOffset>0.10</qualityOffset>
|
||||
</li>
|
||||
<li Class="RitualOutcomeComp_ParticipantCount">
|
||||
<label>participant count</label>
|
||||
<curve>
|
||||
<points>
|
||||
<li>(1, -0.20)</li>
|
||||
<li>(3, -0.05)</li>
|
||||
<li>(5, 0.05)</li>
|
||||
<li>(10, 0.10)</li>
|
||||
</points>
|
||||
</curve>
|
||||
</li>
|
||||
<li Class="RitualOutcomeComp_RitualTargetDefs">
|
||||
<allowAltars>true</allowAltars>
|
||||
<label>started at altar</label>
|
||||
<qualityOffset>0.2</qualityOffset>
|
||||
<expectedThingLabelTip>an altar</expectedThingLabelTip>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.RitualOutcomeComp_NeedBased">
|
||||
<label>statisfied participants</label>
|
||||
<qualityOffset>0.4</qualityOffset>
|
||||
<needDef>Sex</needDef>
|
||||
<minAvgNeed>0.7</minAvgNeed>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.RitualOutcomeComp_NeedBased">
|
||||
<label>completly statisfied participants</label>
|
||||
<qualityOffset>1.0</qualityOffset>
|
||||
<needDef>Sex</needDef>
|
||||
<minAvgNeed>0.8</minAvgNeed>
|
||||
</li>
|
||||
</comps>
|
||||
<outcomeChances>
|
||||
<li>
|
||||
|
@ -92,7 +175,6 @@
|
|||
</outcomeChances>
|
||||
</RitualOutcomeEffectDef>
|
||||
|
||||
|
||||
<RitualOutcomeEffectDef>
|
||||
<defName>BestialGangbang</defName>
|
||||
<description>Depending on ritual quality, participants will get between {MINMOOD} and {MAXMOOD} mood for {MOODDAYS} days.</description>
|
||||
|
@ -125,21 +207,21 @@
|
|||
</li>
|
||||
<li Class="RJWSexperience.Ideology.RitualOutcomeComp_HediffBased">
|
||||
<label>breedee broken</label>
|
||||
<qualityOffset>0.3</qualityOffset>
|
||||
<qualityOffset>0.45</qualityOffset>
|
||||
<hediffDef>FeelingBroken</hediffDef>
|
||||
<minSeverity>0.3</minSeverity>
|
||||
<roleId>victim</roleId>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.RitualOutcomeComp_HediffBased">
|
||||
<label>breedee extremly broken</label>
|
||||
<qualityOffset>0.3</qualityOffset>
|
||||
<qualityOffset>0.45</qualityOffset>
|
||||
<hediffDef>FeelingBroken</hediffDef>
|
||||
<minSeverity>0.5</minSeverity>
|
||||
<roleId>victim</roleId>
|
||||
</li>
|
||||
<li Class="RJWSexperience.Ideology.RitualOutcomeComp_HediffBased">
|
||||
<label>breedee completely broken</label>
|
||||
<qualityOffset>0.6</qualityOffset>
|
||||
<qualityOffset>0.8</qualityOffset>
|
||||
<hediffDef>FeelingBroken</hediffDef>
|
||||
<minSeverity>0.9</minSeverity>
|
||||
<roleId>victim</roleId>
|
||||
|
@ -179,6 +261,70 @@
|
|||
</outcomeChances>
|
||||
</RitualOutcomeEffectDef>
|
||||
|
||||
<RitualOutcomeEffectDef>
|
||||
<defName>BestialGangbang_Consensual</defName>
|
||||
<description>Depending on ritual quality, participants will get between {MINMOOD} and {MAXMOOD} mood for {MOODDAYS} days.</description>
|
||||
<workerClass>RitualOutcomeEffectWorker_Consumable</workerClass>
|
||||
<extraPredictedOutcomeDescriptions>
|
||||
<li>If the {0} is satisfying, one of the participants might gain an inspiration.</li>
|
||||
</extraPredictedOutcomeDescriptions>
|
||||
<comps>
|
||||
<li Class="RitualOutcomeComp_RolePresentNotSubstituted">
|
||||
<roleId>initiator</roleId>
|
||||
<label>moral guide present</label>
|
||||
<qualityOffset>0.10</qualityOffset>
|
||||
</li>
|
||||
<li Class="RitualOutcomeComp_ParticipantCount">
|
||||
<label>participant count</label>
|
||||
<curve>
|
||||
<points>
|
||||
<li>(1, 0.20)</li>
|
||||
<li>(3, 0.40)</li>
|
||||
<li>(5, 0.65)</li>
|
||||
<li>(10, 1.20)</li>
|
||||
</points>
|
||||
</curve>
|
||||
</li>
|
||||
<li Class="RitualOutcomeComp_RitualTargetDefs">
|
||||
<allowAltars>true</allowAltars>
|
||||
<label>started at altar</label>
|
||||
<qualityOffset>0.2</qualityOffset>
|
||||
<expectedThingLabelTip>an altar</expectedThingLabelTip>
|
||||
</li>
|
||||
</comps>
|
||||
<outcomeChances>
|
||||
<li>
|
||||
<label>Terrible</label>
|
||||
<chance>0.05</chance>
|
||||
<memory>TerribleGangbang</memory>
|
||||
<description>The {0} was terrible! The speech was stuttering and incoherent, and the victim was botched - everyone was waiting for it to end.</description>
|
||||
<positivityIndex>-2</positivityIndex>
|
||||
</li>
|
||||
<li>
|
||||
<label>Boring</label>
|
||||
<chance>0.10</chance>
|
||||
<memory>BoringGangbang</memory>
|
||||
<description>The {0} was boring. The speech was repetitive and the victim was noticeably flawed. It just didn't feel dignified.</description>
|
||||
<positivityIndex>-1</positivityIndex>
|
||||
</li>
|
||||
<li>
|
||||
<label>Satisfying</label>
|
||||
<chance>0.65</chance>
|
||||
<memory>FunGangbang</memory>
|
||||
<description>The {0} was satisfying. The speech felt meaningful, and the victim was precise and dignified.</description>
|
||||
<potentialExtraOutcomeDesc>There's a 5% chance that a random participant gets an inspiration.</potentialExtraOutcomeDesc>
|
||||
<positivityIndex>1</positivityIndex>
|
||||
</li>
|
||||
<li>
|
||||
<label>Spectacular</label>
|
||||
<chance>0.2</chance>
|
||||
<memory>UnforgettableGangbang</memory>
|
||||
<description>The {0} was spectacular! The speech brought everyone to the edge of a frenzy and the victim was like succubus.</description>
|
||||
<potentialExtraOutcomeDesc>There's a 10% chance that a random participant gets an inspiration.</potentialExtraOutcomeDesc>
|
||||
<positivityIndex>2</positivityIndex>
|
||||
</li>
|
||||
</outcomeChances>
|
||||
</RitualOutcomeEffectDef>
|
||||
|
||||
<RitualOutcomeEffectDef>
|
||||
<defName>DrugOrgy</defName>
|
||||
|
|
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 6.1 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.8 KiB |
|
@ -1,7 +1,22 @@
|
|||
Version Beta 1.0.2.0
|
||||
This update will mess your pawn's record. Use debug tools.
|
||||
- requires RimWorld 1.3.3117 or later
|
||||
- requires RJW 4.8.1 or later
|
||||
- submissive gender can be designated as comfort
|
||||
- added virgin
|
||||
- added sex history
|
||||
-
|
||||
- added virgin precept
|
||||
- added hymenoplasty(hymen restoration surgery)
|
||||
- added sex history(not applied retroactively)
|
||||
- you can change hotkey in keyboard configuration(default: none)
|
||||
- can collect cum on body
|
||||
- cum can spill out from cum buckets if over the stack count
|
||||
- fixed disabling sex record generation was not worked
|
||||
- removed lust adjustment from precepts that causing massive lust increment
|
||||
- changed gangbang condition
|
||||
- now pawns will go to the nearest cum bucket when cleaning self or masturbating
|
||||
- added consensual ganbang rituals(requires lewd meme)
|
||||
- non-consensual animal gangbang requires both rapist and zoophile memes
|
||||
- adjusted gangbang outcome values
|
||||
|
||||
Version Beta 1.0.1.11b
|
||||
- fixed erros on masturbations
|
||||
|
|