code:
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>

	<MasochistPsycheSerum.label>сыворотка мазохиста</MasochistPsycheSerum.label>
	<MasochistPsycheSerum.description>Делает пользователя мазохистом.</MasochistPsycheSerum.description>
	<MasochistPsycheSerum.ingestible.ingestCommandString>Выпить {0}</MasochistPsycheSerum.ingestible.ingestCommandString>
	<MasochistPsycheSerum.ingestible.ingestReportString>Пьет {0}</MasochistPsycheSerum.ingestible.ingestReportString>

	<NymphomaniacPsycheSerum.label>сыворотка гиперсексуальности</NymphomaniacPsycheSerum.label>
	<NymphomaniacPsycheSerum.description>Делает пользователя гиперсексуальным.</NymphomaniacPsycheSerum.description>
	<NymphomaniacPsycheSerum.ingestible.ingestCommandString>Выпить {0}</NymphomaniacPsycheSerum.ingestible.ingestCommandString>
	<NymphomaniacPsycheSerum.ingestible.ingestReportString>Пьет {0}</NymphomaniacPsycheSerum.ingestible.ingestReportString>

	<NecrophiliacPsycheSerum.label>сыворотка некрофила</NecrophiliacPsycheSerum.label>
	<NecrophiliacPsycheSerum.description>Делает пользователя некрофилом.</NecrophiliacPsycheSerum.description>
	<NecrophiliacPsycheSerum.ingestible.ingestCommandString>Выпить {0}</NecrophiliacPsycheSerum.ingestible.ingestCommandString>
	<NecrophiliacPsycheSerum.ingestible.ingestReportString>Пьет {0}</NecrophiliacPsycheSerum.ingestible.ingestReportString>

	<ZoophilePsycheSerum.label>сыворотка зоофила</ZoophilePsycheSerum.label>
	<ZoophilePsycheSerum.description>Делает пользователя зоофилом.</ZoophilePsycheSerum.description>
	<ZoophilePsycheSerum.ingestible.ingestCommandString>Выпить {0}</ZoophilePsycheSerum.ingestible.ingestCommandString>
	<ZoophilePsycheSerum.ingestible.ingestReportString>Пьет {0}</ZoophilePsycheSerum.ingestible.ingestReportString>

	<CumflationPsycheSerum.label>сыворотка любителя переполнения</CumflationPsycheSerum.label>
	<CumflationPsycheSerum.description>Делает пользователя любителем переполения спермой.</CumflationPsycheSerum.description>
	<CumflationPsycheSerum.ingestible.ingestCommandString>Выпить {0}</CumflationPsycheSerum.ingestible.ingestCommandString>
	<CumflationPsycheSerum.ingestible.ingestReportString>Пьет {0}</CumflationPsycheSerum.ingestible.ingestReportString>

	<AntiMasochistPsycheSerum.label>сыворотка анти-мазохиста</AntiMasochistPsycheSerum.label>
	<AntiMasochistPsycheSerum.description>Пользователь больше не мазохистом.</AntiMasochistPsycheSerum.description>
	<AntiMasochistPsycheSerum.ingestible.ingestCommandString>Выпить {0}</AntiMasochistPsycheSerum.ingestible.ingestCommandString>
	<AntiMasochistPsycheSerum.ingestible.ingestReportString>Пьет {0}</AntiMasochistPsycheSerum.ingestible.ingestReportString>

	<AntiNymphomaniacPsycheSerum.label>сыворотка анти-гиперсексуальности</AntiNymphomaniacPsycheSerum.label>
	<AntiNymphomaniacPsycheSerum.description>Пользователь больше не гиперсексуальный.</AntiNymphomaniacPsycheSerum.description>
	<AntiNymphomaniacPsycheSerum.ingestible.ingestCommandString>Выпить {0}</AntiNymphomaniacPsycheSerum.ingestible.ingestCommandString>
	<AntiNymphomaniacPsycheSerum.ingestible.ingestReportString>Пьет {0}</AntiNymphomaniacPsycheSerum.ingestible.ingestReportString>

	<AntiNecrophiliacPsycheSerum.label>сыворотка анти-некрофила</AntiNecrophiliacPsycheSerum.label>
	<AntiNecrophiliacPsycheSerum.description>Пользователь больше не некрофилом.</AntiNecrophiliacPsycheSerum.description>
	<AntiNecrophiliacPsycheSerum.ingestible.ingestCommandString>Выпить {0}</AntiNecrophiliacPsycheSerum.ingestible.ingestCommandString>
	<AntiNecrophiliacPsycheSerum.ingestible.ingestReportString>Пьет {0}</AntiNecrophiliacPsycheSerum.ingestible.ingestReportString>

	<AntiZoophilePsycheSerum.label>сыворотка анти-зоофила</AntiZoophilePsycheSerum.label>
	<AntiZoophilePsycheSerum.description>Пользователь больше не зоофил.</AntiZoophilePsycheSerum.description>
	<AntiZoophilePsycheSerum.ingestible.ingestCommandString>Выпить {0}</AntiZoophilePsycheSerum.ingestible.ingestCommandString>
	<AntiZoophilePsycheSerum.ingestible.ingestReportString>Пьет {0}</AntiZoophilePsycheSerum.ingestible.ingestReportString>

	<AntiCumflationPsycheSerum.label>сыворотка анти-любителя переполнения</AntiCumflationPsycheSerum.label>
	<AntiCumflationPsycheSerum.description>Пользователь больше не любитель переполения спермой.</AntiCumflationPsycheSerum.description>
	<AntiCumflationPsycheSerum.ingestible.ingestCommandString>Выпить {0}</AntiCumflationPsycheSerum.ingestible.ingestCommandString>
	<AntiCumflationPsycheSerum.ingestible.ingestReportString>Пьет {0}</AntiCumflationPsycheSerum.ingestible.ingestReportString>

</LanguageData>


code:
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>

	<HormonalSerum.label>гормональная сыворотка</HormonalSerum.label>
	<HormonalSerum.description>Гормональная сыворотка. Можно употреблять для удовольствия, но в основном используется для производства других наркотиков.</HormonalSerum.description>
	<HormonalSerum.ingestible.ingestCommandString>Выпить {0}</HormonalSerum.ingestible.ingestCommandString>
	<HormonalSerum.ingestible.ingestReportString>Пьет {0}</HormonalSerum.ingestible.ingestReportString>

</LanguageData>

repo_name: cptyossarian/licentia

license: unknown


code:
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>

	<ElasticisingSerum.label>эластичная сыворотка</ElasticisingSerum.label>
	<ElasticisingSerum.description>Делает отверстия пользователя эластичными.</ElasticisingSerum.description>
	<ElasticisingSerum.ingestible.ingestCommandString>Выпить {0}</ElasticisingSerum.ingestible.ingestCommandString>
	<ElasticisingSerum.ingestible.ingestReportString>Пьет {0}</ElasticisingSerum.ingestible.ingestReportString>

	<EnlargingSerum.label>увеличивающая сыворотка</EnlargingSerum.label>
	<EnlargingSerum.description>Временно увеличивает гениталии.</EnlargingSerum.description>
	<EnlargingSerum.ingestible.ingestCommandString>Выпить {0}</EnlargingSerum.ingestible.ingestCommandString>
	<EnlargingSerum.ingestible.ingestReportString>Пьет {0}</EnlargingSerum.ingestible.ingestReportString>

	<DiminishingSerum.label>уменьшающая сыворотка</DiminishingSerum.label>
	<DiminishingSerum.description>Временно уменьшает гениталии.</DiminishingSerum.description>
	<DiminishingSerum.ingestible.ingestCommandString>Выпить {0}</DiminishingSerum.ingestible.ingestCommandString>
	<DiminishingSerum.ingestible.ingestReportString>Пьет {0}</DiminishingSerum.ingestible.ingestReportString>

	<ReinforcingSerum.label>укрепляющая сыворотка</ReinforcingSerum.label>
	<ReinforcingSerum.description>Делает отверстия пользователя не рвущимися, но растягиваемыми.</ReinforcingSerum.description>
	<ReinforcingSerum.ingestible.ingestCommandString>Выпить {0}</ReinforcingSerum.ingestible.ingestCommandString>
	<ReinforcingSerum.ingestible.ingestReportString>Пьет {0}</ReinforcingSerum.ingestible.ingestReportString>

</LanguageData>


code:
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>

	<Genderbent.stages.0.label>чувство беспокойства</Genderbent.stages.0.label>
	<Genderbent.stages.0.description>Я устал от этого измененного тела.</Genderbent.stages.0.description>
	<Genderbent.stages.1.label>акклиматизированный</Genderbent.stages.1.label>
	<Genderbent.stages.1.description>Я приспособился к своему новому телу.</Genderbent.stages.1.description>
	<Genderbent.stages.2.label>гедербенд</Genderbent.stages.2.label>
	<Genderbent.stages.2.description>Мне так мило и тепло... и эти новые части! Я должен их попробовать!</Genderbent.stages.2.description>
	<Genderbent.stages.3.label>гендерная путаница</Genderbent.stages.3.label>
	<Genderbent.stages.3.description>Что со мной происходит? Я чувствую, что внутри все изменилось.</Genderbent.stages.3.description>

</LanguageData>


code:
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>

	<MutatedParts.stages.0.label>мутировавшие части</MutatedParts.stages.0.label>
	<MutatedParts.stages.0.description>Мне так мило и тепло... и эти новые части! Я должен их попробовать!</MutatedParts.stages.0.description>
	<MutatedParts.stages.1.label>растущие мутировавшие части</MutatedParts.stages.1.label>
	<MutatedParts.stages.1.description>Что со мной происходит? Я чувствую, что внутри все изменилось.</MutatedParts.stages.1.description>

</LanguageData>


code:
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>

	<ProducingHormonalSerum.stages.2.label>гормональный</ProducingHormonalSerum.stages.2.label>
	<ProducingHormonalSerum.stages.2.description>Я такой ненормальный.</ProducingHormonalSerum.stages.2.description>

</LanguageData>


code:
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>

	<AlteredPsyche.stages.1.label>потрясённый</AlteredPsyche.stages.1.label>
	<AlteredPsyche.stages.1.description>Я чувствую себя лучше, но все еще не в себе.</AlteredPsyche.stages.1.description>
	<AlteredPsyche.stages.2.label>смущенный</AlteredPsyche.stages.2.label>
	<AlteredPsyche.stages.2.description>Все мои мысли странные.</AlteredPsyche.stages.2.description>

</LanguageData>


code:
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>

	<HormonalSerumWithdrawal.stages.1.label>ломка по гормональной сыворотке</HormonalSerumWithdrawal.stages.1.label>
	<HormonalSerumWithdrawal.stages.1.description>Мое тело ужасно... Я хочу изменить его, снова насладиться таким развратным удовольствием.</HormonalSerumWithdrawal.stages.1.description>

	<HormonalSerumHigh.stages.0.label>чувствую себя приятно оживленным</HormonalSerumHigh.stages.0.label>
	<HormonalSerumHigh.stages.0.description>Ммм... Я чувствую... тепло.</HormonalSerumHigh.stages.0.description>
	<HormonalSerumHigh.stages.1.label>чувствую себя страстно пламенной</HormonalSerumHigh.stages.1.label>
	<HormonalSerumHigh.stages.1.description>Охх~ Это так хорошо.</HormonalSerumHigh.stages.1.description>
	<HormonalSerumHigh.stages.2.label>гормонально накачанный</HormonalSerumHigh.stages.2.label>
	<HormonalSerumHigh.stages.2.description>*задыхающийся*</HormonalSerumHigh.stages.2.description>
	<HormonalSerumHigh.stages.3.label>гормональный дисбаланс</HormonalSerumHigh.stages.3.label>
	<HormonalSerumHigh.stages.3.description>Почему я так себя чувствую?</HormonalSerumHigh.stages.3.description>

</LanguageData>


code:
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>

	<Diminished.stages.1.label>уменьшение гениталий</Diminished.stages.1.label>
	<Diminished.stages.1.description>Я не могу в это поверить...</Diminished.stages.1.description>
	<Diminished.stages.2.label>сильное уменьшение гениталий</Diminished.stages.2.label>
	<Diminished.stages.2.description>Что? Что вы сделали со мной?</Diminished.stages.2.description>

	<MasochistDiminished.stages.1.label>уменьшение гениталий (Мазохист)</MasochistDiminished.stages.1.label>
	<MasochistDiminished.stages.1.description>Все, что угодно...</MasochistDiminished.stages.1.description>
	<MasochistDiminished.stages.2.label>сильное уменьшение гениталий (Мазохист)</MasochistDiminished.stages.2.label>
	<MasochistDiminished.stages.2.description>Меня поставили на место.</MasochistDiminished.stages.2.description>

</LanguageData>


code:
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>

	<GotOverCumflated.stages.0.label>переполнен спермой</GotOverCumflated.stages.0.label>
	<GotOverCumflated.stages.0.description>Думаю, я все еще чувствую сперму в животе.</GotOverCumflated.stages.0.description>

	<GotOverCumflatedEnjoyed.stages.0.label>понравилось быть переполненным спермой</GotOverCumflatedEnjoyed.stages.0.label>
	<GotOverCumflatedEnjoyed.stages.0.description>Мне нравилось ощущение, что меня переполняют спермой до краев.</GotOverCumflatedEnjoyed.stages.0.description>

	<GotOverCumstuffed.stages.0.label>набитый спермой</GotOverCumstuffed.stages.0.label>
	<GotOverCumstuffed.stages.0.description>Я все еще чувствую вкус спермы во рту.</GotOverCumstuffed.stages.0.description>

	<GotOverCumstuffedEnjoyed.stages.0.label>понравилось быть набитым спермой</GotOverCumstuffedEnjoyed.stages.0.label>
	<GotOverCumstuffedEnjoyed.stages.0.description>Я хочу получить больше спермы ...</GotOverCumstuffedEnjoyed.stages.0.description>

</LanguageData>


code:
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>

	<GotStretched.stages.0.label>боль от растяжения</GotStretched.stages.0.label>
	<GotStretched.stages.0.description>Ой. Это было много...</GotStretched.stages.0.description>

	<MasochistGotStretched.stages.0.label>боль от растяжения (Мазохист)</MasochistGotStretched.stages.0.label>
	<MasochistGotStretched.stages.0.description>Ой. Я был набит до боли. Я хочу больше.</MasochistGotStretched.stages.0.description>

	<KinkyGotStretched.stages.0.label>боль от растяжения</KinkyGotStretched.stages.0.label>
	<KinkyGotStretched.stages.0.description>Ой. Это было много... но мне это вроде как понравилось.</KinkyGotStretched.stages.0.description>

	<KinkyGotInflated.stages.0.label>наполнен спермой</KinkyGotInflated.stages.0.label>
	<KinkyGotInflated.stages.0.description>Я так полон. Мне это нравится.</KinkyGotInflated.stages.0.description>

</LanguageData>


code:
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>

	<Cumflation.stages.1.label>наполнен спермой</Cumflation.stages.1.label>
	<Cumflation.stages.1.description>Это немного странно, но не неприятно. (Незначительно)</Cumflation.stages.1.description>
	<Cumflation.stages.2.label>наполнен спермой</Cumflation.stages.2.label>
	<Cumflation.stages.2.description>Внутри много спермы, и это немного больно. (Умеренно)</Cumflation.stages.2.description>
	<Cumflation.stages.3.label>наполнен спермой</Cumflation.stages.3.label>
	<Cumflation.stages.3.description>Уххх ... мои кишки полны спермой, и это начинает становиться болезненным. (Черезмерно)</Cumflation.stages.3.description>
	<Cumflation.stages.4.label>наполнен спермой</Cumflation.stages.4.label>
	<Cumflation.stages.4.description>Уххх... у меня живот болит... (Экстремально)</Cumflation.stages.4.description>

	<CumflationEnjoyed.stages.1.label>наслаждение наполненостью</CumflationEnjoyed.stages.1.label>
	<CumflationEnjoyed.stages.1.description>Странно, мне это даже нравится... (Незначительно)</CumflationEnjoyed.stages.1.description>
	<CumflationEnjoyed.stages.2.label>наслаждение наполненостью</CumflationEnjoyed.stages.2.label>
	<CumflationEnjoyed.stages.2.description>Я приятно полон спермы. (Умеренно)</CumflationEnjoyed.stages.2.description>
	<CumflationEnjoyed.stages.3.label>наслаждение наполненостью</CumflationEnjoyed.stages.3.label>
	<CumflationEnjoyed.stages.3.description>Ммм... больше... (Черезмерно)</CumflationEnjoyed.stages.3.description>
	<CumflationEnjoyed.stages.4.label>наслаждение наполненостью</CumflationEnjoyed.stages.4.label>
	<CumflationEnjoyed.stages.4.description>Ухххх... Ммм... (Экстремально)</CumflationEnjoyed.stages.4.description>

	<Cumstuffed.stages.1.label>наполнен спермой</Cumstuffed.stages.1.label>
	<Cumstuffed.stages.1.description>Я чувствую себя полным. (Незначительно)</Cumstuffed.stages.1.description>
	<Cumstuffed.stages.2.label>полон спермы</Cumstuffed.stages.2.label>
	<Cumstuffed.stages.2.description>Я не могу выпить больше ни капли. (Умеренно)</Cumstuffed.stages.2.description>
	<Cumstuffed.stages.3.label>заполнен спермой</Cumstuffed.stages.3.label>
	<Cumstuffed.stages.3.description>Хрккк... Меня сейчас вырвет... (Черезмерно)</Cumstuffed.stages.3.description>
	<Cumstuffed.stages.4.label>переполнен спермой</Cumstuffed.stages.4.label>
	<Cumstuffed.stages.4.description>Хрххх..., у меня болит живот... (Экстремально)</Cumstuffed.stages.4.description>

	<CumstuffedEnjoyed.stages.1.label>наслаждение наполненостью</CumstuffedEnjoyed.stages.1.label>
	<CumstuffedEnjoyed.stages.1.description>Я чувствую, как оно плещется внутри меня.</CumstuffedEnjoyed.stages.1.description>
	<CumstuffedEnjoyed.stages.2.label>наслаждение полнотой</CumstuffedEnjoyed.stages.2.label>
	<CumstuffedEnjoyed.stages.2.description>Я хочу большего!</CumstuffedEnjoyed.stages.2.description>
	<CumstuffedEnjoyed.stages.3.label>наслаждение заполненостью</CumstuffedEnjoyed.stages.3.label>
	<CumstuffedEnjoyed.stages.3.description>Ммм... это больно, но я все еще хочу большего.</CumstuffedEnjoyed.stages.3.description>
	<CumstuffedEnjoyed.stages.4.label>наслаждение переполностью</CumstuffedEnjoyed.stages.4.label>
	<CumstuffedEnjoyed.stages.4.description>Ммм... больше...</CumstuffedEnjoyed.stages.4.description>

</LanguageData>


code:
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>

	<Orbital_LicentiaLabs.label>Поставщик Licentia Labs</Orbital_LicentiaLabs.label>

</LanguageData>


code:
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>

	<LikesCumflation.degreeDatas.0.label>нравится наполнение спермой</LikesCumflation.degreeDatas.0.label>
	<LikesCumflation.degreeDatas.0.description>[PAWN_nameDef] нравится ощущение наполнения и быть наполненным большим количеством спермы.</LikesCumflation.degreeDatas.0.description>

</LanguageData>


code:
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>
	<LL_BreastsSizeIncrease>Грудь {0} увеличилась в размерах.</LL_BreastsSizeIncrease>
	<LL_BreastsSizeDecrease>Грудь {0} уменьшилась в размерах.</LL_BreastsSizeDecrease>
	<LL_BreastsMaxSize>Грудь {0} уже достигла максимального размера.</LL_BreastsMaxSize>
	<LL_BreastsMinSize>Грудь {0} уже достигла минимального размера.</LL_BreastsMinSize>

	<LL_PenisSizeIncrease>Пенис {0} увеличился в размерах.</LL_PenisSizeIncrease>
	<LL_PenisSizeDecrease>Пенис {0} уменьшился в размерах.</LL_PenisSizeDecrease>
	<LL_PenisMaxSize>Пенис {0} уже достиг максимального размера.</LL_PenisMaxSize>
	<LL_PenisMinSize>Пенис {0} уже достиг минимального размера.</LL_PenisMinSize>

	<LL_VaginaSizeIncrease>Вагина {0} увеличилась в размерах.</LL_VaginaSizeIncrease>
	<LL_VaginaSizeDecrease>Вагина {0} уменьшилась в размерах.</LL_VaginaSizeDecrease>
	<LL_VaginaMaxSize>Вагина {0} уже достигла максимального размера.</LL_VaginaMaxSize>
	<LL_VaginaMinSize>Вагина {0} уже достигла минимального размера.</LL_VaginaMinSize>

	<LL_AnusMinSize>Анус {0} уже имеет минимальный размер.</LL_AnusMinSize>

	<LL_CumAltered>Производство спермы {0} было изменено.</LL_CumAltered>
	<LL_GenitalsAltered>Гениталии {0} изменены.</LL_GenitalsAltered>
	<LL_BreastsAltered>Грудь {0} была изменена.</LL_BreastsAltered>
	<LL_AnusAltered>Анус {0} изменен.</LL_AnusAltered>

	<LL_GenitalsNotAlterable>Гениталии {0} неизменны.</LL_GenitalsNotAlterable>
	<LL_BreastsNotAlterable>Грудь {0} неизменна.</LL_BreastsNotAlterable>
	<LL_AnusNotAlterable>Анус {0} неизменен.</LL_AnusNotAlterable>

	<LL_BreastsSwapped>Грудь {0} поменялась местами(касаемо пола).</LL_BreastsSwapped>
	<LL_GenitalsSwapped>Гениталии {0} поменялись местами(касаемо пола).</LL_GenitalsSwapped>

	<LL_BreastsReverted>Грудь {0} была восстановлена.</LL_BreastsReverted>
	<LL_GenitalsReverted>Гениталии {0} восстановлены.</LL_GenitalsReverted>
	<LL_AnusReverted>Анус {0} восстановлен.</LL_AnusReverted>
	<LL_Reverted>{0} вернулся к среднему сексуальному телосложению.</LL_Reverted>

	<LL_PsycheAltered>Психика {0} изменилась.</LL_PsycheAltered>

	<LL_VaginaStretched>Вагина {0} была растянута.</LL_VaginaStretched>
	<LL_AnusStretched>Анус {0} был растянут.</LL_AnusStretched>
	<LL_OrificeStretched>{1} {0} был растянут.</LL_OrificeStretched>

	<LL_MadeFuta>{0} теперь фута.</LL_MadeFuta>

</LanguageData>


code:
<?xml version="1.0" encoding="utf-8" ?>
<Patch>

	<Operation Class="PatchOperationAdd">
		<xpath>Defs/rjw.HediffDef_SexPart[defName="DemonTentaclePenis"]</xpath>
		<value>
			<comps>

					<stretchVariance>0.4</stretchVariance>

			</comps>
		</value>
	</Operation>

	<Operation Class="PatchOperationAdd">
		<xpath>Defs/rjw.HediffDef_SexPart[defName="SlimeTentacles"]</xpath>
		<value>
			<comps>

					<stretchVariance>0.4</stretchVariance>

			</comps>
		</value>
	</Operation>

</Patch>

path: Patches/RJW - Patch.xml


code:
<?xml version="1.0" encoding="utf-8"?>
<Patch>
	<Operation Class="PatchOperationAdd">
		<xpath>Defs/ThingDef[defName="Human"]/recipes</xpath>
		<value>

RepairProlapse

RepairExtremeProlapse

		</value>
	</Operation>
	<Operation Class="PatchOperationAdd">
		<xpath>Defs/ThingDef[@Name="AnimalThingBase"]/recipes</xpath>
		<value>

RepairProlapse

RepairExtremeProlapse

		</value>
	</Operation>
	<Operation Class="PatchOperationFindMod">
		<mods>

Humanoid Alien Races 2.0

		</mods>
		<match Class="PatchOperationConditional">
			<xpath>/Defs/AlienRace.ThingDef_AlienRace/alienRace/generalSettings/humanRecipeImport[text()="false"]</xpath>
			<match Class="PatchOperationConditional">
				<xpath>/Defs/AlienRace.ThingDef_AlienRace/recipes</xpath>
				<match Class="PatchOperationAdd">
					<xpath>/Defs/AlienRace.ThingDef_AlienRace/recipes</xpath>
					<value>

RepairProlapse

RepairExtremeProlapse

					</value>
				</match>
				<nomatch Class="PatchOperationAdd">
					<xpath>/Defs/AlienRace.ThingDef_AlienRace/recipes</xpath>
					<value>
						<recipes>

RepairProlapse

RepairExtremeProlapse

						</recipes>
					</value>
				</nomatch>
			</match>
		</match>
	</Operation>
</Patch>


code:
# Licentia Labs stretching

This is a RJW 5.5+ fork of the original mod, that adds support for stretching and prolapsing mechanics and everything related to them. All other features (Serums, Cumflation) were removed to not cause any issues.
Mod name was also changed to prevent any compatibility issues with other mods.

#FOLDER WITH OLD VERSION OF THE MOD MUST BE DELETED

# Licentia Labs

This project was started by a LoversLab member named Lust Licentia, who is currently missing. I am maintaining the mod in his stead until or unless he returns.

## Features

The mod is named primarily after the ability to craft serums (Licentia *Labs*), but there are various features:

- The ability to craft various serums to alter your pawns in various sexy ways, such as enlarging or shrinking genitalia. Using standard RJW crafting items, pawns can turn them into these serums and drink them for their various effects.
- The introduction of stretching and prolapsing mechanics to the basic RJW sex system. If a pawn with genitalia too large for another pawn have sex, then the pawn that is smaller might experience their orifices getting stretched out, damaged, or even prolapsed depending on how large the difference is.
- The introduction of cum inflation mechanics for pawns based on the cum output of the one doing the penetrating. A productive pawn can literally feed their entire colony through sex (oral, anal, or double penetration) at the cost of their own hunger. Too much inflation may not be good for colony productivity, however, as the entire colony might end up as cum balloons too bloated to work!


code:
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.202
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LicentiaLabs", "LicentiaLabs\LicentiaLabs.csproj", "{57515AAF-B37A-4912-A910-4C629FEC734F}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Release|Any CPU = Release|Any CPU
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{57515AAF-B37A-4912-A910-4C629FEC734F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{57515AAF-B37A-4912-A910-4C629FEC734F}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{57515AAF-B37A-4912-A910-4C629FEC734F}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{57515AAF-B37A-4912-A910-4C629FEC734F}.Release|Any CPU.Build.0 = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
	GlobalSection(ExtensibilityGlobals) = postSolution
		SolutionGuid = {945FE524-C8A1-4B14-AC35-7F99B77BDB18}
	EndGlobalSection
EndGlobal


code:
using RimWorld;
using rjw;
using rjw.Modules.Interactions.Helpers;
using rjw.Modules.Interactions.Objects;
using System.Collections.Generic;
using System.Linq;
using Verse;
using static LicentiaLabs.Licentia;

namespace LicentiaLabs
{
    public static class Licentia
    {
        public static class ThoughtDefs
        {
            public static readonly ThoughtDef GotStretched = DefDatabase<ThoughtDef>.GetNamed("GotStretched");
            public static readonly ThoughtDef GotStretchedKinky = DefDatabase<ThoughtDef>.GetNamed("KinkyGotStretched");
            public static readonly ThoughtDef GotStretchedMasochist = DefDatabase<ThoughtDef>.GetNamed("MasochistGotStretched");
        }

        public static class HediffDefs
        {
            public static readonly HediffDef CervixBruise = HediffDef.Named("CervixBruise");
            public static readonly HediffDef ExtremeProlapse = HediffDef.Named("ExtremeProlapse");
            public static readonly HediffDef Stretched = HediffDef.Named("Stretched");
            public static readonly HediffDef StretchTear = HediffDef.Named("StretchTear");
            public static readonly HediffDef Prolapse = HediffDef.Named("Prolapse");
            public static readonly HediffDef Untearable = HediffDef.Named("Untearable");
            public static readonly HediffDef Diminished = HediffDef.Named("Diminished");
            public static readonly HediffDef Elasticised = HediffDef.Named("Elasticised");
            public static readonly HediffDef Enlarged = HediffDef.Named("Enlarged");
        }

        public static class ThingDefs
        {
            public static readonly ThingDef HormonalSerum = ThingDef.Named("HormonalSerum");
        }

        public static class TraitDefs
        {
            public static readonly TraitDef Cumpilation_LikesCumflation = TraitDef.Named("Cumpilation_LikesCumflation");
            public static readonly TraitDef RJW_Traits_Playful_Sadist = TraitDef.Named("RJW_Traits_Playful_Sadist");
            public static readonly TraitDef RJW_Traits_Brutal_Sadist = TraitDef.Named("RJW_Traits_Brutal_Sadist");
            public static readonly TraitDef RJW_Traits_Pliable = TraitDef.Named("RJW_Traits_Pliable");
            public static readonly TraitDef RJW_Traits_Rapetoy = TraitDef.Named("RJW_Traits_Rapetoy");
            public static readonly TraitDef RJW_Traits_Submissive = TraitDef.Named("RJW_Traits_Submissiven");
            public static readonly TraitDef RJW_Traits_Animal_Mind = TraitDef.Named("RJW_Traits_Animal_Mind");
            public static readonly TraitDef RJW_Traits_Sexually_Numb = TraitDef.Named("RJW_Traits_Sexually_Numb");
        }
    }

    public static class LicentiaHelper
    {
        public static readonly IDictionary<SexPartType, BodyPartDef> BodyPartDefBySexPartType = new Dictionary<SexPartType, BodyPartDef>();

        static LicentiaHelper()
        {
            BodyPartDefBySexPartType.Add(SexPartType.Anus, xxx.anusDef);
            BodyPartDefBySexPartType.Add(SexPartType.FemaleBreast, xxx.breastsDef);
            BodyPartDefBySexPartType.Add(SexPartType.FemaleGenital, xxx.genitalsDef);
            BodyPartDefBySexPartType.Add(SexPartType.MaleBreast, xxx.breastsDef);
            BodyPartDefBySexPartType.Add(SexPartType.MaleGenital, xxx.genitalsDef);
        }

        public static bool IsArtificial(Hediff hediff)
        {
            return !(hediff is Hediff_NaturalSexPart);
        }

        public static Hediff TryGetRJWPartHediff(Pawn pawn, SexPartType partType)
        {
            switch (partType)
            {
                case SexPartType.Anus:
                    return TryGetPawnAnusHediff(pawn);

                case SexPartType.FemaleGenital:
                    return TryGetPawnVaginaHediff(pawn);

                case SexPartType.MaleGenital:
                    {
                        var hediffs = TryGetPawnPenisHediff(pawn);
                        if (hediffs.Count > 0)
                        {
                            return hediffs[0];
                        }
                        return null;
                    }
            }

            // default value
            return TryGetPawnBreastHediff(pawn);
        }

        public static List<Hediff> TryGetPawnPenisHediff(Pawn pawn) // used for stretch and futa calculation
        {
            var hediffs = new HashSet<Hediff>();

            var genitalsHediffs = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn));
            if (Genital_Helper.has_penis_fertile(pawn, genitalsHediffs) || Genital_Helper.has_penis_infertile(pawn, genitalsHediffs) || Genital_Helper.has_multipenis(pawn, genitalsHediffs))
            {
                hediffs.AddRange(genitalsHediffs.FindAll((Hediff hediff) => hediff.def.defName.ToLower().Contains("penis")));
                hediffs.AddRange(genitalsHediffs.FindAll((Hediff hediff) => hediff.def.defName.ToLower().Contains("ovipositorf")));
                hediffs.AddRange(genitalsHediffs.FindAll((Hediff hediff) => hediff.def.defName.ToLower().Contains("ovipositorm")));
                hediffs.AddRange(genitalsHediffs.FindAll((Hediff hediff) => hediff.def.defName.ToLower().Contains("tentacle")));
            }
            else if (Genital_Helper.has_ovipositorF(pawn, genitalsHediffs))
            {
                hediffs.AddRange(genitalsHediffs.FindAll((Hediff hediff) => hediff.def.defName.ToLower().Contains("ovipositorf")));
            }

            return hediffs.ToList();
        }

        public static Hediff TryGetPawnVaginaHediff(Pawn pawn) // used for stretch and futa calculation
        {
            Hediff hediff = null;
            var pawnparts = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn));

            if (Genital_Helper.has_vagina(pawn, pawnparts))
            {
                hediff = pawnparts.FindAll((Hediff hed) => hed.def.defName.ToLower().Contains("vagina")).InRandomOrder().FirstOrDefault();

                if (hediff == null)
                    hediff = pawnparts.FindAll((Hediff hed) => hed.def.defName.ToLower().Contains("ovipositorf")).InRandomOrder().FirstOrDefault();
            }
            else
            {
                hediff = null;
            }

            return hediff;
        }

        public static Hediff TryGetPawnAnusHediff(Pawn pawn)
        {
            BodyPartRecord Part = Genital_Helper.get_anusBPR(pawn);
            if (Part is null)
                return null;

            return pawn.health.hediffSet.hediffs.FindAll((Hediff hed) =>
                    hed.Part == Part &&
                    (hed is Hediff_NaturalSexPart || hed is Hediff_ArtificialSexPart) &&
                    (hed.def.defName.ToLower().Contains("anus"))).InRandomOrder().FirstOrDefault();
        }

        public static Hediff TryGetPawnBreastHediff(Pawn pawn)
        {
            BodyPartRecord Part = Genital_Helper.get_breastsBPR(pawn);
            if (Part is null)
                return null;

            return pawn.health.hediffSet.hediffs.FindAll((Hediff hed) =>
                    hed.Part == Part &&
                    (hed is Hediff_NaturalSexPart || hed is Hediff_ArtificialSexPart) &&
                    (hed.def.defName.ToLower().Contains("breasts") || hed.def.defName.ToLower().Contains("chest"))
                    ).InRandomOrder().FirstOrDefault();
        }

        public static bool GetPenetrator(SexProps props, out Pawn penetrator, out Pawn penetrated)
        {
            penetrator = null;
            penetrated = null;

            bool initiatorHasPenis = true;
            bool partnerHasPenis = true;
            if (TryGetPawnPenisHediff(props.pawn).EnumerableNullOrEmpty())
            {
                initiatorHasPenis = false;
            }
            if (TryGetPawnPenisHediff(props.partner).EnumerableNullOrEmpty())
            {
                partnerHasPenis = false;
            }

            if (!initiatorHasPenis && !partnerHasPenis)
            {
                return false;
            }

            InteractionWithExtension interaction = InteractionHelper.GetWithExtension(props.dictionaryKey);
            bool initiatorUsesPenis;
            bool partnerUsesPenis;
            if (!props.isReceiver)
            {
                initiatorUsesPenis = interaction?.DominantHasTag(GenitalTag.CanPenetrate) ?? false;
                partnerUsesPenis = interaction?.SubmissiveHasTag(GenitalTag.CanPenetrate) ?? false;
            }
            else
            {
                initiatorUsesPenis = interaction?.SubmissiveHasTag(GenitalTag.CanPenetrate) ?? false;
                partnerUsesPenis = interaction?.DominantHasTag(GenitalTag.CanPenetrate) ?? false;
            }

            if (initiatorHasPenis && initiatorUsesPenis)
            {
                penetrator = props.pawn;
                penetrated = props.partner;
                return true;
            }
            else if (partnerHasPenis && partnerUsesPenis)
            {
                penetrator = props.partner;
                penetrated = props.pawn;
                return true;
            }

            return false;
        }

        public static bool AddSexPart(Pawn pawn, rjw.SexPartType partType, float severity = 0)
        {
            if (pawn == null)
            {
                return false;
            }

            if (PawnExtensions.TryAddRacePart(pawn, partType))
            {
                Hediff hdf = TryGetRJWPartHediff(pawn, partType);
                HediffComp_SexPart chdf = hdf.TryGetComp<HediffComp_SexPart>();
                if (chdf != null)
                {
                    chdf.UpdateSeverity(severity);
                }

                return true;
            }

            string defaultHediffName = "GenericBreasts";
            switch (partType)
            {
                case SexPartType.Anus:
                    defaultHediffName = "GenericAnus";
                    break;

                case SexPartType.FemaleGenital:
                    defaultHediffName = "GenericVagina";
                    break;

                case SexPartType.MaleGenital:
                    defaultHediffName = "GenericPenis";
                    break;
            }

            BodyPartRecord bpr = pawn.RaceProps.body.AllParts.Find(item => item.def == BodyPartDefBySexPartType[partType]);
            HediffDef hdd = DefDatabase<HediffDef>.GetNamed(defaultHediffName);
            Hediff hd = HediffMaker.MakeHediff(hdd, pawn, bpr);
            HediffComp_SexPart chd = hd.TryGetComp<HediffComp_SexPart>();

            if (chd == null)
            {
                return false;
            }

            chd.Init(pawn);
            chd.UpdateSeverity(severity);
            pawn.health.AddHediff(hd);

            return true;
        }

        public static T Clamp<T>(T value, T min, T max) where T : System.IComparable<T>
        {
            if (value.CompareTo(min) < 0) return min;
            else if (value.CompareTo(max) > 0) return max;
            return value;
        }
    }
}


code:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{57515AAF-B37A-4912-A910-4C629FEC734F}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>LicentiaLabs</RootNamespace>
    <AssemblyName>LicentiaLabs</AssemblyName>
    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <Deterministic>true</Deterministic>
    <TargetFrameworkProfile />
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>false</DebugSymbols>
    <DebugType>none</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>..\..\..\Assemblies\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
    <PlatformTarget>x64</PlatformTarget>
    <Prefer32Bit>false</Prefer32Bit>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>..\..\..\Assemblies\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <Prefer32Bit>false</Prefer32Bit>
    <PlatformTarget>x64</PlatformTarget>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="0Harmony">
      <HintPath>..\..\..\..\..\..\..\workshop\content\294100\2009463077\Current\Assemblies\0Harmony.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="Assembly-CSharp">
      <HintPath>..\..\..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="RJW">
      <HintPath>..\..\..\..\rjw-master\1.5\Assemblies\RJW.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Runtime.InteropServices.RuntimeInformation" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
    <Reference Include="UnityEngine">
      <HintPath>..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="UnityEngine.CoreModule">
      <HintPath>..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
      <Private>False</Private>
    </Reference>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="SerumProduction.cs" />
    <Compile Include="LicentiaHelper.cs" />
    <Compile Include="Mutator.cs" />
    <Compile Include="Patch.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
    <Compile Include="Serums.cs" />
    <Compile Include="Settings.cs" />
    <Compile Include="Stretch.cs" />
  </ItemGroup>
  <ItemGroup>
    <None Include="packages.config" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>


code:
using RimWorld;
using Verse;
using rjw;
using System.Linq;

namespace LicentiaLabs
{
	public class Comp_MutagenicSerum : ThingComp
	{
		public CompProperties_MutagenicSerum Props => (CompProperties_MutagenicSerum)props;

		public override void PostIngested(Pawn pawn)
		{
			var partBPR = Genital_Helper.get_genitalsBPR(pawn);
			var oldParts = Genital_Helper.get_PartsHediffList(pawn, partBPR);
			var newVagina = Props.vaginaDef;
			var newPenis = Props.penisDef;

			if (!oldParts.NullOrEmpty())
			{
				Hediff hd;
                HediffComp_SexPart CompHediff;

				foreach (Hediff hed in oldParts)
				{
					if (LicentiaHelper.IsArtificial(hed))
						continue;

					hd = null;
					CompHediff = null;
					if (hed.def.defName.ToLower().Contains("penis") ||
						hed.def.defName.ToLower().Contains("ovipositorm") ||
						hed.def.defName.ToLower().Contains("tentacle")
						)
					{
						hd = HediffMaker.MakeHediff(newPenis, pawn, partBPR);
					}

					if (hed.def.defName.ToLower().Contains("vagina") ||
						hed.def.defName.ToLower().Contains("ovipositorf")
						)
					{
						hd = HediffMaker.MakeHediff(newVagina, pawn, partBPR);
					}

					if (hd != null)
					{
						CompHediff = hd.TryGetComp<HediffComp_SexPart>();
						if (CompHediff != null)
						{
							//Log.Message("SexPartAdder::PartMaker init comps");
							CompHediff.Init(pawn);
							CompHediff.UpdateSeverity();
						}
						GenderHelper.ChangeSex(pawn, () =>
						{
							pawn.health.RemoveHediff(hed);
							pawn.health.AddHediff(hd, partBPR);
						});
					}
				}

				var message = "LL_GenitalsAltered".Translate(pawn);
				Messages.Message(message, pawn, MessageTypeDefOf.SilentInput);
			}
			else
			{
				Messages.Message("LL_GenitalsNotAlterable".Translate(pawn), pawn, MessageTypeDefOf.SilentInput);

				return;
			}
		}
	}

	public class Comp_MutagenicSerumSpecial : ThingComp
	{

		public CompProperties_MutagenicSerumSpecial Props => (CompProperties_MutagenicSerumSpecial)props;

		public override void PostIngested(Pawn pawn)
		{
			if (Props.breast && GenderHelper.GetSex(pawn) != GenderHelper.Sex.Male)
			{
				var partBPR = Genital_Helper.get_breastsBPR(pawn);
				var oldParts = Genital_Helper.get_PartsHediffList(pawn, partBPR);
				var newParts = Props.breastDef;

				if (!oldParts.NullOrEmpty())
				{
					Hediff hd;
					HediffComp_SexPart CompHediff;

					foreach (Hediff hed in oldParts)
					{
						if (LicentiaHelper.IsArtificial(hed))
							continue;

						hd = null;
						CompHediff = null;
						hd = HediffMaker.MakeHediff(newParts, pawn, partBPR);

						if (hd != null)
						{
							CompHediff = hd.TryGetComp<rjw.HediffComp_SexPart>();
							if (CompHediff != null)
							{
								//Log.Message("SexPartAdder::PartMaker init comps");
								CompHediff.Init(pawn);
								CompHediff.UpdateSeverity();
							}
							GenderHelper.ChangeSex(pawn, () =>
							{
								pawn.health.RemoveHediff(hed);
								pawn.health.AddHediff(hd, partBPR);
							});
						}
					}

					var message = "LL_BreastsAltered".Translate(pawn);
					Messages.Message(message, pawn, MessageTypeDefOf.SilentInput);
				}
			}

			if (Props.anus)
			{
				var partBPR = Genital_Helper.get_anusBPR(pawn);
				var oldParts = Genital_Helper.get_PartsHediffList(pawn, partBPR);
				var newParts = Props.anusDef;

				if (!oldParts.NullOrEmpty())
				{
					Hediff hd;
					HediffComp_SexPart CompHediff;

					foreach (Hediff hed in oldParts)
					{
						if (LicentiaHelper.IsArtificial(hed))
							continue;

						hd = null;
						CompHediff = null;
						hd = HediffMaker.MakeHediff(newParts, pawn, partBPR);

						if (hd != null)
						{
							CompHediff = hd.TryGetComp<rjw.HediffComp_SexPart>();
							if (CompHediff != null)
							{
								//Log.Message("SexPartAdder::PartMaker init comps");
								CompHediff.Init(pawn);
								CompHediff.UpdateSeverity();
							}
							GenderHelper.ChangeSex(pawn, () =>
							{
								pawn.health.RemoveHediff(hed);
								pawn.health.AddHediff(hd, partBPR);
							});
						}
					}

					var message = "LL_AnusAltered".Translate(pawn);
					Messages.Message(message, pawn, MessageTypeDefOf.SilentInput);
				}
			}
		}
	}

	public class Comp_ReverterSerum : ThingComp
	{
		//bool futa = false;
		public override void PostIngested(Pawn pawn)
		{
			if (GenderHelper.GetOriginalSex(pawn) == GenderHelper.Sex.None) {
				// what is happenning??
				return;
			}

			GenderHelper.ChangeSex(pawn, () =>
			{
				// trap, futa, female & male could all revert their anus
				var partBPR = Genital_Helper.get_anusBPR(pawn);
				var oldParts = Genital_Helper.get_PartsHediffList(pawn, partBPR);

				if (!oldParts.NullOrEmpty())
				{
					foreach (Hediff hed in oldParts)
					{
						if (LicentiaHelper.IsArtificial(hed))
							continue;

						pawn.health.RemoveHediff(hed);
						LicentiaHelper.AddSexPart(pawn, SexPartType.Anus);
					}
				}

				partBPR = Genital_Helper.get_genitalsBPR(pawn);
				oldParts = Genital_Helper.get_PartsHediffList(pawn, partBPR);

				// male, trap & futas gets a dic
				if (GenderHelper.GetOriginalSex(pawn) == GenderHelper.Sex.Male
				|| GenderHelper.GetOriginalSex(pawn) == GenderHelper.Sex.Trap
				|| GenderHelper.GetOriginalSex(pawn) == GenderHelper.Sex.Futa)
				{
					if (!oldParts.NullOrEmpty())
					{
						foreach (Hediff hed in oldParts)
						{
							if (LicentiaHelper.IsArtificial(hed))
								continue;

							if (hed.def.defName.ToLower().Contains("penis") ||
								hed.def.defName.ToLower().Contains("ovipositorm") ||
								hed.def.defName.ToLower().Contains("tentacle")
								)
							{
								pawn.health.RemoveHediff(hed);
								LicentiaHelper.AddSexPart(pawn, SexPartType.MaleGenital);
							}
						}
					}
				}

				// female & futa gets a vagoo
				if(GenderHelper.GetOriginalSex(pawn) == GenderHelper.Sex.Female
				|| GenderHelper.GetOriginalSex(pawn) == GenderHelper.Sex.Futa)
				{
					if (!oldParts.NullOrEmpty())
					{
						foreach (Hediff hed in oldParts)
						{
							if (LicentiaHelper.IsArtificial(hed))
								continue;

							if (hed.def.defName.ToLower().Contains("vagina") ||
								hed.def.defName.ToLower().Contains("ovipositorf")
								)
							{
								pawn.health.RemoveHediff(hed);
								LicentiaHelper.AddSexPart(pawn, SexPartType.FemaleGenital);
							}
						}
					}
				}

				partBPR = Genital_Helper.get_breastsBPR(pawn);
				oldParts = Genital_Helper.get_PartsHediffList(pawn, partBPR);

				// males have flat chest
				if (GenderHelper.GetOriginalSex(pawn) == GenderHelper.Sex.Male)
				{
					foreach (Hediff hed in oldParts)
					{
						if (LicentiaHelper.IsArtificial(hed))
							continue;

						pawn.health.RemoveHediff(hed);
						LicentiaHelper.AddSexPart(pawn, SexPartType.MaleBreast, 0.01f);
					}
				}

				// females have classic chest
				if(GenderHelper.GetOriginalSex(pawn) == GenderHelper.Sex.Female
				|| GenderHelper.GetOriginalSex(pawn) == GenderHelper.Sex.Futa)
				{
					foreach (Hediff hed in oldParts)
					{
						if (LicentiaHelper.IsArtificial(hed))
							continue;

						pawn.health.RemoveHediff(hed);
						LicentiaHelper.AddSexPart(pawn, SexPartType.FemaleBreast);
					}
				}
			});

			Messages.Message("LL_Reverted".Translate(pawn), pawn, MessageTypeDefOf.SilentInput);
		}
	}

	public class Comp_TraitSerum : ThingComp
	{
		public CompProperties_TraitSerum Props => (CompProperties_TraitSerum)props;
		public override void PostIngested(Pawn pawn)
		{
			if (Props.addTrait != null)
			{
				if (!Props.replaceTrait)
				{
					pawn.story.traits.GainTrait(new Trait(Props.addTrait));
				}
				else
				{
					pawn.story.traits.allTraits.Remove(pawn.story.traits.GetTrait(Props.removeTrait));
					pawn.story.traits.GainTrait(new Trait(Props.addTrait));
				}
			}
			else
			{
				pawn.story.traits.allTraits.Remove(pawn.story.traits.GetTrait(Props.removeTrait));
			}
			var message = "LL_PsycheAltered".Translate(pawn);
			Messages.Message(message, pawn, MessageTypeDefOf.SilentInput);
		}
	}

	public class CompProperties_MutagenicSerum : CompProperties
	{
		public HediffDef penisDef;
		public HediffDef vaginaDef;

		public CompProperties_MutagenicSerum()
		{
			compClass = typeof(Comp_MutagenicSerum);
		}
	}
	public class CompProperties_MutagenicSerumSpecial : CompProperties
	{
		public bool anus = false;
		public bool breast = false;
		public HediffDef anusDef;
		public HediffDef breastDef;

		public CompProperties_MutagenicSerumSpecial()
		{
			compClass = typeof(Comp_MutagenicSerumSpecial);
		}
	}
	public class CompProperties_ReverterSerum : CompProperties
	{
		public CompProperties_ReverterSerum()
		{
			compClass = typeof(Comp_ReverterSerum);
		}
	}
	public class CompProperties_TraitSerum : CompProperties
	{
		public bool replaceTrait = false;
		public TraitDef addTrait;
		public TraitDef removeTrait;
		public CompProperties_TraitSerum()
		{
			compClass = typeof(Comp_TraitSerum);
		}
	}
}


code:
using Verse;

namespace LicentiaLabs {

	public class Comp_LicentiaPart : HediffComp {
	}

	public class CompProperties_LicentiaPart : HediffCompProperties {
		public float stretchVariance = 0f;
		public float genitalSize = 0.5f;
		public float cumAmount = -1f;
		public HediffDef oppositeSexOrgan;
		public HediffDef oppositeBreasts;
		public HediffDef extrudedSexOrgan;
		public HediffDef retractedSexOrgan;

		public CompProperties_LicentiaPart()
		{
			compClass = typeof(Comp_LicentiaPart);
		}
	}
}


code:
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("LicentiaLabs")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Hewlett-Packard")]
[assembly: AssemblyProduct("LicentiaLabs")]
[assembly: AssemblyCopyright("Copyright © Hewlett-Packard 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components.  If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("57515aaf-b37a-4912-a910-4c629fec734f")]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]


code:
using Verse;

namespace LicentiaLabs
{
    internal class Hediff_ProducingHormonalSerum : HediffWithComps
    {
        public float SerumProgress
        {
            get => Severity;
            private set => Severity = value;
        }

        public override void Tick()
        {

            if (this.pawn.IsHashIntervalTick(1000))
            {
                if (SerumProgress == 1f)
                {
                    GenSpawn.Spawn(Licentia.ThingDefs.HormonalSerum, this.pawn.Position, this.pawn.Map);
                    this.Severity = 0f;
                }

            }
        }
    }
}


code:
using RimWorld;
using Verse;
using rjw;

namespace LicentiaLabs
{
	public class Comp_BreastIncrease : ThingComp
	{
		public override void PostIngested(Pawn pawn)
		{
			var partBPR = Genital_Helper.get_breastsBPR(pawn);
			var Parts = Genital_Helper.get_PartsHediffList(pawn, partBPR);

			if (!Parts.NullOrEmpty())
			{
				foreach (Hediff hed in Parts)
				{
					if (LicentiaHelper.IsArtificial(hed))
						continue;

					GenderHelper.ChangeSex(pawn, () =>
					{
						hed.Severity += 0.1f;
					});
				}
				Messages.Message("LL_BreastsSizeIncrease".Translate(pawn), pawn, MessageTypeDefOf.SilentInput);
			}
		}
	}

	public class Comp_BreastDecrease : ThingComp
	{
		public override void PostIngested(Pawn pawn)
		{
			var partBPR = Genital_Helper.get_breastsBPR(pawn);
			var Parts = Genital_Helper.get_PartsHediffList(pawn, partBPR);

			if (!Parts.NullOrEmpty())
			{
				foreach (Hediff hed in Parts)
				{
					if (LicentiaHelper.IsArtificial(hed))
						continue;

					GenderHelper.ChangeSex(pawn, () =>
					{
						if (hed.Severity <= 0.11f)
						{
							hed.Severity = 0.01f;
						}
						else
						{
							hed.Severity -= 0.1f;
						}
					});
				}
				Messages.Message("LL_BreastsSizeDecrease".Translate(pawn), pawn, MessageTypeDefOf.SilentInput);
			}
		}
	}

	public class Comp_GenitalIncrease : ThingComp
	{
		public override void PostIngested(Pawn pawn)
		{
			var partBPR = Genital_Helper.get_genitalsBPR(pawn);
			var oldParts = Genital_Helper.get_PartsHediffList(pawn, partBPR);

			if (!oldParts.NullOrEmpty())
			{
				foreach (Hediff hed in oldParts)
				{
					if (LicentiaHelper.IsArtificial(hed))
						continue;

					if (hed.def.defName.ToLower().Contains("penis") ||
						hed.def.defName.ToLower().Contains("ovipositorm") ||
						hed.def.defName.ToLower().Contains("tentacle")
						)
					{
						hed.Severity += 0.1f;
					}

					if (hed.def.defName.ToLower().Contains("vagina") ||
						hed.def.defName.ToLower().Contains("ovipositorf")
						)
					{
						if (hed.Severity <= 0.11f)
						{
							hed.Severity = 0.01f;
						}
						else
						{
							hed.Severity -= 0.1f;
						}
					}
				}
				Messages.Message("LL_GenitalsAltered".Translate(pawn), pawn, MessageTypeDefOf.SilentInput);
			}
		}
	}

	public class Comp_GenitalDecrease : ThingComp
	{
		public override void PostIngested(Pawn pawn) {

			var partBPR = Genital_Helper.get_genitalsBPR(pawn);
			var oldParts = Genital_Helper.get_PartsHediffList(pawn, partBPR);

			if (!oldParts.NullOrEmpty())
			{
				foreach (Hediff hed in oldParts)
				{
					if (LicentiaHelper.IsArtificial(hed))
						continue;

					if (hed.def.defName.ToLower().Contains("penis") ||
						hed.def.defName.ToLower().Contains("ovipositorm") ||
						hed.def.defName.ToLower().Contains("tentacle")
						)
					{
						if (hed.Severity <= 0.11f)
						{
							hed.Severity = 0.01f;
						}
						else
						{
							hed.Severity -= 0.1f;
						}
					}

					if (hed.def.defName.ToLower().Contains("vagina") ||
						hed.def.defName.ToLower().Contains("ovipositorf")
						)
					{
						hed.Severity += 0.1f;
					}
				}
				Messages.Message("LL_GenitalsAltered".Translate(pawn), pawn, MessageTypeDefOf.SilentInput);
			}
		}
	}

	//public class Comp_CumIncrease : ThingComp
	//{
	//	public override void PostIngested(Pawn pawn)
	//	{
	//		var partBPR = Genital_Helper.get_genitalsBPR(pawn);
	//		var oldParts = Genital_Helper.get_PartsHediffList(pawn, partBPR);

	//		if (!oldParts.NullOrEmpty())
	//		{
	//			Hediff hd;
	//			HediffComp_SexPart CompHediff;

	//			foreach (Hediff hed in oldParts)
	//			{
	//				if (LicentiaHelper.IsArtificial(hed))
	//					continue;

	//				hd = null;
	//				CompHediff = null;
	//				if (hed.def.defName.ToLower().Contains("penis") ||
	//					hed.def.defName.ToLower().Contains("ovipositorm") ||
	//					hed.def.defName.ToLower().Contains("tentacle")
	//					)
	//				{
	//					hd = hed;
	//				}

	//				if (hed.def.defName.ToLower().Contains("vagina") ||
	//					hed.def.defName.ToLower().Contains("ovipositorf")
	//					)
	//				{
	//					hd = hed;
	//				}

	//				if (hd != null)
	//				{
	//					CompHediff = hed.TryGetComp<rjw.HediffComp_SexPart>();
	//					if (CompHediff != null)
	//					{
 //                           CompHediff.partFluidMultiplier *= 1.1f;
	//					}
	//				}
	//			}
	//			Messages.Message("LL_CumAltered".Translate(pawn), pawn, MessageTypeDefOf.SilentInput);
	//		}
	//	}
	//}

	//public class Comp_CumDecrease : ThingComp
	//{
	//	public override void PostIngested(Pawn pawn)
	//	{
	//		var partBPR = Genital_Helper.get_genitalsBPR(pawn);
	//		var oldParts = Genital_Helper.get_PartsHediffList(pawn, partBPR);

	//		if (!oldParts.NullOrEmpty())
	//		{
	//			Hediff hd;
	//			HediffComp_SexPart CompHediff;

	//			foreach (Hediff hed in oldParts)
	//			{
	//				if (LicentiaHelper.IsArtificial(hed))
	//					continue;

	//				hd = null;
	//				CompHediff = null;
	//				if (hed.def.defName.ToLower().Contains("penis") ||
	//					hed.def.defName.ToLower().Contains("ovipositorm") ||
	//					hed.def.defName.ToLower().Contains("tentacle")
	//					)
	//				{
	//					hd = hed;
	//				}

	//				if (hed.def.defName.ToLower().Contains("vagina") ||
	//					hed.def.defName.ToLower().Contains("ovipositorf")
	//					)
	//				{
	//					hd = hed;
	//				}

	//				if (hd != null)
	//				{
	//					CompHediff = hed.TryGetComp<rjw.HediffComp_SexPart>();
	//					if (CompHediff != null)
	//					{
	//						CompHediff.partFluidMultiplier *= 0.9f;
	//					}
	//				}
	//			}
	//			Messages.Message("LL_CumAltered".Translate(pawn), pawn, MessageTypeDefOf.SilentInput);
	//		}
	//	}
	//}

	public class Comp_AnalTighteningSerum : ThingComp
	{

		public override void PostIngested(Pawn pawn)
		{
			var partBPR = Genital_Helper.get_anusBPR(pawn);
			var Parts = Genital_Helper.get_PartsHediffList(pawn, partBPR);

			if (!Parts.NullOrEmpty())
			{
				foreach (Hediff hed in Parts)
				{
					if (LicentiaHelper.IsArtificial(hed))
						continue;

					if (hed.Severity <= 0.11f)
					{
						hed.Severity = 0.01f;
					}
					else
					{
						hed.Severity -= 0.1f;
					}
				}
				var message = "LL_AnusAltered".Translate(pawn);
				Messages.Message(message, pawn, MessageTypeDefOf.SilentInput);
			}
		}
	}

	public class Comp_Genderbend : ThingComp
	{
		public override void PostIngested(Pawn pawn)
		{
			if (GenderHelper.GetOriginalSex(pawn) == GenderHelper.Sex.Futa) //if futa
			{
				Messages.Message("LL_NoEffectOnFuta".Translate(pawn), pawn, MessageTypeDefOf.SilentInput);
				return;
			}

			GenderHelper.ChangeSex(pawn, () =>
			{
				var partBPR = Genital_Helper.get_genitalsBPR(pawn);
				var Parts = Genital_Helper.get_PartsHediffList(pawn, partBPR);

				if (!Genital_Helper.has_penis_fertile(pawn, Parts) && !Genital_Helper.has_penis_infertile(pawn, Parts))
				{
					LicentiaHelper.AddSexPart(pawn, SexPartType.MaleGenital);
				}
				else
				{
					if (!Parts.NullOrEmpty())
					{
						foreach (Hediff hed in Parts)
						{
							if (LicentiaHelper.IsArtificial(hed))
								continue;

							if (hed.def.defName.ToLower().Contains("penis") ||
								hed.def.defName.ToLower().Contains("ovipositorm") ||
								hed.def.defName.ToLower().Contains("tentacle")
								)
							{
								pawn.health.RemoveHediff(hed);
							}
						}
					}
				}

				if (!Genital_Helper.has_vagina(pawn, Parts))
				{
					LicentiaHelper.AddSexPart(pawn, SexPartType.FemaleGenital);
				}
				else
				{
					if (!Parts.NullOrEmpty())
					{
						foreach (Hediff hed in Parts)
						{
							if (LicentiaHelper.IsArtificial(hed))
								continue;

								if (hed.def.defName.ToLower().Contains("vagina") ||
									hed.def.defName.ToLower().Contains("ovipositorf")
									)
								{
								pawn.health.RemoveHediff(hed);
							}
						}
					}
				}
			});

			Messages.Message("LL_GenitalsSwapped".Translate(pawn), pawn, MessageTypeDefOf.SilentInput);
		}
	}

	public class Comp_FutaSerum : ThingComp
	{
		public override void PostIngested(Pawn pawn)
		{
			if (GenderHelper.GetOriginalSex(pawn) == GenderHelper.Sex.Futa) //if futa
			{
				Messages.Message("LL_NoEffectOnFuta".Translate(pawn), pawn, MessageTypeDefOf.SilentInput);
				return;
			}

			GenderHelper.ChangeSex(pawn, () =>
			{
				var partBPR = Genital_Helper.get_genitalsBPR(pawn);
				var Parts = Genital_Helper.get_PartsHediffList(pawn, partBPR);

				if (!Genital_Helper.has_penis_fertile(pawn, Parts) && !Genital_Helper.has_penis_infertile(pawn, Parts)) {
					LicentiaHelper.AddSexPart(pawn, SexPartType.MaleGenital);
				}

				if (!Genital_Helper.has_vagina(pawn, Parts))
				{
					LicentiaHelper.AddSexPart(pawn, SexPartType.FemaleGenital);
				}

				partBPR = Genital_Helper.get_breastsBPR(pawn);
				Parts = Genital_Helper.get_PartsHediffList(pawn, partBPR);
				if (Parts.NullOrEmpty() || (!Genital_Helper.has_breasts(pawn, Parts) && !Parts.Any((Hediff hed) => hed.def.defName.ToLower().Contains("featureless"))))
				{
					LicentiaHelper.AddSexPart(pawn, SexPartType.FemaleBreast);
				}
			});

			Messages.Message("LL_MadeFuta".Translate(pawn), pawn, MessageTypeDefOf.SilentInput);
		}
	}

	public class CompProperties_BreastIncrease : CompProperties
	{
		public CompProperties_BreastIncrease()
		{
			compClass = typeof(Comp_BreastIncrease);
		}
	}
	public class CompProperties_BreastDecrease : CompProperties
	{
		public CompProperties_BreastDecrease()
		{
			compClass = typeof(Comp_BreastDecrease);
		}
	}
	public class CompProperties_GenitalIncrease : CompProperties
	{
		public CompProperties_GenitalIncrease()
		{
			compClass = typeof(Comp_GenitalIncrease);
		}
	}
	public class CompProperties_GenitalDecrease : CompProperties
	{
		public CompProperties_GenitalDecrease()
		{
			compClass = typeof(Comp_GenitalDecrease);
		}
	}
	//public class CompProperties_CumIncrease : CompProperties
	//{
	//	public CompProperties_CumIncrease()
	//	{
	//		compClass = typeof(Comp_CumIncrease);
	//	}
	//}
	//public class CompProperties_CumDecrease : CompProperties
	//{
	//	public CompProperties_CumDecrease()
	//	{
	//		compClass = typeof(Comp_CumDecrease);
	//	}
	//}
	public class CompProperties_Genderbend: CompProperties
	{
		public CompProperties_Genderbend()
		{
			compClass = typeof(Comp_Genderbend);
		}
	}
	public class CompProperties_FutaSerum: CompProperties
	{
		public CompProperties_FutaSerum()
		{
			compClass = typeof(Comp_FutaSerum);
		}
	}

	public class CompProperties_AnalTighteningSerum : CompProperties
	{
		public CompProperties_AnalTighteningSerum()
		{
			compClass = typeof(Comp_AnalTighteningSerum);
		}
	}
}


code:
using UnityEngine;
using Verse;

namespace LicentiaLabs
{
	public class Settings : ModSettings
	{
		public static bool IsAllowMultiplePenetratorsPerOrifice = true;
		public static bool IsStretchingEnabled = true;
		public static bool IsPermanentStretchEnabled = true;
		public static bool IsStretchTextPlayerFactionVisibleOnly = true;

		public static bool IsDamageEnabled = false;
		public static float DamageMultiplier = 1f;
		public static bool IsProlapseEnabled = false;

		public override void ExposeData()
		{
			Scribe_Values.Look(ref IsAllowMultiplePenetratorsPerOrifice, "IsAllowMultiplePenetratorsPerOrifice", true);
			Scribe_Values.Look(ref IsStretchingEnabled, "IsStretchingEnabled", true);
			Scribe_Values.Look(ref IsPermanentStretchEnabled, "IsPermanentStretchEnabled", true);
			Scribe_Values.Look(ref IsStretchTextPlayerFactionVisibleOnly, "IsStretchTextPlayerFactionVisibleOnly", true);

			Scribe_Values.Look(ref IsDamageEnabled, "IsDamageEnabled", false);
			Scribe_Values.Look(ref DamageMultiplier, "DamageMultiplier", 1f);
			Scribe_Values.Look(ref IsProlapseEnabled, "IsProlapseEnabled", false);
			base.ExposeData();
		}

		private static readonly float height_modifier = 100f;

		public static void DoWindowContents(Rect inRect)
		{
			Rect viewRect = new Rect(0f, 0f, inRect.width - 16f, inRect.height + height_modifier);

            Listing_Standard listingStandard = new Listing_Standard
            {
                maxOneColumn = true,
                ColumnWidth = viewRect.width / 2.05f
            };
            listingStandard.Begin(inRect);
			listingStandard.Gap(4f);
			listingStandard.CheckboxLabeled("Enable multiple penetrators per orifice", ref IsAllowMultiplePenetratorsPerOrifice, "Allow orifices to have a chance of being targeted by more than one penetrator at once, if more are available.");
			listingStandard.Gap(4f);
			listingStandard.CheckboxLabeled("Enable stretching effects", ref IsStretchingEnabled, "Allow orifices to be stretched, which affects colonists' moods.");
			listingStandard.Gap(4f);
			listingStandard.CheckboxLabeled("Enable permanent stretching", ref IsPermanentStretchEnabled, "Allow orifices to be permanently stretched by large penetrators (at least 1.5x size of orifice).");
			listingStandard.Gap(4f);
			listingStandard.CheckboxLabeled("Stretch messages for player faction only:", ref IsStretchTextPlayerFactionVisibleOnly, "Only show stretch messages for player faction");

			listingStandard.Gap(40f);
			listingStandard.CheckboxLabeled("Enable orifice damage", ref IsDamageEnabled, "Allow orifices to be damaged by overly large penetrations.");
			listingStandard.Gap(4f);
			listingStandard.Label("Damage multiplier (ranges from 0.1x to 2x): " + DamageMultiplier);
			DamageMultiplier = listingStandard.Slider(DamageMultiplier, 0.1f, 2f);
			listingStandard.Gap(4f);
			listingStandard.CheckboxLabeled("Enable orifice prolapsing", ref IsProlapseEnabled, "Allow orifices to be prolapsed, which, in extreme cases, may require surgery.");
			listingStandard.End();
		}
	}

	public class LicentiaLabs : Mod
	{
		private readonly Settings settings;

		public LicentiaLabs(ModContentPack content) : base(content)
		{
			settings = GetSettings<Settings>();
		}

		public override string SettingsCategory()
		{
			return "RJW Licentia Labs";
		}

		public override void DoSettingsWindowContents(Rect inRect)
		{
			Settings.DoWindowContents(inRect);
		}
	}
}


code:
using HarmonyLib;
using RimWorld;
using rjw;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Verse;

namespace LicentiaLabs
{
    public static class StretchHelper
    {
        public static void Stretch(SexProps props)
        {
            if (!LicentiaHelper.GetPenetrator(props, out Pawn penetrator, out Pawn recipient))
            {
                // If there is not penetrator involved, then there will be no inflation.
                return;
            }

            if (props.pawn != recipient)
            {
                // RJW calls SatisfyPersonal 2 times with props.pawn pointing to different participant.
                return;
            }

            if (IsElasticised(recipient))
            {
                // Elasticised recipients cannot be stretched.
                return;
            }

            // Collect some information about the act beforehand, namely the dimensions of the hediffs being
            // used for penetrating and for being penetrated.
            // Collect penetrator dimensions.
            var adjustedPenetratorDimensions = GetAdjustedHediffDimensions(penetrator, LicentiaHelper.TryGetPawnPenisHediff(penetrator));
            if (adjustedPenetratorDimensions.EnumerableNullOrEmpty())
            {
                return;
            }

            // Collect orifice dimensions.
            var pawnOrifices = new List<Hediff>();
            if (props.sexType == xxx.rjwSextype.DoublePenetration || props.sexType == xxx.rjwSextype.Vaginal)
            {
                pawnOrifices.Add(LicentiaHelper.TryGetPawnVaginaHediff(recipient));
            }
            if (props.sexType == xxx.rjwSextype.DoublePenetration || props.sexType == xxx.rjwSextype.Anal)
            {
                pawnOrifices.Add(LicentiaHelper.TryGetPawnAnusHediff(recipient));
            }
            if (pawnOrifices.EnumerableNullOrEmpty())
            {
                return;
            }
            var adjustedOrificeDimensions = GetAdjustedHediffDimensions(recipient, pawnOrifices, float.MaxValue / 2);
            if (adjustedOrificeDimensions.EnumerableNullOrEmpty())
            {
                return;
            }

            // Map penetrators (not their dimensions, just the penetrator Hediffs themselves) to orifices.
            var targetMappings = MapOrificesToPenetrators(adjustedPenetratorDimensions.Keys, pawnOrifices);

            // Determine what the new severity increase should be.
            foreach (var mapping in targetMappings)
            {
                var orifice = mapping.Key;
                if (LicentiaHelper.IsArtificial(orifice))
                {
                    // Artificial orifices cannot be stretched.
                    continue;
                }

                // Collect the penetrator dimensions.
                var penetrators = mapping.Value;
                var penetratorDimensions = CalculateTotalPenetratorDimensions(penetrators, adjustedPenetratorDimensions);
                var orificeDimensions = adjustedOrificeDimensions.TryGetValue(orifice);

                var isStretched = DoesStretchingOccur(penetratorDimensions, orificeDimensions, props.isRape, out var isPermanentlyStretched);
                if (!isStretched.Item1 && !isStretched.Item2)
                {
                    // Orifice is larger than penetrators in all dimensions.
                    continue;
                }

                // Find the larger of the permanent severities for the orifice to add to the real
                // orifice severity.
                var lengthPermSeverity = StretchOrifice(recipient, isPermanentlyStretched.Item1, isStretched.Item1, orifice, penetratorDimensions.Item1, orificeDimensions.Item1, out float lengthDamage);
                var girthPermSeverity = StretchOrifice(recipient, isPermanentlyStretched.Item2, isStretched.Item2, orifice, penetratorDimensions.Item2, orificeDimensions.Item2, out float girthDamage);
                var greaterPermSeverity = Math.Max(lengthPermSeverity, girthPermSeverity);
                if (greaterPermSeverity > 0f)
                {
                   float permTotal = orifice.Severity += greaterPermSeverity;
                   HediffComp_SexPart hediffComp = orifice.TryGetComp<HediffComp_SexPart>();
                   hediffComp.UpdateSeverity(permTotal);
                }

                GiveStretchThoughts(recipient);

                if (DamageHelper.IsPawnInvulnerable(recipient) || orifice.Part == null)
                {
                    continue;
                }

                if (Settings.IsDamageEnabled)
                {
                    if (lengthDamage > 0f)
                    {
                        if (Settings.IsDamageEnabled)
                        {
                            if (orifice.def.defName.Contains("Vagina"))
                            {
                                DamageHelper.ApplyDamage(recipient, orifice.Part, Licentia.HediffDefs.CervixBruise, lengthDamage);
                            }
                            else
                            {
                                DamageHelper.ApplyDamage(recipient, orifice.Part, Licentia.HediffDefs.StretchTear, lengthDamage);
                            }
                        }
                    }
                    if (girthDamage > 0f)
                    {
                        DamageHelper.ApplyDamage(recipient, orifice.Part, Licentia.HediffDefs.StretchTear, girthDamage);
                    }
                }

                float higherDamage = Math.Max(lengthDamage, girthDamage);
                if (Settings.IsProlapseEnabled && higherDamage > 0f)
                {
                    // When length damage is below 1.5f, apply a regular prolapse. If over 1.5f, apply an extreme
                    // prolapse. Severity will scale linearly from 0f to 1f for regular prolapse severity, while
                    // extreme prolapse severity will be fixed to 1.0f.
                    if (higherDamage <= 1.5f)
                    {
                        DamageHelper.ApplyDamage(recipient, orifice.Part, Licentia.HediffDefs.Prolapse, higherDamage * 2f / 3f);
                    }
                    else if (higherDamage <= 2.5f)
                    {
                        // To lessen the number of extreme prolapses, the threshold for damage can go up to 2.5f
                        // but the receipient Pawn will receive a regular prolapse instead at max severity.
                        DamageHelper.ApplyDamage(recipient, orifice.Part, Licentia.HediffDefs.Prolapse, 1f);
                    }
                    else
                    {
                        DamageHelper.ApplyDamage(recipient, orifice.Part, Licentia.HediffDefs.ExtremeProlapse, 1f);
                    }
                }
            }
        }

        /// <summary>
        /// Checks to see if the given <c>Pawn</c> is a valid stretch target.
        /// </summary>
        /// <param name="stretchee">the <c>Pawn</c> to be checked</param>
        /// <returns><c>true</c> if the <paramref name="stretchee"/> has used an elasticise serum recently,
        /// <c>false</c> otherwise.</returns>
        public static bool IsElasticised(Pawn stretchee)
        {
            return false;
        }

        /// <summary>
        /// Calculates the lengths and girths of each genital <c>Hediff</c> specified in the <paramref name="hediffs"/>
        /// list. It is assumed that each <c>Hediff</c> belongs to the provided <paramref name="pawn"/>.
        /// If lengths and girths are not available, then <c>Hediff</c> severity will be used as the
        /// substitute.
        /// </summary>
        /// <param name="pawn">the <c>Pawn</c> that is assumed to own all of the <c>Hediff</c>s</param>
        /// <param name="hediffs">the <c>Hediff</c>s containing the <c>Hediff</c>s to be calculated</param>
        /// <param name="defaultValue">the value to be used if no dimension value could be obtained</param>
        /// <returns>A Dictionary of <c>Hediff</c>s to tuples of the <c>Hediff</c>s' lengths and girths in
        /// that order.</returns>
        public static Dictionary<Hediff, (float, float)> GetAdjustedHediffDimensions(Pawn pawn, IEnumerable<Hediff> hediffs, float defaultValue = float.MinValue)
        {
            Dictionary<Hediff, (float, float)> hediffDimensions = new Dictionary<Hediff, (float, float)>();

            // Theoretically, a Pawn could have both enlargement and diminishment effects active at the same time.
            var adjustmentValue = 0f;

            // Calculate the length and girth of each Hediff.
            foreach (var hediff in hediffs)
            {
                // Some HediffComps have varying stretch amounts.
                var stretchVariance = hediff.def.CompProps<CompProperties_LicentiaPart>()?.stretchVariance;
                if (stretchVariance.HasValue)
                {
                    adjustmentValue += Rand.Range(0, (float)stretchVariance) / 2f;
                }

                // Try to use length and girth if at all possible, and use Severity only as a fallback.
                HediffComp_SexPart rjwHediff = hediff.TryGetComp<HediffComp_SexPart>();
                if (rjwHediff != null)
                {
                    if (!PartSizeCalculator.TryGetLength(hediff, out float length)) length = defaultValue == float.MinValue ? hediff.Severity : defaultValue;
                    length += adjustmentValue;
                    if (!PartSizeCalculator.TryGetGirth(hediff, out float girth)) girth = defaultValue == float.MinValue ? hediff.Severity : defaultValue;
                    girth += adjustmentValue;
                    if (length < 0 || girth < 0)
                    {
                        continue;
                    }
                    hediffDimensions.Add(hediff, (length, girth));
                }
                else
                {
                    if (hediff.Severity < 0)
                    {
                        continue;
                    }
                    hediffDimensions.Add(hediff, (hediff.Severity, hediff.Severity));
                }
            }

            return hediffDimensions;
        }

        /// <summary>
        /// Tries to pair penetrators with orifices. If there are more penetrators than there are orifices,
        /// then the targets will be doubled up and later may have a chance of multiple penetrators targeting
        /// the same orifice, increasing effective girth when calculated for stretching.
        /// </summary>
        /// <param name="penetrators">the penetrator <c>Hediff</c>s</param>
        /// <param name="orifices">the orifice <c>Hediff</c>s; count must be greater than 0</param>
        /// <returns>A Dictionary mapping orifice <c>Hediff</c>s to one or more penetrator <c>Hediff</c>s</returns>
        public static Dictionary<Hediff, List<Hediff>> MapOrificesToPenetrators(IEnumerable<Hediff> penetrators, IList<Hediff> orifices)
        {
            var penetratorList = penetrators.ToList();
            penetratorList.Shuffle();

            var output = new Dictionary<Hediff, List<Hediff>>();
            var nOrifices = orifices.Count();
            for (int ii = 0; ii < penetratorList.Count(); ++ii)
            {
                var orifice = orifices[ii % nOrifices];
                if (!output.TryGetValue(orifice, out List<Hediff> mappedPenetrators))
                {
                    mappedPenetrators = new List<Hediff>();
                    output.Add(orifice, mappedPenetrators);
                }
                var penetrator = penetratorList[ii];
                mappedPenetrators.Add(penetrator);

                if (ii == nOrifices - 1 && !Settings.IsAllowMultiplePenetratorsPerOrifice)
                {
                    break;
                }
            }
            return output;
        }

        /// <summary>
        /// Determines what the final total penetrator dimensions will be. The maximum penetrator length
        /// and some form of summation of girths will be used, meaning that the overall penetrator dimensions
        /// will be that of some aggregate penetrator roughly resembling all of the penetrators used.
        /// </summary>
        /// <param name="penetrators">the <c>Hediff</c>s performing the penetrating</param>
        /// <param name="penetratorDimensions">the Dictionary that will serve as a lookup for dimensions
        /// of each of the <paramref name="penetrators"/></param>
        /// <returns>A tuple of the aggregate penetrator's length and girth in that order.</returns>
        public static (float, float) CalculateTotalPenetratorDimensions(IEnumerable<Hediff> penetrators, Dictionary<Hediff, (float, float)> penetratorDimensions)
        {
            var length = 0f;
            var totalGirth = 0f;
            foreach (var penetrator in penetrators)
            {
                var dimensions = penetratorDimensions.TryGetValue(penetrator);
                if (length == 0f || totalGirth == 0f || true/*Rand.Range(0f, 1f) > 0.5f*/)
                {
                    length = Math.Max(length, dimensions.Item1);
                    totalGirth += dimensions.Item2;
                }
            }
            return (length, totalGirth);
        }

        /// <summary>
        /// Determines based on preset thresholds whether the orifice being penetrated should be stretched
        /// or not.
        /// </summary>
        /// <param name="penetrator">The aggregate length and girth of the penetrator</param>
        /// <param name="orifice">The length and girth of the receiving orifice</param>
        /// <param name="isRape">lowers the threshold for stretching effects from simple comparison to
        /// modifying the penetrating dimensions to 125% their actual dimensions to simulate the damaging
        /// effects of non-consensual intercourse.</param>
        /// <param name="isPermanentlyStretched">Contains whether the length or girth are valid stretching
        /// candidates</param>
        /// <returns>Whether there was any stretching at all in either length or girth directions.</returns>
        public static (bool, bool) DoesStretchingOccur((float, float) penetrator, (float, float) orifice, bool isRape, out (bool, bool) isPermanentlyStretched)
        {
            // Check for stretching length-wise.
            bool isLengthStretched = penetrator.Item1 * (isRape ? 1.25f : 1f) > orifice.Item1;
            bool isLengthStretchedPerm = Settings.IsPermanentStretchEnabled && penetrator.Item1 * (isRape ? 1.25f : 1f) > orifice.Item1 * 1.5;

            // Check for stretching girth-wise.
            bool isGirthStretched = penetrator.Item2 * (isRape ? 1.25f : 1f) > orifice.Item2;
            bool isGirthStretchedPerm = Settings.IsPermanentStretchEnabled && penetrator.Item2 * (isRape ? 1.25f : 1f) > orifice.Item2 * 1.5;

            isPermanentlyStretched = (isLengthStretchedPerm, isGirthStretchedPerm);
            return (isLengthStretched, isGirthStretched);
        }

        /// <summary>
        /// Adds a "Stretched" <c>Hediff</c> to the orifice currently being stretched. Also returns the
        /// severity increase for the orifice if permanent stretching has taken place and is enabled. One
        /// of the two parameters <paramref name="isPermanentlyStretched"/> or <paramref name="isStretched"/>
        /// must be true for this function to have any effect.
        /// </summary>
        /// <param name="penetratedPawn">the <c>Pawn</c> receiving the penetration</param>
        /// <param name="isPermanentlyStretched">if true, then permanent stretching is to be performed</param>
        /// <param name="isStretched">if true, then temporary stretching is to be performed</param>
        /// <param name="orifice">the orifice <c>Hediff</c> being stretched</param>
        /// <param name="penetratorDimension">the current dimension being checked (length or girth) for
        /// the penetrator</param>
        /// <param name="orificeDimension">the current dimension being checked (length or girth) for
        /// the receiving orifice</param>
        /// <param name="uniqueDamage">the damage to be uniquely received by the penetrated orifice; scales
        /// from 0f to 2f when the adjusted dimension ratio between penetrator and orifice was >150%.</param>
        /// <returns></returns>
        public static float StretchOrifice(Pawn penetratedPawn, bool isPermanentlyStretched, bool isStretched, Hediff orifice, float penetratorDimension, float orificeDimension, out float uniqueDamage)
        {
            float severityIncrease = 0f;
            Hediff hediff = null;
            if (isPermanentlyStretched)
            {
                // Attempt to increase the severity of the stretched orifice, as that is the only way that the
                // orifice can increase in size (and prevent stretching again).
                // TODO: Could use an algorithm for directly converting dimension differences into severity.
                var ratio = Math.Min(penetratorDimension / orificeDimension / 1.5f, 0.12f) * Rand.Range(0.85f, 1.15f); // The maximum an orifice can stretch by is 10%-14% its current severity.
                GenderHelper.ChangeSex(penetratedPawn, () =>
                {
                    var stretchAmount = orifice.Severity * ratio;
                    severityIncrease = LicentiaHelper.Clamp(stretchAmount, 0.05f, 0.25f); // Clamp the actual severity increase to prevent rapid changes.
                });

                // Stretching severity will scale from 25% (lasting one day) to 100% (lasting 4 days) depending
                // on how badly the orifice was stretched.
                hediff = HediffMaker.MakeHediff(Licentia.HediffDefs.Stretched, penetratedPawn);
                hediff.Severity = 0.25f + LicentiaHelper.Clamp(0.75f * (ratio / 0.12f), 0.25f, 0.75f);
                penetratedPawn.health.AddHediff(hediff, orifice.Part);

                if (!Settings.IsStretchTextPlayerFactionVisibleOnly || (penetratedPawn.Faction?.IsPlayer ?? false))
                {
                    Messages.Message("LL_OrificeStretched".Translate(penetratedPawn, orifice.def.defName.ToLower()), penetratedPawn, MessageTypeDefOf.SilentInput);
                }
            }
            else if (isStretched)
            {
                // If any stretching occurred at all, there will be a minimum of 25% severity for stretching. Mild
                // stretching will last one day.
                hediff = HediffMaker.MakeHediff(Licentia.HediffDefs.Stretched, penetratedPawn);
                hediff.Severity = 0.25f;
                penetratedPawn.health.AddHediff(hediff, orifice.Part);
            }
            else
            {
                // For some reason, this function was called without any stretching taking place.
                uniqueDamage = 0f;
                return 0f;
            }

            // Stretch severity ranges between 0.25f and 1.0f, which means the severity of the damage can
            // range between 0f (regular stretching does not cause tears) and 2.0f, which is 25% of the orifice
            // HP for a >150% stretch.
            // Formula here is a linear relationship: y = 2.6666...x + 0.6666...
            uniqueDamage = Settings.DamageMultiplier * ((2f + 2f / 3f) * hediff?.Severity ?? 0f) - (2f / 3f);
            return severityIncrease;
        }

        /// <summary>
        /// Gives the <paramref name="stretchee"/> a thought about having been stretched. For <c>Pawn</c>s
        /// that enjoy pain or the act of stretching itself, a positive thought will be gained. Otherwise,
        /// the <c>Pawn</c> will gain a negative thought.
        /// </summary>
        /// <param name="stretchee">the <c>Pawn</c> that was stretched and will be receiving a thought</param>
        public static void GiveStretchThoughts(Pawn stretchee)
        {
            if (xxx.is_animal(stretchee))
            {
                return;
            }

            string pawn_quirks = CompRJW.Comp(stretchee).quirks.ToString();
            if (pawn_quirks.Contains("Impregnation fetish") ||
                pawn_quirks.Contains("Teratophile") ||
                pawn_quirks.Contains("Incubator") ||
                pawn_quirks.Contains("Breeder") ||
                xxx.is_zoophile(stretchee))
            {
                stretchee.needs.mood.thoughts.memories.TryGainMemory(Licentia.ThoughtDefs.GotStretchedKinky);
            }
            else if (xxx.is_masochist(stretchee))
            {
                stretchee.needs.mood.thoughts.memories.TryGainMemory(Licentia.ThoughtDefs.GotStretchedMasochist);
            }
            else
            {
                stretchee.needs.mood.thoughts.memories.TryGainMemory(Licentia.ThoughtDefs.GotStretched);
            }
        }
    }

    public static class DamageHelper
    {
        public static bool IsPawnInvulnerable(Pawn pawn)
        {
            return false;
        }

        public static void ApplyDamage(Pawn pawn, BodyPartRecord part, HediffDef damageType, float damage)
        {
            if (part == null)
            {
                return;
            }

            var hediff = HediffMaker.MakeHediff(damageType, pawn);
            hediff.Severity = damage;
            pawn.health.AddHediff(hediff, part);
        }
    }

    [StaticConstructorOnStartup]
    internal static class First
    {
        static First()
        {
            var har = new Harmony("LL");
            har.PatchAll(Assembly.GetExecutingAssembly());
        }
    }

    [HarmonyPatch(typeof(SexUtility))]
    [HarmonyPatch("SatisfyPersonal")]
    [HarmonyPatch(new Type[] { typeof(SexProps), typeof(float) })]
    public static class StretchPatch
    {
        [HarmonyPostfix]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Parameter is provided by RJW through Harmony.")]
        public static void SatisfyPersonal(SexProps props, float satisfaction)
        {
            if (props.isCoreLovin || !Settings.IsStretchingEnabled || props.pawn?.Dead == true || props.partner == null || props.partner.Dead == true)
            {
                return;
            }

            StretchHelper.Stretch(props);
        }
    }
}


code:
<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Lib.Harmony" version="2.0.2" targetFramework="net472" />
</packages>


code:
# IDE, temp, generated, and other local-only files
.idea/
*.iml
node_modules/
tweego.exe
*.html
*.7z

* Ignoring working folder for Quin2k
mod/
*.code-workspace
release/

path: .gitignore

license: mit


code:
<NotepadPlus>
	<UserLang name="Sugarcube4" ext="twee tw" udlVersion="2.1">
		<Settings>
			<Global caseIgnored="no" allowFoldOfComments="no" foldCompact="yes" forcePureLC="0" decimalSeparator="0" />
			<Prefix Keywords1="yes" Keywords2="no" Keywords3="no" Keywords4="no" Keywords5="no" Keywords6="no" Keywords7="no" Keywords8="no" />
		</Settings>
		<KeywordLists>
			<Keywords name="Comments">00 01 02 03/% 03/* 03<!-- 04%/ 04*/ 04--></Keywords>
			<Keywords name="Numbers, prefix1"></Keywords>
			<Keywords name="Numbers, prefix2"></Keywords>
			<Keywords name="Numbers, extras1"></Keywords>
			<Keywords name="Numbers, extras2"></Keywords>
			<Keywords name="Numbers, suffix1"></Keywords>
			<Keywords name="Numbers, suffix2"></Keywords>
			<Keywords name="Numbers, range"></Keywords>
			<Keywords name="Operators1">+ - * / = += -= *= /= ++ -- == != === !== > < >= <= ! && || & | ( )</Keywords>
			<Keywords name="Operators2"></Keywords>
			<Keywords name="Folders in code1, open"><<if</Keywords>
			<Keywords name="Folders in code1, middle"></Keywords>
			<Keywords name="Folders in code1, close"><</if>></Keywords>
			<Keywords name="Folders in code2, open"></Keywords>
			<Keywords name="Folders in code2, middle"></Keywords>
			<Keywords name="Folders in code2, close"></Keywords>
			<Keywords name="Folders in comment, open"></Keywords>
			<Keywords name="Folders in comment, middle"></Keywords>
			<Keywords name="Folders in comment, close"></Keywords>
			<Keywords name="Keywords1">$ _</Keywords>
			<Keywords name="Keywords2"></Keywords>
			<Keywords name="Keywords3"></Keywords>
			<Keywords name="Keywords4"></Keywords>
			<Keywords name="Keywords5"></Keywords>
			<Keywords name="Keywords6"></Keywords>
			<Keywords name="Keywords7"></Keywords>
			<Keywords name="Keywords8"></Keywords>
			<Keywords name="Delimiters">00:: 01 02((EOL)) 03<< 04 05>> 06[[ 07 08]] 09< 10 11> 12'' 13 14'' 15// 16 17// 18@@ 19 20@@ 21[img[ 22 23]]</Keywords>
		</KeywordLists>
		<Styles>
			<WordsStyle name="DEFAULT" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
			<WordsStyle name="COMMENTS" fgColor="808080" bgColor="FFFFFF" fontName="" fontStyle="2" nesting="0" />
			<WordsStyle name="LINE COMMENTS" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
			<WordsStyle name="NUMBERS" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
			<WordsStyle name="KEYWORDS1" fgColor="004080" bgColor="FFFFFF" fontName="" fontStyle="1" nesting="0" />
			<WordsStyle name="KEYWORDS2" fgColor="8080C0" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
			<WordsStyle name="KEYWORDS3" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
			<WordsStyle name="KEYWORDS4" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
			<WordsStyle name="KEYWORDS5" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
			<WordsStyle name="KEYWORDS6" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
			<WordsStyle name="KEYWORDS7" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
			<WordsStyle name="KEYWORDS8" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
			<WordsStyle name="OPERATORS" fgColor="800040" bgColor="FFFFFF" fontName="" fontStyle="1" nesting="0" />
			<WordsStyle name="FOLDER IN CODE1" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="1" nesting="0" />
			<WordsStyle name="FOLDER IN CODE2" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
			<WordsStyle name="FOLDER IN COMMENT" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
			<WordsStyle name="DELIMITERS1" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="5" fontSize="12" nesting="0" />
			<WordsStyle name="DELIMITERS2" fgColor="800080" bgColor="FFFFFF" fontName="" fontStyle="1" nesting="50334724" />
			<WordsStyle name="DELIMITERS3" fgColor="0000FF" bgColor="FFFFFF" fontName="" fontStyle="1" nesting="1024" />
			<WordsStyle name="DELIMITERS4" fgColor="0000FF" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
			<WordsStyle name="DELIMITERS5" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="1" nesting="32" />
			<WordsStyle name="DELIMITERS6" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="2" nesting="16" />
			<WordsStyle name="DELIMITERS7" fgColor="008000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
			<WordsStyle name="DELIMITERS8" fgColor="8080FF" bgColor="FFFFFF" fontName="" fontStyle="1" nesting="0" />
		</Styles>
	</UserLang>
</NotepadPlus>


code:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="48" height="48" version="1.1" inkscape:version="0.48.0 r9654">
  <defs id="defs4"/>
  <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="11.313708" inkscape:cx="27.203376" inkscape:cy="26.578528" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" inkscape:window-width="1280" inkscape:window-height="968" inkscape:window-x="-4" inkscape:window-y="-4" inkscape:window-maximized="1">
	<inkscape:grid type="xygrid" id="grid2985" empspacing="5" visible="true" enabled="true" snapvisiblegridlinesonly="true"/>
  </sodipodi:namedview>
  <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(0,-1004.3622)">
	<g id="g3000" transform="translate(-6,1003)">
	  <path sodipodi:nodetypes="ccccc" inkscape:connector-curvature="0" id="path2987" d="m 30,2.3621826 -20,10.0000004 20,10 20,-10 z" style="fill:#f9f9f9;stroke:none"/>
	  <path style="fill:#ececec;stroke:none" d="m 30,22.362183 0,25 20,-10 0,-25 z" id="path2989" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccc"/>
	  <path sodipodi:nodetypes="ccccc" inkscape:connector-curvature="0" id="path2991" d="m 30,22.362183 0,25 -20,-10 0,-25 z" style="fill:#cccccc;stroke:none"/>
	  <path inkscape:connector-curvature="0" id="path2993" d="M 30,2.3749996 10,12.375 l 0,25 20,10 20,-10 0,-25 L 30,2.3749996 z" style="fill:none;stroke:#4d4d4d;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"/>
	</g>
  </g>
  <metadata>
	<rdf:RDF>
	  <cc:Work>
		<dc:format>image/svg+xml</dc:format>
		<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
		<cc:license rdf:resource="http://creativecommons.org/licenses/publicdomain/"/>
		<dc:publisher>
		  <cc:Agent rdf:about="http://openclipart.org/">
			<dc:title>Open Clip Art Library</dc:title>
		  </cc:Agent>
		</dc:publisher>
		<dc:title>Sugar Cube icon</dc:title>
		<dc:date>2010-10-10T11:46:52</dc:date>
		<dc:description>A sugar cube.</dc:description>
		<dc:source>http://openclipart.org/detail/89407/sugar-cube-icon-by-jhnri4</dc:source>
		<dc:creator>
		  <cc:Agent>
			<dc:title>jhnri4</dc:title>
		  </cc:Agent>
		</dc:creator>
		<dc:subject>
		  <rdf:Bag>
			<rdf:li>SVG</rdf:li>
			<rdf:li>block</rdf:li>
			<rdf:li>clip art</rdf:li>
			<rdf:li>clipart</rdf:li>
			<rdf:li>cube</rdf:li>
			<rdf:li>icon</rdf:li>
			<rdf:li>sugar</rdf:li>
			<rdf:li>white</rdf:li>
		  </rdf:Bag>
		</dc:subject>
	  </cc:Work>
	  <cc:License rdf:about="http://creativecommons.org/licenses/publicdomain/">
		<cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
		<cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
		<cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
	  </cc:License>
	</rdf:RDF>
  </metadata>
</svg>


code:
#!/bin/bash

if [ ! -f "$(command -v tweego)" ]; then
	echo "Cannot find tweego. Please install tweego before compiling."
	exit 1
fi

VERSION="$(git describe --tags --always --dirty)"

TWEEGO_PATH="./StoryFormats" tweego -o "Degrees of Lewdity $VERSION.html" game
cp "Degrees of Lewdity $VERSION.html" "Degrees of Lewdity.html"
echo "Done: \"Degrees of Lewdity.html\""

path: compile


code:
@set TWEEGO_PATH=%cd%\StoryFormats
@tweego -o "Degrees of Lewdity VERSION.html" game


code:
#!/usr/bin/env python3
import fileinput
import re
import sys

WARNING = '\033[93m'
ENDC = '\033[0m'

def myprint(*args):
	global filename
	print(WARNING, filename + ":", ENDC,*args)

def yield_line_and_islastline(f):
	global filename
	global linenumber
	try:
		prevline = next(f)
		filename = fileinput.filename()
		linenumber = fileinput.filelineno()
	except StopIteration:
		return
	for line in f:
		yield (prevline, f.isfirstline())
		filename = fileinput.filename()
		linenumber = fileinput.filelineno()
		prevline = line
	yield prevline, True

pattern = re.compile(r'(<<(\/?) *(if|for|else|switch|case|replace|link)[^a-zA-Z][^<>]*)')

tagfound = []
try:
	for line, isLastLine in yield_line_and_islastline(fileinput.input()):
		for (whole,end,tag) in re.findall(pattern,line):
			if tag == "else" or tag == 'case':
				if len(tagfound) == 0:
					myprint("Found", tag, "but with no opening tag:")
					myprint("  ", linenumber,":", whole)
					fileinput.nextfile()
				lasttag = tagfound[-1]
				if (tag == "else" and lasttag["tag"] != "if") or (tag == "case" and lasttag["tag"] != "switch"):
					myprint("Mismatched else: Opening tag was:")
					myprint("  ",lasttag["linenumber"],":", lasttag["whole"])
					myprint("But this tag was:")
					myprint("  ",linenumber,":", whole)
					fileinput.nextfile()
					break
			elif end != '/':
				tagfound.append({"whole": whole, "linenumber":linenumber,"tag":tag})
			else:
				if len(tagfound) == 0:
					myprint("Found closing tag but with no opening tag:")
					myprint("  ", linenumber,":", whole)
					fileinput.nextfile()
					break
				lasttag = tagfound.pop()
				if lasttag["tag"] != tag:
					myprint("Mismatched tag: Opening tag was:")
					myprint("  ",lasttag["linenumber"],":", lasttag["whole"])
					myprint("Closing tag was:")
					myprint("  ",linenumber,":", whole)
					fileinput.nextfile()
					break

		if isLastLine:
			if len(tagfound) != 0:
				myprint("End of file found but", len(tagfound), ("tag hasn't" if len(tagfound)==1 else "tags haven't"), "been closed:")
			for tag in tagfound:
				myprint("  ", tag["linenumber"],":", tag["whole"])
			tagfound = []
except UnicodeDecodeError as e:
	myprint(e)
	print("   Hint: In Linux, you can get more details about Unicode errors by running:")
	print("	 isutf8", fileinput.filename())
	print("   :Note it might be caused by ", filename)