Compare commits

...

34 Commits

Author SHA1 Message Date
MrDarkside 9552bc9b33 Merge branch 'MrDarkside-main-patch-33001' into 'main'
Update 1.4/Languages/Russian/Keyed/RJW_Menstruation.xml

See merge request lutepickle/rjw_menstruation!4
2024-03-18 04:34:00 +00:00
lutepickle daeefe8218 Merge branch 'dev' 2024-03-17 16:33:09 -07:00
lutepickle e3647caf2a Build dll, change Rimworld reference in 1.4 to NuGet 2024-03-17 16:32:41 -07:00
lutepickle 9a6efaf37d Have pheromones apply in caravans 2024-03-13 10:07:25 -07:00
lutepickle cca7676bc0 Have ovulation and implant chance cache be nullable 2024-03-13 08:10:50 -07:00
lutepickle ba8801370f Have TotalFertCum account for destroyed pawns and animals 2024-03-13 08:03:02 -07:00
lutepickle c393ab45c0 Build 2024-03-11 16:48:26 -07:00
lutepickle f580d3232b Have breeder pawns boost implant chance for non-Biotech 2024-03-05 19:14:28 -08:00
lutepickle e964b2af93 Failsafe in the dialog window if a biotech pregnancy somehow gets a null mother (theoretically possible on implant error) 2024-03-05 16:01:33 -08:00
lutepickle 6e56664d41 Switch TickIntervalMinimum to being based on the named constant 2024-03-05 15:46:36 -08:00
lutepickle 4e88184f9b Add graphics to genes by Alpenglow 2024-03-05 09:06:02 -08:00
lutepickle 06ccb04a55 Clean up a bunch of unnecessary using statements 2024-03-04 18:25:44 -08:00
lutepickle 8bea56b65a Fix miscapitalization in CycleDisabledGenes.xml 2024-03-02 10:21:21 -08:00
lutepickle c6e4d81a20 Don't fertilize from destroyed pawns 2024-02-28 19:48:52 -08:00
lutepickle 1cdb12fd3a Replace some uses of Rand.Range with Utility.VariationRange 2024-02-27 21:56:59 -08:00
lutepickle 7e407a1cf9 Don't call Notify_UpdatedGenes if the gene isn't menstruation-related 2024-02-27 14:58:20 -08:00
lutepickle 32800a3499 Null check for apparel tracker in DirtyEffect 2024-02-22 22:09:12 -08:00
lutepickle ff95b8da39 It's safe and a bit quicker to unconditionally remove forced in CheckDirty 2024-02-17 15:37:14 -08:00
lutepickle 8306439576 Refactor allraces and allkinds 2024-02-16 22:03:03 -08:00
lutepickle ebb486179b Reformat RandomOvulationChance 2024-02-16 20:47:59 -08:00
lutepickle f79050483d Remove the originsize system. Nobody used it 2024-02-16 20:24:10 -08:00
lutepickle d483e22ac2 Little cleanup 2024-02-16 16:55:53 -08:00
lutepickle 7e5b2000da Mark the Conit fork of Birds & Bees as incompatible 2024-02-16 13:52:46 -08:00
lutepickle 836d3d69c8 Let CalculatedImpactChance return early to avoid unnecessarily hitting OvulationChance 2024-02-12 22:19:10 -08:00
lutepickle 50310988ca Be sure the periodic can go into anestrus if it initializes into ovulatory 2024-02-11 10:47:01 -08:00
lutepickle 82dea0f425 Always attempt to ovulate at least one egg 2024-02-11 07:30:25 -08:00
lutepickle bd39194fd1 Add Outland - Genetics' egglaying genes to the no cycle list 2024-02-11 06:43:56 -08:00
lutepickle 56b11069da Little refactor in GetBabyInfo and GetFatherInfo 2024-02-10 10:11:24 -08:00
lutepickle 02b0045fb3 Some input sanitization for the egg life span and ovulation genes 2024-02-08 21:33:39 -08:00
lutepickle fcbc19825e Move gene properties and cycle disabled genes to ModExtensions 2024-02-08 20:30:49 -08:00
lutepickle 7b00579969 Exclude Erin's Covyia egg genes from cycling 2024-02-08 16:00:13 -08:00
lutepickle cb8267bf0f Let a pawn be randomly initialized into their ovulatory stage 2024-02-04 19:49:20 -08:00
lutepickle 2dda753ab9 Be sure CheckDirty updates the stats if the old absorber had stats and the new doesn't 2024-02-04 17:07:10 -08:00
MrDarkside 56c59f441d Update 1.4/Languages/Russian/Keyed/RJW_Menstruation.xml 2022-12-27 13:50:58 +00:00
40 changed files with 413 additions and 208 deletions

Binary file not shown.

View File

@ -9,7 +9,8 @@
<GeneDef Name="Menstruation_EggLifetime" Abstract="True"> <GeneDef Name="Menstruation_EggLifetime" Abstract="True">
<displayCategory>Menstruation</displayCategory> <displayCategory>Menstruation</displayCategory>
<exclusionTags> <iconPath>UI/Genes/Placeholder</iconPath>
<exclusionTags>
<li>Menstruation_EggLifetime</li> <li>Menstruation_EggLifetime</li>
</exclusionTags> </exclusionTags>
</GeneDef> </GeneDef>
@ -18,33 +19,49 @@
<defName>Menstruation_ShortEggLifetime</defName> <defName>Menstruation_ShortEggLifetime</defName>
<label>short egg lifetime</label> <label>short egg lifetime</label>
<description>Unfertilized eggs with this gene last three-quarters as long.</description> <description>Unfertilized eggs with this gene last three-quarters as long.</description>
<iconPath>UI/Genes/Placeholder</iconPath> <iconPath>UI/Genes/ShortEggLifetime</iconPath>
<biostatMet>1</biostatMet> <biostatMet>1</biostatMet>
<displayOrderInCategory>10</displayOrderInCategory> <displayOrderInCategory>10</displayOrderInCategory>
<modExtensions>
<li Class ="RJW_Menstruation.MenstruationModExtension">
<eggLifeTimeFactor>0.75</eggLifeTimeFactor>
</li>
</modExtensions>
</GeneDef> </GeneDef>
<GeneDef ParentName="Menstruation_EggLifetime"> <GeneDef ParentName="Menstruation_EggLifetime">
<defName>Menstruation_DoubleEggLifetime</defName> <defName>Menstruation_DoubleEggLifetime</defName>
<label>double egg lifetime</label> <label>double egg lifetime</label>
<description>Unfertilized eggs with this gene last twice as long.</description> <description>Unfertilized eggs with this gene last twice as long.</description>
<iconPath>UI/Genes/Placeholder</iconPath> <iconPath>UI/Genes/DoubleEggLifetime</iconPath>
<biostatMet>-1</biostatMet> <biostatMet>-1</biostatMet>
<displayOrderInCategory>12</displayOrderInCategory> <displayOrderInCategory>12</displayOrderInCategory>
<modExtensions>
<li Class ="RJW_Menstruation.MenstruationModExtension">
<eggLifeTimeFactor>2.0</eggLifeTimeFactor>
</li>
</modExtensions>
</GeneDef> </GeneDef>
<GeneDef ParentName="Menstruation_EggLifetime"> <GeneDef ParentName="Menstruation_EggLifetime">
<defName>Menstruation_QuadEggLifetime</defName> <defName>Menstruation_QuadEggLifetime</defName>
<label>quadrule egg lifetime</label> <label>quadrule egg lifetime</label>
<description>Eggs with this gene last four times as long.</description> <description>Eggs with this gene last four times as long.</description>
<iconPath>UI/Genes/Placeholder</iconPath> <iconPath>UI/Genes/QuadEggLifetime</iconPath>
<biostatMet>-2</biostatMet> <biostatMet>-2</biostatMet>
<biostatCpx>1</biostatCpx> <biostatCpx>1</biostatCpx>
<displayOrderInCategory>16</displayOrderInCategory> <displayOrderInCategory>16</displayOrderInCategory>
<modExtensions>
<li Class ="RJW_Menstruation.MenstruationModExtension">
<eggLifeTimeFactor>4.0</eggLifeTimeFactor>
</li>
</modExtensions>
</GeneDef> </GeneDef>
<GeneDef Name="Menstruation_Estrus" Abstract="True"> <GeneDef Name="Menstruation_Estrus" Abstract="True">
<displayCategory>Menstruation</displayCategory> <displayCategory>Menstruation</displayCategory>
<exclusionTags> <iconPath>UI/Genes/Placeholder</iconPath>
<exclusionTags>
<li>Menstruation_Estrus</li> <li>Menstruation_Estrus</li>
</exclusionTags> </exclusionTags>
</GeneDef> </GeneDef>
@ -53,24 +70,35 @@
<defName>Menstruation_NeverEstrus</defName> <defName>Menstruation_NeverEstrus</defName>
<label>never estrus</label> <label>never estrus</label>
<description>Carriers of this gene will never go into estrus.</description> <description>Carriers of this gene will never go into estrus.</description>
<iconPath>UI/Genes/Placeholder</iconPath> <iconPath>UI/Genes/NeverEstrus</iconPath>
<biostatMet>1</biostatMet> <biostatMet>1</biostatMet>
<displayOrderInCategory>20</displayOrderInCategory> <displayOrderInCategory>20</displayOrderInCategory>
<modExtensions>
<li Class ="RJW_Menstruation.MenstruationModExtension">
<neverEstrus>true</neverEstrus>
</li>
</modExtensions>
</GeneDef> </GeneDef>
<GeneDef ParentName="Menstruation_Estrus"> <GeneDef ParentName="Menstruation_Estrus">
<defName>Menstruation_FullEstrus</defName> <defName>Menstruation_FullEstrus</defName>
<label>full estrus</label> <label>full estrus</label>
<description>Carriers of this gene will enter full estrus every menstrual cycle, regardless of vagina type.</description> <description>Carriers of this gene will enter full estrus every menstrual cycle, regardless of vagina type.</description>
<iconPath>UI/Genes/Placeholder</iconPath> <iconPath>UI/Genes/FullEstrus</iconPath>
<biostatMet>-1</biostatMet> <biostatMet>-1</biostatMet>
<biostatCpx>1</biostatCpx> <biostatCpx>1</biostatCpx>
<displayOrderInCategory>25</displayOrderInCategory> <displayOrderInCategory>25</displayOrderInCategory>
<modExtensions>
<li Class ="RJW_Menstruation.MenstruationModExtension">
<alwaysEstrus>true</alwaysEstrus>
</li>
</modExtensions>
</GeneDef> </GeneDef>
<GeneDef Name="Menstruation_Ovulation" Abstract="True"> <GeneDef Name="Menstruation_Ovulation" Abstract="True">
<displayCategory>Menstruation</displayCategory> <displayCategory>Menstruation</displayCategory>
<exclusionTags> <iconPath>UI/Genes/Placeholder</iconPath>
<exclusionTags>
<li>Menstruation_Ovulation</li> <li>Menstruation_Ovulation</li>
</exclusionTags> </exclusionTags>
</GeneDef> </GeneDef>
@ -79,18 +107,28 @@
<defName>Menstruation_DoubleOvulation</defName> <defName>Menstruation_DoubleOvulation</defName>
<label>double ovulation</label> <label>double ovulation</label>
<description>Carriers of this gene will ovulate twice as many eggs.</description> <description>Carriers of this gene will ovulate twice as many eggs.</description>
<iconPath>UI/Genes/Placeholder</iconPath> <iconPath>UI/Genes/DoubleOvulation</iconPath>
<biostatMet>-1</biostatMet> <biostatMet>-1</biostatMet>
<displayOrderInCategory>30</displayOrderInCategory> <displayOrderInCategory>30</displayOrderInCategory>
<modExtensions>
<li Class ="RJW_Menstruation.MenstruationModExtension">
<ovulationFactor>2</ovulationFactor>
</li>
</modExtensions>
</GeneDef> </GeneDef>
<GeneDef ParentName="Menstruation_Ovulation"> <GeneDef ParentName="Menstruation_Ovulation">
<defName>Menstruation_QuadOvulation</defName> <defName>Menstruation_QuadOvulation</defName>
<label>quadruple ovulation</label> <label>quadruple ovulation</label>
<description>Carriers of this gene will ovulate four times as many eggs.</description> <description>Carriers of this gene will ovulate four times as many eggs.</description>
<iconPath>UI/Genes/Placeholder</iconPath> <iconPath>UI/Genes/QuadOvulation</iconPath>
<biostatMet>-1</biostatMet> <biostatMet>-1</biostatMet>
<displayOrderInCategory>35</displayOrderInCategory> <displayOrderInCategory>35</displayOrderInCategory>
<modExtensions>
<li Class ="RJW_Menstruation.MenstruationModExtension">
<ovulationFactor>4</ovulationFactor>
</li>
</modExtensions>
</GeneDef> </GeneDef>
<GeneDef> <GeneDef>
@ -98,9 +136,14 @@
<label>no bleeding</label> <label>no bleeding</label>
<displayCategory>Menstruation</displayCategory> <displayCategory>Menstruation</displayCategory>
<description>Carriers of this gene will not bleed at the end of their cycle.</description> <description>Carriers of this gene will not bleed at the end of their cycle.</description>
<iconPath>UI/Genes/Placeholder</iconPath> <iconPath>UI/Genes/NoBleeding</iconPath>
<biostatMet>-1</biostatMet> <biostatMet>-1</biostatMet>
<displayOrderInCategory>40</displayOrderInCategory> <displayOrderInCategory>40</displayOrderInCategory>
<modExtensions>
<li Class ="RJW_Menstruation.MenstruationModExtension">
<noBleeding>true</noBleeding>
</li>
</modExtensions>
</GeneDef> </GeneDef>
<!-- Pheromones? --> <!-- Pheromones? -->

View File

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>
<Mod_Title>RJW обновление беремености</Mod_Title>
<Menstrual_Blood>менструальная кровь</Menstrual_Blood>
<Info_noCum>Пусто</Info_noCum>
<Stage_Follicular>фолликул</Stage_Follicular>
<Stage_Ovulatory>Овуляция</Stage_Ovulatory>
<Stage_Luteal>Лютеиновая</Stage_Luteal>
<Stage_Bleeding>В период</Stage_Bleeding>
<Stage_Pregnant>Беременная</Stage_Pregnant>
<Stage_Recover>Восстановление после рождения</Stage_Recover>
<Stage_None>Нету</Stage_None>
<Stage_Climacteric>Климакс</Stage_Climacteric>
<Stage_Menopause>Менопауза</Stage_Menopause>
<Stage_Anestrus>Анэструс</Stage_Anestrus>
<Stage_Follicular_Desc>Яичники готовятся выпустить яйцеклетку. Овуляция произойдет в конце этой фазы.</Stage_Follicular_Desc>
<Stage_Follicular_Induced_Desc>Яичники готовятся выпустить яйцеклетку. Овуляция произойдет, если сперма попадает в матку.</Stage_Follicular_Induced_Desc>
<Stage_Ovulatory_Desc>Яичники выпускают яйцеклетку в матку.</Stage_Ovulatory_Desc>
<Stage_Luteal_Desc>Матка готова принять оплодотворенную яйцеклетку. Беременность наступит, если кто-то оплодотворит до окончания этапа.</Stage_Luteal_Desc>
<Stage_Bleeding_Desc>Матка сбрасывает свою слизистую оболочку вместе с любыми яйцеклетками, которые не смогли имплантироваться.</Stage_Bleeding_Desc>
<Stage_Pregnant_Desc>Ребенок растет в утробе матери. Со временем и заботой он станет новым жителем этого мира.</Stage_Pregnant_Desc>
<Stage_Recover_Desc>Матка восстанавливается после недавней беременности.</Stage_Recover_Desc>
<Stage_None_Desc>Матка не является фертильной и не может забеременеть.</Stage_None_Desc>
<Stage_Climacteric_Desc>Яичники близки к истощению, и менструальный цикл стал нерегулярным.</Stage_Climacteric_Desc>
<Stage_Menopause_Desc>Яичники истощены, и матка больше не может производить яйцеклетки.</Stage_Menopause_Desc>
<Stage_Anestrus_Desc>У матки закончился цикл. Цикл возобновится, как только будут выполнены условия.</Stage_Anestrus_Desc>
<Button_HealthTab>Статус</Button_HealthTab>
<Button_MilkTooltip>Лактация</Button_MilkTooltip>
<Dialog_WombInfo01>Состояние</Dialog_WombInfo01>
<Dialog_WombInfo02>Зародыш</Dialog_WombInfo02>
<Dialog_WombInfo03>Отец</Dialog_WombInfo03>
<Dialog_WombInfo04>Список спермы</Dialog_WombInfo04>
<Dialog_WombInfo05>Оплодотворенная</Dialog_WombInfo05>
<Dialog_WombInfo06>оплодотворение</Dialog_WombInfo06>
<Dialog_WombInfo07>Овулирование</Dialog_WombInfo07>
<Dialog_WombInfo08></Dialog_WombInfo08>
<Dialog_WombInfo09></Dialog_WombInfo09>
<Dialog_DoCleanWomb_Tooltip>Соберите сперму в ведро</Dialog_DoCleanWomb_Tooltip>
<Dialog_DontCleanWomb_Tooltip>Хранить сперму в утробе матери</Dialog_DontCleanWomb_Tooltip>
<Dialog_FatherUnknown>Неизвестно</Dialog_FatherUnknown>
<Option1_Label_1>Включить значок матки</Option1_Label_1>
<Option1_Label_2>Кнопка включения вкладки здоровье</Option1_Label_2>
<Option2_Label>Включить животный цикл</Option2_Label>
<Option2_Desc>Имитировать циклы животных.&#10;Не рекомендуется.</Option2_Desc>
<Option3_Label>Шанс имплантации</Option3_Label>
<Option3_Desc>Базовый шанс имплантации оплодотворенной яйцеклетки&#10;Это значение влияет на вероятность оплодотворения.</Option3_Desc>
<Option4_Label>Шанс оплодотворения</Option4_Label>
<Option4_Desc>Вероятность оплодотворения на мл сперматозоидов в час&#10;Это значение влияет на вероятность оплодотворения.</Option4_Desc>
<Option5_Label>Коэффициент распада спермы в час</Option5_Label>
<Option5_Desc>Количество спермы в матке будет уменьшаться на эту величину каждый час &#10;Это значение влияет на вероятность оплодотворения.</Option5_Desc>
<Option6_Label>Коэффициент распада фертильности спермы в час</Option6_Label>
<Option6_Desc>Сперма будет терять фертильность на это количество каждый час &#10;Это значение косвенно влияет на вероятность оплодотворения.</Option6_Desc>
<Option7_Label>Ускорение цикла</Option7_Label>
<Option7_Desc>Ускорить менструальный цикл&#10;Это может привести к ранней менопаузе и бесплодию.&#10;Рекомендуется установить значение ниже x12.&#10;Временная шкала Rimworld: x6(по умолчанию)</Option7_Desc>
<Option8_Label>Debug</Option8_Label>
<Option8_Desc>Показывать отладочную информацию.&#10;Также переопределяет "Уровень информации о зародыше" для всех.</Option8_Desc>
<Option9_Label>Статус матки</Option9_Label>
<Option9_Desc>Нарисовать значок матки в окне состояния.</Option9_Desc>
<Option10_Label>Состояние влагалища и груди</Option10_Label>
<Option10_Desc>Нарисовать значки влагалища, ануса и груди в окне состояния.</Option10_Desc>
<Option11_Label>Уровень информации о плоде</Option11_Label>
<Option11_Desc_1>Показать всю информацию о плоде.</Option11_Desc_1>
<Option11_Desc_2>Показать всю информацию о плоде после обнаруженной беременности.</Option11_Desc_2>
<Option11_Desc_3>Показывать только изображение плода после обнаруженной беременности.</Option11_Desc_3>
<Option11_Desc_4>Не показывайть никакой информации о плоде.</Option11_Desc_4>
<Option12_Label>Включить менопаузу</Option12_Label>
<Option12_Desc>Включите эффект менопаузы, который делает пешку бесплодной с течением времени&#10;Если у вас есть проблемы с гонками на долгую жизнь, отключите эту опцию.</Option12_Desc>
<Option13_Label>Использовать многоплодную беременность</Option13_Label>
<Option13_Desc>Использовать многоплодную беременность вместо беременности RJW по умолчанию&#10;Отключите эту опцию, если у вас проблемы с оплодотворением&#10;Беременность RJW должна быть включена.</Option13_Desc>
<Option14_Label>Включить Разнояйцевых близнецов</Option14_Label>
<Option14_Desc>Допускать беременность от нескольких яйцеклеток одновременно.</Option14_Desc>
<Option15_Label>Включить Монозиготных близнецов</Option15_Label>
<Option15_Desc>Дайть возможность одной яйцеклетке привести к появлению нескольких идентичных потомков.</Option15_Desc>
<Option16_Label>Шанс монозиготных близнецов</Option16_Label>
<Option16_Desc>Вероятность появления идентичных близнецов.</Option16_Desc>
<Option17_Label>Макс монозиготных близнецов</Option17_Label>
<Option17_Desc>Максимальное количество идентичных братьев и сестер.</Option17_Desc>
<Option18_Label>Включить наложение яиц</Option18_Label>
<Option18_Desc>Включить наложение яйца на значок матки.</Option18_Desc>
<Option19_Label_1>Количество кровотечения</Option19_Label_1>
<Option19_Label_2>Предполагаемое общее количество кровотечения</Option19_Label_2>
<Option19_Desc>Приблизительное количество кровотечения.&#10;Нормальное количество кровотечения у человека составляет около 20 ~ 80 мл за цикл.</Option19_Desc>
<Option20_Label_1>Колонист</Option20_Label_1>
<Option20_Label_2>Пленник</Option20_Label_2>
<Option20_Label_3>Союзная фракция</Option20_Label_3>
<Option20_Label_4>Нейтральная</Option20_Label_4>
<Option20_Label_5>Вражеская Фракция</Option20_Label_5>
<Option21_Label>Помеченые пешки:</Option21_Label>
<Option21_Desc>Для этих пешек появятся штуковина и кнопка</Option21_Desc>
<Option22_Label>Использовать гибридное расширение</Option22_Label>
<Option22_Desc>Переопределяет гибридное определение RJW и RaceSupport.&#10;Доминирующее гибридное расширение определяет, чье определение используется первым. Не рекомендуется изменять это.</Option22_Desc>
<Option23_Label>Доминирующее гибридное расширение</Option23_Label>
<Option23_Label_1>Мать</Option23_Label_1>
<Option23_Label_2>Отец</Option23_Label_2>
<Option_MaxBreastIncrementFactor_Label>Рост груди во время беременности</Option_MaxBreastIncrementFactor_Label>
<Option_MaxBreastIncrementFactor_Desc>Изменить, насколько вырастет грудь беременной пешки во время беременности. Некоторые пешки будут расти больше, чем другие.</Option_MaxBreastIncrementFactor_Desc>
<Option_MaxNippleIncrementFactor_Label>Изменение сосков во время беременности</Option_MaxNippleIncrementFactor_Label>
<Option_MaxNippleIncrementFactor_Desc>Изменить, насколько сильно изменятся соски беременной пешки в процессе.</Option_MaxNippleIncrementFactor_Desc>
<Option_PermanentNippleChange_Label>Постоянное изменение сосков после беременности</Option_PermanentNippleChange_Label>
<Option_PermanentNippleChange_Desc>Приблизительно определяет, какая часть сосков беременной пешки останется измененной после окончания беременности.</Option_PermanentNippleChange_Desc>
<Option28_Label>Настройка гибридов</Option28_Label>
<Option28_Tooltip>Откройте пользовательский гибридный редактор.&#10;Это переопределит гибридные определения XML-файлов.</Option28_Tooltip>
<Option29_Label>Разрешить сжатие значка</Option29_Label>
<Option29_Desc>Значок станет меньше, если это необходимо.</Option29_Desc>
<Option30_Label>Множитель продолжительности жизни яйца</Option30_Label>
<Option30_Desc>Увеличить продолжительность жизни яйцеклетки.&#10;Все неимплантированные яйцеклетки погибнут в конце лютеиновой стадии, независимо от этого параметра.</Option30_Desc>
<Option31_Label>Включить трансформацию влагалища после рождения</Option31_Label>
<Option31_Desc>Включить постоянное растяжение влагалища после родов.&#10;Если вы используете другой мод, обрабатывающий это, отключите эту опцию.</Option31_Desc>
<Option32_Label>Сила превращения</Option32_Label>
<Option32_Desc>Установить силу превращения.</Option32_Desc>
<Option_EnableGatherCumGizmo_Label>Включить сбор спермы gizmo</Option_EnableGatherCumGizmo_Label>
<Option_EstrusOverride_Label>Течка переопределяет настройки подключения RJW</Option_EstrusOverride_Label>
<Option_EstrusOverride_Desc>Если включено, пешка с видимой течкой будет использовать эти настройки для потенциальных подключений к оплодотворению вместо настроек RJW.&#10;Все настройки по умолчанию соответствуют их аналогам RJW.</Option_EstrusOverride_Desc>
<Option_EstrusFuckability_Label>Минимальная возможность перепихнуться во время течки</Option_EstrusFuckability_Label>
<Option_EstrusAttractability_Label>Подключение минимальная привлекательность во время течки</Option_EstrusAttractability_Label>
<Option_EstrusRelationship_Label>Минимальное мнение о перепихоне во время течки</Option_EstrusRelationship_Label>
<EstimatedCumLifespan>Расчетная продолжительность жизни спермотозоидов</EstimatedCumLifespan>
<EstimatedEggLifespan>Предполагаемый срок жизни яйца</EstimatedEggLifespan>
<FertilityDesc>Вероятность имплантации оплодотворенных яйцеклеток.&#10;Вероятность оплодотворения в этот час: {0}%</FertilityDesc>
<Option_PregnancyFromBaseRJW_Label>Использовать базовый RJW pregnancy</Option_PregnancyFromBaseRJW_Label>
<Option_PregnancyFromMultiplePregnancy_Label>Использовать менструацию при многоплодной беременности</Option_PregnancyFromMultiplePregnancy_Label>
<Option_PregnancyFromBiotech_Label>Использовать систему беремености из biotech</Option_PregnancyFromBiotech_Label>
<Option_EnableDraftedIcon_Label>Показывать статус матки при призыве</Option_EnableDraftedIcon_Label>
<Option_EnableDraftedIcon_Desc>Нарисуйте значок матки для набранных пешек</Option_EnableDraftedIcon_Desc>
<Button_ResetToDefault>Вернусть всё по умолчанию</Button_ResetToDefault>
<Gizmo_GatherCum>Собрать сперму</Gizmo_GatherCum>
<FloatMenu_CleanSelf>Вагинальное мытье</FloatMenu_CleanSelf>
<CustomHybrid_List_Title>Пользовательский гибридный редактор</CustomHybrid_List_Title>
<CustomHybrid_Title>Гибриды из {0}</CustomHybrid_Title>
<CustomHybrid_Tooltip>Когда {0} скрещивается с {1}, {2} родится с вероятностью {3}.&#10;Если обе расы имеют гибридные определения друг для друга, будет использоваться определение отца.</CustomHybrid_Tooltip>
<CannotNoEggs>Никаких яиц</CannotNoEggs>
</LanguageData>

View File

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<Patch>
<Operation Class="PatchOperationFindMod">
<mods>
<li>Alpha Genes</li>
</mods>
<match Class="PatchOperationAddModExtension">
<xpath>/Defs/GeneDef[defName="AG_EggLaying"]</xpath>
<value>
<li Class="RJW_Menstruation.MenstruationModExtension">
<disableCycle>true</disableCycle>
</li>
</value>
</match>
</Operation>
<Operation Class="PatchOperationFindMod">
<mods>
<li>Vanilla Races Expanded - Saurid</li>
</mods>
<match Class="PatchOperationAddModExtension">
<xpath>/Defs/GeneDef[defName="VRESaurids_Oviparous"]</xpath>
<value>
<li Class="RJW_Menstruation.MenstruationModExtension">
<disableCycle>true</disableCycle>
</li>
</value>
</match>
</Operation>
<Operation Class="PatchOperationFindMod">
<mods>
<li>Vanilla Races Expanded - Phytokin</li>
</mods>
<match Class="PatchOperationAddModExtension">
<xpath>/Defs/GeneDef[defName="VRE_SaplingBirth"]</xpath>
<value>
<li Class="RJW_Menstruation.MenstruationModExtension">
<disableCycle>true</disableCycle>
</li>
</value>
</match>
</Operation>
<Operation Class="PatchOperationFindMod">
<mods>
<li>Erin's Corvyia</li>
</mods>
<match Class="PatchOperationAddModExtension">
<xpath>/Defs/GeneDef[defName="ERN_EggLayer"]</xpath>
<value>
<li Class="RJW_Menstruation.MenstruationModExtension">
<disableCycle>true</disableCycle>
</li>
</value>
</match>
</Operation>
<Operation Class="PatchOperationFindMod">
<mods>
<li>Outland - Genetics</li>
</mods>
<match Class="PatchOperationAddModExtension">
<xpath>/Defs/GeneDef[defName="Outland_EggLayer"]</xpath>
<value>
<li Class="RJW_Menstruation.MenstruationModExtension">
<disableCycle>true</disableCycle>
</li>
</value>
</match>
</Operation>
</Patch>

View File

@ -144,11 +144,5 @@
</li> </li>
</comps> </comps>
</value> </value>
</Operation> </Operation>
</Patch> </Patch>

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -1,5 +1,4 @@
using AlienRace; using AlienRace;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using Verse; using Verse;

View File

@ -21,7 +21,7 @@ namespace RJW_Menstruation
public const int ColonistTickIntervalDefault = GenDate.TicksPerHour; public const int ColonistTickIntervalDefault = GenDate.TicksPerHour;
public const int NonColonistTickIntervalDefault = GenDate.TicksPerHour; public const int NonColonistTickIntervalDefault = GenDate.TicksPerHour;
public const int AnimalTickIntervalDefault = GenDate.TicksPerHour; public const int AnimalTickIntervalDefault = GenDate.TicksPerHour;
public const int TickIntervalMinimum = 20; public const int TickIntervalMinimum = GenTicks.TicksPerRealSecond / 3;
public const int TickIntervalMaximum = 4 * GenDate.TicksPerHour; public const int TickIntervalMaximum = 4 * GenDate.TicksPerHour;
public const float EnzygoticTwinsChanceDefault = 0.002f; public const float EnzygoticTwinsChanceDefault = 0.002f;
public const int EnzygoticTwinsChanceAdjustDefault = 2; public const int EnzygoticTwinsChanceAdjustDefault = 2;

View File

@ -1,7 +1,6 @@
using RimWorld; using RimWorld;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
using Verse; using Verse;

View File

@ -1,5 +1,4 @@
using RimWorld; using RimWorld;
using rjw;
using System.Collections.Generic; using System.Collections.Generic;
using Verse; using Verse;

View File

@ -109,5 +109,7 @@ namespace RJW_Menstruation
if (curStage == Stage.Luteal && !hadOvulatoryStage) return false; if (curStage == Stage.Luteal && !hadOvulatoryStage) return false;
else return base.ShouldBeInEstrus(); else return base.ShouldBeInEstrus();
} }
protected override float RandomOvulationChance => 0;
} }
} }

View File

@ -123,11 +123,10 @@ namespace RJW_Menstruation
protected string customwombtex = null; protected string customwombtex = null;
protected string customvagtex = null; protected string customvagtex = null;
protected bool estrusflag = false; protected bool estrusflag = false;
protected float ovulationChanceCache = -1.0f; // Dirtied every simulation protected float? ovulationChanceCache = null; // Dirtied every simulation
protected float implantationChanceCache = -1.0f; protected float? implantationChanceCache = null;
protected int opcache = -1; protected int opcache = -1;
protected float antisperm = 0.0f; protected float antisperm = 0.0f;
protected float? originvagsize = null;
// RJW pregnancy, or Biotech pregnancy/labor/laborpushing // RJW pregnancy, or Biotech pregnancy/labor/laborpushing
protected Hediff pregnancy = null; protected Hediff pregnancy = null;
@ -179,7 +178,8 @@ namespace RJW_Menstruation
public float HoursBetweenSimulations => (float)TickInterval / GenDate.TicksPerHour; public float HoursBetweenSimulations => (float)TickInterval / GenDate.TicksPerHour;
public Hediff Pregnancy { public Hediff Pregnancy
{
get get
{ {
if (pregnancy == null) return null; if (pregnancy == null) return null;
@ -255,11 +255,11 @@ namespace RJW_Menstruation
public float TotalCum public float TotalCum
{ {
get => cums?.Sum(cum => cum.Volume) ?? 0; get => cums?.Sum(cum => cum.Volume) ?? 0;
} }
public float TotalFertCum public float TotalFertCum
{ {
get => cums?.Sum(cum => cum.FertVolume) ?? 0; get => cums?.Where(cum => CumCanFertilize(cum)).Sum(cum => cum.FertVolume) ?? 0;
} }
public float TotalCumPercent public float TotalCumPercent
{ {
@ -289,7 +289,7 @@ namespace RJW_Menstruation
private bool calculatingOvulationChance = false; private bool calculatingOvulationChance = false;
public bool CalculatingOvulationChance { get => calculatingOvulationChance; } public bool CalculatingOvulationChance { get => calculatingOvulationChance; }
protected float CalculatedOvulationChance() private float CalculatedOvulationChance()
{ {
float ovulationChance = 1.0f; float ovulationChance = 1.0f;
if (EggHealth <= 0.0f) return 0.0f; if (EggHealth <= 0.0f) return 0.0f;
@ -315,19 +315,20 @@ namespace RJW_Menstruation
return ovulationChance; return ovulationChance;
} }
protected float CalculatedImplantChance() private float CalculatedImplantChance()
{ {
if (ModsConfig.BiotechActive && xxx.is_human(Pawn)) if (ModsConfig.BiotechActive && xxx.is_human(Pawn))
{ {
// Implant factor will be based solely on pawn age, plus any rollover from ovulation chance // Implant factor will be based solely on pawn age, plus any rollover from ovulation chance
float factor = 1.0f; float factor = 1.0f;
StatDefOf.Fertility.GetStatPart<StatPart_FertilityByGenderAge>()?.TransformValue(StatRequest.For(Pawn), ref factor); StatDefOf.Fertility.GetStatPart<StatPart_FertilityByGenderAge>()?.TransformValue(StatRequest.For(Pawn), ref factor);
if (factor <= 0.0f) return 0.0f;
if (OvulationChance > 1.0f) factor *= OvulationChance; if (OvulationChance > 1.0f) factor *= OvulationChance;
return Props.baseImplantationChanceFactor * FertilityModifier * factor; return Props.baseImplantationChanceFactor * FertilityModifier * factor;
} }
else else
{ {
return Pawn.health.capacities.GetLevel(xxx.reproduction) * Props.baseImplantationChanceFactor * FertilityModifier; return Pawn.health.capacities.GetLevel(xxx.reproduction) * Props.baseImplantationChanceFactor * FertilityModifier * (Pawn.IsBreeder() ? 10.0f : 1.0f);
} }
} }
@ -335,8 +336,8 @@ namespace RJW_Menstruation
{ {
get get
{ {
if (ovulationChanceCache < 0.0f) ovulationChanceCache = CalculatedOvulationChance(); if (ovulationChanceCache == null) ovulationChanceCache = CalculatedOvulationChance();
return ovulationChanceCache; return ovulationChanceCache.Value;
} }
} }
@ -345,8 +346,8 @@ namespace RJW_Menstruation
{ {
get get
{ {
if (implantationChanceCache < 0.0f) implantationChanceCache = CalculatedImplantChance(); if (implantationChanceCache == null) implantationChanceCache = CalculatedImplantChance();
return implantationChanceCache; return implantationChanceCache.Value;
} }
} }
@ -356,7 +357,7 @@ namespace RJW_Menstruation
{ {
if (cums.NullOrEmpty()) yield return Translations.Info_noCum; if (cums.NullOrEmpty()) yield return Translations.Info_noCum;
else foreach (Cum cum in cums) else foreach (Cum cum in cums)
yield return string.Format("{0}: {1:0.##}ml", cum.notcum ? cum.notcumLabel : cum.pawn?.Label, cum.Volume); yield return string.Format("{0}: {1:0.##}ml", cum.notcum ? cum.notcumLabel : cum.pawn?.Label, cum.Volume);
} }
} }
public Color GetCumMixtureColor public Color GetCumMixtureColor
@ -563,19 +564,6 @@ namespace RJW_Menstruation
} }
} }
public float OriginVagSize
{
get
{
if (originvagsize == null)
{
originvagsize = parent.Severity;
}
return originvagsize ?? 0.1f;
}
set => originvagsize = value;
}
public int CurStageIntervalTicks public int CurStageIntervalTicks
{ {
get => currentIntervalTicks; get => currentIntervalTicks;
@ -608,7 +596,7 @@ namespace RJW_Menstruation
else if (Pawn.story?.bodyType == BodyTypeDefOf.Female) discoveryTime = 0.35f; else if (Pawn.story?.bodyType == BodyTypeDefOf.Female) discoveryTime = 0.35f;
// Estimated; there's no way to get the exact value after the fact without writing it into the save // Estimated; there's no way to get the exact value after the fact without writing it into the save
float lutealProgressWhenImplanted = Math.Min(0.5f, maxImplantDelayHours / (Props.lutealIntervalDays * GenDate.HoursPerDay)); float lutealProgressWhenImplanted = Math.Min(0.5f, maxImplantDelayHours / (Props.lutealIntervalDays * GenDate.HoursPerDay));
return GenMath.LerpDouble(0, discoveryTime, lutealProgressWhenImplanted, 1.0f, pregnancy.Severity); return GenMath.LerpDouble(0, discoveryTime, lutealProgressWhenImplanted, 1.0f, pregnancy.Severity);
} }
} }
@ -656,7 +644,6 @@ namespace RJW_Menstruation
Scribe_Values.Look(ref ovarypower, "ovarypower", ovarypower, true); Scribe_Values.Look(ref ovarypower, "ovarypower", ovarypower, true);
Scribe_Values.Look(ref eggstack, "eggstack", 0); Scribe_Values.Look(ref eggstack, "eggstack", 0);
Scribe_Values.Look(ref estrusflag, "estrusflag", false); Scribe_Values.Look(ref estrusflag, "estrusflag", false);
Scribe_Values.Look(ref originvagsize, "originvagsize", originvagsize, true);
Scribe_Values.Look(ref DoCleanWomb, "DoCleanWomb", false); Scribe_Values.Look(ref DoCleanWomb, "DoCleanWomb", false);
Scribe_References.Look(ref pregnancy, "pregnancy"); Scribe_References.Look(ref pregnancy, "pregnancy");
if (Scribe.mode == LoadSaveMode.PostLoadInit) if (Scribe.mode == LoadSaveMode.PostLoadInit)
@ -679,23 +666,18 @@ namespace RJW_Menstruation
ovulationFactor = 1f; ovulationFactor = 1f;
noBleeding = false; noBleeding = false;
opcache = -1; opcache = -1;
if (Pawn.genes == null || !ModsConfig.BiotechActive) return; if (Pawn.genes == null || !ModsConfig.BiotechActive) return;
foreach (MenstruationModExtension extension in Pawn.genes.GenesListForReading.Select(gene => gene.def.GetModExtension<MenstruationModExtension>()).Where(ext => ext != null))
foreach (GeneDef geneDef in Pawn.genes.GenesListForReading.Select(gene => gene.def))
{ {
if (geneDef == VariousDefOf.ShortEggLifetime) eggLifeSpanTicks = eggLifeSpanTicks * 3 / 4; eggLifeSpanTicks = (int)(eggLifeSpanTicks * extension.eggLifeTimeFactor);
else if (geneDef == VariousDefOf.DoubleEggLifetime) eggLifeSpanTicks *= 2; if (extension.alwaysEstrus) estrusLevel = EstrusLevel.Visible;
else if (geneDef == VariousDefOf.QuadEggLifetime) eggLifeSpanTicks *= 4; else if (extension.neverEstrus) estrusLevel = EstrusLevel.None;
ovulationFactor *= extension.ovulationFactor;
else if (geneDef == VariousDefOf.NeverEstrus) estrusLevel = EstrusLevel.None; if (extension.noBleeding) noBleeding = true;
else if (geneDef == VariousDefOf.FullEstrus) estrusLevel = EstrusLevel.Visible;
else if (geneDef == VariousDefOf.DoubleOvulation) ovulationFactor = 2f;
else if (geneDef == VariousDefOf.QuadOvulation) ovulationFactor = 4f;
else if (geneDef == VariousDefOf.NoBleeding) noBleeding = true;
} }
if (eggLifeSpanTicks < 0) eggLifeSpanTicks = 0;
if (ovulationFactor < 0f) ovulationFactor = 0f;
} }
public bool ShouldSimulate() public bool ShouldSimulate()
@ -724,7 +706,7 @@ namespace RJW_Menstruation
{ {
if (Pawn.IsHashIntervalTick(recalculateTickInterval)) TickInterval = -1; // Every so often, force TickInterval to be recalculated in case the pawn's status changed. if (Pawn.IsHashIntervalTick(recalculateTickInterval)) TickInterval = -1; // Every so often, force TickInterval to be recalculated in case the pawn's status changed.
if (!Pawn.IsHashIntervalTick(TickInterval)) return; if (!Pawn.IsHashIntervalTick(TickInterval)) return;
if (!ShouldSimulate()) return; if (!ShouldSimulate()) return;
// Initialize immediately if needed, but if there's an error, then don't spam it every tick // Initialize immediately if needed, but if there's an error, then don't spam it every tick
@ -733,7 +715,7 @@ namespace RJW_Menstruation
Log.Warning($"{Pawn}'s womb is ticking, but was not initialized first"); Log.Warning($"{Pawn}'s womb is ticking, but was not initialized first");
Initialize(); Initialize();
} }
if (initError) Log.Warning($"Attempting to process {Pawn}'s womb uninitialized"); if (initError) Log.Warning($"Attempting to process {Pawn}'s womb uninitialized");
if (Pregnancy != null && curStage != Stage.Pregnant) if (Pregnancy != null && curStage != Stage.Pregnant)
@ -743,7 +725,7 @@ namespace RJW_Menstruation
} }
BeforeSimulator(); BeforeSimulator();
if (ShouldBeInfertile()) GoNextStage(Stage.Infertile); if (ShouldBeInfertile()) GoNextStage(Stage.Infertile);
switch (curStage) switch (curStage)
{ {
@ -820,7 +802,7 @@ namespace RJW_Menstruation
tip.Append(": "); tip.Append(": ");
tip.Append(GetCurStageLabel); tip.Append(GetCurStageLabel);
string fertInfo = GetFertilizingInfo; string fertInfo = GetFertilizingInfo;
if(CurrentVisibleStage == Stage.Luteal && fertInfo.Length > 0) if (CurrentVisibleStage == Stage.Luteal && fertInfo.Length > 0)
{ {
tip.AppendLine(); tip.AppendLine();
tip.Append(fertInfo); tip.Append(fertInfo);
@ -831,7 +813,7 @@ namespace RJW_Menstruation
protected virtual int TicksToNextStage() protected virtual int TicksToNextStage()
{ {
return Math.Max(0,(currentIntervalTicks - curStageTicks) / Configurations.CycleAcceleration); return Math.Max(0, (currentIntervalTicks - curStageTicks) / Configurations.CycleAcceleration);
} }
public override string CompDebugString() public override string CompDebugString()
@ -1176,7 +1158,7 @@ namespace RJW_Menstruation
if (cycleSpeed < 0f) cycleSpeed = Utility.RandGaussianLike(0.8f, 1.2f); if (cycleSpeed < 0f) cycleSpeed = Utility.RandGaussianLike(0.8f, 1.2f);
if (cycleVariability < 0f) cycleVariability = MenstruationUtility.RandomVariabilityPercent(); if (cycleVariability < 0f) cycleVariability = MenstruationUtility.RandomVariabilityPercent();
InitOvary(); InitOvary();
if (currentIntervalTicks < 0) if (currentIntervalTicks < 0)
@ -1284,8 +1266,8 @@ namespace RJW_Menstruation
protected virtual void BeforeSimulator() protected virtual void BeforeSimulator()
{ {
ovulationChanceCache = -1.0f; ovulationChanceCache = null;
implantationChanceCache = -1.0f; implantationChanceCache = null;
CumOut(); CumOut();
} }
@ -1353,10 +1335,18 @@ namespace RJW_Menstruation
} }
} }
public bool CumCanFertilize(Cum cum)
{
return !cum.notcum &&
cum.FertVolume > 0 &&
!(cum.pawn?.Destroyed ?? true) &&
(RJWPregnancySettings.bestial_pregnancy_enabled || xxx.is_animal(Pawn) == xxx.is_animal(cum.pawn));
}
protected Pawn Fertilize() protected Pawn Fertilize()
{ {
if (cums.NullOrEmpty()) return null; if (cums.NullOrEmpty()) return null;
List<Cum> eligibleCum = cums.FindAll(cum => !cum.notcum && cum.FertVolume > 0 && cum.pawn != null && (RJWPregnancySettings.bestial_pregnancy_enabled || xxx.is_animal(Pawn) == xxx.is_animal(cum.pawn))); List<Cum> eligibleCum = cums.FindAll(cum => CumCanFertilize(cum));
if (eligibleCum.Count == 0) return null; if (eligibleCum.Count == 0) return null;
float totalFertPower = eligibleCum.Sum(cum => cum.FertVolume); float totalFertPower = eligibleCum.Sum(cum => cum.FertVolume);
@ -1364,7 +1354,7 @@ namespace RJW_Menstruation
//float fertFailChancePerHour = Mathf.Pow(1.0f - Configurations.FertilizeChance, totalFertPower * Props.basefertilizationChanceFactor); //float fertFailChancePerHour = Mathf.Pow(1.0f - Configurations.FertilizeChance, totalFertPower * Props.basefertilizationChanceFactor);
//float fertFailChancePerInterval = Mathf.Pow(fertFailChancePerHour, (float)TickInterval / GenDate.TicksPerHour); //float fertFailChancePerInterval = Mathf.Pow(fertFailChancePerHour, (float)TickInterval / GenDate.TicksPerHour);
float fertFailChancePerInterval = Mathf.Pow(1.0f - Configurations.FertilizeChance, totalFertPower * Props.basefertilizationChanceFactor * HoursBetweenSimulations); float fertFailChancePerInterval = Mathf.Pow(1.0f - Configurations.FertilizeChance, totalFertPower * Props.basefertilizationChanceFactor * HoursBetweenSimulations);
if (Rand.Chance(fertFailChancePerInterval)) return null; if (Rand.Chance(fertFailChancePerInterval)) return null;
Pawn.records.AddTo(VariousDefOf.AmountofFertilizedEggs, 1); Pawn.records.AddTo(VariousDefOf.AmountofFertilizedEggs, 1);
@ -1494,7 +1484,7 @@ namespace RJW_Menstruation
float interspeciesFactor = InterspeciesImplantFactor(egg.fertilizer); float interspeciesFactor = InterspeciesImplantFactor(egg.fertilizer);
float implantChance = Configurations.ImplantationChance * ImplantChance * interspeciesFactor; float implantChance = Configurations.ImplantationChance * ImplantChance * interspeciesFactor;
Log.Message($"Fertilized egg of {Pawn} failed to implant (chance {implantChance.ToStringPercent()}, " + Log.Message($"Fertilized egg of {Pawn} failed to implant (chance {implantChance.ToStringPercent()}, " +
(interspeciesFactor < 1.0f ? $"interspecies factor {interspeciesFactor.ToStringPercent()}, " : "" ) + (interspeciesFactor < 1.0f ? $"interspecies factor {interspeciesFactor.ToStringPercent()}, " : "") +
$"father {egg.fertilizer})"); $"father {egg.fertilizer})");
} }
deadeggs.Add(egg); deadeggs.Add(egg);
@ -1525,7 +1515,7 @@ namespace RJW_Menstruation
protected void BleedOut() protected void BleedOut()
{ {
// ~1.5 per hour times acceleration // ~1.5 per hour times acceleration
float bledAmount = 0.03f * Configurations.BleedingAmount * Configurations.CycleAcceleration * Rand.Range(0.5f, 1.5f) * HoursBetweenSimulations; float bledAmount = Utility.VariationRange(0.03f * Configurations.BleedingAmount * Configurations.CycleAcceleration * HoursBetweenSimulations, 0.5f);
CumIn(Pawn, bledAmount, Translations.Menstrual_Blood, -5.0f, Pawn.RaceProps?.BloodDef ?? ThingDefOf.Filth_Blood); CumIn(Pawn, bledAmount, Translations.Menstrual_Blood, -5.0f, Pawn.RaceProps?.BloodDef ?? ThingDefOf.Filth_Blood);
Cum blood = GetNotCum(Translations.Menstrual_Blood); Cum blood = GetNotCum(Translations.Menstrual_Blood);
if (blood != null) blood.Color = BloodColor; if (blood != null) blood.Color = BloodColor;
@ -1580,9 +1570,6 @@ namespace RJW_Menstruation
return amount; return amount;
} }
protected void EggDecay() protected void EggDecay()
{ {
HashSet<Egg> deadeggs = new HashSet<Egg>(); HashSet<Egg> deadeggs = new HashSet<Egg>();
@ -1602,7 +1589,7 @@ namespace RJW_Menstruation
protected void AddCrampPain() protected void AddCrampPain()
{ {
Hediff hediff = HediffMaker.MakeHediff(VariousDefOf.Hediff_MenstrualCramp, Pawn); Hediff hediff = HediffMaker.MakeHediff(VariousDefOf.Hediff_MenstrualCramp, Pawn);
hediff.Severity = crampPain * Rand.Range(0.9f, 1.1f); hediff.Severity = Utility.VariationRange(crampPain, 0.1f);
HediffCompProperties_SeverityPerDay Prop = (HediffCompProperties_SeverityPerDay)hediff.TryGetComp<HediffComp_SeverityPerDay>().props; HediffCompProperties_SeverityPerDay Prop = (HediffCompProperties_SeverityPerDay)hediff.TryGetComp<HediffComp_SeverityPerDay>().props;
Prop.severityPerDay = -hediff.Severity / (currentIntervalTicks / GenDate.TicksPerDay) * Configurations.CycleAcceleration; Prop.severityPerDay = -hediff.Severity / (currentIntervalTicks / GenDate.TicksPerDay) * Configurations.CycleAcceleration;
Pawn.health.AddHediff(hediff, parent.Part); Pawn.health.AddHediff(hediff, parent.Part);
@ -1659,7 +1646,7 @@ namespace RJW_Menstruation
eggnum = 1f; eggnum = 1f;
} }
eggnum *= ovulationFactor; eggnum *= ovulationFactor;
int toOvulate = (int)eggnum + eggstack; int toOvulate = Math.Max(1, (int)eggnum + eggstack);
int ovulated = 0; int ovulated = 0;
for (int i = 0; i < toOvulate; i++) for (int i = 0; i < toOvulate; i++)
@ -1670,7 +1657,7 @@ namespace RJW_Menstruation
} }
ovarypower -= ovulated; ovarypower -= ovulated;
eggstack = 0; eggstack = 0;
if (Configurations.Debug && ovulated != toOvulate) if (Configurations.Debug && ovulated < toOvulate)
Log.Message($"{Pawn} ovulated {ovulated}/{toOvulate} eggs ({OvulationChance.ToStringPercent()} chance)"); Log.Message($"{Pawn} ovulated {ovulated}/{toOvulate} eggs ({OvulationChance.ToStringPercent()} chance)");
GoNextStage(Stage.Luteal); GoNextStage(Stage.Luteal);
@ -1817,10 +1804,10 @@ namespace RJW_Menstruation
} }
else pawnMemories.TryGainMemory(VariousDefOf.CameInsideFFetish, cummer); else pawnMemories.TryGainMemory(VariousDefOf.CameInsideFFetish, cummer);
} }
else if (Pawn.relations.OpinionOf(cummer) <= -5) else if (Pawn.relations.OpinionOf(cummer) <= -5)
pawnMemories.TryGainMemory(VariousDefOf.HaterCameInsideF, cummer); pawnMemories.TryGainMemory(VariousDefOf.HaterCameInsideF, cummer);
else if (Pawn.IsInEstrus() && Pawn.relations.OpinionOf(cummer) < RJWHookupSettings.MinimumRelationshipToHookup) else if (Pawn.IsInEstrus() && Pawn.relations.OpinionOf(cummer) < RJWHookupSettings.MinimumRelationshipToHookup)
pawnMemories.TryGainMemory(VariousDefOf.HaterCameInsideFEstrus, cummer); pawnMemories.TryGainMemory(VariousDefOf.HaterCameInsideFEstrus, cummer);
else if (!Pawn.relations.DirectRelationExists(PawnRelationDefOf.Spouse, cummer) && !Pawn.relations.DirectRelationExists(PawnRelationDefOf.Fiance, cummer)) else if (!Pawn.relations.DirectRelationExists(PawnRelationDefOf.Spouse, cummer) && !Pawn.relations.DirectRelationExists(PawnRelationDefOf.Fiance, cummer))
{ {
if (Pawn.health.capacities.GetLevel(xxx.reproduction) < 0.50f) pawnMemories.TryGainMemory(VariousDefOf.CameInsideFLowFert, cummer); if (Pawn.health.capacities.GetLevel(xxx.reproduction) < 0.50f) pawnMemories.TryGainMemory(VariousDefOf.CameInsideFLowFert, cummer);
@ -1881,15 +1868,15 @@ namespace RJW_Menstruation
switch (stage) switch (stage)
{ {
case Stage.Follicular: case Stage.Follicular:
return (int)(Props.follicularIntervalDays * GenDate.TicksPerDay * (1 + Rand.Range(-cycleVariability, cycleVariability) * 1.5f * variabilityFactor) / (1 + (cycleSpeed - 1) * 1.5f)); return (int)(Utility.VariationRange(Props.follicularIntervalDays * GenDate.TicksPerDay, cycleVariability * 1.5f * variabilityFactor) / (1 + (cycleSpeed - 1) * 1.5f));
case Stage.Ovulatory: case Stage.Ovulatory:
return Props.ovulationIntervalHours * GenDate.TicksPerHour; // No variability for now return Props.ovulationIntervalHours * GenDate.TicksPerHour; // No variability for now
case Stage.Luteal: case Stage.Luteal:
return (int)(Props.lutealIntervalDays * GenDate.TicksPerDay * (1 + Rand.Range(-cycleVariability, cycleVariability) * 0.5f * variabilityFactor) / (1 + (cycleSpeed - 1) * 0.5f)); return (int)(Utility.VariationRange(Props.lutealIntervalDays * GenDate.TicksPerDay, cycleVariability * 0.5f * variabilityFactor) / (1 + (cycleSpeed - 1) * 0.5f));
case Stage.Bleeding: case Stage.Bleeding:
return (int)(Props.bleedingIntervalDays * GenDate.TicksPerDay * (1 + Rand.Range(-cycleVariability, cycleVariability) * 0.5f * variabilityFactor) / (1 + (cycleSpeed - 1) * 0.5f)); return (int)(Utility.VariationRange(Props.bleedingIntervalDays * GenDate.TicksPerDay, cycleVariability * 0.5f * variabilityFactor) / (1 + (cycleSpeed - 1) * 0.5f));
case Stage.Recover: case Stage.Recover:
return (int)(Props.recoveryIntervalDays * GenDate.TicksPerDay * Rand.Range(0.95f, 1.05f)); return (int)Utility.VariationRange(Props.recoveryIntervalDays * GenDate.TicksPerDay, 0.05f);
case Stage.Pregnant: case Stage.Pregnant:
return (int)(MenstruationUtility.GestationHours(pregnancy) * GenDate.TicksPerHour); return (int)(MenstruationUtility.GestationHours(pregnancy) * GenDate.TicksPerHour);
default: default:
@ -1917,10 +1904,13 @@ namespace RJW_Menstruation
else return Rand.Range(0.6f, 1.0f); else return Rand.Range(0.6f, 1.0f);
} }
protected virtual float RandomOvulationChance => (float)Props.ovulationIntervalHours / GenDate.HoursPerDay;
protected Stage RandomStage() protected Stage RandomStage()
{ {
Stage stage = Rand.ElementByWeight( Stage stage = Rand.ElementByWeight(
Stage.Follicular, Props.follicularIntervalDays - Props.bleedingIntervalDays, Stage.Follicular, Props.follicularIntervalDays - Props.bleedingIntervalDays,
Stage.Ovulatory, RandomOvulationChance,
Stage.Luteal, Props.lutealIntervalDays, Stage.Luteal, Props.lutealIntervalDays,
Stage.Bleeding, Props.bleedingIntervalDays); Stage.Bleeding, Props.bleedingIntervalDays);
@ -1929,6 +1919,9 @@ namespace RJW_Menstruation
case Stage.Follicular: case Stage.Follicular:
curStageTicks = Rand.Range(0, (Props.follicularIntervalDays - Props.bleedingIntervalDays) * GenDate.TicksPerDay); curStageTicks = Rand.Range(0, (Props.follicularIntervalDays - Props.bleedingIntervalDays) * GenDate.TicksPerDay);
break; break;
case Stage.Ovulatory:
curStageTicks = Rand.Range(0, Props.ovulationIntervalHours * GenDate.TicksPerHour);
break;
case Stage.Luteal: case Stage.Luteal:
curStageTicks = Rand.Range(0, Props.lutealIntervalDays * GenDate.TicksPerDay); curStageTicks = Rand.Range(0, Props.lutealIntervalDays * GenDate.TicksPerDay);
break; break;
@ -2029,28 +2022,6 @@ namespace RJW_Menstruation
public class HediffComp_Anus : HediffComp public class HediffComp_Anus : HediffComp
{ {
protected float? originanussize; public CompProperties_Anus Props => (CompProperties_Anus)props;
public float OriginAnusSize
{
get
{
if (originanussize == null)
{
originanussize = parent.Severity;
}
return originanussize ?? 0.1f;
}
}
public override void CompExposeData()
{
base.CompExposeData();
Scribe_Values.Look(ref originanussize, "originanussize", originanussize, true);
}
public override void CompPostTick(ref float severityAdjustment)
{
}
} }
} }

View File

@ -1,5 +1,4 @@
using RimWorld; using RimWorld;
using System.Linq;
using Verse; using Verse;
namespace RJW_Menstruation namespace RJW_Menstruation
@ -29,14 +28,14 @@ namespace RJW_Menstruation
protected override void InitializeExtraValues() protected override void InitializeExtraValues()
{ {
base.InitializeExtraValues(); base.InitializeExtraValues();
if (averageCycleIntervalTicks < 0) if (averageCycleIntervalTicks < 0)
{ {
averageCycleIntervalTicks = (int)(Props.cycleIntervalDays.RandomInRange * GenDate.TicksPerDay / cycleSpeed); averageCycleIntervalTicks = (int)(Props.cycleIntervalDays.RandomInRange * GenDate.TicksPerDay / cycleSpeed);
if (ticksToNextCycle < -50000) if (ticksToNextCycle < -50000)
ticksToNextCycle = Rand.Range(0, averageCycleIntervalTicks); ticksToNextCycle = Rand.Range(0, averageCycleIntervalTicks);
// Make the cutoff halfway into cycle, just to be sure there isn't a double-cycle the first time // Make the cutoff halfway into cycle, just to be sure there isn't a double-cycle the first time
if ((curStage == Stage.Follicular || curStage == Stage.Luteal || curStage == Stage.Bleeding) if ((curStage == Stage.Follicular || curStage == Stage.Ovulatory || curStage == Stage.Luteal || curStage == Stage.Bleeding)
&& (averageCycleIntervalTicks - ticksToNextCycle) / 2 >= GenDate.TicksPerDay * (Props.follicularIntervalDays + Props.lutealIntervalDays) / cycleSpeed) && (averageCycleIntervalTicks - ticksToNextCycle) / 2 >= GenDate.TicksPerDay * (Props.follicularIntervalDays + Props.lutealIntervalDays) / cycleSpeed)
GoNextStage(Stage.Anestrus); GoNextStage(Stage.Anestrus);
} }
@ -99,14 +98,14 @@ namespace RJW_Menstruation
base.PregnantAction(); base.PregnantAction();
if (curStage != Stage.Pregnant) if (curStage != Stage.Pregnant)
// Go halfway into the cycle // Go halfway into the cycle
ticksToNextCycle = (int)(averageCycleIntervalTicks * (1 + Rand.Range(-cycleVariability, cycleVariability))) / 2; ticksToNextCycle = (int)Utility.VariationRange(averageCycleIntervalTicks, cycleVariability) / 2;
} }
protected override void AnestrusAction() protected override void AnestrusAction()
{ {
if (ticksToNextCycle <= 0 && IsBreedingSeason()) if (ticksToNextCycle <= 0 && IsBreedingSeason())
{ {
ticksToNextCycle = (int)(averageCycleIntervalTicks * (1 + Rand.Range(-cycleVariability, cycleVariability))); ticksToNextCycle = (int)Utility.VariationRange(averageCycleIntervalTicks, cycleVariability);
GoNextStage(Stage.Follicular); GoNextStage(Stage.Follicular);
} }
} }

View File

@ -1,6 +1,7 @@
 
using RimWorld; using RimWorld;
using RimWorld.Planet;
using rjw; using rjw;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -46,6 +47,8 @@ namespace RJW_Menstruation
protected IEnumerable<Pawn> AffectedPawns() protected IEnumerable<Pawn> AffectedPawns()
{ {
if(Pawn.GetCaravan() is Caravan caravan)
foreach (Pawn p in caravan.PawnsListForReading.Where(p => p != Pawn)) yield return p;
Map mapHeld = Pawn.MapHeld; Map mapHeld = Pawn.MapHeld;
if (mapHeld == null) yield break; if (mapHeld == null) yield break;
foreach (Pawn pawn in mapHeld.mapPawns.AllPawnsSpawned) foreach (Pawn pawn in mapHeld.mapPawns.AllPawnsSpawned)

View File

@ -1,5 +1,4 @@
using HarmonyLib; using HarmonyLib;
using Mono.Cecil.Cil;
using RimWorld; using RimWorld;
using rjw; using rjw;
using System; using System;
@ -203,7 +202,7 @@ namespace RJW_Menstruation
if (comp?.HasBaby ?? false) if (comp?.HasBaby ?? false)
{ {
OutcomeChance thisOutcome = outcome; OutcomeChance thisOutcome = outcome;
Precept_Ritual precept_Ritual = (Precept_Ritual)comp.Pawn.Ideo.GetPrecept(PreceptDefOf.ChildBirth); Precept_Ritual precept_Ritual = (Precept_Ritual)comp.Pawn.Ideo.GetPrecept(RimWorld.PreceptDefOf.ChildBirth);
float birthQuality = PregnancyUtility.GetBirthQualityFor(mother); float birthQuality = PregnancyUtility.GetBirthQualityFor(mother);
do do
{ {

View File

@ -1,14 +1,10 @@
using RimWorld; using RimWorld;
using RimWorld.Planet;
using rjw; using rjw;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.Linq; using System.Linq;
using System.Text;
using UnityEngine; using UnityEngine;
using Verse; using Verse;
using Verse.AI;
namespace RJW_Menstruation namespace RJW_Menstruation
{ {
@ -141,7 +137,7 @@ namespace RJW_Menstruation
else if (gestationProgress < 0.8f) icon = fetustex + "04"; else if (gestationProgress < 0.8f) icon = fetustex + "04";
else icon = fetustex + "05"; else icon = fetustex + "05";
return TryGetTwinsIcon(icon, babycount) ?? ContentFinder<Texture2D>.Get((icon), true); return TryGetTwinsIcon(icon, babycount) ?? ContentFinder<Texture2D>.Get(icon, true);
} }
public static Texture2D TryGetTwinsIcon(string path, int babycount) public static Texture2D TryGetTwinsIcon(string path, int babycount)
@ -160,7 +156,7 @@ namespace RJW_Menstruation
List<Hediff_InsectEgg> insectEggs = new List<Hediff_InsectEgg>(); List<Hediff_InsectEgg> insectEggs = new List<Hediff_InsectEgg>();
comp.Pawn.health.hediffSet.GetHediffs(ref insectEggs); comp.Pawn.health.hediffSet.GetHediffs(ref insectEggs);
if (!insectEggs.NullOrEmpty() && insectEggs.Sum(hediff => hediff.eggssize) > 1.0f) return null; // same logic as "Stuffed" in GetInsectEggedIcon if (insectEggs?.Sum(hediff => hediff.eggssize) > 1.0f) return null; // same logic as "Stuffed" in GetInsectEggedIcon
string icon = comp.WombTex; string icon = comp.WombTex;
float cumpercent = comp.TotalCumPercent; float cumpercent = comp.TotalCumPercent;
@ -183,7 +179,7 @@ namespace RJW_Menstruation
else if (cumpercent < 0.89f) icon += "_Cum_15"; else if (cumpercent < 0.89f) icon += "_Cum_15";
else if (cumpercent < 0.95f) icon += "_Cum_16"; else if (cumpercent < 0.95f) icon += "_Cum_16";
else icon += "_Cum_17"; else icon += "_Cum_17";
Texture2D cumtex = ContentFinder<Texture2D>.Get((icon), true); Texture2D cumtex = ContentFinder<Texture2D>.Get(icon, true);
return cumtex; return cumtex;
} }
public static Texture2D GetInsectEggedIcon(this HediffComp_Menstruation comp) public static Texture2D GetInsectEggedIcon(this HediffComp_Menstruation comp)
@ -306,15 +302,13 @@ namespace RJW_Menstruation
} }
public static Texture2D GetGenitalIcon(this Pawn pawn, HediffComp_Menstruation comp, bool drawOrigin = false) public static Texture2D GetGenitalIcon(this Pawn pawn, HediffComp_Menstruation comp)
{ {
Hediff hediff = comp?.parent; Hediff hediff = comp?.parent;
if (hediff == null) return ContentFinder<Texture2D>.Get("Genitals/Vagina00", true); if (hediff == null) return ContentFinder<Texture2D>.Get("Genitals/Vagina00", true);
//HediffComp_Menstruation comp = hediff.GetMenstruationComp(); //HediffComp_Menstruation comp = hediff.GetMenstruationComp();
string icon; string icon;
float severity; float severity = hediff.Severity;
if (drawOrigin) severity = comp.OriginVagSize;
else severity = hediff.Severity;
if (comp != null) icon = comp.VagTex; if (comp != null) icon = comp.VagTex;
else icon = "Genitals/Vagina"; else icon = "Genitals/Vagina";
@ -331,30 +325,18 @@ namespace RJW_Menstruation
else if (severity < 1.01f) icon += "10"; //cavernous else if (severity < 1.01f) icon += "10"; //cavernous
else icon += "11"; //abyssal else icon += "11"; //abyssal
return ContentFinder<Texture2D>.Get((icon), true); return ContentFinder<Texture2D>.Get(icon, true);
} }
public static Texture2D GetAnalIcon(this Pawn pawn, bool drawOrigin = false) public static Texture2D GetAnalIcon(this Pawn pawn)
{ {
Hediff hediff = pawn.health.hediffSet.hediffs.FirstOrDefault(h => VariousDefOf.AllAnuses.Contains(h.def)) ?? Hediff hediff = pawn.health.hediffSet.hediffs.FirstOrDefault(h => VariousDefOf.AllAnuses.Contains(h.def)) ??
pawn.health.hediffSet.hediffs.FirstOrDefault(h => h.def.defName.ToLower().Contains("anus")); pawn.health.hediffSet.hediffs.FirstOrDefault(h => h.def.defName.ToLower().Contains("anus"));
if (hediff == null) return ContentFinder<Texture2D>.Get(("Genitals/Anal00"), true); if (hediff == null) return ContentFinder<Texture2D>.Get("Genitals/Anal00", true);
string icon = ((CompProperties_Anus)hediff.GetAnusComp()?.props)?.analTex ?? "Genitals/Anal";
float severity = hediff.Severity;
string icon;
float severity;
HediffComp_Anus comp = hediff.GetAnusComp();
if (comp != null)
{
CompProperties_Anus Props = (CompProperties_Anus)comp.props;
icon = Props.analTex ?? "Genitals/Anal";
if (drawOrigin) severity = comp.OriginAnusSize;
else severity = hediff.Severity;
}
else
{
icon = "Genitals/Anal";
severity = hediff.Severity;
}
if (severity < 0.20f) icon += "00"; //micro if (severity < 0.20f) icon += "00"; //micro
else if (severity < 0.40f) icon += "01"; //tight else if (severity < 0.40f) icon += "01"; //tight
else if (severity < 0.60f) icon += "02"; //average else if (severity < 0.60f) icon += "02"; //average
@ -362,7 +344,7 @@ namespace RJW_Menstruation
else if (severity < 1.01f) icon += "04"; //cavernous else if (severity < 1.01f) icon += "04"; //cavernous
else icon += "05"; //abyssal else icon += "05"; //abyssal
return ContentFinder<Texture2D>.Get((icon), true); return ContentFinder<Texture2D>.Get(icon, true);
} }
public static float GestationHours(this Hediff hediff) public static float GestationHours(this Hediff hediff)
@ -398,7 +380,8 @@ namespace RJW_Menstruation
if (!Configurations.EnableAnimalCycle && pawn.IsAnimal()) return false; if (!Configurations.EnableAnimalCycle && pawn.IsAnimal()) return false;
if (pawn.GetComp<CompEggLayer>() != null) return false; if (pawn.GetComp<CompEggLayer>() != null) return false;
if (pawn.RaceHasOviPregnancy()) return false; if (pawn.RaceHasOviPregnancy()) return false;
if (ModsConfig.BiotechActive && pawn.genes != null &&
if (ModsConfig.BiotechActive && pawn.genes != null &&
pawn.genes.GenesListForReading.Select(gene => gene.def).Intersect(VariousDefOf.EggLayerGenes).Any()) return false; pawn.genes.GenesListForReading.Select(gene => gene.def).Intersect(VariousDefOf.EggLayerGenes).Any()) return false;
return true; return true;
@ -452,7 +435,7 @@ namespace RJW_Menstruation
if (precept != null) return true; if (precept != null) return true;
else return pawn.IsBreeder() || else return pawn.IsBreeder() ||
pawn.HasImpregnationFetish(); pawn.HasImpregnationFetish();
} }
public static float DamagePants(this Pawn pawn, float fluidAmount) public static float DamagePants(this Pawn pawn, float fluidAmount)

View File

@ -1,5 +1,4 @@
using RimWorld; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using Verse; using Verse;

View File

@ -1,10 +1,7 @@
using RimWorld; using RimWorld;
using rjw; using rjw;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Text;
using Verse; using Verse;
namespace RJW_Menstruation namespace RJW_Menstruation

View File

@ -0,0 +1,15 @@
using Verse;
namespace RJW_Menstruation
{
public class MenstruationModExtension : DefModExtension
{
public float eggLifeTimeFactor = 1.0f;
public bool neverEstrus = false;
public bool alwaysEstrus = false;
public float ovulationFactor = 1.0f;
public bool noBleeding = false;
public bool disableCycle = false;
}
}

View File

@ -1,11 +1,11 @@
using HarmonyLib; using HarmonyLib;
using System.Linq;
using RimWorld; using RimWorld;
using Verse;
using System.Collections.Generic;
using System.Reflection;
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit; using System.Reflection.Emit;
using Verse;
namespace RJW_Menstruation namespace RJW_Menstruation
{ {
@ -195,8 +195,9 @@ namespace RJW_Menstruation
[HarmonyPatch(typeof(Pawn_GeneTracker), "Notify_GenesChanged")] [HarmonyPatch(typeof(Pawn_GeneTracker), "Notify_GenesChanged")]
public class Notify_GenesChanged_Patch public class Notify_GenesChanged_Patch
{ {
public static void Postfix(Pawn_GeneTracker __instance) public static void Postfix(Pawn_GeneTracker __instance, GeneDef addedOrRemovedGene)
{ {
if (!addedOrRemovedGene.HasModExtension<MenstruationModExtension>()) return;
foreach (HediffComp_Menstruation comp in __instance.pawn.GetMenstruationComps()) foreach (HediffComp_Menstruation comp in __instance.pawn.GetMenstruationComps())
comp.Notify_UpdatedGenes(); comp.Notify_UpdatedGenes();
} }

View File

@ -2,7 +2,6 @@
using RimWorld; using RimWorld;
using rjw; using rjw;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
using Verse; using Verse;

View File

@ -1,5 +1,4 @@
using AlienRace; using HarmonyLib;
using HarmonyLib;
using rjw; using rjw;
using rjw.Modules.Interactions.Internals.Implementation; using rjw.Modules.Interactions.Internals.Implementation;
using rjw.Modules.Interactions.Rules.PartKindUsageRules; using rjw.Modules.Interactions.Rules.PartKindUsageRules;

View File

@ -1,6 +1,5 @@
using HarmonyLib; using HarmonyLib;
using RimWorld; using RimWorld;
using rjw;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;

View File

@ -20,9 +20,8 @@ namespace RJW_Menstruation
StringBuilder res = new StringBuilder(); StringBuilder res = new StringBuilder();
IEnumerable<Pawn> babiesdistinct = babies.Distinct(new RaceComparer());
int iteration = 0; int iteration = 0;
foreach (Pawn baby in babiesdistinct) foreach (Pawn baby in babies.Distinct(new RaceComparer()))
{ {
int num = babies.Where(x => x.def.Equals(baby.def)).Count(); int num = babies.Where(x => x.def.Equals(baby.def)).Count();
if (iteration > 0) res.Append(", "); if (iteration > 0) res.Append(", ");
@ -43,9 +42,8 @@ namespace RJW_Menstruation
if (!is_parent_known && Configurations.InfoDetail != Configurations.DetailLevel.All) if (!is_parent_known && Configurations.InfoDetail != Configurations.DetailLevel.All)
return res.Append(Translations.Dialog_FatherUnknown).ToString(); return res.Append(Translations.Dialog_FatherUnknown).ToString();
IEnumerable<Pawn> babiesdistinct = babies.Distinct(new FatherComparer(mother));
int iteration = 0; int iteration = 0;
foreach (Pawn baby in babiesdistinct) foreach (Pawn baby in babies.Distinct(new FatherComparer(mother)))
{ {
if (iteration > 0) res.Append(", "); if (iteration > 0) res.Append(", ");
res.Append(Utility.GetFather(baby, mother)?.LabelShort ?? Translations.Dialog_FatherUnknown); res.Append(Utility.GetFather(baby, mother)?.LabelShort ?? Translations.Dialog_FatherUnknown);

View File

@ -74,6 +74,7 @@
<Compile Include="HediffComps\MenstruationUtility.cs" /> <Compile Include="HediffComps\MenstruationUtility.cs" />
<Compile Include="Hediff_Estrus.cs" /> <Compile Include="Hediff_Estrus.cs" />
<Compile Include="IngestionOutcomeDoers.cs" /> <Compile Include="IngestionOutcomeDoers.cs" />
<Compile Include="MenstruationModExtension.cs" />
<Compile Include="Patch\Biotech_Patch.cs" /> <Compile Include="Patch\Biotech_Patch.cs" />
<Compile Include="Patch\GC_Patch.cs" /> <Compile Include="Patch\GC_Patch.cs" />
<Compile Include="Patch\Gizmo_Patch.cs" /> <Compile Include="Patch\Gizmo_Patch.cs" />
@ -108,10 +109,6 @@
<HintPath>..\..\..\..\..\..\..\..\workshop\content\294100\2830943477\1.4\Assemblies\AnimalGenetics.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\workshop\content\294100\2830943477\1.4\Assemblies\AnimalGenetics.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="Assembly-CSharp">
<HintPath>..\..\..\..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="RJW"> <Reference Include="RJW">
<HintPath>..\..\..\..\..\rjw\1.4\Assemblies\RJW.dll</HintPath> <HintPath>..\..\..\..\..\rjw\1.4\Assemblies\RJW.dll</HintPath>
<Private>False</Private> <Private>False</Private>
@ -172,6 +169,9 @@
</BootstrapperPackage> </BootstrapperPackage>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Krafs.Rimworld.Ref">
<Version>1.4.3901</Version>
</PackageReference>
<PackageReference Include="Lib.Harmony"> <PackageReference Include="Lib.Harmony">
<Version>2.2.2</Version> <Version>2.2.2</Version>
<ExcludeAssets>runtime</ExcludeAssets> <ExcludeAssets>runtime</ExcludeAssets>

View File

@ -219,14 +219,14 @@ namespace RJW_Menstruation
public void CheckDirty() public void CheckDirty()
{ {
if (absorbedfluids > this.GetStatValue(VariousDefOf.MaxAbsorbable) && !(Wearer?.apparel?.IsLocked(this) ?? false)) if (absorbedfluids > this.GetStatValue(VariousDefOf.MaxAbsorbable) && !(Wearer?.apparel?.IsLocked(this) ?? false) && DirtyDef != def && DirtyDef != null)
{ {
bool oldHasStats = !def.equippedStatOffsets.NullOrEmpty();
bool newHasStats = !DirtyDef.equippedStatOffsets.NullOrEmpty();
def = DirtyDef; def = DirtyDef;
dirty = true; dirty = true;
OutfitForcedHandler forcedHandler = Wearer.outfits?.forcedHandler; Wearer.outfits?.forcedHandler?.SetForced(this, false);
if (forcedHandler?.IsForced(this) ?? false) if (oldHasStats || newHasStats)
forcedHandler.SetForced(this, false);
if (!def.equippedStatOffsets.NullOrEmpty())
Wearer.health.capacities.Notify_CapacityLevelsDirty(); Wearer.health.capacities.Notify_CapacityLevelsDirty();
Wearer.apparel.Notify_ApparelChanged(); Wearer.apparel.Notify_ApparelChanged();
} }
@ -272,7 +272,7 @@ namespace RJW_Menstruation
public override void DirtyEffect(int tickInterval) public override void DirtyEffect(int tickInterval)
{ {
if (wearTicks > MinHrstoDirtyEffect * GenDate.TicksPerHour && Rand.MTBEventOccurs(100.0f, GenDate.TicksPerHour, tickInterval) && !Wearer.apparel.IsLocked(this)) if (wearTicks > MinHrstoDirtyEffect * GenDate.TicksPerHour && Rand.MTBEventOccurs(100.0f, GenDate.TicksPerHour, tickInterval) && !(Wearer.apparel?.IsLocked(this) ?? false))
{ {
Wearer.health.AddHediff(HediffDefOf.WoundInfection, Genital_Helper.get_genitalsBPR(Wearer)); Wearer.health.AddHediff(HediffDefOf.WoundInfection, Genital_Helper.get_genitalsBPR(Wearer));
} }

View File

@ -227,7 +227,7 @@ namespace RJW_Menstruation
string feinfo = PregnancyCommon.GetBabyInfo(babiescomp?.babies); string feinfo = PregnancyCommon.GetBabyInfo(babiescomp?.babies);
string fainfo = PregnancyCommon.GetFatherInfo(babiescomp?.babies, babiescomp.Pawn, true) + " "; // Keep all parents known, for now string fainfo = PregnancyCommon.GetFatherInfo(babiescomp?.babies, babiescomp.Pawn, true) + " "; // Keep all parents known, for now
if (feinfo == "Null") feinfo = "1 " + p.Mother.def.label + " " + Translations.Dialog_WombInfo02; if (feinfo == "Null") feinfo = "1 " + (p.Mother ?? pawn).def.label + " " + Translations.Dialog_WombInfo02;
if (fainfo == "Null ") if (fainfo == "Null ")
{ {
string father = p.Father?.LabelShort ?? Translations.Dialog_FatherUnknown; string father = p.Father?.LabelShort ?? Translations.Dialog_FatherUnknown;
@ -388,10 +388,9 @@ namespace RJW_Menstruation
Rect genitalIconRect = new Rect(rect.x, rect.y + fontheight, genitalRectWidth, genitalRectHeight); Rect genitalIconRect = new Rect(rect.x, rect.y + fontheight, genitalRectWidth, genitalRectHeight);
Rect genitalVaginaLabelRect = new Rect(rect.x, rect.y + 10f, genitalRectWidth, fontheight); Rect genitalVaginaLabelRect = new Rect(rect.x, rect.y + 10f, genitalRectWidth, fontheight);
Rect genitalAnusLabelRect = new Rect(rect.x, rect.y + fontheight + genitalRectHeight, genitalRectWidth, fontheight); Rect genitalAnusLabelRect = new Rect(rect.x, rect.y + fontheight + genitalRectHeight, genitalRectWidth, fontheight);
bool showOrigin = Mouse.IsOver(genitalIconRect) && Input.GetMouseButton(0);
vagina = pawn.GetGenitalIcon(comp, showOrigin); vagina = pawn.GetGenitalIcon(comp);
anal = pawn.GetAnalIcon(showOrigin); anal = pawn.GetAnalIcon();
GUI.color = new Color(1.00f, 0.47f, 0.47f, 1); GUI.color = new Color(1.00f, 0.47f, 0.47f, 1);
GUI.Box(rect, "", boxstyle); GUI.Box(rect, "", boxstyle);
GUI.color = Utility.SafeSkinColor(pawn); GUI.color = Utility.SafeSkinColor(pawn);

View File

@ -80,7 +80,7 @@ namespace RJW_Menstruation
try try
{ {
res = part.FluidAmmount * part.FluidModifier * pawn.BodySize / pawn.RaceProps.baseBodySize * Rand.Range(0.8f, 1.2f); res = VariationRange(part.FluidAmmount * part.FluidModifier * pawn.BodySize / pawn.RaceProps.baseBodySize, 0.2f);
} }
catch (NullReferenceException) catch (NullReferenceException)
{ {

View File

@ -45,14 +45,6 @@ namespace RJW_Menstruation
public static readonly RecordDef AmountofCreampied = DefDatabase<RecordDef>.GetNamed("AmountofCreampied"); public static readonly RecordDef AmountofCreampied = DefDatabase<RecordDef>.GetNamed("AmountofCreampied");
public static readonly RecordDef AmountofFertilizedEggs = DefDatabase<RecordDef>.GetNamed("AmountofFertilizedEggs"); public static readonly RecordDef AmountofFertilizedEggs = DefDatabase<RecordDef>.GetNamed("AmountofFertilizedEggs");
public static readonly TaleDef TaleCameInside = DefDatabase<TaleDef>.GetNamed("CameInside"); public static readonly TaleDef TaleCameInside = DefDatabase<TaleDef>.GetNamed("CameInside");
public static readonly GeneDef ShortEggLifetime = DefDatabase<GeneDef>.GetNamed("Menstruation_ShortEggLifetime");
public static readonly GeneDef DoubleEggLifetime = DefDatabase<GeneDef>.GetNamed("Menstruation_DoubleEggLifetime");
public static readonly GeneDef QuadEggLifetime = DefDatabase<GeneDef>.GetNamed("Menstruation_QuadEggLifetime");
public static readonly GeneDef NeverEstrus = DefDatabase<GeneDef>.GetNamed("Menstruation_NeverEstrus");
public static readonly GeneDef FullEstrus = DefDatabase<GeneDef>.GetNamed("Menstruation_FullEstrus");
public static readonly GeneDef DoubleOvulation = DefDatabase<GeneDef>.GetNamed("Menstruation_DoubleOvulation");
public static readonly GeneDef QuadOvulation = DefDatabase<GeneDef>.GetNamed("Menstruation_QuadOvulation");
public static readonly GeneDef NoBleeding = DefDatabase<GeneDef>.GetNamed("Menstruation_NoBleeding");
private static List<ThingDef> allraces = null; private static List<ThingDef> allraces = null;
private static List<PawnKindDef> allkinds = null; private static List<PawnKindDef> allkinds = null;
@ -66,9 +58,8 @@ namespace RJW_Menstruation
get get
{ {
if (allraces != null) return allraces; if (allraces != null) return allraces;
allraces = DefDatabase<ThingDef>.AllDefsListForReading.Where(thingdef => thingdef.race?.IsFlesh ?? false).ToList();
List<ThingDef> allThings = DefDatabase<ThingDef>.AllDefsListForReading;
allraces = allThings.FindAll(x => x.race != null && x.race.IsFlesh);
return allraces; return allraces;
} }
} }
@ -77,9 +68,8 @@ namespace RJW_Menstruation
get get
{ {
if (allkinds != null) return allkinds; if (allkinds != null) return allkinds;
allkinds = DefDatabase<PawnKindDef>.AllDefsListForReading.Where(pawnkinddef => pawnkinddef.race != null).ToList();
List<PawnKindDef> allKinds = DefDatabase<PawnKindDef>.AllDefsListForReading;
allkinds = allKinds.FindAll(x => x.race != null);
return allkinds; return allkinds;
} }
} }
@ -157,13 +147,7 @@ namespace RJW_Menstruation
get get
{ {
if (egglayergenes != null) return egglayergenes; if (egglayergenes != null) return egglayergenes;
egglayergenes = new HashSet<GeneDef> egglayergenes = DefDatabase<GeneDef>.AllDefsListForReading.Where(geneDef => geneDef.GetModExtension<MenstruationModExtension>()?.disableCycle ?? false).ToHashSet();
{
DefDatabase<GeneDef>.GetNamedSilentFail("AG_EggLaying"), // Alpha Genes
DefDatabase<GeneDef>.GetNamedSilentFail("VRESaurids_Oviparous"), // VE Saurid
DefDatabase<GeneDef>.GetNamedSilentFail("VRE_SaplingBirth"), // VE Phytokin
};
egglayergenes.Remove(null);
return egglayergenes; return egglayergenes;
} }

View File

@ -1,7 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ModMetaData> <ModMetaData>
<packageId>rjw.menstruation</packageId>
<name>RJW Menstruation Cycle</name> <name>RJW Menstruation Cycle</name>
<author>lutepickle</author> <author>lutepickle</author>
<url>https://gitgud.io/lutepickle/rjw_menstruation/</url>
<supportedVersions> <supportedVersions>
<li>1.2</li> <li>1.2</li>
<li>1.3</li> <li>1.3</li>
@ -28,13 +30,17 @@
<li>Abraxas.RJW.RaceSupport</li> <li>Abraxas.RJW.RaceSupport</li>
<li>rjw.milk.humanoid</li> <li>rjw.milk.humanoid</li>
</loadAfter> </loadAfter>
<packageId>rjw.menstruation</packageId> <incompatibleWithByVersion>
<v1.4>
<li>conit.thebirdsandthebees</li> <!--Breaks fertility calculations-->
</v1.4>
</incompatibleWithByVersion>
<description>Adds menstruation mechanics to vaginas: <description>Adds menstruation mechanics to vaginas:
Wombs cycle between follicular, luteal, and bleeding phases Wombs cycle between follicular, luteal, and bleeding phases
Tracks eggs ovulated and cum in wombs to determine pregnancy Tracks eggs ovulated and cum in wombs to determine pregnancy
Womb icon and status window Womb icon and status window
Estrus effects Estrus and pheromone effects
Race-specific fetus images for many vanilla animals Race-specific fetus images for many vanilla animals
Pregnancies from multiple eggs and different fathers Pregnancies from multiple eggs and different fathers
Identical siblings Identical siblings

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Manifest> <Manifest>
<identifier>RJW Menstruation</identifier> <identifier>RJW Menstruation</identifier>
<version>1.0.9.3</version> <version>1.0.9.4</version>
<dependencies> <dependencies>
</dependencies> </dependencies>
<incompatibleWith /> <incompatibleWith />

View File

@ -1,3 +1,8 @@
Version 1.0.9.4
- Added graphics for the menstruation genes with thanks to Alpenglow.
- Pawns in estrus now give their pheromones to their caravan-mates.
- Pawns with the egglaying genes from Erin's Corvyia and Outland - Genetics no longer have a menstrual cycle.
Version 1.0.9.3 Version 1.0.9.3
- The biosculptor egg restoration cycle will now give more eggs to races that ovulate more than one egg at a time. - The biosculptor egg restoration cycle will now give more eggs to races that ovulate more than one egg at a time.
- All pawns can now use all menstruation genes, regardless of gender or having a womb. - All pawns can now use all menstruation genes, regardless of gender or having a womb.