diff --git a/1.3/Assemblies/RJW_Menstruation.dll b/1.3/Assemblies/RJW_Menstruation.dll index 82593ee..7395d1b 100644 Binary files a/1.3/Assemblies/RJW_Menstruation.dll and b/1.3/Assemblies/RJW_Menstruation.dll differ diff --git a/1.3/Languages/ChineseTraditional/DefInjected/Drugs/Pills_Menstruation.xml b/1.3/Languages/ChineseTraditional/DefInjected/Drugs/Pills_Menstruation.xml new file mode 100644 index 0000000..437c98e --- /dev/null +++ b/1.3/Languages/ChineseTraditional/DefInjected/Drugs/Pills_Menstruation.xml @@ -0,0 +1,11 @@ + + + 止痛藥 + 在接下來的24小時內舒緩痛經。 + +亦作用於其他類型的疼痛。 + 環孢素 + 一種免疫抑製劑。 + +用以清除體內的精子抗體,但會在24小時期間降低身體的免疫力。 + diff --git a/1.3/Languages/ChineseTraditional/DefInjected/HediffDef/Hediffs_Cum.xml b/1.3/Languages/ChineseTraditional/DefInjected/HediffDef/Hediffs_Cum.xml new file mode 100644 index 0000000..8402405 --- /dev/null +++ b/1.3/Languages/ChineseTraditional/DefInjected/HediffDef/Hediffs_Cum.xml @@ -0,0 +1,12 @@ + + + 精子抗體 + 精子抗體 + 精子抗體。 +增加精子的失活率。 + {0}體內存有精子抗體。 + 多產 + 多產 + 多產。 + {0}有著多產的身體。 + diff --git a/1.3/Languages/ChineseTraditional/DefInjected/HediffDef/Hediffs_Menstruation.xml b/1.3/Languages/ChineseTraditional/DefInjected/HediffDef/Hediffs_Menstruation.xml new file mode 100644 index 0000000..2abf1bf --- /dev/null +++ b/1.3/Languages/ChineseTraditional/DefInjected/HediffDef/Hediffs_Menstruation.xml @@ -0,0 +1,25 @@ + + + 月經來潮 + 絕經 + 絕經 + 卵巢中的卵子耗盡。肚子再也生不出孩子了。 + {0}已絕經。 + [廢止] + 更年期 + 更年期 + 隨著卵巢枯竭,排卵變得不規則。更年期即將到來。 + [廢止] + 發情期 + 發情期 + 由於子宮進入月經週期中最多產的階段,身體受激素影響而變得渴望懷孕。性慾急遽膨脹。 +增加發生陰道性交的頻率,並且對性伴侶的選擇標準降低。 + 發情期(隱性) + 發情期 + 由於子宮進入月經週期中最多產的階段,身體受激素影響而變得渴望懷孕。輕微增加性慾。 +輕微增加發生陰道性交的頻率。 + 止痛藥 + 緩解源自於痛經及此類神經痛的苦楚。 + 環孢素 + 由於免疫抑製劑的作用,身體抵抗感染和疾病的能力受扼制。 + diff --git a/1.3/Languages/ChineseTraditional/DefInjected/JobDefs/Jobs_MilkSelf.xml b/1.3/Languages/ChineseTraditional/DefInjected/JobDefs/Jobs_MilkSelf.xml new file mode 100644 index 0000000..7d17897 --- /dev/null +++ b/1.3/Languages/ChineseTraditional/DefInjected/JobDefs/Jobs_MilkSelf.xml @@ -0,0 +1,4 @@ + + + 自行擠奶 + diff --git a/1.3/Languages/ChineseTraditional/DefInjected/KeyBindings/KeyBindings_Menstruation.xml b/1.3/Languages/ChineseTraditional/DefInjected/KeyBindings/KeyBindings_Menstruation.xml new file mode 100644 index 0000000..5b95326 --- /dev/null +++ b/1.3/Languages/ChineseTraditional/DefInjected/KeyBindings/KeyBindings_Menstruation.xml @@ -0,0 +1,4 @@ + + + 月經週期: 開啟狀態視窗 + diff --git a/1.3/Languages/ChineseTraditional/DefInjected/Recipe_Surgery/Recipes_Surgery_Breast.xml b/1.3/Languages/ChineseTraditional/DefInjected/Recipe_Surgery/Recipes_Surgery_Breast.xml new file mode 100644 index 0000000..7477d9d --- /dev/null +++ b/1.3/Languages/ChineseTraditional/DefInjected/Recipe_Surgery/Recipes_Surgery_Breast.xml @@ -0,0 +1,21 @@ + + + 增大乳暈 + 增大乳暈。 + 正通過手術增大乳暈 + 縮小乳暈 + 縮小乳暈。 + 正通過手術縮小乳暈 + 增大乳頭 + 增大乳頭。 + 正通過手術增大乳頭。 + 縮小乳頭 + 縮小乳頭。 + 正通過手術縮小乳頭 + 染黑乳頭 + 染黑乳頭。 + 正通過手術染黑乳頭 + 白化乳頭 + 使乳頭顏色變粉。 + 正通過手術粉化乳頭 + diff --git a/1.3/Languages/ChineseTraditional/DefInjected/RecordDefs/Records_Womb.xml b/1.3/Languages/ChineseTraditional/DefInjected/RecordDefs/Records_Womb.xml new file mode 100644 index 0000000..3393215 --- /dev/null +++ b/1.3/Languages/ChineseTraditional/DefInjected/RecordDefs/Records_Womb.xml @@ -0,0 +1,7 @@ + + + 體內射精 + 我子宮中的精液,以毫升計。 + 受精卵 + 我體內同精子結合的卵子數。 + diff --git a/1.3/Languages/ChineseTraditional/DefInjected/Stats/Stats_Absorber.xml b/1.3/Languages/ChineseTraditional/DefInjected/Stats/Stats_Absorber.xml new file mode 100644 index 0000000..801727f --- /dev/null +++ b/1.3/Languages/ChineseTraditional/DefInjected/Stats/Stats_Absorber.xml @@ -0,0 +1,4 @@ + + + {0}毫升 + diff --git a/1.3/Languages/ChineseTraditional/DefInjected/TaleDefs/Tales_Cum.xml b/1.3/Languages/ChineseTraditional/DefInjected/TaleDefs/Tales_Cum.xml new file mode 100644 index 0000000..da44ed4 --- /dev/null +++ b/1.3/Languages/ChineseTraditional/DefInjected/TaleDefs/Tales_Cum.xml @@ -0,0 +1,20 @@ + + + 體內射精 + tale_noun->[FUCKER_nameDef]在[FUCKED_nameDef]體內射了精。 + image->[FUCKER_nameFull]的陰莖深深刺入了[FUCKED_nameFull]的陰道[circumstance_group] + image->[FUCKER_nameFull]的陰莖消失在了[FUCKED_nameFull]的黑洞中[circumstance_group] + image->[FUCKED_nameFull]的陰道被[FUCKER_nameFull]的陰莖灌得滿滿的[circumstance_group] + image->[FUCKED_nameFull]的陰道緊緊吸住了[FUCKER_nameFull]的陰莖[circumstance_group] + circumstance_phrase->,於是[FUCKER_nameDef]不得不咬緊牙關 + circumstance_phrase->,但[FUCKER_nameDef]卻滿臉傻笑 + circumstance_phrase->,整得[FUCKED_nameDef]在狂喜中不停顫抖 + circumstance_phrase->,而後[FUCKER_nameDef]將[FUCKER_possessive]濃稠精液射入[FUCKED_nameDef]的體內 + circumstance_phrase->。接著,[FUCKED_nameDef]深情地看著[FUCKER_nameDef]的眼眸。 + desc_sentence->[FUCKER_nameDef]的精液緩緩流出[FUCKED_nameDef]的陰道,順著大腿滴到了地上。 + desc_sentence->[FUCKER_nameDef]的精液衝進了[FUCKED_nameDef]的子宮,同[FUCKED_possessive]的卵子結合了。 + desc_sentence->[FUCKER_nameDef]的精液射入了[FUCKED_nameDef]的子宮。 + desc_sentence->[FUCKED_nameDef]的子宮被精液灌得滿滿的。 + desc_sentence->汗水從[FUCKER_nameDef]的臉上滴落。 + desc_sentence->[FUCKED_nameDef]氣喘吁吁。 + diff --git a/1.3/Languages/ChineseTraditional/DefInjected/ThoughtDef/RJWMenstruation.xml b/1.3/Languages/ChineseTraditional/DefInjected/ThoughtDef/RJWMenstruation.xml index f83a56a..e793dd3 100644 --- a/1.3/Languages/ChineseTraditional/DefInjected/ThoughtDef/RJWMenstruation.xml +++ b/1.3/Languages/ChineseTraditional/DefInjected/ThoughtDef/RJWMenstruation.xml @@ -1,23 +1,23 @@  褲濕啦 - 真讓人困惱... + 能不能有什麼東西來吸體液啊? 被{0}中出了 我擔心我可能會懷孕... 被{0}中出了 雖然機率很低,但我還是擔心懷孕... 被{0}中出了 - 我想我懷孕了 + 好期待懷孕啊! 被{0}中出了 - 我愛做愛 + 雖說不太可能懷孕,但是這個幻想真的好有趣! 中出了{0} 超爽的 被{0}中出了 - 那龜孫子上了我,我不想懷上他的孩子... + 我不想要他的孩子! 被{0}中出了 - 那龜孫子上了我.... + 雖說不太可能懷上,但是這真的很噁! 中出了{0} - 我上了一個婊子 + 我上了那個婊子...哈! 不想要的懷孕 - 我該怎麼辦?... + 我該怎麼照顧寶寶?怎麼辦怎麼辦怎麼辦... \ No newline at end of file diff --git a/1.3/Languages/ChineseTraditional/DefInjected/ThoughtDefs/Thoughts_sex.xml b/1.3/Languages/ChineseTraditional/DefInjected/ThoughtDefs/Thoughts_sex.xml new file mode 100644 index 0000000..7cd43fc --- /dev/null +++ b/1.3/Languages/ChineseTraditional/DefInjected/ThoughtDefs/Thoughts_sex.xml @@ -0,0 +1,11 @@ + + + {0}內射了 + 我著了什麼魔,竟然讓他做出了這種事! + 不情願的妊娠 + 有個寶寶在我肚子裡。但願我能搞定這事。 + 吃了避孕藥 + 總算把這事了結了。 + 吃了避孕藥 + 我想要小孩! + diff --git a/1.3/Languages/ChineseTraditional/Keyed/RJW_Menstruation.xml b/1.3/Languages/ChineseTraditional/Keyed/RJW_Menstruation.xml index 3ce1dfe..1f4b8e7 100644 --- a/1.3/Languages/ChineseTraditional/Keyed/RJW_Menstruation.xml +++ b/1.3/Languages/ChineseTraditional/Keyed/RJW_Menstruation.xml @@ -1,65 +1,142 @@  - RJW Menstruation Cycle - - 月經血 - 清空 - 卵泡期 - 排卵 - 黃體期 - 月經來潮 - 懷孕 - 從出生中恢復 - - 更年期 - 狀態 - 胎兒 - 父親 - 陰道精液列表 - 已受精 - 受精中 - 排卵 - - - - 啟用子宮圖標 - 啟用子宮圖標框 - 啟用動物經期 - 模擬動物的經期. 此選項將在保存讀取後生效 不推薦開啟此選項 - 植入機會 - 設置受精卵的植入機會 - 受精的機會 - 設置每小時受精的機會 - 每小時陰道中的精液量衰減率 - 陰道中的精液量將以這個比率減少 - 每小時生育率衰減率 - 精液列表的生育率將以這個比率減少 - 循環加速 - 加快月經週期 - 除錯 - 顯示除錯資訊 - 子宮狀態 - 在狀態窗口中繪製子宮圖標 - 陰道狀態 - 在狀態窗口中繪製陰道和肛門圖標 - 胎兒信息級別 - 顯示有關胎兒的所有信息 - 顯示妊娠後胎兒的所有信息 - 不顯示有關胎兒的信息,但顯示懷孕後胎兒的圖像 - 不顯示胎兒圖像和信息 - 啟用更年期 - 啟用更年期效果,使小人隨著時間的推移而變得不育 如果您較長壽的外星人種族有碰到任何問題,請關閉此選項. 此選項將在保存讀取後生效 - 多重懷孕 - 使用多重懷孕代替RJW的默認懷孕 - 啟用異卵雙胞胎 - 啟用複數個卵子可以個別受精 - 啟用雙胞胎 - 允許單個卵子產生多個後代 - 雙胞胎出現率 - 設置雙胞胎的出現率 - 最大雙胞胎數量 - 設置最大雙胞胎數量 - - 清洗陰道 - - \ No newline at end of file + RJW-月經週期 + 經血 + + 卵泡期 + 排卵 + 黃體期 + 月經來潮 + 妊娠 + 從生產中恢復 + + 更年期 + 狀態 + 胎兒 + 父親 + 陰道精液列表 + 已受精 + 受精中 + 排卵 + + + 啟用子宮圖標 + 啟用子宮圖標框 + 啟用動物經期 + 模擬動物的經期. +此選項將在保存讀取後生效 +不推薦開啟此選項 + 著床機會 + 設置受精卵的著床機會 + 受精的機會 + 設置每小時受精的機會 + 每小時陰道中的精液量衰減率 + 陰道中的精液量將以這個比率減少 + 每小時精子活力衰減率 + 列表中精液的活力將按此比率減少。該值間接影響生育率。 + 月經加速 + 加快月經週期 + 除錯 + 顯示除錯資訊 + 子宮狀態 + 在狀態窗口中繪製子宮圖標 + 陰道狀態 + 在狀態窗口中繪製陰道和肛門圖標 + 胎兒信息級別 + 顯示有關胎兒的所有信息 + 顯示妊娠後胎兒的所有信息 + 不顯示有關胎兒的信息,但顯示懷孕後胎兒的圖像 + 不顯示胎兒圖像和信息 + 啟用更年期 + 啟用更年期效果,使小人隨著時間的推移而變得不育 +如果您較長壽的外星人種族有碰到任何問題,請關閉此選項. +此選項將在保存讀取後生效 + 啟用多胎妊娠 + 使用多胎妊娠代替RJW的默認懷孕 + 啟用異卵雙胞胎 + 啟用複數個卵子分別受精 + 啟用同卵雙胞胎 + 允許單個卵子產生多個後代 + 雙胞胎出現率 + 設置雙胞胎的出現率 + 最大雙胞胎數量 + 設置最大雙胞胎數量 + 清洗陰道 + + + 絕經 + 乏情期 + 卵巢正準備釋放卵子。排卵將在此階段結束時發生。 + 卵巢正準備釋放卵子。如果精液進入子宮,就會發生排卵。 + 卵巢正在將卵子釋放至子宮中。 + 子宮已準備好接受受精卵。如果在該階段結束之前有受精卵著床,將進入懷孕階段。 + 子宮內膜正在脫落,並將所有未能著床的受精卵排出。 + 寶寶正在子宮中茁壯成長。假以時日,這個世界將會迎來一個新居民。 + 子宮正從最近的妊娠中恢復。 + 子宮處於不孕的狀態。 + 隨著卵巢枯竭,月經週期變得不規則。 + 卵巢枯竭,身體已經無法再產生卵子。 + 處於繁殖季節之外。月經週期會在時機到來時恢復。 + 狀態 + 自行擠奶 + 將精液擠入桶中 + 將精液留在子宮中 + 不明 + 啟用子宮圖標 + 啟用健康面板中的按鈕 + 啟用卵細胞覆蓋層 + 在子宮圖示上顯示卵細胞狀態 + 出血量 + 預估總出血量 + 預估的出血量。 +正常人類女性在月經週期內大約會流失20~80毫升的血。 + 殖民者 + 囚犯 + 同盟派系 + 中立 + 敵對派系 + 本模組作用於: + 這些小人的「RJW月經週期」工具欄對玩家可見。 + 使用進階雜交定義 + 複寫RJW和RaceSupport插件的雜交定義。Overrides RJW and RaceSupport's hybrid definition. +主導混合擴展決定了首先使用誰的定義。不建議更改此設置。Dominant hybrid extension determines whose definition used first. Not recommended to change this. + 主導混合擴展Dominant hybrid extension + 母本 + 父本 + 胸部在孕期增大 + 調整小人的乳房在懷孕期間的增長幅度。有些小人可能會比其他人長得更大。 + 乳頭在孕期間改變 + 變更乳頭在孕期間的改變幅度。 + 永久改變乳頭 + 乳頭在孕期間的改變會在孕期結束後保留多少? + 客製化雜交細節 + 開啟雜交編輯器 +該選項會複寫XML文件中的雜交定義。 + 允許圖標縮小 + 允許圖標在特殊場合縮小。 + 卵細胞生命期乘數 + 以倍數延長卵細胞的生命期 +無論此數值為何,所有未著床的卵子都會在黃體期結束時死亡。 + 啟用產後陰道擴張 + 令陰道在產後永久擴張。 +若存在其他模組擁有類似功能,請關閉此功能。 + 擴張力度 + 調節擴張力度。 + 啟用「擠出精液」按鈕 + 令「發情期」機制複寫RJW的濫交選項 + 啟用時,處於顯式發情期的小人將會使用以下選項來選定床伴。RJW的原始設定會被忽略。 +所有數值與RJW的對應選項相同。 + 發情期床伴:最低fuckability + 發情期床伴:最低吸引度 + 發情期床伴:最低態度值 + 預估精子壽命 + 預估卵子壽命 + 受精卵著床機率。 +本小時內受精機率:{0}% + 回歸預設值 + 擠出精液 + 客製化雜交編輯器 + {0}之雜交 + 當{0}與{1}產生後代,有{3}的概率生出{2}。 +若兩個種族相互間皆存在雜交定義,則以父本的定義為準。 + diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Breast.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Breast.cs index 57d6e5a..e7eaf60 100644 --- a/1.3/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Breast.cs +++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Breast.cs @@ -210,25 +210,16 @@ namespace RJW_Menstruation protected long CalculateLastBirth() { long youngestAge = (long)(BabyHalfAge * GenDate.TicksPerYear) * -2; // So a newborn isn't considered a new mother, either - if ((Pawn.relations?.ChildrenCount ?? 0) > 0) - { - foreach (Pawn child in Pawn.relations.Children) - { - bool isFetus = false; - if (Pawn.health.hediffSet.GetHediffs().Any(preg => preg.babies.Contains(child))) - { - isFetus = true; - break; - } - - if ( - Pawn.ageTracker.BirthAbsTicks - child.ageTracker.BirthAbsTicks > ageOfLastBirth && - !isFetus && - child.GetMother() == Pawn // Don't do Dad's boobs - ) - youngestAge = Pawn.ageTracker.BirthAbsTicks - child.ageTracker.BirthAbsTicks; - } - } + + if ((Pawn.relations == null)) return youngestAge; + + bool hasChild = Pawn.relations.Children. + Where(child => !Pawn.health.hediffSet.GetHediffs().Any(preg => preg.babies.Contains(child))). // no fetuses + Where(child => child.GetMother() == Pawn). // not Dad + TryMinBy(child => child.ageTracker.AgeBiologicalTicks, out Pawn youngest); + + if (hasChild) youngestAge = Pawn.ageTracker.AgeBiologicalTicks - youngest.ageTracker.AgeBiologicalTicks; + return youngestAge; } @@ -337,6 +328,11 @@ namespace RJW_Menstruation } } + public void GaveBirth() + { + ageOfLastBirth = Pawn.ageTracker.AgeBiologicalTicks; + } + public void AdjustNippleProgress(float amount) { nippleProgress = Mathf.Clamp01(nippleProgress + amount); diff --git a/1.3/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs b/1.3/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs index 8c91cb6..0f4123c 100644 --- a/1.3/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs +++ b/1.3/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs @@ -72,6 +72,7 @@ namespace RJW_Menstruation pawn.health.RemoveHediff(this); HediffComp_Menstruation comp = this.GetMenstruationComp(); if(comp != null) comp.Pregnancy = null; + pawn.GetBreastComp()?.GaveBirth(); } public string GetBabyInfo() diff --git a/1.4/Assemblies/RJW_Menstruation.dll b/1.4/Assemblies/RJW_Menstruation.dll new file mode 100644 index 0000000..ad2bc84 Binary files /dev/null and b/1.4/Assemblies/RJW_Menstruation.dll differ diff --git a/1.4/Assemblies/RJW_Menstruation.dll.config b/1.4/Assemblies/RJW_Menstruation.dll.config new file mode 100644 index 0000000..4bfa005 --- /dev/null +++ b/1.4/Assemblies/RJW_Menstruation.dll.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/1.4/Defs/DNADef/DNADefs.xml b/1.4/Defs/DNADef/DNADefs.xml new file mode 100644 index 0000000..09b3a1c --- /dev/null +++ b/1.4/Defs/DNADef/DNADefs.xml @@ -0,0 +1,14 @@ + + + + + + + + \ No newline at end of file diff --git a/1.4/Defs/Drugs/Pills_Menstruation.xml b/1.4/Defs/Drugs/Pills_Menstruation.xml new file mode 100644 index 0000000..9f65c17 --- /dev/null +++ b/1.4/Defs/Drugs/Pills_Menstruation.xml @@ -0,0 +1,188 @@ + + + + + OvaryRegenerationPill + + Recovers the ovaries' health, restoring some quantity of eggs. Less effective on ovaries with few eggs remaining. Cannot recover menopause. + + Things/Item/ORPill + Graphic_StackCount + + false + + 2400 + 160 + 0.05 + + Industrial + + Medical + +
  • + 0.3 +
  • +
    +
    + + DrugProduction + +
  • DrugLab
  • +
    +
    + + 10 + 4 + 8 + + +
  • + 0 + 1000 + + 0.08 + 0.14 + +
  • +
    +
    + + + SuperovulationInducingAgent + + Induce superovulation, causing the next ovulation to produce 1-4 extra eggs. May hasten the onset of menopause. + + Things/Item/SIA + Graphic_StackCount + + false + + 2400 + 140 + 0.05 + + Industrial + + Medical + +
  • +
  • +
    +
    + + DrugProduction + +
  • DrugLab
  • +
    +
    + + 12 + 6 + + +
  • + 0 + 1000 + + 0.08 + 0.14 + +
  • +
    +
    + + + PainReliever + + Relieves menstrual pain for 24 hours. Also effective on other sources of pain. + + Things/Item/PainReliever + Graphic_StackCount + + false + + 1000 + 12 + 0.01 + + Industrial + + Medical + +
  • + Hediff_PainReliever + 1.0 +
  • +
    +
    + + DrugProduction + +
  • DrugLab
  • +
    +
    + + 1 + + +
  • + 0 + 1000 + + 0.08 + 0.14 + +
  • +
    +
    + + + Cyclosporine + + An immunosuppressant. Can cure antisperm antibody, but reduces the body's ability to fight off infection and disease for 24 hours. + + Things/Item/Cyclosporine + Graphic_StackCount + + false + + 1000 + 12 + 0.01 + + Industrial + + Medical + +
  • + Hediff_Cyclosporine + 1.0 +
  • +
  • + Hediff_ASA + -0.20 +
  • +
    +
    + + DrugProduction + +
  • DrugLab
  • +
    +
    + + 1 + + +
  • + 0 + 1000 + + 0.08 + 0.14 + +
  • +
    +
    + +
    \ No newline at end of file diff --git a/1.4/Defs/HediffDef/Hediffs_Cum.xml b/1.4/Defs/HediffDef/Hediffs_Cum.xml new file mode 100644 index 0000000..8ad5b54 --- /dev/null +++ b/1.4/Defs/HediffDef/Hediffs_Cum.xml @@ -0,0 +1,111 @@ + + + + HediffWithComps + Hediff_ASA + + antisperm antibody + Antisperm antibody. Increases death rate of sperm. + {0} has an antisperm antibody + (0.8,0.1,0.1) + false + false + false + true + 1 + 0.1 + + true + + +
  • + false +
  • +
  • + 0.40 + true +
  • +
    + + +
    + + + HediffWithComps + Hediff_ForceFertile + + fertile + fertile + {0} is fertile + (0.3,0.3,0.8) + false + false + false + true + 3 + 0.1 + + true + + +
  • + false + +
  • + RJW_Fertility + 0.05 +
  • + + +
  • + 0.20 + false + +
  • + RJW_Fertility + 0.25 +
  • + + +
  • + 0.40 + true + +
  • + RJW_Fertility + 0.50 +
  • + + +
  • + 0.60 + true + +
  • + RJW_Fertility + 0.75 +
  • + + +
  • + 0.80 + true + +
  • + RJW_Fertility + 1.00 +
  • + + +
    + +
  • + -1.0 + true +
  • +
    +
    + + + +
    \ No newline at end of file diff --git a/1.4/Defs/HediffDef/Hediffs_Menstruation.xml b/1.4/Defs/HediffDef/Hediffs_Menstruation.xml new file mode 100644 index 0000000..375d63d --- /dev/null +++ b/1.4/Defs/HediffDef/Hediffs_Menstruation.xml @@ -0,0 +1,166 @@ + + + + HediffWithComps + Hediff_MenstrualCramp + + in period + Bleeding from the vagina at the end of the menstrual cycle. Often painful. + (0.70,0.00,0.00) + true + false + false + false + 1 + 0.1 + + true + + +
  • + + + 0.50 + 0.95 + + 0.005 +
  • +
  • + 0.2 + + + 0.40 + 0.95 + + 0.01 +
  • +
  • + 0.4 + + + 0.20 + 0.95 + + 0.10 +
  • +
  • + 0.6 + + + 0.0 + 0.95 + + 0.20 +
  • +
    + +
  • + -0.1 +
  • +
    +
    + + + RJW_Menstruation.Hediff_Estrus + Hediff_Estrus + + estrus + A condition caused by a womb entering the most fertile phase of its menstrual cycle. Sexual arousal and desire increase dramatically as the body yearns to become pregnant. Increased chance of vaginal sex occurring and potentially lower standards in mate selection. + (1.00,0.60,0.75) + false + false + false + false + 10000 + 1.0 + + true + + +
  • + + 5.0 + 1.5 + +
  • +
    +
    + + + RJW_Menstruation.Hediff_Estrus + Hediff_Estrus_Concealed + + estrus + A condition caused by a womb its most fertile phase of the menstrual cycle. Sexual arousal and desire increase slightly. Slightly increased chance of vaginal sex. + (1.00,0.60,0.75) + false + false + false + false + 10000 + 1.0 + + true + + +
  • + false + + 1.10 + 1.05 + +
  • +
    +
    + + + + HediffWithComps + Hediff_PainReliever + + A mild reprieve from menstrual (and other) sources of pain. + (0.75,0.75,1.0) + false + false + false + false + 5 + 1.0 + +
  • + -0.1 +
  • +
    + +
  • + -1.0 +
  • +
    +
    + + + HediffWithComps + Hediff_Cyclosporine + + Under the effect of an immunosuppressant, hampering the body's ability to fight off infection and disease. + (0.75,0.75,1.0) + false + false + false + false + 10 + 1.0 + +
  • + + -0.25 + +
  • +
    + +
  • + -1.0 +
  • +
    +
    +
    \ No newline at end of file diff --git a/1.4/Defs/JobDefs/Jobs_CleanSelf.xml b/1.4/Defs/JobDefs/Jobs_CleanSelf.xml new file mode 100644 index 0000000..fbfaad1 --- /dev/null +++ b/1.4/Defs/JobDefs/Jobs_CleanSelf.xml @@ -0,0 +1,10 @@ + + + + + VaginaWashing + RJW_Menstruation.JobDriver_VaginaWashing + washing vagina + true + + \ No newline at end of file diff --git a/1.4/Defs/JobDefs/Jobs_MilkSelf.xml b/1.4/Defs/JobDefs/Jobs_MilkSelf.xml new file mode 100644 index 0000000..79df022 --- /dev/null +++ b/1.4/Defs/JobDefs/Jobs_MilkSelf.xml @@ -0,0 +1,9 @@ + + + + LactateSelf + RJW_Menstruation.JobDriver_MilkSelf + lactating self + true + + diff --git a/1.4/Defs/KeyBindings/KeyBindings_Menstruation.xml b/1.4/Defs/KeyBindings/KeyBindings_Menstruation.xml new file mode 100644 index 0000000..6044f12 --- /dev/null +++ b/1.4/Defs/KeyBindings/KeyBindings_Menstruation.xml @@ -0,0 +1,9 @@ + + + + + OpenStatusWindow + + Q + + diff --git a/1.4/Defs/Recipe_Surgery/Recipes_Surgery_Breast.xml b/1.4/Defs/Recipe_Surgery/Recipes_Surgery_Breast.xml new file mode 100644 index 0000000..e19496d --- /dev/null +++ b/1.4/Defs/Recipe_Surgery/Recipes_Surgery_Breast.xml @@ -0,0 +1,80 @@ + + + + Surgery + Recipe_Surgery + MedicalOperationSpeed + Medicine + 0.2 + 400 + false + +
  • Human
  • +
    + 100 + +
  • + + +
  • Medicine
  • + + + 1 + +
    + + +
  • Medicine
  • +
    +
    +
    + + + Surgery_ExpandAreola + + Expand the areolae. + RJW_Menstruation.Recipe_ExpandAreola + expanding areolae + + + + Surgery_ContractAreola + + Contract the areolae. + RJW_Menstruation.Recipe_ContractAreola + contracting areolae + + + + Surgery_ExpandNipple + + Expand the nipples. + RJW_Menstruation.Recipe_ExpandNipple + expanding nipples + + + + Surgery_ContractNipple + + Contract the nipples. + RJW_Menstruation.Recipe_ContractNipple + contracting nipples + + + + Surgery_DarkenNipple + + Darken the nipples. + RJW_Menstruation.Recipe_DarkenNipple + darkening nipples + + + + Surgery_LightenNipple + + Lighten the nipples. + RJW_Menstruation.Recipe_LightenNipple + lightening nipples + + +
    diff --git a/1.4/Defs/RecordDefs/Records_Womb.xml b/1.4/Defs/RecordDefs/Records_Womb.xml new file mode 100644 index 0000000..6228687 --- /dev/null +++ b/1.4/Defs/RecordDefs/Records_Womb.xml @@ -0,0 +1,19 @@ + + + + + AmountofCreampied + + The milliliters of cum that's been ejaculated into my womb. + Float + + + + AmountofFertilizedEggs + + The number of my eggs that sperm has fertilized. + Int + + + + diff --git a/1.4/Defs/Stats/Stats_Absorber.xml b/1.4/Defs/Stats/Stats_Absorber.xml new file mode 100644 index 0000000..b45fda3 --- /dev/null +++ b/1.4/Defs/Stats/Stats_Absorber.xml @@ -0,0 +1,27 @@ + + + + + MaxAbsorbable + + Maximum amount of fluid that this item can absorb. + Apparel + 0 + FloatOne + {0} ml + false + 60 + +
  • + 0.5 + 0.8 + 1 + 1.2 + 1.4 + 2.0 + 5.0 +
  • +
    +
    + +
    diff --git a/1.4/Defs/TaleDefs/Tales_Cum.xml b/1.4/Defs/TaleDefs/Tales_Cum.xml new file mode 100644 index 0000000..105f2b2 --- /dev/null +++ b/1.4/Defs/TaleDefs/Tales_Cum.xml @@ -0,0 +1,32 @@ + + + + CameInside + + Tale_DoublePawn + Volatile + FUCKER + FUCKED + 1.5 + + +
  • tale_noun->[FUCKER_nameDef] coming inside of [FUCKED_nameDef]
  • +
  • image->[FUCKER_nameFull]'s penis deep inside of [FUCKED_nameFull]'s vagina [circumstance_group]
  • +
  • image->[FUCKER_nameFull]'s penis vanishing into [FUCKED_nameFull]'s vagina [circumstance_group]
  • +
  • image->[FUCKED_nameFull]'s vagina being filled by [FUCKER_nameFull]'s penis [circumstance_group]
  • +
  • image->[FUCKED_nameFull]'s vagina gripping [FUCKER_nameFull]'s penis tight [cirsumstance_group]
  • +
  • circumstance_phrase->while [FUCKER_nameDef] grits [FUCKER_possessive] teeth
  • +
  • circumstance_phrase->while [FUCKER_nameDef] wears a triumphant smirk
  • +
  • circumstance_phrase->as [FUCKED_nameDef] shudders in ecstasy
  • +
  • circumstance_phrase->as [FUCKER_nameDef] shoots [FUCKER_possessive] load into [FUCKED_nameDef]
  • +
  • circumstance_phrase->while [FUCKED_nameDef] looks into [FUCKER_nameDef]'s eyes with a smile
  • +
  • desc_sentence->[FUCKER_nameDef]'s cum oozes out of [FUCKED_nameDef]'s vagina and drips onto the floor.
  • +
  • desc_sentence->[FUCKER_nameDef]'s sperm races into [FUCKED_nameDef]'s womb and enters [FUCKED_possessive] egg.
  • +
  • desc_sentence->[FUCKER_nameDef]'s cum shoots into [FUCKED_nameDef]'s womb.
  • +
  • desc_sentence->[FUCKED_nameDef]'s womb is filled with cum.
  • +
  • desc_sentence->Sweat runs down [FUCKER_nameDef]'s face.
  • +
  • desc_sentence->[FUCKED_nameDef] is panting heavily.
  • +
    +
    +
    +
    \ No newline at end of file diff --git a/1.4/Defs/ThingDefs/ApparelLayerDefs_Absorber.xml b/1.4/Defs/ThingDefs/ApparelLayerDefs_Absorber.xml new file mode 100644 index 0000000..85fec8c --- /dev/null +++ b/1.4/Defs/ThingDefs/ApparelLayerDefs_Absorber.xml @@ -0,0 +1,8 @@ + + + + Absorber + + 500 + + diff --git a/1.4/Defs/ThingDefs/Apparel_Absorbers.xml b/1.4/Defs/ThingDefs/Apparel_Absorbers.xml new file mode 100644 index 0000000..c27e718 --- /dev/null +++ b/1.4/Defs/ThingDefs/Apparel_Absorbers.xml @@ -0,0 +1,263 @@ + + + + + Absorber_Tampon + + A tampon for absorbing fluids from a vagina. May cause an infection if worn for too long. + RJW_Menstruation.Absorber_Tampon + + Things/Item/Tampon + Graphic_Single + + Never + false + Sellable + + 20 + 0.01 + 1000 + 1.0 + 2 + 10 + + 5 + +
  • Fabric
  • +
    + + UnfinishedApparel + ComplexClothing + GeneralLaborSpeed + Crafting + Tailor + Recipe_Tailor + +
  • ElectricTailoringBench
  • +
  • HandTailoringBench
  • +
    + true + + 4 + +
    + +
  • ApparelUtility
  • +
    + + true + false + false + 0 + Female + +
  • GenitalsBPG
  • +
    + +
  • Absorber
  • +
    + +
  • Absorber
  • +
    +
    + +
  • + false + true + 10 + Absorber_Tampon_Dirty +
  • +
    +
    + + + Absorber_Tampon_Dirty + + A wet used tampon. May cause infection if left in. + RJW_Menstruation.Absorber_Tampon + + Things/Item/Tampon + Graphic_Single + + Never + false + None + + 20 + 0.05 + 0 + 1000 + 0.2 + 2 + 10 + -5 + + +
  • Fabric
  • +
    + +
  • ApparelUtility
  • +
    + + true + false + false + 0 + Female + +
  • GenitalsBPG
  • +
    + +
  • Absorber
  • +
    + +
  • Absorber
  • +
    +
    + +
  • + false + true + 8 + Absorber_Tampon_Dirty +
  • +
    +
    + + + + Absorber_Pad + + A pad for absorbing fluids from a vagina. + RJW_Menstruation.Absorber + + Things/Item/Pad + Graphic_Single + + Never + false + Sellable + + 40 + 0.02 + 1000 + 1.0 + 4 + 25 + 0.02 + 0.02 + 0.05 + 0.01 + 0.04 + 0.05 + 1 + -1 + + 10 + +
  • Fabric
  • +
    + + UnfinishedApparel + GeneralLaborSpeed + Crafting + Tailor + Recipe_Tailor + +
  • ElectricTailoringBench
  • +
  • HandTailoringBench
  • +
    + true + + 4 + +
    + +
  • ApparelUtility
  • +
    + + true + true + false + 0 + Female + +
  • GenitalsBPG
  • +
    + +
  • Absorber
  • +
    + +
  • Absorber
  • +
    +
    + +
  • + true + false + Absorber_Pad_Dirty +
  • +
    +
    + + + Absorber_Pad_Dirty + + A wet used pad. + RJW_Menstruation.Absorber + + Things/Item/Pad + Graphic_Single + + Never + false + None + + 40 + 0.10 + 0 + 1000 + 0.2 + 4 + 25 + -5 + 0.02 + 0.02 + 0.05 + 0.01 + 0.04 + 0.1 + -4 + 2 + + +
  • Fabric
  • +
    + +
  • ApparelUtility
  • +
    + + true + true + false + 0 + Female + +
  • GenitalsBPG
  • +
    + +
  • Absorber
  • +
    + +
  • Absorber
  • +
    +
    + +
  • + true + false + Absorber_Pad_Dirty +
  • +
    +
    +
    diff --git a/1.4/Defs/ThingDefs/Filth_Mixture.xml b/1.4/Defs/ThingDefs/Filth_Mixture.xml new file mode 100644 index 0000000..fda4e41 --- /dev/null +++ b/1.4/Defs/ThingDefs/Filth_Mixture.xml @@ -0,0 +1,25 @@ + + + + + FilthMixture + + RJW_Menstruation.Filth_Colored + + -30 + -10 + + + Graphic_Random + Things/Filth/PoolSoft + (255, 255, 255, 180) + + + true + 40 + true + + + + + \ No newline at end of file diff --git a/1.4/Defs/ThoughtDefs/Thoughts_sex.xml b/1.4/Defs/ThoughtDefs/Thoughts_sex.xml new file mode 100644 index 0000000..d66d16b --- /dev/null +++ b/1.4/Defs/ThoughtDefs/Thoughts_sex.xml @@ -0,0 +1,231 @@ + + + + + LeakingFluids + Thought_Memory + 0.05 + 1 + 0.4 + +
  • + + Can't I get something to absorb this? + -2 +
  • +
    +
    + + + HaterCameInsideM + Thought_MemorySocial + 1.0 + 5 + 0.4 + +
  • + + I came inside of my rival! + 5 + 1 +
  • +
    +
    + + + CameInsideM + Thought_MemorySocial + 1.0 + 5 + 0.4 + +
  • + + That felt so good. + 2 + 1 +
  • +
    +
    + + + CameInsideFFetish + Thought_MemorySocial + 3.0 + 5 + 0.1 + 1 + +
  • + + I hope I get pregnant. + 10 + 5 +
  • +
    +
    + + + HaterCameInsideF + Thought_MemorySocial + 7.0 + 5 + 0.1 + 1 + +
  • + + I don't want to be pregnant with his baby! + -5 + -10 +
  • +
    +
    + + + HaterCameInsideFEstrus + Thought_MemorySocial + 7.0 + 5 + 0.1 + 1 + +
  • + + What was I thinking, letting him do that? + -2 + -5 +
  • +
    +
    + + + CameInsideFLowFert + Thought_MemorySocial + 3.0 + 5 + 0.1 + 1 + +
  • + + I'm worried I might get pregnant. The chance is low, but... + -1 +
  • +
    +
    + + + CameInsideF + Thought_MemorySocial + 7.0 + 5 + 0.1 + 1 + +
  • + + I'm worried I might get pregnant. + -3 + -2 +
  • +
    +
    + + + CameInsideFFetishSafe + Thought_MemorySocial + 3.0 + 5 + 0.1 + 1 + +
  • + + I don't think I'll get pregnant, but it's fun to fantasize. + 3 + 1 +
  • +
    +
    + + + HaterCameInsideFSafe + Thought_MemorySocial + 3.0 + 5 + 0.1 + 1 + +
  • + + I probably won't get pregnant, but I still don't like it. + -2 + -5 +
  • +
    +
    + + + UnwantedPregnancy + Thought_Memory + 14.0 + 5 + 0.1 + +
  • + + How will I take care of a baby? What am I going to do? + -10 +
  • +
    +
    + + + UnwantedPregnancyMild + Thought_Memory + 14.0 + 5 + 0.1 + +
  • + + I'm having a baby. I hope I can manage. + -3 +
  • +
    +
    + + + TookContraceptivePill + Thought_Memory + 7.0 + 5 + 0.1 + +
  • + + Everything will be okay now. + 1 +
  • +
    +
    + + + HateTookContraceptivePill + Thought_Memory + 7.0 + 5 + 0.1 + +
  • + + I want to get pregnant. + -3 +
  • +
    +
    + + + +
    diff --git a/1.4/Languages/ChineseSimplified/DefInjected/ApparelLayerDef/RJWMenstruation.xml b/1.4/Languages/ChineseSimplified/DefInjected/ApparelLayerDef/RJWMenstruation.xml new file mode 100644 index 0000000..bd0c960 --- /dev/null +++ b/1.4/Languages/ChineseSimplified/DefInjected/ApparelLayerDef/RJWMenstruation.xml @@ -0,0 +1,4 @@ + + + 生殖器 + \ No newline at end of file diff --git a/1.4/Languages/ChineseSimplified/DefInjected/HediffDef/RJWMenstruation.xml b/1.4/Languages/ChineseSimplified/DefInjected/HediffDef/RJWMenstruation.xml new file mode 100644 index 0000000..c1baebe --- /dev/null +++ b/1.4/Languages/ChineseSimplified/DefInjected/HediffDef/RJWMenstruation.xml @@ -0,0 +1,14 @@ + + + + 中枢性疼痛 + 经期中 + 不快 + 恼人 + 疼痛 + 痛苦 + + + + + \ No newline at end of file diff --git a/1.4/Languages/ChineseSimplified/DefInjected/JobDef/RJWMenstruation.xml b/1.4/Languages/ChineseSimplified/DefInjected/JobDef/RJWMenstruation.xml new file mode 100644 index 0000000..6d73d1d --- /dev/null +++ b/1.4/Languages/ChineseSimplified/DefInjected/JobDef/RJWMenstruation.xml @@ -0,0 +1,7 @@ + + + 清洗阴道 + + + + \ No newline at end of file diff --git a/1.4/Languages/ChineseSimplified/DefInjected/StatDef/RJWMenstruation.xml b/1.4/Languages/ChineseSimplified/DefInjected/StatDef/RJWMenstruation.xml new file mode 100644 index 0000000..6c2c93a --- /dev/null +++ b/1.4/Languages/ChineseSimplified/DefInjected/StatDef/RJWMenstruation.xml @@ -0,0 +1,7 @@ + + + 可吸收量 + 最大可吸收的液体量 + + + \ No newline at end of file diff --git a/1.4/Languages/ChineseSimplified/DefInjected/ThingDef/RJWMenstruation.xml b/1.4/Languages/ChineseSimplified/DefInjected/ThingDef/RJWMenstruation.xml new file mode 100644 index 0000000..75ebeeb --- /dev/null +++ b/1.4/Languages/ChineseSimplified/DefInjected/ThingDef/RJWMenstruation.xml @@ -0,0 +1,31 @@ + + + + +卫生棉条 + +从阴道吸收液体的卫生棉条 + +湿的卫生棉条 + +使用过的湿卫生棉条 + +卫生棉 + +从阴道吸收液体的卫生棉 + +湿的卫生棉 + +使用过的湿卫生棉 + +卵巢再生药物 + +使卵巢再生以增加可排卵的卵子 卵子消耗量越大,效果越差 不能缓解更年期症状 + +排卵药 + +诱导排卵的药物 可导致更年期提前 + +混合物 + + \ No newline at end of file diff --git a/1.4/Languages/ChineseSimplified/DefInjected/ThoughtDef/RJWMenstruation.xml b/1.4/Languages/ChineseSimplified/DefInjected/ThoughtDef/RJWMenstruation.xml new file mode 100644 index 0000000..48c020b --- /dev/null +++ b/1.4/Languages/ChineseSimplified/DefInjected/ThoughtDef/RJWMenstruation.xml @@ -0,0 +1,23 @@ + + + 裤湿啦 + 真让人困恼... + 被{0}中出了 + 我担心我可能会怀孕... + 被{0}中出了 + 虽然几率很低,但我还是担心怀孕... + 被{0}中出了 + 我想我怀孕了 + 被{0}中出了 + 我爱做爱 + 中出了{0} + 超爽的 + 被{0}中出了 + 那龟孙子上了我,我不想怀上他的孩子... + 被{0}中出了 + 那龟孙子上了我.... + 中出了{0} + 我上了一个婊子 + 不想要的怀孕 + 我该怎麽办?... + \ No newline at end of file diff --git a/1.4/Languages/ChineseSimplified/Keyed/RJW_Menstruation.xml b/1.4/Languages/ChineseSimplified/Keyed/RJW_Menstruation.xml new file mode 100644 index 0000000..d10b3fe --- /dev/null +++ b/1.4/Languages/ChineseSimplified/Keyed/RJW_Menstruation.xml @@ -0,0 +1,110 @@ + + + RJW Menstruation Cycle + + 月经血 + + 卵泡期 + 排卵 + 黄体期 + 月经来潮 + 怀孕 + 产后恢复 + + 更年期 + 非发情期 + 状态 + 挤自己奶 + 状态 + 胎儿 + 父亲 + 阴道精液列表 + 已受精 + 受精中 + 排卵 + + + + 激活子宫图标 + 激活子宫图标框 + 激活动物经期 + 仿真动物的经期. 此选项将在保存读取后生效 不推荐开启此选项 + 植入机会 + 设置受精卵的植入机会 + 受精的机会 + 设置每小时受精的机会 + 每小时阴道中的精液量衰减率 + 阴道中的精液量将以这个比率减少 + 每小时生育率衰减率 + 精液列表的生育率将以这个比率减少 + 循环加速 + 加快月经周期 + 调试 + 显示调试信息 + 子宫状态 + 在状态窗口中绘制子宫图标 + 阴道状态 + 在状态窗口中绘制阴道和肛门图标 + 胎儿信息级别 + 显示有关胎儿的所有信息 + 显示妊娠后胎儿的所有信息 + 不显示有关胎儿的信息,但显示怀孕後胎儿的图象 + 不显示胎儿图象和信息 + 激活更年期 + 激活更年期效果,使小人随着时间的推移而变得不育 如果您较长寿的外星人种族有碰到任何问题,请关闭此选项. 此选项将在保存读取后生效 + 多重怀孕 + 使用多重怀孕代替RJW的默认怀孕 + 激活异卵双胞胎 + 激活复数个卵子可以个别受精 + 激活双胞胎 + 允许单个卵子生成多个后代 + 双胞胎出现率 + 设置双胞胎的出现率 + 最大双胞胎数量 + 设置最大双胞胎数量 + 启用卵子图标 + 启用覆盖在子宫图标上的卵子图标 + 经血数量 + 预计经血总量 + 设置经血量 根据阴道不同出血量有变化 通常人类女性的经血量为20-80ml左右每月 + 殖民者 + 囚犯 + 盟友派系 + 中立者 + 敌对派系 + 目标小人 + 按钮和图标会出现在这些人物上 + 使用杂交扩展 + 覆盖RJW and RaceSupport的杂交定义 主杂交决定了谁的定义用在前面,不建议改变此项 + 主杂交扩展 + 母方 + 父方 + 怀孕后乳头动态变化 + 设定每次怀孕,乳头/乳晕变得更深色/宽大的程度。 + 怀孕后乳头固定变化 + 设定每次怀孕,乳头/乳晕永久性变得更深色/宽大的程度。 + 最大变化 + 乳头/乳晕不会变得比这个值更深色/宽大。 + 乳头变化速度 + 设定乳头/乳晕的变化速度。 1 = 立刻变化 + 自定义杂交 + 打开自定义杂交编辑器 该项会覆盖XML文件定义的杂交。 + 允许缩放图标 + 如有需要,允许图标缩小。 + 卵子生命周期倍增 + 倍增卵子生命周期。 在已受精阶段结束后,卵子将无视该选项死去。 + 启用产后阴道变化 + 启用产后永久阴道扩张。 如果你在用另一mod处理该项,关闭该选项。 + 变形力度 + 设置变形力度。 + 预计精子生命周期 + 预计卵子生命周期 + 1小时内受精几率: {0}% 受精卵着床几率。 白色覆盖层表示子宫内精子受精的几率。 + + 清洗阴道 + + 自定义杂交编辑器 + {0}的杂交种 + 当{0}与{1}交配,将有{3}几率生出{2}。 如果两个种族都有对方的杂交定义,将会使用父方的定义。 + + diff --git a/1.4/Languages/ChineseTraditional/DefInjected/ApparelLayerDef/RJWMenstruation.xml b/1.4/Languages/ChineseTraditional/DefInjected/ApparelLayerDef/RJWMenstruation.xml new file mode 100644 index 0000000..a90d863 --- /dev/null +++ b/1.4/Languages/ChineseTraditional/DefInjected/ApparelLayerDef/RJWMenstruation.xml @@ -0,0 +1,4 @@ + + + 生殖器 + \ No newline at end of file diff --git a/1.4/Languages/ChineseTraditional/DefInjected/Drugs/Pills_Menstruation.xml b/1.4/Languages/ChineseTraditional/DefInjected/Drugs/Pills_Menstruation.xml new file mode 100644 index 0000000..437c98e --- /dev/null +++ b/1.4/Languages/ChineseTraditional/DefInjected/Drugs/Pills_Menstruation.xml @@ -0,0 +1,11 @@ + + + 止痛藥 + 在接下來的24小時內舒緩痛經。 + +亦作用於其他類型的疼痛。 + 環孢素 + 一種免疫抑製劑。 + +用以清除體內的精子抗體,但會在24小時期間降低身體的免疫力。 + diff --git a/1.4/Languages/ChineseTraditional/DefInjected/HediffDef/Hediffs_Cum.xml b/1.4/Languages/ChineseTraditional/DefInjected/HediffDef/Hediffs_Cum.xml new file mode 100644 index 0000000..8402405 --- /dev/null +++ b/1.4/Languages/ChineseTraditional/DefInjected/HediffDef/Hediffs_Cum.xml @@ -0,0 +1,12 @@ + + + 精子抗體 + 精子抗體 + 精子抗體。 +增加精子的失活率。 + {0}體內存有精子抗體。 + 多產 + 多產 + 多產。 + {0}有著多產的身體。 + diff --git a/1.4/Languages/ChineseTraditional/DefInjected/HediffDef/Hediffs_Menstruation.xml b/1.4/Languages/ChineseTraditional/DefInjected/HediffDef/Hediffs_Menstruation.xml new file mode 100644 index 0000000..df23159 --- /dev/null +++ b/1.4/Languages/ChineseTraditional/DefInjected/HediffDef/Hediffs_Menstruation.xml @@ -0,0 +1,16 @@ + + + 月經來潮 + 發情期 + 發情期 + 由於子宮進入月經週期中最多產的階段,身體受激素影響而變得渴望懷孕。性慾急遽膨脹。 +增加發生陰道性交的頻率,並且對性伴侶的選擇標準降低。 + 發情期(隱性) + 發情期 + 由於子宮進入月經週期中最多產的階段,身體受激素影響而變得渴望懷孕。輕微增加性慾。 +輕微增加發生陰道性交的頻率。 + 止痛藥 + 緩解源自於痛經及此類神經痛的苦楚。 + 環孢素 + 由於免疫抑製劑的作用,身體抵抗感染和疾病的能力受扼制。 + diff --git a/1.4/Languages/ChineseTraditional/DefInjected/HediffDef/RJWMenstruation.xml b/1.4/Languages/ChineseTraditional/DefInjected/HediffDef/RJWMenstruation.xml new file mode 100644 index 0000000..3cce982 --- /dev/null +++ b/1.4/Languages/ChineseTraditional/DefInjected/HediffDef/RJWMenstruation.xml @@ -0,0 +1,14 @@ + + + + 中樞性疼痛 + 經期中 + 不快 + 惱人 + 疼痛 + 痛苦 + + + + + \ No newline at end of file diff --git a/1.4/Languages/ChineseTraditional/DefInjected/JobDef/RJWMenstruation.xml b/1.4/Languages/ChineseTraditional/DefInjected/JobDef/RJWMenstruation.xml new file mode 100644 index 0000000..fc04f3d --- /dev/null +++ b/1.4/Languages/ChineseTraditional/DefInjected/JobDef/RJWMenstruation.xml @@ -0,0 +1,7 @@ + + + 清洗陰道 + + + + \ No newline at end of file diff --git a/1.4/Languages/ChineseTraditional/DefInjected/JobDefs/Jobs_MilkSelf.xml b/1.4/Languages/ChineseTraditional/DefInjected/JobDefs/Jobs_MilkSelf.xml new file mode 100644 index 0000000..7d17897 --- /dev/null +++ b/1.4/Languages/ChineseTraditional/DefInjected/JobDefs/Jobs_MilkSelf.xml @@ -0,0 +1,4 @@ + + + 自行擠奶 + diff --git a/1.4/Languages/ChineseTraditional/DefInjected/KeyBindings/KeyBindings_Menstruation.xml b/1.4/Languages/ChineseTraditional/DefInjected/KeyBindings/KeyBindings_Menstruation.xml new file mode 100644 index 0000000..5b95326 --- /dev/null +++ b/1.4/Languages/ChineseTraditional/DefInjected/KeyBindings/KeyBindings_Menstruation.xml @@ -0,0 +1,4 @@ + + + 月經週期: 開啟狀態視窗 + diff --git a/1.4/Languages/ChineseTraditional/DefInjected/Recipe_Surgery/Recipes_Surgery_Breast.xml b/1.4/Languages/ChineseTraditional/DefInjected/Recipe_Surgery/Recipes_Surgery_Breast.xml new file mode 100644 index 0000000..7477d9d --- /dev/null +++ b/1.4/Languages/ChineseTraditional/DefInjected/Recipe_Surgery/Recipes_Surgery_Breast.xml @@ -0,0 +1,21 @@ + + + 增大乳暈 + 增大乳暈。 + 正通過手術增大乳暈 + 縮小乳暈 + 縮小乳暈。 + 正通過手術縮小乳暈 + 增大乳頭 + 增大乳頭。 + 正通過手術增大乳頭。 + 縮小乳頭 + 縮小乳頭。 + 正通過手術縮小乳頭 + 染黑乳頭 + 染黑乳頭。 + 正通過手術染黑乳頭 + 白化乳頭 + 使乳頭顏色變粉。 + 正通過手術粉化乳頭 + diff --git a/1.4/Languages/ChineseTraditional/DefInjected/RecordDefs/Records_Womb.xml b/1.4/Languages/ChineseTraditional/DefInjected/RecordDefs/Records_Womb.xml new file mode 100644 index 0000000..3393215 --- /dev/null +++ b/1.4/Languages/ChineseTraditional/DefInjected/RecordDefs/Records_Womb.xml @@ -0,0 +1,7 @@ + + + 體內射精 + 我子宮中的精液,以毫升計。 + 受精卵 + 我體內同精子結合的卵子數。 + diff --git a/1.4/Languages/ChineseTraditional/DefInjected/StatDef/RJWMenstruation.xml b/1.4/Languages/ChineseTraditional/DefInjected/StatDef/RJWMenstruation.xml new file mode 100644 index 0000000..d485637 --- /dev/null +++ b/1.4/Languages/ChineseTraditional/DefInjected/StatDef/RJWMenstruation.xml @@ -0,0 +1,7 @@ + + + 可吸收量 + 最大可吸收的液體量 + + + \ No newline at end of file diff --git a/1.4/Languages/ChineseTraditional/DefInjected/Stats/Stats_Absorber.xml b/1.4/Languages/ChineseTraditional/DefInjected/Stats/Stats_Absorber.xml new file mode 100644 index 0000000..801727f --- /dev/null +++ b/1.4/Languages/ChineseTraditional/DefInjected/Stats/Stats_Absorber.xml @@ -0,0 +1,4 @@ + + + {0}毫升 + diff --git a/1.4/Languages/ChineseTraditional/DefInjected/TaleDefs/Tales_Cum.xml b/1.4/Languages/ChineseTraditional/DefInjected/TaleDefs/Tales_Cum.xml new file mode 100644 index 0000000..da44ed4 --- /dev/null +++ b/1.4/Languages/ChineseTraditional/DefInjected/TaleDefs/Tales_Cum.xml @@ -0,0 +1,20 @@ + + + 體內射精 + tale_noun->[FUCKER_nameDef]在[FUCKED_nameDef]體內射了精。 + image->[FUCKER_nameFull]的陰莖深深刺入了[FUCKED_nameFull]的陰道[circumstance_group] + image->[FUCKER_nameFull]的陰莖消失在了[FUCKED_nameFull]的黑洞中[circumstance_group] + image->[FUCKED_nameFull]的陰道被[FUCKER_nameFull]的陰莖灌得滿滿的[circumstance_group] + image->[FUCKED_nameFull]的陰道緊緊吸住了[FUCKER_nameFull]的陰莖[circumstance_group] + circumstance_phrase->,於是[FUCKER_nameDef]不得不咬緊牙關 + circumstance_phrase->,但[FUCKER_nameDef]卻滿臉傻笑 + circumstance_phrase->,整得[FUCKED_nameDef]在狂喜中不停顫抖 + circumstance_phrase->,而後[FUCKER_nameDef]將[FUCKER_possessive]濃稠精液射入[FUCKED_nameDef]的體內 + circumstance_phrase->。接著,[FUCKED_nameDef]深情地看著[FUCKER_nameDef]的眼眸。 + desc_sentence->[FUCKER_nameDef]的精液緩緩流出[FUCKED_nameDef]的陰道,順著大腿滴到了地上。 + desc_sentence->[FUCKER_nameDef]的精液衝進了[FUCKED_nameDef]的子宮,同[FUCKED_possessive]的卵子結合了。 + desc_sentence->[FUCKER_nameDef]的精液射入了[FUCKED_nameDef]的子宮。 + desc_sentence->[FUCKED_nameDef]的子宮被精液灌得滿滿的。 + desc_sentence->汗水從[FUCKER_nameDef]的臉上滴落。 + desc_sentence->[FUCKED_nameDef]氣喘吁吁。 + diff --git a/1.4/Languages/ChineseTraditional/DefInjected/ThingDef/RJWMenstruation.xml b/1.4/Languages/ChineseTraditional/DefInjected/ThingDef/RJWMenstruation.xml new file mode 100644 index 0000000..9404fb7 --- /dev/null +++ b/1.4/Languages/ChineseTraditional/DefInjected/ThingDef/RJWMenstruation.xml @@ -0,0 +1,31 @@ + + + + +衛生棉條 + +從陰道吸收液體的衛生棉條 + +濕的衛生棉條 + +使用過的濕衛生棉條 + +衛生棉 + +從陰道吸收液體的衛生棉 + +濕的衛生棉 + +使用過的濕衛生棉 + +卵巢再生藥物 + +使卵巢再生以增加可排卵的卵子 卵子消耗量越大,效果越差 不能緩解更年期症狀 + +排卵藥 + +誘導排卵的藥物 可導致更年期提前 + +混合物 + + \ No newline at end of file diff --git a/1.4/Languages/ChineseTraditional/DefInjected/ThoughtDef/RJWMenstruation.xml b/1.4/Languages/ChineseTraditional/DefInjected/ThoughtDef/RJWMenstruation.xml new file mode 100644 index 0000000..e793dd3 --- /dev/null +++ b/1.4/Languages/ChineseTraditional/DefInjected/ThoughtDef/RJWMenstruation.xml @@ -0,0 +1,23 @@ + + + 褲濕啦 + 能不能有什麼東西來吸體液啊? + 被{0}中出了 + 我擔心我可能會懷孕... + 被{0}中出了 + 雖然機率很低,但我還是擔心懷孕... + 被{0}中出了 + 好期待懷孕啊! + 被{0}中出了 + 雖說不太可能懷孕,但是這個幻想真的好有趣! + 中出了{0} + 超爽的 + 被{0}中出了 + 我不想要他的孩子! + 被{0}中出了 + 雖說不太可能懷上,但是這真的很噁! + 中出了{0} + 我上了那個婊子...哈! + 不想要的懷孕 + 我該怎麼照顧寶寶?怎麼辦怎麼辦怎麼辦... + \ No newline at end of file diff --git a/1.4/Languages/ChineseTraditional/DefInjected/ThoughtDefs/Thoughts_sex.xml b/1.4/Languages/ChineseTraditional/DefInjected/ThoughtDefs/Thoughts_sex.xml new file mode 100644 index 0000000..7cd43fc --- /dev/null +++ b/1.4/Languages/ChineseTraditional/DefInjected/ThoughtDefs/Thoughts_sex.xml @@ -0,0 +1,11 @@ + + + {0}內射了 + 我著了什麼魔,竟然讓他做出了這種事! + 不情願的妊娠 + 有個寶寶在我肚子裡。但願我能搞定這事。 + 吃了避孕藥 + 總算把這事了結了。 + 吃了避孕藥 + 我想要小孩! + diff --git a/1.4/Languages/ChineseTraditional/Keyed/RJW_Menstruation.xml b/1.4/Languages/ChineseTraditional/Keyed/RJW_Menstruation.xml new file mode 100644 index 0000000..1f4b8e7 --- /dev/null +++ b/1.4/Languages/ChineseTraditional/Keyed/RJW_Menstruation.xml @@ -0,0 +1,142 @@ + + + RJW-月經週期 + 經血 + + 卵泡期 + 排卵 + 黃體期 + 月經來潮 + 妊娠 + 從生產中恢復 + + 更年期 + 狀態 + 胎兒 + 父親 + 陰道精液列表 + 已受精 + 受精中 + 排卵 + + + 啟用子宮圖標 + 啟用子宮圖標框 + 啟用動物經期 + 模擬動物的經期. +此選項將在保存讀取後生效 +不推薦開啟此選項 + 著床機會 + 設置受精卵的著床機會 + 受精的機會 + 設置每小時受精的機會 + 每小時陰道中的精液量衰減率 + 陰道中的精液量將以這個比率減少 + 每小時精子活力衰減率 + 列表中精液的活力將按此比率減少。該值間接影響生育率。 + 月經加速 + 加快月經週期 + 除錯 + 顯示除錯資訊 + 子宮狀態 + 在狀態窗口中繪製子宮圖標 + 陰道狀態 + 在狀態窗口中繪製陰道和肛門圖標 + 胎兒信息級別 + 顯示有關胎兒的所有信息 + 顯示妊娠後胎兒的所有信息 + 不顯示有關胎兒的信息,但顯示懷孕後胎兒的圖像 + 不顯示胎兒圖像和信息 + 啟用更年期 + 啟用更年期效果,使小人隨著時間的推移而變得不育 +如果您較長壽的外星人種族有碰到任何問題,請關閉此選項. +此選項將在保存讀取後生效 + 啟用多胎妊娠 + 使用多胎妊娠代替RJW的默認懷孕 + 啟用異卵雙胞胎 + 啟用複數個卵子分別受精 + 啟用同卵雙胞胎 + 允許單個卵子產生多個後代 + 雙胞胎出現率 + 設置雙胞胎的出現率 + 最大雙胞胎數量 + 設置最大雙胞胎數量 + 清洗陰道 + + + 絕經 + 乏情期 + 卵巢正準備釋放卵子。排卵將在此階段結束時發生。 + 卵巢正準備釋放卵子。如果精液進入子宮,就會發生排卵。 + 卵巢正在將卵子釋放至子宮中。 + 子宮已準備好接受受精卵。如果在該階段結束之前有受精卵著床,將進入懷孕階段。 + 子宮內膜正在脫落,並將所有未能著床的受精卵排出。 + 寶寶正在子宮中茁壯成長。假以時日,這個世界將會迎來一個新居民。 + 子宮正從最近的妊娠中恢復。 + 子宮處於不孕的狀態。 + 隨著卵巢枯竭,月經週期變得不規則。 + 卵巢枯竭,身體已經無法再產生卵子。 + 處於繁殖季節之外。月經週期會在時機到來時恢復。 + 狀態 + 自行擠奶 + 將精液擠入桶中 + 將精液留在子宮中 + 不明 + 啟用子宮圖標 + 啟用健康面板中的按鈕 + 啟用卵細胞覆蓋層 + 在子宮圖示上顯示卵細胞狀態 + 出血量 + 預估總出血量 + 預估的出血量。 +正常人類女性在月經週期內大約會流失20~80毫升的血。 + 殖民者 + 囚犯 + 同盟派系 + 中立 + 敵對派系 + 本模組作用於: + 這些小人的「RJW月經週期」工具欄對玩家可見。 + 使用進階雜交定義 + 複寫RJW和RaceSupport插件的雜交定義。Overrides RJW and RaceSupport's hybrid definition. +主導混合擴展決定了首先使用誰的定義。不建議更改此設置。Dominant hybrid extension determines whose definition used first. Not recommended to change this. + 主導混合擴展Dominant hybrid extension + 母本 + 父本 + 胸部在孕期增大 + 調整小人的乳房在懷孕期間的增長幅度。有些小人可能會比其他人長得更大。 + 乳頭在孕期間改變 + 變更乳頭在孕期間的改變幅度。 + 永久改變乳頭 + 乳頭在孕期間的改變會在孕期結束後保留多少? + 客製化雜交細節 + 開啟雜交編輯器 +該選項會複寫XML文件中的雜交定義。 + 允許圖標縮小 + 允許圖標在特殊場合縮小。 + 卵細胞生命期乘數 + 以倍數延長卵細胞的生命期 +無論此數值為何,所有未著床的卵子都會在黃體期結束時死亡。 + 啟用產後陰道擴張 + 令陰道在產後永久擴張。 +若存在其他模組擁有類似功能,請關閉此功能。 + 擴張力度 + 調節擴張力度。 + 啟用「擠出精液」按鈕 + 令「發情期」機制複寫RJW的濫交選項 + 啟用時,處於顯式發情期的小人將會使用以下選項來選定床伴。RJW的原始設定會被忽略。 +所有數值與RJW的對應選項相同。 + 發情期床伴:最低fuckability + 發情期床伴:最低吸引度 + 發情期床伴:最低態度值 + 預估精子壽命 + 預估卵子壽命 + 受精卵著床機率。 +本小時內受精機率:{0}% + 回歸預設值 + 擠出精液 + 客製化雜交編輯器 + {0}之雜交 + 當{0}與{1}產生後代,有{3}的概率生出{2}。 +若兩個種族相互間皆存在雜交定義,則以父本的定義為準。 + diff --git a/1.4/Languages/English/Keyed/RJW_Menstruation.xml b/1.4/Languages/English/Keyed/RJW_Menstruation.xml new file mode 100644 index 0000000..e428696 --- /dev/null +++ b/1.4/Languages/English/Keyed/RJW_Menstruation.xml @@ -0,0 +1,134 @@ + + + RJW Menstruation Cycle + + menstrual blood + Empty + Follicular + Ovulation + Luteal + In period + Pregnant + Recovering from birth + None + Climacteric + Menopause + Anestrus + The ovaries are preparing to release an egg. Ovulation will occur at the end of this phase. + The ovaries are preparing to release an egg. Ovulation will occur if semen enters the womb. + The ovaries are releasing an egg into the womb. + The womb is prepared to recieve a fertilized egg. Pregnancy will result if one implants before the end of the stage. + The womb is shedding its lining, along with any eggs that failed to implant. + A baby is growing inside the womb. With time and care, it will become a new resident of this world. + The womb is recovering from its recent pregnancy. + The womb is not fertile and cannot become pregnant. + The ovaries have neared exhaustion and the menstrual cycle has become irregular. + The ovaries have been exhausted and the womb can no longer produce eggs. + The womb is out of breeding season. The cycle will resume once conditions are met. + Status + Lactate self + State + Fetus + Father + Cum list + Fertilized + Fertilizing + Ovulated + + + Gather cum into bucket + Store cum in womb + Unknown + + + + Enable womb icon + Enable button in health tab + Enable animal cycle + Simulate animal cycles. This option will apply after next load Not recommended. + Implantation chance + Base implantation chance of fertilized egg This value affects the chance of impregnation. + Fertilization chance + The fertilization chance per ml of sperm per hour This value affects the chance of impregnation. + Cum decay ratio per hour + The amount of cum in the womb will drop by this amount every hour This value affects the chance of impregnation. + Cum fertility decay ratio per hour + Cum will lose fertility by this amount every hour This value affects fertilization chance indirectly. + Cycle acceleration + Accelerate menstruation cycle This can cause early menopause and infertility. Setting this lower than x12 is recommended. Rimworld's timescale: x6(default) + Debug + Show debug information. Also overrides "Fetus information level" to All. + Womb status + Draw womb icon in status window. + Vagina and breast status + Draw vagina, anus and breast icons in the status window. + Fetus information level + Show all information about a fetus. + Show all information about a fetus after discovered pregnancy. + Show only image of a fetus after discovered pregnancy. + Do not show any information about a fetus. + Enable menopause + Enable menopause effect that makes pawn infertile in time progress If you have problems with long life races, turn off this option. This option will apply after save loaded. + Use multiple pregnancy + Use multiple pregnancy instead RJW's default pregnancy Disable this option if you are in trouble with impregnation RJW pregnancy should be turned on. + Enable hetero ovular twins + Allow pregnancy from multiple eggs at the same time. + Enable enzygotic twins + Enable a single egg to result in multiple identical offspring. + Enzygotic twins chance + The chance of identical twins. + Max enzygotic twins + The maximum number of identical siblings. + Enable egg overlay + Enable egg overlay on womb icon. + Bleeding amount + Estimated total bleeding amount + The approximate bleeding amount. The normal bleeding amount of a human is about 20~80ml per cycle. + Colonist + Prisoner + Allied Faction + Neutral + Hostile Faction + Target pawns: + The gizmo and button will appear for these pawns + Use hybrid extension + Overrides RJW and RaceSupport's hybrid definition. Dominant hybrid extension determines whose definition used first. Not recommended to change this. + Dominant hybrid extension + Mother + Father + Breast growth during pregnancy + Change how much a pregnant pawn's breasts will grow when pregnant. Some pawns will grow more than others. + Nipple change during pregnancy + Change how much a pregnant pawn's nipples will change during pregnancy. + Permanent nipple change after pregnancy + Adjusts approximately how much of a pregnant pawn's nipples will remain changed after the pregnancy ends. + Customize Hybrids + Open custom hybrid editor. This will overrides hybrid definitions of XML files. + Allow shrink icon + Let icon become smaller if needed. + Egg lifespan multiplier + Multiply egg's lifespan. All non-implanted eggs will die at end of luteal stage regardless of this setting. + Enable vagina morph after birth + Enable permanent vagina stretch after birth. If you are using another mod handling this, turn off this option. + Morph power + Set morph power. + Enable gather cum gizmo + Estrus overrides RJW hookup settings + If enabled, a pawn in visible estrus will use these settings for potential impregnation hookups instead of the RJW settings. All settings default to their RJW counterparts. + Hookup minimum fuckability in estrus + Hookup minimum attractability in estrus + Hookup minimum opinion in estrus + Estimated sperm lifespan + Estimated egg lifespan + Implantation chance of fertilized eggs. Chance of fertilization this hour: {0}% + Reset to default + + Gather cum + Vaginal washing + + Custom Hybrid Editor + Hybrids of {0} + When {0} breed with {1}, {2} will be born at {3} chance. If both races have hybrid definitions for each other, the father's definition will be used. + + + \ No newline at end of file diff --git a/1.4/Languages/Korean/DefInjected/ApparelLayerDef/RJWMenstruation.xml b/1.4/Languages/Korean/DefInjected/ApparelLayerDef/RJWMenstruation.xml new file mode 100644 index 0000000..9c687e3 --- /dev/null +++ b/1.4/Languages/Korean/DefInjected/ApparelLayerDef/RJWMenstruation.xml @@ -0,0 +1,4 @@ + + + 성기 + \ No newline at end of file diff --git a/1.4/Languages/Korean/DefInjected/HediffDef/RJWMenstruation.xml b/1.4/Languages/Korean/DefInjected/HediffDef/RJWMenstruation.xml new file mode 100644 index 0000000..0b9539a --- /dev/null +++ b/1.4/Languages/Korean/DefInjected/HediffDef/RJWMenstruation.xml @@ -0,0 +1,18 @@ + + + 생리통 + 생리중입니다. + 불편함 + 짜증남 + 아픔 + 고통스러움 + 발정기 + 발정기입니다. + 발정기(숨김) + 발정기입니다. + 진통제 + 약간의 고통을 줄여줍니다. + + + + \ No newline at end of file diff --git a/1.4/Languages/Korean/DefInjected/JobDef/RJWMenstruation.xml b/1.4/Languages/Korean/DefInjected/JobDef/RJWMenstruation.xml new file mode 100644 index 0000000..67ae283 --- /dev/null +++ b/1.4/Languages/Korean/DefInjected/JobDef/RJWMenstruation.xml @@ -0,0 +1,7 @@ + + + 질세척 하는중 + + + + \ No newline at end of file diff --git a/1.4/Languages/Korean/DefInjected/RecipeDef/BreastSurgeries.xml b/1.4/Languages/Korean/DefInjected/RecipeDef/BreastSurgeries.xml new file mode 100644 index 0000000..8c501f4 --- /dev/null +++ b/1.4/Languages/Korean/DefInjected/RecipeDef/BreastSurgeries.xml @@ -0,0 +1,15 @@ + + + 유륜확대 수술 + 유륜을 크게만듭니다. + 유륜확대 수술중 + 유륜축소 수술 + 유륜을 작게만듭니다. + 유륜축소 수술중 + 유두확대 수술 + 유두를 크게만듭니다. + 유두확대 수술중 + 유두축소 수술 + 유두를 작게만듭니다. + 유두축소 수술중 + \ No newline at end of file diff --git a/1.4/Languages/Korean/DefInjected/RecordDef/RJWMenstruation.xml b/1.4/Languages/Korean/DefInjected/RecordDef/RJWMenstruation.xml new file mode 100644 index 0000000..b807e13 --- /dev/null +++ b/1.4/Languages/Korean/DefInjected/RecordDef/RJWMenstruation.xml @@ -0,0 +1,5 @@ + + + 질내사정 + 질내사정당한 정액 양 + \ No newline at end of file diff --git a/1.4/Languages/Korean/DefInjected/StatDef/RJWMenstruation.xml b/1.4/Languages/Korean/DefInjected/StatDef/RJWMenstruation.xml new file mode 100644 index 0000000..f92112e --- /dev/null +++ b/1.4/Languages/Korean/DefInjected/StatDef/RJWMenstruation.xml @@ -0,0 +1,7 @@ + + + 흡수량 + 액체를 흡수할수 있는 정도입니다. + + + \ No newline at end of file diff --git a/1.4/Languages/Korean/DefInjected/ThingDef/RJWMenstruation.xml b/1.4/Languages/Korean/DefInjected/ThingDef/RJWMenstruation.xml new file mode 100644 index 0000000..c48a975 --- /dev/null +++ b/1.4/Languages/Korean/DefInjected/ThingDef/RJWMenstruation.xml @@ -0,0 +1,20 @@ + + + 탐폰 + 보지에서 나오는 액체를 흡수하는 탐폰입니다. 오래 착용하고 있을 경우 감염이 발생할수도 있습니다. + 더러운 탐폰 + 사용된 축축한 탐폰입니다. + 생리대 + 보지에서 나오는 액체를 흡수하는 생리대입니다. 흡수량 이상의 액체가 나올경우 샐수있습니다. + 젖은 생리대 + 사용된 축축한 생리대입니다. + 난소 재생약 + 난소를 재생시켜 배출할수있는 난자의 양을 증가시킵니다. 난자 소모량이 클수록 효과가 줄어듭니다. 폐경을 회복시키지 않습니다. + 과배란 유도제 + 과배란을 유도하는 약물입니다. 조기폐경을 초래할수도 있습니다. + 진통제 + 하루동안 약간의 통증을 줄여줍니다. + 혼합물 + + + \ No newline at end of file diff --git a/1.4/Languages/Korean/DefInjected/ThoughtDef/RJWMenstruation.xml b/1.4/Languages/Korean/DefInjected/ThoughtDef/RJWMenstruation.xml new file mode 100644 index 0000000..9509437 --- /dev/null +++ b/1.4/Languages/Korean/DefInjected/ThoughtDef/RJWMenstruation.xml @@ -0,0 +1,29 @@ + + + 가랑이가 축축함 + 찝찝해... + {0}에게 질내사정당함 + 임신할까봐 걱정돼... + {0}에게 질내사정당함 + 확률은 낮겠지만 임신할까봐 걱정돼... + {0}에게 질내사정당함 + 임신할것 같아 + {0}에게 질내사정당함 + 좋았어... + {0}에게 질내사정함 + 질싸를하니 기분이 좋네 + {0}에게 질내사정당함 + 그새끼의 자식을 임신하고 싶지 않아... + {0}에게 질내사정당함 + 안전일이였지만 기분나빠 + {0}에게 질내사정함 + 그년한테 질싸를했어 + 원치않은 임신 + 어떻게 해야하지?... 그년한테 질싸를했어 + 원치않은 임신 + 어떻게 해야하지?... + 피임약 복용 + 괜찮을거야 + 피임약 복용 + 임신하고싶어 + \ No newline at end of file diff --git a/1.4/Languages/Korean/Keyed/RJW_Menstruation.xml b/1.4/Languages/Korean/Keyed/RJW_Menstruation.xml new file mode 100644 index 0000000..829fcf5 --- /dev/null +++ b/1.4/Languages/Korean/Keyed/RJW_Menstruation.xml @@ -0,0 +1,110 @@ + + + RJW Menstruation Cycle + + 생리혈 + 없음 + 난포기 + 배란 + 황체기 + 생리중 + 임신 + 회복기 + 없음 + 갱년기 + 휴지기 + 상태창 + 모유 짜기 + 상태 + 태아 + + 정액목록 + 수정됨 + 수정중 + 배란 + + + + 자궁아이콘 활성화 + 건강탭에 버튼 추가 + 동물주기 활성화 + 동물의 월경주기를 시뮬레이션합니다. 변경한후에 세이브로드가 필요합니다. not recommended + 착상확률 + 수정란의 착상확률을 설정합니다. + 수정확률 + 1시간마다 정자가 난자를 수정시킬확률을 설정합니다. + 시간당 정액배출비율 + 이 비율만큼 매 시간마다 정액이 배출됩니다. + 시간당 정자 사망비율 + 이 비율만큼 매 시간마다 정자가 사망해 정액이 생식능력을 잃습니다. 정자 예상수명: 정액이 대부분의 생식능력을 잃는 시간입니다. + 주기 가속 + 월경주기를 더 빠르게합니다. 이 설정은 조기폐경과 난임을 유발할수도 있습니다. 12배속 이하로 설정하는것을 권장합니다. 림월드의 시간배율: x6(default) + Debug + 디버그정보를 보여줍니다. + 자궁 그림 + 상태창에 자궁그림을 표시합니다. + 가슴, 보지 그림 + 상태창에 가슴, 보지와 항문그림을 표시합니다. + 태아 정보 + 태아에 대한 모든 정보를 표시합니다. + 임신을 발견한 이후에 태아에 대한 모든 정보를 표시합니다. + 태아에 대한 정보를 표시하지 않지만, 임신한 이후 태아이미지를 표시합니다. + 태아에 대한 어떠한 정보도 표시하지 않습니다. + 폐경기 활성화 + 시간이 지남에따라 불임상태로 만드는 폐경기를 활성화합니다. 수명이 긴 종족을 사용할때 문제가 있으면 이 옵션을 끄세요. 변경한후에 세이브로드가 필요합니다. + 다중임신 + RJW의 기본임신 대신 다중임신을 사용합니다. 임신에 문제가 있다면 이 기능을 끄는것으로 해결될수도 있습니다. RJW 임신이 활성화 되어야 합니다. + 이란성 쌍둥이 활성화 + 다수의 난자가 임신으로 이어지게 합니다. + 일란성 쌍둥이 활성화 + 하나의 난자가 다수의 태아로 나뉘게 합니다. + 일란성 쌍둥이 확률 + 일란성 쌍둥이가 발생할 확률을 설정합니다. + 최대 일란성 쌍둥이 수 + 일란성 쌍둥이의 수를 제한합니다. + 난자 오버레이 + 자궁그림 위에 난자그림를 표시합니다. + 생리양 + 예상되는 총 생리양 + 생리혈의 양을 설정합니다. 실제 생리양은 보지에따라 다를수 있습니다. 일반적인 인간 여성의 생리량은 약 20~80ml입니다. + 정착민 + 죄수 + 동맹관계 + 중립 + 적대관계 + 표시 대상 + 아이콘과 버튼을 표시할 대상입니다. + 잡종 정의 대체 + RJW와 RaceSupport의 잡종정의를 대체합니다. 우선순위는 누구의 잡종 정의를 우선으로 사용할지 정합니다. 변경하지 않는것을 추천합니다. + 우선순위 + + + 임신후 유두 변화량 + 임신후에 유두가 얼마나 어두워지고 커지는지 설정합니다. + 유두 영구변화량 + 매번 임신할때마다 유두가 얼마나 영구적으로 어두워지고 커지는지 설정합니다. + 최대 변화량 + 유두는 이 값 이상으로 변하지 않습니다. + 유두 변화 속도 + 유두가 얼마나 빨리 변하는지 설정합니다. + 잡종 정의 변경하기 + 사용자 지정 잡종 편집기를 엽니다. 이 설정은 XML파일의 잡종 정의를 대체합니다. + 아이콘 축소 허용 + 아이콘 축소를 허용합니다. + 난자 수명 배수 + 난자 수명을 늘립니다. 이 설정에 관계없이 황체기가 끝나면 난자는 죽습니다. + 출산 이후 보지 변화 활성화 + 출산 이후 보지가 영구적으로 늘어나게 합니다. 만약 이 설정을 다루고있는 다른 모드가 있다면, 이 설정을 끄세요. + 변화 강도 + 변화 강도를 설정합니다. + 정자 예상수명 + 난자 예상수명 + 한시간 안에 수정될 확률: {0}% 수정란이 임신으로 진행될 확률입니다. 흰색 오버레이는 정자가 난자를 수정시킬 확률을 표시하는 것입니다. + + 질세척 + + 사용자 지정 잡종 편집기 + {0}의 잡종설정 + {0}이(가) {1}와(과) 교미했을 때, {2}이(가) {3}의 확률로 태어납니다. 만약 두 종족이 서로에 대한 잡종 정의가 있을경우 아버지 쪽의 정의가 우선적으로 사용됩니다. + + \ No newline at end of file diff --git a/1.4/Languages/Spanish/Keyed/RJW_Menstruation.xml b/1.4/Languages/Spanish/Keyed/RJW_Menstruation.xml new file mode 100644 index 0000000..e428b7d --- /dev/null +++ b/1.4/Languages/Spanish/Keyed/RJW_Menstruation.xml @@ -0,0 +1,84 @@ + + + RJW Ciclo menstrual + + sangre menstrual + Vacía + Folicular + Ovulación + Luteal + En periodo + Embarazada + Recuperándose del nacimiento + Ninguna + Climaterio + Anestro + Estado + Estado + Fetos + Padre + Semen lista + Fecundada + Fertil + Ovulación + + + + habilitar icono de útero + habilitar el botón en la pestaña de salud + habilitar ciclo animal + simular el ciclo del animal. esta opción se aplicará después del cargado no recomendado + posibilidad de implantación + establecer la posibilidad de implantación del óvulo fertilizado este valor determina la posibilidad de finalización de la impregnación + oportunidad de fertilización + establecer la posibilidad de fertilización de 1 ml de esperma cada hora este valor determina la posibilidad inicial de impregnación + Relación de descomposición semen por hora + el semen disminuirá en esta proporción este valor afecta indirectamente al cambio de fertilidad + índice de descomposición de la fertilidad acumulada por hora + el semen perderá la fertilidad en esta proporción este valor afecta indirectamente a la probabilidad de fertilidad + acelerar el ciclo X + acelerar el ciclo de la menstruación + Depurar + mostrar información de depuración. + estado del útero + dibujar icono de útero en la ventana de estado + estado de la vagina + dibujar el icono de vagina y ano en la ventana de estado + Nivel de información del feto + Mostrar toda la información sobre el feto + Mostrar toda la información sobre el feto después de un embarazo notado + No muestre información sobre el feto, pero muestre la imagen del feto después de un embarazo notado + No mostrar la imagen ni la información del feto. + permitir la menopausia + Permitir el efecto de la menopausia que hace que el peón sea infértil con el paso del tiempo. Si tiene problemas con las carreras de larga duración, desactive esta opción. esta opción se aplicará después de guardar cargado + usar embarazo múltiple + use embarazo múltiple en lugar del embarazo predeterminado de RJW deshabilite esta opción si tiene problemas con la impregnación + permitir gemelos hetero ovulares + permitir que varios óvulos puedan quedar embarazadas + permitir gemelos enzimáticos + permitir que un solo huevo dé como resultado múltiples crías + posibilidad de gemelos enzimáticos + Establecer la posibilidad de gemel@s + gemelos enzimáticos max + Establecer el número máximo de gemelos + habilitar la superposición de huevos + habilitar la superposición de huevos en el icono del útero + cantidad de sangrado + cantidad total estimada de sangrado + establecer la cantidad de sangrado la cantidad de sangrado real puede ser diferente dependiendo de la vagina la cantidad de sangrado genérico de una mujer humana es de aproximadamente 20 ~ 80 ml por mes + Colonos + Prisionero + todas las Facciones + Neutral + Facción enemiga + objetivo de colonos + el artilugio y el botón aparecerán para estos peones + usar extensión híbrida + anula la definición híbrida de RJW y RaceSupport La extensión híbrida dominante determina qué definición se usa primero. No se recomienda cambiar esto + Extensión híbrida dominante + Madre + Padre + + Lavado Vaginal + + \ No newline at end of file diff --git a/1.4/MilkModule/Assemblies/MilkModule.dll b/1.4/MilkModule/Assemblies/MilkModule.dll new file mode 100644 index 0000000..c91f14d Binary files /dev/null and b/1.4/MilkModule/Assemblies/MilkModule.dll differ diff --git a/1.4/MilkModule/Defs/JobDefs/Jobs_MilkSelf_MC.xml b/1.4/MilkModule/Defs/JobDefs/Jobs_MilkSelf_MC.xml new file mode 100644 index 0000000..69cdc4d --- /dev/null +++ b/1.4/MilkModule/Defs/JobDefs/Jobs_MilkSelf_MC.xml @@ -0,0 +1,9 @@ + + + + LactateSelf_MC + MilkModule.JobDriver_MilkSelf_MC + lactating self + true + + diff --git a/1.4/Patches/Drugs.xml b/1.4/Patches/Drugs.xml new file mode 100644 index 0000000..6f53daf --- /dev/null +++ b/1.4/Patches/Drugs.xml @@ -0,0 +1,17 @@ + + + + + /Defs/ThingDef[defName="RJW_FertPill"]/ingestible/outcomeDoers + +
  • + + + + + /Defs/ThingDef[defName="RJW_Contraceptive"]/ingestible/outcomeDoers + +
  • + + + \ No newline at end of file diff --git a/1.4/Patches/Hediffs_PrivateParts.xml b/1.4/Patches/Hediffs_PrivateParts.xml new file mode 100644 index 0000000..6b6a570 --- /dev/null +++ b/1.4/Patches/Hediffs_PrivateParts.xml @@ -0,0 +1,154 @@ + + + + + + + + + + + + /Defs/rjw.HediffDef_PartBase[defName="Vagina"] + + +
  • + 10 + 1.0 + 1.0 + 14 + 14 + 6 + 30 + 1 + Womb/Womb + Genitals/Vagina + true +
  • + +
    +
    + + + + /Defs/rjw.HediffDef_PartBase[defName="GenericVagina"] + + +
  • + 10 + 1.0 + 1.0 + 14 + 14 + 0 + 30 + 3 + Womb/Womb + Genitals/Vagina +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="HydraulicVagina"] + + +
  • + 10 + Womb/Womb + Genitals/BionicVagina + true + 0 +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="BionicVagina"] + + +
  • + 10 + Womb/Womb + Genitals/BionicVagina + true + 0 +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="ArchotechVagina"] + + +
  • + 10 + 2.0 + 2.0 + 14 + 14 + 0 + 0 + 3 + Womb/Womb + Genitals/Vagina + true + 4 +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="Anus"] + + +
  • + Genitals/Anal +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="HydraulicAnus"] + + +
  • + Genitals/BionicAnal +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="BionicAnus"] + + +
  • + Genitals/BionicAnal +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="ArchotechAnus"] + + +
  • + Genitals/Anal +
  • +
    +
    +
    + + + + + + +
    \ No newline at end of file diff --git a/1.4/Patches/Hediffs_PrivateParts_Animal.xml b/1.4/Patches/Hediffs_PrivateParts_Animal.xml new file mode 100644 index 0000000..723eafc --- /dev/null +++ b/1.4/Patches/Hediffs_PrivateParts_Animal.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + /Defs/rjw.HediffDef_PartBase[defName="DogVagina"] + + +
  • + 8 + 1.0 + 1.0 + 14 + 166 + 8 + 15 + 4 + Womb/Womb + Genitals/Vagina + 9 +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="CatVagina"] + + +
  • + 6 + 1.0 + 2.0 + 9 + 10 + 0 + 15 + 1 + Womb/Womb + Genitals/Vagina + FirstHalf + 9 +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="HorseVagina"] + + +
  • + 25 + 1.0 + 1.0 + 7 + 14 + 0 + 30 + 1 + Womb/Womb + Genitals/Vagina + FirstHalf + 5 +
  • +
    +
    +
    + + + + /Defs/rjw.HediffDef_PartBase[defName="DragonVagina"] + + +
  • + 50 + 0.5 + 0.2 + 270 + 30 + 0 + 300 + 30 + Womb/Womb + Genitals/Vagina + 0 +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="NarrowVagina"] + + +
  • + 10 + 1.0 + 1.0 + 5 + 16 + 0 + 15 + 2 + Womb/Womb + Genitals/Vagina + 1 +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="RodentVagina"] + + +
  • + 5 + 1.0 + 2.0 + 6 + 9 + 0 + 3 + 1 + Womb/Womb + Genitals/Vagina + 6 +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="SlimeVagina"] + + +
  • + 5 + 2.0 + 2.0 + 12 + 9 + 0 + 3 + 1 + Womb/Womb + Genitals/Vagina + 6 +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="DemonVagina"] + + +
  • + 10 + 2.0 + 2.0 + 14 + 14 + 0 + 3 + 1 + Womb/Womb + Genitals/Vagina + 6 +
  • +
    +
    +
    + + +
    \ No newline at end of file diff --git a/1.4/Patches/Hediffs_PrivateParts_Breasts.xml b/1.4/Patches/Hediffs_PrivateParts_Breasts.xml new file mode 100644 index 0000000..fff7a18 --- /dev/null +++ b/1.4/Patches/Hediffs_PrivateParts_Breasts.xml @@ -0,0 +1,65 @@ + + + + + + /Defs/rjw.HediffDef_PartBase[defName="Breasts"] + + +
  • + Breasts/Breast + (55,20,0) +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="HydraulicBreasts"] + + +
  • + Breasts_Artificial/Breast + (255,255,255) +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="BionicBreasts"] + + +
  • + Breasts_Artificial/Breast + (255,255,255) +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="ArchotechBreasts"] + + +
  • + Breasts/Breast + (255,255,255) +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="SlimeBreasts"] + + +
  • + Breasts/Breast + (55,20,0) +
  • +
    +
    +
    + +
    \ No newline at end of file diff --git a/1.4/Patches/Item_Resource_Stuffs.xml b/1.4/Patches/Item_Resource_Stuffs.xml new file mode 100644 index 0000000..2bdc062 --- /dev/null +++ b/1.4/Patches/Item_Resource_Stuffs.xml @@ -0,0 +1,38 @@ + + + + + /Defs/ThingDef[defName="Cloth"]/stuffProps/statFactors + + 1.0 + + + + + /Defs/ThingDef[defName="Synthread"]/stuffProps/statFactors + + 2.0 + + + + + /Defs/ThingDef[defName="DevilstrandCloth"]/stuffProps/statFactors + + 0.5 + + + + + /Defs/ThingDef[defName="Hyperweave"]/stuffProps/statFactors + + 0.25 + + + + + /Defs/ThingDef[@Name="WoolBase"]/stuffProps/statFactors + + 1.5 + + + \ No newline at end of file diff --git a/1.4/Patches/MilkPatch.xml b/1.4/Patches/MilkPatch.xml new file mode 100644 index 0000000..5097577 --- /dev/null +++ b/1.4/Patches/MilkPatch.xml @@ -0,0 +1,17 @@ + + + + /Defs/ThingDef[defName="HumanMilk" or defName="HumanoidMilk"]/graphicData + + /Defs/ThingDef[defName="HumanMilk" or defName="HumanoidMilk"]/graphicData + + + Things/Item/Milkbottle + Graphic_StackCount + + + + + + + diff --git a/1.4/Patches/PawnModExtensions.xml b/1.4/Patches/PawnModExtensions.xml new file mode 100644 index 0000000..4daadde --- /dev/null +++ b/1.4/Patches/PawnModExtensions.xml @@ -0,0 +1,55 @@ + + + + + + + + /Defs/ThingDef[defName="Human"] + +
  • + Fetus/Fetus_Default + (255,255,255,255) + 0.2 + +
  • + 0.005 + Hediff_ASA + 0.01 +
  • + + + + +
    +
    +
    \ No newline at end of file diff --git a/1.4/Patches/PawnModExtensions_Animals.xml b/1.4/Patches/PawnModExtensions_Animals.xml new file mode 100644 index 0000000..91a2e87 --- /dev/null +++ b/1.4/Patches/PawnModExtensions_Animals.xml @@ -0,0 +1,844 @@ + + + + + + + /Defs/ThingDef[@Name="BigBirdThingBase"] + +
  • + Fetus/Birds/Fetus_Bird + (255,255,255,255) + 0.2 + + +
  • +
    +
    + + + /Defs/ThingDef[defName="Chicken"] + +
  • + Fetus/Birds/Fetus_Bird + (255,255,255,255) + 0.2 + + +
  • +
    +
    + + + /Defs/ThingDef[defName="Duck"] + +
  • + Fetus/Birds/Fetus_Bird + (255,255,255,255) + 0.2 + + +
  • +
    +
    + + + /Defs/ThingDef[defName="Goose"] + +
  • + Fetus/Birds/Fetus_Bird + (255,255,255,255) + 0.2 + + +
  • +
    +
    + + + /Defs/ThingDef[defName="Husky"] + +
  • + Fetus/Canines/Fetus_Dog + (255,255,255,255) + 0.05 + + +
  • +
    +
    + + + /Defs/ThingDef[defName="LabradorRetriever"] + +
  • + Fetus/Canines/Fetus_Dog + (255,255,255,255) + 0.05 + + +
  • +
    +
    + + + /Defs/ThingDef[defName="YorkshireTerrier"] + +
  • + Fetus/Canines/Fetus_Dog + (255,255,255,255) + 0.05 + + +
  • +
    +
    + + + + /Defs/ThingDef[defName="Warg"] + +
  • + Fetus/Canines/Fetus_Dog + (255,255,255,255) + 0.05 + + +
  • +
    +
    + + + /Defs/ThingDef[@Name="ThingBaseWolf"] + +
  • + Fetus/Canines/Fetus_Dog + (255,255,255,255) + 0.05 + + +
  • +
    +
    + + + /Defs/ThingDef[@Name="ThingBaseFox"] + +
  • + Fetus/Canines/Fetus_Dog + (255,255,255,255) + 0.05 + + +
  • +
    +
    + + + /Defs/ThingDef[defName="Pig"] + +
  • + Fetus/Livestocks/Fetus_Pig + (255,255,255,255) + 0.8 + + +
  • +
    +
    + + + /Defs/ThingDef[defName="WildBoar"] + +
  • + Fetus/Livestocks/Fetus_Pig + (255,255,255,255) + 0.8 + + +
  • +
    +
    + + + /Defs/ThingDef[@Name="BaseInsect"] + +
  • + Fetus/Insects/Fetus_Insect + (153,212,89,255) + 0.5 + + +
  • +
    +
    + + + Defs/ThingDef[defName="Turkey"] + +
  • + Fetus/Birds/Fetus_Bird + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Sheep"] + +
  • + Fetus/Livestocks/Fetus_S_Bovine + (255,255,255,255) + 0.3 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Goat"] + +
  • + Fetus/Livestocks/Fetus_S_Bovine + (255,255,255,255) + 0.3 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Ibex"] + +
  • + Fetus/Livestocks/Fetus_S_Bovine + (255,255,255,255) + 0.3 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Deer"] + +
  • + Fetus/Livestocks/Fetus_S_Bovine + (255,255,255,255) + 0.3 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Gazelle"] + +
  • + Fetus/Livestocks/Fetus_Bovine + (255,255,255,255) + 0.3 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Alpaca"] + +
  • + Fetus/Livestocks/Fetus_Bovine + (255,255,255,255) + 0.3 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Yak"] + +
  • + Fetus/Livestocks/Fetus_Bovine + (255,255,255,255) + 0.3 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Elk"] + +
  • + Fetus/Livestocks/Fetus_Bovine + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Caribou"] + +
  • + Fetus/Livestocks/Fetus_S_Bovine + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Horse"] + +
  • + Fetus/Livestocks/Fetus_Bovine + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Donkey"] + +
  • + Fetus/Livestocks/Fetus_Bovine + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Cow"] + +
  • + Fetus/Livestocks/Fetus_Bovine + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Boomalope"] + +
  • + Fetus/Livestocks/Fetus_Bovine + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Muffalo"] + +
  • + Fetus/Livestocks/Fetus_Bovine + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Bison"] + +
  • + Fetus/Livestocks/Fetus_S_Bovine + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Dromedary"] + +
  • + Fetus/Livestocks/Fetus_Bovine + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Elephant"] + +
  • + Fetus/Livestocks/Fetus_Elephant + (255,255,255,255) + 0.5 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Rhinoceros"] + +
  • + Fetus/Livestocks/Fetus_Elephant + (255,255,255,255) + 0.5 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Cat"] + +
  • + Fetus/Feline/Fetus_Cat + (255,255,255,255) + 0.1 + + + + +
  • +
    +
    + + + Defs/ThingDef[@Name="BigCatThingBase"] + +
  • + Fetus/Feline/Fetus_Cat + (255,255,255,255) + 0.2 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Cougar"] + +
  • + Fetus/Feline/Fetus_Cat + (255,255,255,255) + 0.2 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Panther"] + +
  • + Fetus/Feline/Fetus_Cat + (255,255,255,255) + 0.2 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Iguana"] + +
  • + Fetus/Reptile/Fetus_Lizard + (255,255,255,255) + 0.5 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Tortoise"] + +
  • + Fetus/Reptile/Fetus_Lizard + (255,255,255,255) + 0.5 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Cobra"] + +
  • + Fetus/Reptile/Fetus_Snake + (255,255,255,255) + 0.5 + + + + +
  • +
    +
    + + + Defs/ThingDef[@Name="BaseHare"] + +
  • + Fetus/Pests/Fetus_Rodent + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Rat"] + +
  • + Fetus/Pests/Fetus_Rodent + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Boomrat"] + +
  • + Fetus/Pests/Fetus_Rodent + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="GuineaPig"] + +
  • + Fetus/Pests/Fetus_Rodent + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Chinchilla"] + +
  • + Fetus/Pests/Fetus_Rodent + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Snowhare"] + +
  • + Fetus/Pests/Fetus_Rodent + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Capybara"] + +
  • + Fetus/Pests/Fetus_Rodent + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Raccoon"] + +
  • + Fetus/Pests/Fetus_Rodent + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Alphabeaver"] + +
  • + Fetus/Pests/Fetus_Rodent + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Squirrel"] + +
  • + Fetus/Pests/Fetus_Rodent + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Monkey"] + +
  • + Fetus/Primate/Fetus_Monkey + (255,255,255,255) + 0.2 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Megasloth"] + +
  • + Fetus/Livestocks/Fetus_S_Bovine + (255,255,255,255) + 0.9 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Thrumbo"] + +
  • + Fetus/Livestocks/Fetus_S_Bovine + (255,255,255,255) + 0.7 + + + + +
  • +
    +
    + + + Defs/ThingDef[@Name="BaseMechanoid"] + +
  • + Fetus/Mech/Fetus_Mech + (255,255,255,255) + 0.9 + + + + +
  • +
    +
    + + + Defs/ThingDef[@Name="BaseMechanoidWalker"] + +
  • + Fetus/Mech/Fetus_Mech + (255,255,255,255) + 0.9 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Cassowary"] + +
  • + Fetus/Birds/Fetus_Bird + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + + + Defs/ThingDef[defName="Emu"] + +
  • + Fetus/Birds/Fetus_Bird + (255,255,255,255) + 0.4 + + + + +
  • +
    +
    + +
    \ No newline at end of file diff --git a/1.4/Patches/RJW_StatDefs.xml b/1.4/Patches/RJW_StatDefs.xml new file mode 100644 index 0000000..f83365a --- /dev/null +++ b/1.4/Patches/RJW_StatDefs.xml @@ -0,0 +1,19 @@ + + + + + /Defs/StatDef[defName="SexFrequency"]/parts + +
  • +
  • + + + + + /Defs/StatDef[defName="SexSatisfaction"]/parts + +
  • +
  • + + + \ No newline at end of file diff --git a/1.4/RJW Menstruation Race Support/About/About.xml b/1.4/RJW Menstruation Race Support/About/About.xml new file mode 100644 index 0000000..b3aa6ce --- /dev/null +++ b/1.4/RJW Menstruation Race Support/About/About.xml @@ -0,0 +1,26 @@ + + + RJW Menstruation Cycle Race Support + a + +
  • 1.2
  • + + +
  • + rjw.menstruation + RJW Menstruation + https://github.com/moreoreganostodump/RJW_Menstruation +
  • +
  • + Abraxas.RJW.RaceSupport + RJW - RaceSupport + https://gitgud.io/Abraxas/rjw-race-support +
  • +
    + +
  • Abraxas.RJW.RaceSupport
  • +
  • rjw.menstruation
  • +
    + rjw.menstruation.racesupport + good good + \ No newline at end of file diff --git a/1.4/RJW Menstruation Race Support/About/Manifest.xml b/1.4/RJW Menstruation Race Support/About/Manifest.xml new file mode 100644 index 0000000..1904137 --- /dev/null +++ b/1.4/RJW Menstruation Race Support/About/Manifest.xml @@ -0,0 +1,12 @@ + + + RJW Menstruation Race Support + 8.9.0 + + + + + + + + \ No newline at end of file diff --git a/1.4/RJW Menstruation Race Support/Patches/Hediffs_PrivateParts_Animal_RaceSupport.xml b/1.4/RJW Menstruation Race Support/Patches/Hediffs_PrivateParts_Animal_RaceSupport.xml new file mode 100644 index 0000000..e2a3d47 --- /dev/null +++ b/1.4/RJW Menstruation Race Support/Patches/Hediffs_PrivateParts_Animal_RaceSupport.xml @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + /Defs/rjw.HediffDef_PartBase[defName="CervineVagina"] + + +
  • + 18 + 1.0 + 1.0 + 10 + 10 + 4 + 30 + 2 + Womb/Womb + Genitals/Vagina + SecondHalf +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="CactoidVagina"] + + +
  • + 8 + 1.0 + 1.0 + 8 + 12 + 0 + 0 + 2 + Womb/Womb + Genitals/Vagina + Summer +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="TreeVagina"] + + +
  • + 15 + 1.0 + 1.0 + 10 + 12 + 0 + 30 + 2 + Womb/Womb + Genitals/Vagina + Fall +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="PistilVagina"] + + +
  • + 8 + 1.0 + 1.0 + 6 + 12 + 0 + 30 + 2 + Womb/Womb + Genitals/Vagina + Fall +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="NephilaSlimeVagina"] + + +
  • + 12 + 1.0 + 1.0 + 14 + 20 + 0 + 30 + 8 + Womb/Womb + Genitals/Vagina +
  • +
    +
    +
    + + + + /Defs/rjw.HediffDef_PartBase[defName="GhostVagina"] + + +
  • + 2 + 0.1 + 0.1 + 14 + 14 + 0 + 0 + 1 + Womb/Womb + Genitals/Vagina + true +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="NecroVagina"] + + +
  • + 10 + 0.1 + 0.1 + 14 + 14 + 0 + 0 + 1 + Womb/Womb + Genitals/Vagina + true +
  • +
    +
    +
    + + + +
    \ No newline at end of file diff --git a/1.4/RJW Menstruation Race Support/Patches/Hediffs_PrivateParts_Breasts_RaceSupport.xml b/1.4/RJW Menstruation Race Support/Patches/Hediffs_PrivateParts_Breasts_RaceSupport.xml new file mode 100644 index 0000000..cd1f6cc --- /dev/null +++ b/1.4/RJW Menstruation Race Support/Patches/Hediffs_PrivateParts_Breasts_RaceSupport.xml @@ -0,0 +1,103 @@ + + + + + + + /Defs/rjw.HediffDef_PartBase[defName="BigRaceBreats"] + + +
  • + Breasts/Breast + (55,20,0) +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="OrcBreasts"] + + +
  • + Breasts/Breast + (55,20,0) +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="GhoulBreasts"] + + +
  • + Breasts/Breast + (55,20,0) +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="GhostBreasts"] + + +
  • + Breasts/Breast + (55,20,0) +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="NecroBreasts"] + + +
  • + Breasts/Breast + (55,20,0) +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="NephilaBreasts"] + + +
  • + Breasts/Breast + (55,20,0) +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="NephilaSlimeBreasts"] + + +
  • + Breasts/Breast + (55,20,0) +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="UdderBreasts"] + + +
  • + Breasts_Udder/Breast + (55,20,0) +
  • +
    +
    +
    + + +
    \ No newline at end of file diff --git a/1.4/RJW Menstruation Race Support/Patches/Hediffs_PrivateParts_Humanlike_RaceSupport.xml b/1.4/RJW Menstruation Race Support/Patches/Hediffs_PrivateParts_Humanlike_RaceSupport.xml new file mode 100644 index 0000000..2629d3b --- /dev/null +++ b/1.4/RJW Menstruation Race Support/Patches/Hediffs_PrivateParts_Humanlike_RaceSupport.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + /Defs/rjw.HediffDef_PartBase[defName="ElfVagina"] + + +
  • + 10 + 1.0 + 1.0 + 1800 + 1800 + 6 + 30 + 1 + Womb/Womb + Genitals/Vagina + true +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="ElfAnus"] + + +
  • + Genitals/Anal +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="OrcVagina"] + + +
  • + 10 + 1.0 + 1.0 + 7 + 10 + 0 + 10 + 1 + Womb/Womb + Genitals/Vagina + true +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="OrcAnus"] + + +
  • + Genitals/Anal +
  • +
    +
    +
    + + + + + /Defs/rjw.HediffDef_PartBase[defName="GhoulVagina"] + + +
  • + 10 + 0.2 + 0.2 + 14 + 14 + 0 + 10 + 1 + Womb/Womb + Genitals/Vagina + true +
  • +
    +
    +
    + + + /Defs/rjw.HediffDef_PartBase[defName="GhoulAnus"] + + +
  • + Genitals/Anal +
  • +
    +
    +
    + + + +
    \ No newline at end of file diff --git a/1.4/Textures/Breasts/Breast_Breast00.png b/1.4/Textures/Breasts/Breast_Breast00.png new file mode 100644 index 0000000..beda441 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast00.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast00_Areola00.png b/1.4/Textures/Breasts/Breast_Breast00_Areola00.png new file mode 100644 index 0000000..be79e56 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast00_Areola00.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast00_Areola01.png b/1.4/Textures/Breasts/Breast_Breast00_Areola01.png new file mode 100644 index 0000000..c42ee6f Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast00_Areola01.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast00_Areola02.png b/1.4/Textures/Breasts/Breast_Breast00_Areola02.png new file mode 100644 index 0000000..8598345 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast00_Areola02.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast00_Areola03.png b/1.4/Textures/Breasts/Breast_Breast00_Areola03.png new file mode 100644 index 0000000..9dbd415 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast00_Areola03.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast00_Areola04.png b/1.4/Textures/Breasts/Breast_Breast00_Areola04.png new file mode 100644 index 0000000..9dbd415 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast00_Areola04.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast00_Nipple00.png b/1.4/Textures/Breasts/Breast_Breast00_Nipple00.png new file mode 100644 index 0000000..13d7e47 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast00_Nipple00.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast00_Nipple01.png b/1.4/Textures/Breasts/Breast_Breast00_Nipple01.png new file mode 100644 index 0000000..0aaefa6 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast00_Nipple01.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast00_Nipple02.png b/1.4/Textures/Breasts/Breast_Breast00_Nipple02.png new file mode 100644 index 0000000..e3aa6ce Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast00_Nipple02.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast00_Nipple03.png b/1.4/Textures/Breasts/Breast_Breast00_Nipple03.png new file mode 100644 index 0000000..45a1d9c Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast00_Nipple03.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast01.png b/1.4/Textures/Breasts/Breast_Breast01.png new file mode 100644 index 0000000..c54c8c8 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast01.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast01_Areola00.png b/1.4/Textures/Breasts/Breast_Breast01_Areola00.png new file mode 100644 index 0000000..bd86b22 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast01_Areola00.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast01_Areola01.png b/1.4/Textures/Breasts/Breast_Breast01_Areola01.png new file mode 100644 index 0000000..46f6d83 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast01_Areola01.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast01_Areola02.png b/1.4/Textures/Breasts/Breast_Breast01_Areola02.png new file mode 100644 index 0000000..025df96 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast01_Areola02.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast01_Areola03.png b/1.4/Textures/Breasts/Breast_Breast01_Areola03.png new file mode 100644 index 0000000..7461883 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast01_Areola03.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast01_Areola04.png b/1.4/Textures/Breasts/Breast_Breast01_Areola04.png new file mode 100644 index 0000000..7461883 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast01_Areola04.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast01_Nipple00.png b/1.4/Textures/Breasts/Breast_Breast01_Nipple00.png new file mode 100644 index 0000000..773e36e Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast01_Nipple00.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast01_Nipple01.png b/1.4/Textures/Breasts/Breast_Breast01_Nipple01.png new file mode 100644 index 0000000..65cdafd Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast01_Nipple01.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast01_Nipple02.png b/1.4/Textures/Breasts/Breast_Breast01_Nipple02.png new file mode 100644 index 0000000..95bb135 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast01_Nipple02.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast01_Nipple03.png b/1.4/Textures/Breasts/Breast_Breast01_Nipple03.png new file mode 100644 index 0000000..9b4c8b0 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast01_Nipple03.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast02.png b/1.4/Textures/Breasts/Breast_Breast02.png new file mode 100644 index 0000000..0932f21 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast02.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast02_Areola00.png b/1.4/Textures/Breasts/Breast_Breast02_Areola00.png new file mode 100644 index 0000000..f858076 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast02_Areola00.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast02_Areola01.png b/1.4/Textures/Breasts/Breast_Breast02_Areola01.png new file mode 100644 index 0000000..4789c27 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast02_Areola01.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast02_Areola02.png b/1.4/Textures/Breasts/Breast_Breast02_Areola02.png new file mode 100644 index 0000000..697d89b Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast02_Areola02.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast02_Areola03.png b/1.4/Textures/Breasts/Breast_Breast02_Areola03.png new file mode 100644 index 0000000..af901c4 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast02_Areola03.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast02_Areola04.png b/1.4/Textures/Breasts/Breast_Breast02_Areola04.png new file mode 100644 index 0000000..af901c4 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast02_Areola04.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast02_Nipple00.png b/1.4/Textures/Breasts/Breast_Breast02_Nipple00.png new file mode 100644 index 0000000..b3dea3e Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast02_Nipple00.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast02_Nipple01.png b/1.4/Textures/Breasts/Breast_Breast02_Nipple01.png new file mode 100644 index 0000000..22491c0 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast02_Nipple01.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast02_Nipple02.png b/1.4/Textures/Breasts/Breast_Breast02_Nipple02.png new file mode 100644 index 0000000..2fe26ca Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast02_Nipple02.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast02_Nipple03.png b/1.4/Textures/Breasts/Breast_Breast02_Nipple03.png new file mode 100644 index 0000000..a0784f3 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast02_Nipple03.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast03.png b/1.4/Textures/Breasts/Breast_Breast03.png new file mode 100644 index 0000000..fafd312 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast03.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast03_Areola00.png b/1.4/Textures/Breasts/Breast_Breast03_Areola00.png new file mode 100644 index 0000000..16b8635 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast03_Areola00.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast03_Areola01.png b/1.4/Textures/Breasts/Breast_Breast03_Areola01.png new file mode 100644 index 0000000..17403b5 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast03_Areola01.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast03_Areola02.png b/1.4/Textures/Breasts/Breast_Breast03_Areola02.png new file mode 100644 index 0000000..2faf922 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast03_Areola02.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast03_Areola03.png b/1.4/Textures/Breasts/Breast_Breast03_Areola03.png new file mode 100644 index 0000000..d1e9a2e Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast03_Areola03.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast03_Areola04.png b/1.4/Textures/Breasts/Breast_Breast03_Areola04.png new file mode 100644 index 0000000..fa00db7 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast03_Areola04.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast03_Nipple00.png b/1.4/Textures/Breasts/Breast_Breast03_Nipple00.png new file mode 100644 index 0000000..0328271 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast03_Nipple00.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast03_Nipple01.png b/1.4/Textures/Breasts/Breast_Breast03_Nipple01.png new file mode 100644 index 0000000..b3e9763 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast03_Nipple01.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast03_Nipple02.png b/1.4/Textures/Breasts/Breast_Breast03_Nipple02.png new file mode 100644 index 0000000..cc2815a Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast03_Nipple02.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast03_Nipple03.png b/1.4/Textures/Breasts/Breast_Breast03_Nipple03.png new file mode 100644 index 0000000..c535d7c Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast03_Nipple03.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast04.png b/1.4/Textures/Breasts/Breast_Breast04.png new file mode 100644 index 0000000..18617c0 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast04.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast04_Areola00.png b/1.4/Textures/Breasts/Breast_Breast04_Areola00.png new file mode 100644 index 0000000..5d8b969 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast04_Areola00.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast04_Areola01.png b/1.4/Textures/Breasts/Breast_Breast04_Areola01.png new file mode 100644 index 0000000..58928d4 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast04_Areola01.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast04_Areola02.png b/1.4/Textures/Breasts/Breast_Breast04_Areola02.png new file mode 100644 index 0000000..a33ce42 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast04_Areola02.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast04_Areola03.png b/1.4/Textures/Breasts/Breast_Breast04_Areola03.png new file mode 100644 index 0000000..6ffa519 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast04_Areola03.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast04_Areola04.png b/1.4/Textures/Breasts/Breast_Breast04_Areola04.png new file mode 100644 index 0000000..667cb45 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast04_Areola04.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast04_Nipple00.png b/1.4/Textures/Breasts/Breast_Breast04_Nipple00.png new file mode 100644 index 0000000..92a314e Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast04_Nipple00.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast04_Nipple01.png b/1.4/Textures/Breasts/Breast_Breast04_Nipple01.png new file mode 100644 index 0000000..5bedd39 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast04_Nipple01.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast04_Nipple02.png b/1.4/Textures/Breasts/Breast_Breast04_Nipple02.png new file mode 100644 index 0000000..9a0a009 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast04_Nipple02.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast04_Nipple03.png b/1.4/Textures/Breasts/Breast_Breast04_Nipple03.png new file mode 100644 index 0000000..df459fe Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast04_Nipple03.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast05.png b/1.4/Textures/Breasts/Breast_Breast05.png new file mode 100644 index 0000000..a47cd91 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast05.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast05_Areola00.png b/1.4/Textures/Breasts/Breast_Breast05_Areola00.png new file mode 100644 index 0000000..cdbe3fe Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast05_Areola00.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast05_Areola01.png b/1.4/Textures/Breasts/Breast_Breast05_Areola01.png new file mode 100644 index 0000000..47a2f3e Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast05_Areola01.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast05_Areola02.png b/1.4/Textures/Breasts/Breast_Breast05_Areola02.png new file mode 100644 index 0000000..3806769 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast05_Areola02.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast05_Areola03.png b/1.4/Textures/Breasts/Breast_Breast05_Areola03.png new file mode 100644 index 0000000..8d71895 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast05_Areola03.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast05_Areola04.png b/1.4/Textures/Breasts/Breast_Breast05_Areola04.png new file mode 100644 index 0000000..391d265 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast05_Areola04.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast05_Nipple00.png b/1.4/Textures/Breasts/Breast_Breast05_Nipple00.png new file mode 100644 index 0000000..381bf10 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast05_Nipple00.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast05_Nipple01.png b/1.4/Textures/Breasts/Breast_Breast05_Nipple01.png new file mode 100644 index 0000000..319e916 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast05_Nipple01.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast05_Nipple02.png b/1.4/Textures/Breasts/Breast_Breast05_Nipple02.png new file mode 100644 index 0000000..ba23c95 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast05_Nipple02.png differ diff --git a/1.4/Textures/Breasts/Breast_Breast05_Nipple03.png b/1.4/Textures/Breasts/Breast_Breast05_Nipple03.png new file mode 100644 index 0000000..bc3c0a4 Binary files /dev/null and b/1.4/Textures/Breasts/Breast_Breast05_Nipple03.png differ diff --git a/1.4/Textures/Breasts/average_nip_2.png b/1.4/Textures/Breasts/average_nip_2.png new file mode 100644 index 0000000..64dcf78 Binary files /dev/null and b/1.4/Textures/Breasts/average_nip_2.png differ diff --git a/1.4/Textures/Breasts/average_nip_preg.png b/1.4/Textures/Breasts/average_nip_preg.png new file mode 100644 index 0000000..b27916d Binary files /dev/null and b/1.4/Textures/Breasts/average_nip_preg.png differ diff --git a/1.4/Textures/Breasts/enormous_nip_gray.png b/1.4/Textures/Breasts/enormous_nip_gray.png new file mode 100644 index 0000000..e89ebd2 Binary files /dev/null and b/1.4/Textures/Breasts/enormous_nip_gray.png differ diff --git a/1.4/Textures/Breasts/enormous_nip_pink.png b/1.4/Textures/Breasts/enormous_nip_pink.png new file mode 100644 index 0000000..7092748 Binary files /dev/null and b/1.4/Textures/Breasts/enormous_nip_pink.png differ diff --git a/1.4/Textures/Breasts/enormous_nip_preg.png b/1.4/Textures/Breasts/enormous_nip_preg.png new file mode 100644 index 0000000..2c2c232 Binary files /dev/null and b/1.4/Textures/Breasts/enormous_nip_preg.png differ diff --git a/1.4/Textures/Breasts/enoromous_nip.png b/1.4/Textures/Breasts/enoromous_nip.png new file mode 100644 index 0000000..b9336b0 Binary files /dev/null and b/1.4/Textures/Breasts/enoromous_nip.png differ diff --git a/1.4/Textures/Breasts/huge_nip_preg.png b/1.4/Textures/Breasts/huge_nip_preg.png new file mode 100644 index 0000000..778cfd2 Binary files /dev/null and b/1.4/Textures/Breasts/huge_nip_preg.png differ diff --git a/1.4/Textures/Breasts/large_nip_2.png b/1.4/Textures/Breasts/large_nip_2.png new file mode 100644 index 0000000..b0e654f Binary files /dev/null and b/1.4/Textures/Breasts/large_nip_2.png differ diff --git a/1.4/Textures/Breasts/large_nip_preg.png b/1.4/Textures/Breasts/large_nip_preg.png new file mode 100644 index 0000000..de7d9dc Binary files /dev/null and b/1.4/Textures/Breasts/large_nip_preg.png differ diff --git a/1.4/Textures/Breasts/small_nip_2.png b/1.4/Textures/Breasts/small_nip_2.png new file mode 100644 index 0000000..119551d Binary files /dev/null and b/1.4/Textures/Breasts/small_nip_2.png differ diff --git a/1.4/Textures/Breasts/small_nip_preg.png b/1.4/Textures/Breasts/small_nip_preg.png new file mode 100644 index 0000000..2644ea3 Binary files /dev/null and b/1.4/Textures/Breasts/small_nip_preg.png differ diff --git a/1.4/Textures/Breasts/tiny_nip.png b/1.4/Textures/Breasts/tiny_nip.png new file mode 100644 index 0000000..6f51a84 Binary files /dev/null and b/1.4/Textures/Breasts/tiny_nip.png differ diff --git a/1.4/Textures/Breasts/tiny_nip_2.png b/1.4/Textures/Breasts/tiny_nip_2.png new file mode 100644 index 0000000..278fb1e Binary files /dev/null and b/1.4/Textures/Breasts/tiny_nip_2.png differ diff --git a/1.4/Textures/Breasts/tiny_nip_preg.png b/1.4/Textures/Breasts/tiny_nip_preg.png new file mode 100644 index 0000000..a9d261c Binary files /dev/null and b/1.4/Textures/Breasts/tiny_nip_preg.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast00.png b/1.4/Textures/Breasts_Artificial/Breast_Breast00.png new file mode 100644 index 0000000..beda441 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast00.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast00_Areola00.png b/1.4/Textures/Breasts_Artificial/Breast_Breast00_Areola00.png new file mode 100644 index 0000000..18cb983 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast00_Areola00.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast00_Areola01.png b/1.4/Textures/Breasts_Artificial/Breast_Breast00_Areola01.png new file mode 100644 index 0000000..79826b7 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast00_Areola01.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast00_Areola02.png b/1.4/Textures/Breasts_Artificial/Breast_Breast00_Areola02.png new file mode 100644 index 0000000..b73184b Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast00_Areola02.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast00_Areola03.png b/1.4/Textures/Breasts_Artificial/Breast_Breast00_Areola03.png new file mode 100644 index 0000000..9b5b67d Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast00_Areola03.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast00_Areola04.png b/1.4/Textures/Breasts_Artificial/Breast_Breast00_Areola04.png new file mode 100644 index 0000000..9b5b67d Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast00_Areola04.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast00_Nipple00.png b/1.4/Textures/Breasts_Artificial/Breast_Breast00_Nipple00.png new file mode 100644 index 0000000..10cee25 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast00_Nipple00.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast00_Nipple01.png b/1.4/Textures/Breasts_Artificial/Breast_Breast00_Nipple01.png new file mode 100644 index 0000000..3b6ed72 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast00_Nipple01.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast00_Nipple02.png b/1.4/Textures/Breasts_Artificial/Breast_Breast00_Nipple02.png new file mode 100644 index 0000000..b0fdf2b Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast00_Nipple02.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast00_Nipple03.png b/1.4/Textures/Breasts_Artificial/Breast_Breast00_Nipple03.png new file mode 100644 index 0000000..c52310a Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast00_Nipple03.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast01.png b/1.4/Textures/Breasts_Artificial/Breast_Breast01.png new file mode 100644 index 0000000..c54c8c8 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast01.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast01_Areola00.png b/1.4/Textures/Breasts_Artificial/Breast_Breast01_Areola00.png new file mode 100644 index 0000000..77bc3ba Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast01_Areola00.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast01_Areola01.png b/1.4/Textures/Breasts_Artificial/Breast_Breast01_Areola01.png new file mode 100644 index 0000000..2367c70 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast01_Areola01.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast01_Areola02.png b/1.4/Textures/Breasts_Artificial/Breast_Breast01_Areola02.png new file mode 100644 index 0000000..268b654 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast01_Areola02.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast01_Areola03.png b/1.4/Textures/Breasts_Artificial/Breast_Breast01_Areola03.png new file mode 100644 index 0000000..c929254 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast01_Areola03.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast01_Areola04.png b/1.4/Textures/Breasts_Artificial/Breast_Breast01_Areola04.png new file mode 100644 index 0000000..c929254 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast01_Areola04.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast01_Nipple00.png b/1.4/Textures/Breasts_Artificial/Breast_Breast01_Nipple00.png new file mode 100644 index 0000000..ca3ff68 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast01_Nipple00.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast01_Nipple01.png b/1.4/Textures/Breasts_Artificial/Breast_Breast01_Nipple01.png new file mode 100644 index 0000000..5fb9842 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast01_Nipple01.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast01_Nipple02.png b/1.4/Textures/Breasts_Artificial/Breast_Breast01_Nipple02.png new file mode 100644 index 0000000..e0861b2 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast01_Nipple02.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast01_Nipple03.png b/1.4/Textures/Breasts_Artificial/Breast_Breast01_Nipple03.png new file mode 100644 index 0000000..9c56089 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast01_Nipple03.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast02.png b/1.4/Textures/Breasts_Artificial/Breast_Breast02.png new file mode 100644 index 0000000..0932f21 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast02.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast02_Areola00.png b/1.4/Textures/Breasts_Artificial/Breast_Breast02_Areola00.png new file mode 100644 index 0000000..f0604f3 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast02_Areola00.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast02_Areola01.png b/1.4/Textures/Breasts_Artificial/Breast_Breast02_Areola01.png new file mode 100644 index 0000000..2f4554e Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast02_Areola01.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast02_Areola02.png b/1.4/Textures/Breasts_Artificial/Breast_Breast02_Areola02.png new file mode 100644 index 0000000..cc03879 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast02_Areola02.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast02_Areola03.png b/1.4/Textures/Breasts_Artificial/Breast_Breast02_Areola03.png new file mode 100644 index 0000000..ab2aad7 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast02_Areola03.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast02_Areola04.png b/1.4/Textures/Breasts_Artificial/Breast_Breast02_Areola04.png new file mode 100644 index 0000000..ab2aad7 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast02_Areola04.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast02_Nipple00.png b/1.4/Textures/Breasts_Artificial/Breast_Breast02_Nipple00.png new file mode 100644 index 0000000..3e9d639 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast02_Nipple00.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast02_Nipple01.png b/1.4/Textures/Breasts_Artificial/Breast_Breast02_Nipple01.png new file mode 100644 index 0000000..00f943e Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast02_Nipple01.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast02_Nipple02.png b/1.4/Textures/Breasts_Artificial/Breast_Breast02_Nipple02.png new file mode 100644 index 0000000..09e9e76 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast02_Nipple02.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast02_Nipple03.png b/1.4/Textures/Breasts_Artificial/Breast_Breast02_Nipple03.png new file mode 100644 index 0000000..99e8ab1 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast02_Nipple03.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast03.png b/1.4/Textures/Breasts_Artificial/Breast_Breast03.png new file mode 100644 index 0000000..fafd312 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast03.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast03_Areola00.png b/1.4/Textures/Breasts_Artificial/Breast_Breast03_Areola00.png new file mode 100644 index 0000000..b8b38d9 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast03_Areola00.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast03_Areola01.png b/1.4/Textures/Breasts_Artificial/Breast_Breast03_Areola01.png new file mode 100644 index 0000000..233b047 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast03_Areola01.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast03_Areola02.png b/1.4/Textures/Breasts_Artificial/Breast_Breast03_Areola02.png new file mode 100644 index 0000000..0272334 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast03_Areola02.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast03_Areola03.png b/1.4/Textures/Breasts_Artificial/Breast_Breast03_Areola03.png new file mode 100644 index 0000000..b878073 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast03_Areola03.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast03_Areola04.png b/1.4/Textures/Breasts_Artificial/Breast_Breast03_Areola04.png new file mode 100644 index 0000000..f060499 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast03_Areola04.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast03_Nipple00.png b/1.4/Textures/Breasts_Artificial/Breast_Breast03_Nipple00.png new file mode 100644 index 0000000..3b7d15a Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast03_Nipple00.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast03_Nipple01.png b/1.4/Textures/Breasts_Artificial/Breast_Breast03_Nipple01.png new file mode 100644 index 0000000..dece1e6 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast03_Nipple01.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast03_Nipple02.png b/1.4/Textures/Breasts_Artificial/Breast_Breast03_Nipple02.png new file mode 100644 index 0000000..f5968f5 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast03_Nipple02.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast03_Nipple03.png b/1.4/Textures/Breasts_Artificial/Breast_Breast03_Nipple03.png new file mode 100644 index 0000000..865c01f Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast03_Nipple03.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast04.png b/1.4/Textures/Breasts_Artificial/Breast_Breast04.png new file mode 100644 index 0000000..18617c0 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast04.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast04_Areola00.png b/1.4/Textures/Breasts_Artificial/Breast_Breast04_Areola00.png new file mode 100644 index 0000000..177e676 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast04_Areola00.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast04_Areola01.png b/1.4/Textures/Breasts_Artificial/Breast_Breast04_Areola01.png new file mode 100644 index 0000000..9d81fbc Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast04_Areola01.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast04_Areola02.png b/1.4/Textures/Breasts_Artificial/Breast_Breast04_Areola02.png new file mode 100644 index 0000000..10c52cf Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast04_Areola02.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast04_Areola03.png b/1.4/Textures/Breasts_Artificial/Breast_Breast04_Areola03.png new file mode 100644 index 0000000..cebd475 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast04_Areola03.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast04_Areola04.png b/1.4/Textures/Breasts_Artificial/Breast_Breast04_Areola04.png new file mode 100644 index 0000000..d6e1edd Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast04_Areola04.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast04_Nipple00.png b/1.4/Textures/Breasts_Artificial/Breast_Breast04_Nipple00.png new file mode 100644 index 0000000..b2114a1 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast04_Nipple00.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast04_Nipple01.png b/1.4/Textures/Breasts_Artificial/Breast_Breast04_Nipple01.png new file mode 100644 index 0000000..56549c7 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast04_Nipple01.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast04_Nipple02.png b/1.4/Textures/Breasts_Artificial/Breast_Breast04_Nipple02.png new file mode 100644 index 0000000..90609a1 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast04_Nipple02.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast04_Nipple03.png b/1.4/Textures/Breasts_Artificial/Breast_Breast04_Nipple03.png new file mode 100644 index 0000000..f8a4b5f Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast04_Nipple03.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast05.png b/1.4/Textures/Breasts_Artificial/Breast_Breast05.png new file mode 100644 index 0000000..a47cd91 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast05.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast05_Areola00.png b/1.4/Textures/Breasts_Artificial/Breast_Breast05_Areola00.png new file mode 100644 index 0000000..1daed14 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast05_Areola00.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast05_Areola01.png b/1.4/Textures/Breasts_Artificial/Breast_Breast05_Areola01.png new file mode 100644 index 0000000..42c012b Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast05_Areola01.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast05_Areola02.png b/1.4/Textures/Breasts_Artificial/Breast_Breast05_Areola02.png new file mode 100644 index 0000000..b2fb152 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast05_Areola02.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast05_Areola03.png b/1.4/Textures/Breasts_Artificial/Breast_Breast05_Areola03.png new file mode 100644 index 0000000..5b5a19d Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast05_Areola03.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast05_Areola04.png b/1.4/Textures/Breasts_Artificial/Breast_Breast05_Areola04.png new file mode 100644 index 0000000..0c75fe2 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast05_Areola04.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast05_Nipple00.png b/1.4/Textures/Breasts_Artificial/Breast_Breast05_Nipple00.png new file mode 100644 index 0000000..a57f42d Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast05_Nipple00.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast05_Nipple01.png b/1.4/Textures/Breasts_Artificial/Breast_Breast05_Nipple01.png new file mode 100644 index 0000000..a661789 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast05_Nipple01.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast05_Nipple02.png b/1.4/Textures/Breasts_Artificial/Breast_Breast05_Nipple02.png new file mode 100644 index 0000000..c717d19 Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast05_Nipple02.png differ diff --git a/1.4/Textures/Breasts_Artificial/Breast_Breast05_Nipple03.png b/1.4/Textures/Breasts_Artificial/Breast_Breast05_Nipple03.png new file mode 100644 index 0000000..f74257d Binary files /dev/null and b/1.4/Textures/Breasts_Artificial/Breast_Breast05_Nipple03.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast00.png b/1.4/Textures/Breasts_Udder/Breast_Breast00.png new file mode 100644 index 0000000..beda441 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast00.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast00_Areola00.png b/1.4/Textures/Breasts_Udder/Breast_Breast00_Areola00.png new file mode 100644 index 0000000..d7e8c74 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast00_Areola00.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast00_Areola01.png b/1.4/Textures/Breasts_Udder/Breast_Breast00_Areola01.png new file mode 100644 index 0000000..517ca76 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast00_Areola01.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast00_Areola02.png b/1.4/Textures/Breasts_Udder/Breast_Breast00_Areola02.png new file mode 100644 index 0000000..73be5c0 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast00_Areola02.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast00_Areola03.png b/1.4/Textures/Breasts_Udder/Breast_Breast00_Areola03.png new file mode 100644 index 0000000..442cc73 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast00_Areola03.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast00_Areola04.png b/1.4/Textures/Breasts_Udder/Breast_Breast00_Areola04.png new file mode 100644 index 0000000..442cc73 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast00_Areola04.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast00_Nipple00.png b/1.4/Textures/Breasts_Udder/Breast_Breast00_Nipple00.png new file mode 100644 index 0000000..3a74b0e Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast00_Nipple00.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast00_Nipple01.png b/1.4/Textures/Breasts_Udder/Breast_Breast00_Nipple01.png new file mode 100644 index 0000000..68866c0 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast00_Nipple01.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast00_Nipple02.png b/1.4/Textures/Breasts_Udder/Breast_Breast00_Nipple02.png new file mode 100644 index 0000000..e5851a4 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast00_Nipple02.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast00_Nipple03.png b/1.4/Textures/Breasts_Udder/Breast_Breast00_Nipple03.png new file mode 100644 index 0000000..29a743b Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast00_Nipple03.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast01.png b/1.4/Textures/Breasts_Udder/Breast_Breast01.png new file mode 100644 index 0000000..c54c8c8 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast01.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast01_Areola00.png b/1.4/Textures/Breasts_Udder/Breast_Breast01_Areola00.png new file mode 100644 index 0000000..cdc1587 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast01_Areola00.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast01_Areola01.png b/1.4/Textures/Breasts_Udder/Breast_Breast01_Areola01.png new file mode 100644 index 0000000..5f8f8bf Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast01_Areola01.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast01_Areola02.png b/1.4/Textures/Breasts_Udder/Breast_Breast01_Areola02.png new file mode 100644 index 0000000..2b4a561 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast01_Areola02.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast01_Areola03.png b/1.4/Textures/Breasts_Udder/Breast_Breast01_Areola03.png new file mode 100644 index 0000000..354213b Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast01_Areola03.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast01_Areola04.png b/1.4/Textures/Breasts_Udder/Breast_Breast01_Areola04.png new file mode 100644 index 0000000..354213b Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast01_Areola04.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast01_Nipple00.png b/1.4/Textures/Breasts_Udder/Breast_Breast01_Nipple00.png new file mode 100644 index 0000000..ddf295e Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast01_Nipple00.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast01_Nipple01.png b/1.4/Textures/Breasts_Udder/Breast_Breast01_Nipple01.png new file mode 100644 index 0000000..8b58e02 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast01_Nipple01.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast01_Nipple02.png b/1.4/Textures/Breasts_Udder/Breast_Breast01_Nipple02.png new file mode 100644 index 0000000..ac732ab Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast01_Nipple02.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast01_Nipple03.png b/1.4/Textures/Breasts_Udder/Breast_Breast01_Nipple03.png new file mode 100644 index 0000000..cbd8f29 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast01_Nipple03.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast02.png b/1.4/Textures/Breasts_Udder/Breast_Breast02.png new file mode 100644 index 0000000..b838a5b Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast02.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast02_Areola00.png b/1.4/Textures/Breasts_Udder/Breast_Breast02_Areola00.png new file mode 100644 index 0000000..483b3e8 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast02_Areola00.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast02_Areola01.png b/1.4/Textures/Breasts_Udder/Breast_Breast02_Areola01.png new file mode 100644 index 0000000..fb1167d Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast02_Areola01.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast02_Areola02.png b/1.4/Textures/Breasts_Udder/Breast_Breast02_Areola02.png new file mode 100644 index 0000000..8cc2263 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast02_Areola02.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast02_Areola03.png b/1.4/Textures/Breasts_Udder/Breast_Breast02_Areola03.png new file mode 100644 index 0000000..410c09d Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast02_Areola03.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast02_Areola04.png b/1.4/Textures/Breasts_Udder/Breast_Breast02_Areola04.png new file mode 100644 index 0000000..410c09d Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast02_Areola04.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast02_Nipple00.png b/1.4/Textures/Breasts_Udder/Breast_Breast02_Nipple00.png new file mode 100644 index 0000000..b89ac93 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast02_Nipple00.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast02_Nipple01.png b/1.4/Textures/Breasts_Udder/Breast_Breast02_Nipple01.png new file mode 100644 index 0000000..cdf16b3 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast02_Nipple01.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast02_Nipple02.png b/1.4/Textures/Breasts_Udder/Breast_Breast02_Nipple02.png new file mode 100644 index 0000000..2c6f816 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast02_Nipple02.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast02_Nipple03.png b/1.4/Textures/Breasts_Udder/Breast_Breast02_Nipple03.png new file mode 100644 index 0000000..85918ac Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast02_Nipple03.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast03.png b/1.4/Textures/Breasts_Udder/Breast_Breast03.png new file mode 100644 index 0000000..3bae590 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast03.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast03_Areola00.png b/1.4/Textures/Breasts_Udder/Breast_Breast03_Areola00.png new file mode 100644 index 0000000..2ca6985 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast03_Areola00.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast03_Areola01.png b/1.4/Textures/Breasts_Udder/Breast_Breast03_Areola01.png new file mode 100644 index 0000000..8f5cb00 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast03_Areola01.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast03_Areola02.png b/1.4/Textures/Breasts_Udder/Breast_Breast03_Areola02.png new file mode 100644 index 0000000..18ae626 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast03_Areola02.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast03_Areola03.png b/1.4/Textures/Breasts_Udder/Breast_Breast03_Areola03.png new file mode 100644 index 0000000..f4ea4a9 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast03_Areola03.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast03_Areola04.png b/1.4/Textures/Breasts_Udder/Breast_Breast03_Areola04.png new file mode 100644 index 0000000..12ac5e2 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast03_Areola04.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast03_Nipple00.png b/1.4/Textures/Breasts_Udder/Breast_Breast03_Nipple00.png new file mode 100644 index 0000000..2057727 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast03_Nipple00.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast03_Nipple01.png b/1.4/Textures/Breasts_Udder/Breast_Breast03_Nipple01.png new file mode 100644 index 0000000..d654c44 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast03_Nipple01.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast03_Nipple02.png b/1.4/Textures/Breasts_Udder/Breast_Breast03_Nipple02.png new file mode 100644 index 0000000..f67a900 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast03_Nipple02.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast03_Nipple03.png b/1.4/Textures/Breasts_Udder/Breast_Breast03_Nipple03.png new file mode 100644 index 0000000..a72ee3a Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast03_Nipple03.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast04.png b/1.4/Textures/Breasts_Udder/Breast_Breast04.png new file mode 100644 index 0000000..79d5d7c Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast04.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast04_Areola00.png b/1.4/Textures/Breasts_Udder/Breast_Breast04_Areola00.png new file mode 100644 index 0000000..9c238d5 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast04_Areola00.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast04_Areola01.png b/1.4/Textures/Breasts_Udder/Breast_Breast04_Areola01.png new file mode 100644 index 0000000..4ce7271 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast04_Areola01.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast04_Areola02.png b/1.4/Textures/Breasts_Udder/Breast_Breast04_Areola02.png new file mode 100644 index 0000000..3fd03be Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast04_Areola02.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast04_Areola03.png b/1.4/Textures/Breasts_Udder/Breast_Breast04_Areola03.png new file mode 100644 index 0000000..2206511 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast04_Areola03.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast04_Areola04.png b/1.4/Textures/Breasts_Udder/Breast_Breast04_Areola04.png new file mode 100644 index 0000000..9f29885 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast04_Areola04.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast04_Nipple00.png b/1.4/Textures/Breasts_Udder/Breast_Breast04_Nipple00.png new file mode 100644 index 0000000..b6e7171 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast04_Nipple00.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast04_Nipple01.png b/1.4/Textures/Breasts_Udder/Breast_Breast04_Nipple01.png new file mode 100644 index 0000000..cca4f40 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast04_Nipple01.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast04_Nipple02.png b/1.4/Textures/Breasts_Udder/Breast_Breast04_Nipple02.png new file mode 100644 index 0000000..ae73fac Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast04_Nipple02.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast04_Nipple03.png b/1.4/Textures/Breasts_Udder/Breast_Breast04_Nipple03.png new file mode 100644 index 0000000..10321ea Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast04_Nipple03.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast05.png b/1.4/Textures/Breasts_Udder/Breast_Breast05.png new file mode 100644 index 0000000..1633611 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast05.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast05_Areola00.png b/1.4/Textures/Breasts_Udder/Breast_Breast05_Areola00.png new file mode 100644 index 0000000..f86149c Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast05_Areola00.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast05_Areola01.png b/1.4/Textures/Breasts_Udder/Breast_Breast05_Areola01.png new file mode 100644 index 0000000..c08a8a3 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast05_Areola01.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast05_Areola02.png b/1.4/Textures/Breasts_Udder/Breast_Breast05_Areola02.png new file mode 100644 index 0000000..761f003 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast05_Areola02.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast05_Areola03.png b/1.4/Textures/Breasts_Udder/Breast_Breast05_Areola03.png new file mode 100644 index 0000000..59b5486 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast05_Areola03.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast05_Areola04.png b/1.4/Textures/Breasts_Udder/Breast_Breast05_Areola04.png new file mode 100644 index 0000000..fc44d6f Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast05_Areola04.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast05_Nipple00.png b/1.4/Textures/Breasts_Udder/Breast_Breast05_Nipple00.png new file mode 100644 index 0000000..eea1166 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast05_Nipple00.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast05_Nipple01.png b/1.4/Textures/Breasts_Udder/Breast_Breast05_Nipple01.png new file mode 100644 index 0000000..98126a5 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast05_Nipple01.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast05_Nipple02.png b/1.4/Textures/Breasts_Udder/Breast_Breast05_Nipple02.png new file mode 100644 index 0000000..de737de Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast05_Nipple02.png differ diff --git a/1.4/Textures/Breasts_Udder/Breast_Breast05_Nipple03.png b/1.4/Textures/Breasts_Udder/Breast_Breast05_Nipple03.png new file mode 100644 index 0000000..5216cd6 Binary files /dev/null and b/1.4/Textures/Breasts_Udder/Breast_Breast05_Nipple03.png differ diff --git a/1.4/Textures/Eggs/Egg.png b/1.4/Textures/Eggs/Egg.png new file mode 100644 index 0000000..8c10e1e Binary files /dev/null and b/1.4/Textures/Eggs/Egg.png differ diff --git a/1.4/Textures/Eggs/Egg_Fertilized00.png b/1.4/Textures/Eggs/Egg_Fertilized00.png new file mode 100644 index 0000000..f613a47 Binary files /dev/null and b/1.4/Textures/Eggs/Egg_Fertilized00.png differ diff --git a/1.4/Textures/Eggs/Egg_Fertilized01.png b/1.4/Textures/Eggs/Egg_Fertilized01.png new file mode 100644 index 0000000..4d8a6fd Binary files /dev/null and b/1.4/Textures/Eggs/Egg_Fertilized01.png differ diff --git a/1.4/Textures/Eggs/Egg_Fertilized02.png b/1.4/Textures/Eggs/Egg_Fertilized02.png new file mode 100644 index 0000000..cee7dc5 Binary files /dev/null and b/1.4/Textures/Eggs/Egg_Fertilized02.png differ diff --git a/1.4/Textures/Eggs/Egg_Fertilizing00.png b/1.4/Textures/Eggs/Egg_Fertilizing00.png new file mode 100644 index 0000000..7aa6375 Binary files /dev/null and b/1.4/Textures/Eggs/Egg_Fertilizing00.png differ diff --git a/1.4/Textures/Eggs/Egg_Fertilizing01.png b/1.4/Textures/Eggs/Egg_Fertilizing01.png new file mode 100644 index 0000000..9920103 Binary files /dev/null and b/1.4/Textures/Eggs/Egg_Fertilizing01.png differ diff --git a/1.4/Textures/Eggs/Egg_Fertilizing02.png b/1.4/Textures/Eggs/Egg_Fertilizing02.png new file mode 100644 index 0000000..2b7eecc Binary files /dev/null and b/1.4/Textures/Eggs/Egg_Fertilizing02.png differ diff --git a/1.4/Textures/Eggs/Egg_Implanted00.png b/1.4/Textures/Eggs/Egg_Implanted00.png new file mode 100644 index 0000000..0fe1934 Binary files /dev/null and b/1.4/Textures/Eggs/Egg_Implanted00.png differ diff --git a/1.4/Textures/Eggs/Eggs.zip b/1.4/Textures/Eggs/Eggs.zip new file mode 100644 index 0000000..7d60763 Binary files /dev/null and b/1.4/Textures/Eggs/Eggs.zip differ diff --git a/1.4/Textures/Fetus/Birds/Fetus_Bird00.png b/1.4/Textures/Fetus/Birds/Fetus_Bird00.png new file mode 100644 index 0000000..0732d3a Binary files /dev/null and b/1.4/Textures/Fetus/Birds/Fetus_Bird00.png differ diff --git a/1.4/Textures/Fetus/Birds/Fetus_Bird01.png b/1.4/Textures/Fetus/Birds/Fetus_Bird01.png new file mode 100644 index 0000000..ebe78a4 Binary files /dev/null and b/1.4/Textures/Fetus/Birds/Fetus_Bird01.png differ diff --git a/1.4/Textures/Fetus/Birds/Fetus_Bird02.png b/1.4/Textures/Fetus/Birds/Fetus_Bird02.png new file mode 100644 index 0000000..5282c1b Binary files /dev/null and b/1.4/Textures/Fetus/Birds/Fetus_Bird02.png differ diff --git a/1.4/Textures/Fetus/Birds/Fetus_Bird03.png b/1.4/Textures/Fetus/Birds/Fetus_Bird03.png new file mode 100644 index 0000000..7709759 Binary files /dev/null and b/1.4/Textures/Fetus/Birds/Fetus_Bird03.png differ diff --git a/1.4/Textures/Fetus/Birds/Fetus_Bird04.png b/1.4/Textures/Fetus/Birds/Fetus_Bird04.png new file mode 100644 index 0000000..9ccc7e0 Binary files /dev/null and b/1.4/Textures/Fetus/Birds/Fetus_Bird04.png differ diff --git a/1.4/Textures/Fetus/Birds/Fetus_Bird05.png b/1.4/Textures/Fetus/Birds/Fetus_Bird05.png new file mode 100644 index 0000000..afd7ec8 Binary files /dev/null and b/1.4/Textures/Fetus/Birds/Fetus_Bird05.png differ diff --git a/1.4/Textures/Fetus/Canines/Fetus_Dog00.png b/1.4/Textures/Fetus/Canines/Fetus_Dog00.png new file mode 100644 index 0000000..94801e0 Binary files /dev/null and b/1.4/Textures/Fetus/Canines/Fetus_Dog00.png differ diff --git a/1.4/Textures/Fetus/Canines/Fetus_Dog01.png b/1.4/Textures/Fetus/Canines/Fetus_Dog01.png new file mode 100644 index 0000000..754d5e2 Binary files /dev/null and b/1.4/Textures/Fetus/Canines/Fetus_Dog01.png differ diff --git a/1.4/Textures/Fetus/Canines/Fetus_Dog02.png b/1.4/Textures/Fetus/Canines/Fetus_Dog02.png new file mode 100644 index 0000000..7b695d5 Binary files /dev/null and b/1.4/Textures/Fetus/Canines/Fetus_Dog02.png differ diff --git a/1.4/Textures/Fetus/Canines/Fetus_Dog03.png b/1.4/Textures/Fetus/Canines/Fetus_Dog03.png new file mode 100644 index 0000000..d9113ed Binary files /dev/null and b/1.4/Textures/Fetus/Canines/Fetus_Dog03.png differ diff --git a/1.4/Textures/Fetus/Canines/Fetus_Dog04.png b/1.4/Textures/Fetus/Canines/Fetus_Dog04.png new file mode 100644 index 0000000..c0ce6ed Binary files /dev/null and b/1.4/Textures/Fetus/Canines/Fetus_Dog04.png differ diff --git a/1.4/Textures/Fetus/Canines/Fetus_Dog05.png b/1.4/Textures/Fetus/Canines/Fetus_Dog05.png new file mode 100644 index 0000000..3a13bb1 Binary files /dev/null and b/1.4/Textures/Fetus/Canines/Fetus_Dog05.png differ diff --git a/1.4/Textures/Fetus/Feline/Fetus_Cat00.png b/1.4/Textures/Fetus/Feline/Fetus_Cat00.png new file mode 100644 index 0000000..954e91d Binary files /dev/null and b/1.4/Textures/Fetus/Feline/Fetus_Cat00.png differ diff --git a/1.4/Textures/Fetus/Feline/Fetus_Cat01.png b/1.4/Textures/Fetus/Feline/Fetus_Cat01.png new file mode 100644 index 0000000..39f41e3 Binary files /dev/null and b/1.4/Textures/Fetus/Feline/Fetus_Cat01.png differ diff --git a/1.4/Textures/Fetus/Feline/Fetus_Cat02.png b/1.4/Textures/Fetus/Feline/Fetus_Cat02.png new file mode 100644 index 0000000..0e7d9f1 Binary files /dev/null and b/1.4/Textures/Fetus/Feline/Fetus_Cat02.png differ diff --git a/1.4/Textures/Fetus/Feline/Fetus_Cat03.png b/1.4/Textures/Fetus/Feline/Fetus_Cat03.png new file mode 100644 index 0000000..9a6f92a Binary files /dev/null and b/1.4/Textures/Fetus/Feline/Fetus_Cat03.png differ diff --git a/1.4/Textures/Fetus/Feline/Fetus_Cat04.png b/1.4/Textures/Fetus/Feline/Fetus_Cat04.png new file mode 100644 index 0000000..eff51af Binary files /dev/null and b/1.4/Textures/Fetus/Feline/Fetus_Cat04.png differ diff --git a/1.4/Textures/Fetus/Feline/Fetus_Cat05.png b/1.4/Textures/Fetus/Feline/Fetus_Cat05.png new file mode 100644 index 0000000..ced0f5a Binary files /dev/null and b/1.4/Textures/Fetus/Feline/Fetus_Cat05.png differ diff --git a/1.4/Textures/Fetus/Fetus_Default00.png b/1.4/Textures/Fetus/Fetus_Default00.png new file mode 100644 index 0000000..cc26dc5 Binary files /dev/null and b/1.4/Textures/Fetus/Fetus_Default00.png differ diff --git a/1.4/Textures/Fetus/Fetus_Default00_Multiplet_2.png b/1.4/Textures/Fetus/Fetus_Default00_Multiplet_2.png new file mode 100644 index 0000000..9f851df Binary files /dev/null and b/1.4/Textures/Fetus/Fetus_Default00_Multiplet_2.png differ diff --git a/1.4/Textures/Fetus/Fetus_Default01.png b/1.4/Textures/Fetus/Fetus_Default01.png new file mode 100644 index 0000000..57521c2 Binary files /dev/null and b/1.4/Textures/Fetus/Fetus_Default01.png differ diff --git a/1.4/Textures/Fetus/Fetus_Default01_Multiplet_2.png b/1.4/Textures/Fetus/Fetus_Default01_Multiplet_2.png new file mode 100644 index 0000000..5c8ddcb Binary files /dev/null and b/1.4/Textures/Fetus/Fetus_Default01_Multiplet_2.png differ diff --git a/1.4/Textures/Fetus/Fetus_Default02.png b/1.4/Textures/Fetus/Fetus_Default02.png new file mode 100644 index 0000000..b64ddca Binary files /dev/null and b/1.4/Textures/Fetus/Fetus_Default02.png differ diff --git a/1.4/Textures/Fetus/Fetus_Default02_Multiplet_2.png b/1.4/Textures/Fetus/Fetus_Default02_Multiplet_2.png new file mode 100644 index 0000000..8013057 Binary files /dev/null and b/1.4/Textures/Fetus/Fetus_Default02_Multiplet_2.png differ diff --git a/1.4/Textures/Fetus/Fetus_Default03.png b/1.4/Textures/Fetus/Fetus_Default03.png new file mode 100644 index 0000000..62a0f74 Binary files /dev/null and b/1.4/Textures/Fetus/Fetus_Default03.png differ diff --git a/1.4/Textures/Fetus/Fetus_Default03_Multiplet_2.png b/1.4/Textures/Fetus/Fetus_Default03_Multiplet_2.png new file mode 100644 index 0000000..317e9e6 Binary files /dev/null and b/1.4/Textures/Fetus/Fetus_Default03_Multiplet_2.png differ diff --git a/1.4/Textures/Fetus/Fetus_Default04.png b/1.4/Textures/Fetus/Fetus_Default04.png new file mode 100644 index 0000000..76e40fd Binary files /dev/null and b/1.4/Textures/Fetus/Fetus_Default04.png differ diff --git a/1.4/Textures/Fetus/Fetus_Default04_Multiplet_2.png b/1.4/Textures/Fetus/Fetus_Default04_Multiplet_2.png new file mode 100644 index 0000000..1ba0822 Binary files /dev/null and b/1.4/Textures/Fetus/Fetus_Default04_Multiplet_2.png differ diff --git a/1.4/Textures/Fetus/Fetus_Default05.png b/1.4/Textures/Fetus/Fetus_Default05.png new file mode 100644 index 0000000..7a39105 Binary files /dev/null and b/1.4/Textures/Fetus/Fetus_Default05.png differ diff --git a/1.4/Textures/Fetus/Fetus_Default05_Multiplet_2.png b/1.4/Textures/Fetus/Fetus_Default05_Multiplet_2.png new file mode 100644 index 0000000..74af81c Binary files /dev/null and b/1.4/Textures/Fetus/Fetus_Default05_Multiplet_2.png differ diff --git a/1.4/Textures/Fetus/Fetus_Early00.png b/1.4/Textures/Fetus/Fetus_Early00.png new file mode 100644 index 0000000..234a82a Binary files /dev/null and b/1.4/Textures/Fetus/Fetus_Early00.png differ diff --git a/1.4/Textures/Fetus/Fetus_Early00_Multiplet_2.png b/1.4/Textures/Fetus/Fetus_Early00_Multiplet_2.png new file mode 100644 index 0000000..6934605 Binary files /dev/null and b/1.4/Textures/Fetus/Fetus_Early00_Multiplet_2.png differ diff --git a/1.4/Textures/Fetus/Fetus_Old.zip b/1.4/Textures/Fetus/Fetus_Old.zip new file mode 100644 index 0000000..90f4e17 Binary files /dev/null and b/1.4/Textures/Fetus/Fetus_Old.zip differ diff --git a/1.4/Textures/Fetus/Insects/Fetus_Insect00.png b/1.4/Textures/Fetus/Insects/Fetus_Insect00.png new file mode 100644 index 0000000..d9c5762 Binary files /dev/null and b/1.4/Textures/Fetus/Insects/Fetus_Insect00.png differ diff --git a/1.4/Textures/Fetus/Insects/Fetus_Insect01.png b/1.4/Textures/Fetus/Insects/Fetus_Insect01.png new file mode 100644 index 0000000..a079980 Binary files /dev/null and b/1.4/Textures/Fetus/Insects/Fetus_Insect01.png differ diff --git a/1.4/Textures/Fetus/Insects/Fetus_Insect02.png b/1.4/Textures/Fetus/Insects/Fetus_Insect02.png new file mode 100644 index 0000000..a2b710c Binary files /dev/null and b/1.4/Textures/Fetus/Insects/Fetus_Insect02.png differ diff --git a/1.4/Textures/Fetus/Insects/Fetus_Insect03.png b/1.4/Textures/Fetus/Insects/Fetus_Insect03.png new file mode 100644 index 0000000..9569db2 Binary files /dev/null and b/1.4/Textures/Fetus/Insects/Fetus_Insect03.png differ diff --git a/1.4/Textures/Fetus/Insects/Fetus_Insect04.png b/1.4/Textures/Fetus/Insects/Fetus_Insect04.png new file mode 100644 index 0000000..2ee2ea4 Binary files /dev/null and b/1.4/Textures/Fetus/Insects/Fetus_Insect04.png differ diff --git a/1.4/Textures/Fetus/Insects/Fetus_Insect05.png b/1.4/Textures/Fetus/Insects/Fetus_Insect05.png new file mode 100644 index 0000000..22487ea Binary files /dev/null and b/1.4/Textures/Fetus/Insects/Fetus_Insect05.png differ diff --git a/1.4/Textures/Fetus/Insects/Insect_Early00.png b/1.4/Textures/Fetus/Insects/Insect_Early00.png new file mode 100644 index 0000000..917bd14 Binary files /dev/null and b/1.4/Textures/Fetus/Insects/Insect_Early00.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_Bovine00.png b/1.4/Textures/Fetus/Livestocks/Fetus_Bovine00.png new file mode 100644 index 0000000..cc3f27f Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_Bovine00.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_Bovine01.png b/1.4/Textures/Fetus/Livestocks/Fetus_Bovine01.png new file mode 100644 index 0000000..d0301a2 Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_Bovine01.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_Bovine02.png b/1.4/Textures/Fetus/Livestocks/Fetus_Bovine02.png new file mode 100644 index 0000000..36177c8 Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_Bovine02.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_Bovine03.png b/1.4/Textures/Fetus/Livestocks/Fetus_Bovine03.png new file mode 100644 index 0000000..aa679f8 Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_Bovine03.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_Bovine04.png b/1.4/Textures/Fetus/Livestocks/Fetus_Bovine04.png new file mode 100644 index 0000000..b11e248 Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_Bovine04.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_Bovine05.png b/1.4/Textures/Fetus/Livestocks/Fetus_Bovine05.png new file mode 100644 index 0000000..a5823a5 Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_Bovine05.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_Elephant00.png b/1.4/Textures/Fetus/Livestocks/Fetus_Elephant00.png new file mode 100644 index 0000000..284cc1c Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_Elephant00.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_Elephant01.png b/1.4/Textures/Fetus/Livestocks/Fetus_Elephant01.png new file mode 100644 index 0000000..418f10c Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_Elephant01.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_Elephant02.png b/1.4/Textures/Fetus/Livestocks/Fetus_Elephant02.png new file mode 100644 index 0000000..0ce2a51 Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_Elephant02.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_Elephant03.png b/1.4/Textures/Fetus/Livestocks/Fetus_Elephant03.png new file mode 100644 index 0000000..3fa7aff Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_Elephant03.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_Elephant04.png b/1.4/Textures/Fetus/Livestocks/Fetus_Elephant04.png new file mode 100644 index 0000000..4c7507d Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_Elephant04.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_Elephant05.png b/1.4/Textures/Fetus/Livestocks/Fetus_Elephant05.png new file mode 100644 index 0000000..3231d3f Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_Elephant05.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_Pig00.png b/1.4/Textures/Fetus/Livestocks/Fetus_Pig00.png new file mode 100644 index 0000000..cc3f27f Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_Pig00.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_Pig01.png b/1.4/Textures/Fetus/Livestocks/Fetus_Pig01.png new file mode 100644 index 0000000..e08968f Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_Pig01.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_Pig02.png b/1.4/Textures/Fetus/Livestocks/Fetus_Pig02.png new file mode 100644 index 0000000..169cb7b Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_Pig02.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_Pig03.png b/1.4/Textures/Fetus/Livestocks/Fetus_Pig03.png new file mode 100644 index 0000000..f35c741 Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_Pig03.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_Pig04.png b/1.4/Textures/Fetus/Livestocks/Fetus_Pig04.png new file mode 100644 index 0000000..36dc41e Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_Pig04.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_Pig05.png b/1.4/Textures/Fetus/Livestocks/Fetus_Pig05.png new file mode 100644 index 0000000..4563e8e Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_Pig05.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_S_Bovine00.png b/1.4/Textures/Fetus/Livestocks/Fetus_S_Bovine00.png new file mode 100644 index 0000000..36e074d Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_S_Bovine00.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_S_Bovine01.png b/1.4/Textures/Fetus/Livestocks/Fetus_S_Bovine01.png new file mode 100644 index 0000000..2ede985 Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_S_Bovine01.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_S_Bovine02.png b/1.4/Textures/Fetus/Livestocks/Fetus_S_Bovine02.png new file mode 100644 index 0000000..a286064 Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_S_Bovine02.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_S_Bovine03.png b/1.4/Textures/Fetus/Livestocks/Fetus_S_Bovine03.png new file mode 100644 index 0000000..6ccd8c1 Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_S_Bovine03.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_S_Bovine04.png b/1.4/Textures/Fetus/Livestocks/Fetus_S_Bovine04.png new file mode 100644 index 0000000..793a22a Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_S_Bovine04.png differ diff --git a/1.4/Textures/Fetus/Livestocks/Fetus_S_Bovine05.png b/1.4/Textures/Fetus/Livestocks/Fetus_S_Bovine05.png new file mode 100644 index 0000000..5867419 Binary files /dev/null and b/1.4/Textures/Fetus/Livestocks/Fetus_S_Bovine05.png differ diff --git a/1.4/Textures/Fetus/Mech/Fetus_Mech00.png b/1.4/Textures/Fetus/Mech/Fetus_Mech00.png new file mode 100644 index 0000000..6c776d2 Binary files /dev/null and b/1.4/Textures/Fetus/Mech/Fetus_Mech00.png differ diff --git a/1.4/Textures/Fetus/Mech/Fetus_Mech01.png b/1.4/Textures/Fetus/Mech/Fetus_Mech01.png new file mode 100644 index 0000000..41639e7 Binary files /dev/null and b/1.4/Textures/Fetus/Mech/Fetus_Mech01.png differ diff --git a/1.4/Textures/Fetus/Mech/Fetus_Mech02.png b/1.4/Textures/Fetus/Mech/Fetus_Mech02.png new file mode 100644 index 0000000..3f92a2f Binary files /dev/null and b/1.4/Textures/Fetus/Mech/Fetus_Mech02.png differ diff --git a/1.4/Textures/Fetus/Mech/Fetus_Mech03.png b/1.4/Textures/Fetus/Mech/Fetus_Mech03.png new file mode 100644 index 0000000..b499fca Binary files /dev/null and b/1.4/Textures/Fetus/Mech/Fetus_Mech03.png differ diff --git a/1.4/Textures/Fetus/Mech/Fetus_Mech04.png b/1.4/Textures/Fetus/Mech/Fetus_Mech04.png new file mode 100644 index 0000000..f0743f4 Binary files /dev/null and b/1.4/Textures/Fetus/Mech/Fetus_Mech04.png differ diff --git a/1.4/Textures/Fetus/Mech/Fetus_Mech05.png b/1.4/Textures/Fetus/Mech/Fetus_Mech05.png new file mode 100644 index 0000000..df9007b Binary files /dev/null and b/1.4/Textures/Fetus/Mech/Fetus_Mech05.png differ diff --git a/1.4/Textures/Fetus/Pests/Fetus_Rodent00.png b/1.4/Textures/Fetus/Pests/Fetus_Rodent00.png new file mode 100644 index 0000000..36e074d Binary files /dev/null and b/1.4/Textures/Fetus/Pests/Fetus_Rodent00.png differ diff --git a/1.4/Textures/Fetus/Pests/Fetus_Rodent01.png b/1.4/Textures/Fetus/Pests/Fetus_Rodent01.png new file mode 100644 index 0000000..2ede985 Binary files /dev/null and b/1.4/Textures/Fetus/Pests/Fetus_Rodent01.png differ diff --git a/1.4/Textures/Fetus/Pests/Fetus_Rodent02.png b/1.4/Textures/Fetus/Pests/Fetus_Rodent02.png new file mode 100644 index 0000000..a286064 Binary files /dev/null and b/1.4/Textures/Fetus/Pests/Fetus_Rodent02.png differ diff --git a/1.4/Textures/Fetus/Pests/Fetus_Rodent03.png b/1.4/Textures/Fetus/Pests/Fetus_Rodent03.png new file mode 100644 index 0000000..6ccd8c1 Binary files /dev/null and b/1.4/Textures/Fetus/Pests/Fetus_Rodent03.png differ diff --git a/1.4/Textures/Fetus/Pests/Fetus_Rodent04.png b/1.4/Textures/Fetus/Pests/Fetus_Rodent04.png new file mode 100644 index 0000000..793a22a Binary files /dev/null and b/1.4/Textures/Fetus/Pests/Fetus_Rodent04.png differ diff --git a/1.4/Textures/Fetus/Pests/Fetus_Rodent05.png b/1.4/Textures/Fetus/Pests/Fetus_Rodent05.png new file mode 100644 index 0000000..5867419 Binary files /dev/null and b/1.4/Textures/Fetus/Pests/Fetus_Rodent05.png differ diff --git a/1.4/Textures/Fetus/Primate/Fetus_Monkey00.png b/1.4/Textures/Fetus/Primate/Fetus_Monkey00.png new file mode 100644 index 0000000..c9373bf Binary files /dev/null and b/1.4/Textures/Fetus/Primate/Fetus_Monkey00.png differ diff --git a/1.4/Textures/Fetus/Primate/Fetus_Monkey01.png b/1.4/Textures/Fetus/Primate/Fetus_Monkey01.png new file mode 100644 index 0000000..41f7990 Binary files /dev/null and b/1.4/Textures/Fetus/Primate/Fetus_Monkey01.png differ diff --git a/1.4/Textures/Fetus/Primate/Fetus_Monkey02.png b/1.4/Textures/Fetus/Primate/Fetus_Monkey02.png new file mode 100644 index 0000000..66c4c66 Binary files /dev/null and b/1.4/Textures/Fetus/Primate/Fetus_Monkey02.png differ diff --git a/1.4/Textures/Fetus/Primate/Fetus_Monkey03.png b/1.4/Textures/Fetus/Primate/Fetus_Monkey03.png new file mode 100644 index 0000000..779d224 Binary files /dev/null and b/1.4/Textures/Fetus/Primate/Fetus_Monkey03.png differ diff --git a/1.4/Textures/Fetus/Primate/Fetus_Monkey04.png b/1.4/Textures/Fetus/Primate/Fetus_Monkey04.png new file mode 100644 index 0000000..824c129 Binary files /dev/null and b/1.4/Textures/Fetus/Primate/Fetus_Monkey04.png differ diff --git a/1.4/Textures/Fetus/Primate/Fetus_Monkey05.png b/1.4/Textures/Fetus/Primate/Fetus_Monkey05.png new file mode 100644 index 0000000..5c24e15 Binary files /dev/null and b/1.4/Textures/Fetus/Primate/Fetus_Monkey05.png differ diff --git a/1.4/Textures/Fetus/Reptile/Fetus_Lizard00.png b/1.4/Textures/Fetus/Reptile/Fetus_Lizard00.png new file mode 100644 index 0000000..0146135 Binary files /dev/null and b/1.4/Textures/Fetus/Reptile/Fetus_Lizard00.png differ diff --git a/1.4/Textures/Fetus/Reptile/Fetus_Lizard01.png b/1.4/Textures/Fetus/Reptile/Fetus_Lizard01.png new file mode 100644 index 0000000..6fcdbfa Binary files /dev/null and b/1.4/Textures/Fetus/Reptile/Fetus_Lizard01.png differ diff --git a/1.4/Textures/Fetus/Reptile/Fetus_Lizard02.png b/1.4/Textures/Fetus/Reptile/Fetus_Lizard02.png new file mode 100644 index 0000000..1d46463 Binary files /dev/null and b/1.4/Textures/Fetus/Reptile/Fetus_Lizard02.png differ diff --git a/1.4/Textures/Fetus/Reptile/Fetus_Lizard03.png b/1.4/Textures/Fetus/Reptile/Fetus_Lizard03.png new file mode 100644 index 0000000..bb537f4 Binary files /dev/null and b/1.4/Textures/Fetus/Reptile/Fetus_Lizard03.png differ diff --git a/1.4/Textures/Fetus/Reptile/Fetus_Lizard04.png b/1.4/Textures/Fetus/Reptile/Fetus_Lizard04.png new file mode 100644 index 0000000..fe10857 Binary files /dev/null and b/1.4/Textures/Fetus/Reptile/Fetus_Lizard04.png differ diff --git a/1.4/Textures/Fetus/Reptile/Fetus_Lizard05.png b/1.4/Textures/Fetus/Reptile/Fetus_Lizard05.png new file mode 100644 index 0000000..f24bc74 Binary files /dev/null and b/1.4/Textures/Fetus/Reptile/Fetus_Lizard05.png differ diff --git a/1.4/Textures/Fetus/Reptile/Fetus_Snake00.png b/1.4/Textures/Fetus/Reptile/Fetus_Snake00.png new file mode 100644 index 0000000..0146135 Binary files /dev/null and b/1.4/Textures/Fetus/Reptile/Fetus_Snake00.png differ diff --git a/1.4/Textures/Fetus/Reptile/Fetus_Snake01.png b/1.4/Textures/Fetus/Reptile/Fetus_Snake01.png new file mode 100644 index 0000000..afd9795 Binary files /dev/null and b/1.4/Textures/Fetus/Reptile/Fetus_Snake01.png differ diff --git a/1.4/Textures/Fetus/Reptile/Fetus_Snake02.png b/1.4/Textures/Fetus/Reptile/Fetus_Snake02.png new file mode 100644 index 0000000..70756b3 Binary files /dev/null and b/1.4/Textures/Fetus/Reptile/Fetus_Snake02.png differ diff --git a/1.4/Textures/Fetus/Reptile/Fetus_Snake03.png b/1.4/Textures/Fetus/Reptile/Fetus_Snake03.png new file mode 100644 index 0000000..b87191b Binary files /dev/null and b/1.4/Textures/Fetus/Reptile/Fetus_Snake03.png differ diff --git a/1.4/Textures/Fetus/Reptile/Fetus_Snake04.png b/1.4/Textures/Fetus/Reptile/Fetus_Snake04.png new file mode 100644 index 0000000..085b455 Binary files /dev/null and b/1.4/Textures/Fetus/Reptile/Fetus_Snake04.png differ diff --git a/1.4/Textures/Fetus/Reptile/Fetus_Snake05.png b/1.4/Textures/Fetus/Reptile/Fetus_Snake05.png new file mode 100644 index 0000000..98e3c58 Binary files /dev/null and b/1.4/Textures/Fetus/Reptile/Fetus_Snake05.png differ diff --git a/1.4/Textures/Fetus/Slime_Abomi02.png b/1.4/Textures/Fetus/Slime_Abomi02.png new file mode 100644 index 0000000..1d23d46 Binary files /dev/null and b/1.4/Textures/Fetus/Slime_Abomi02.png differ diff --git a/1.4/Textures/Fetus/~Dev/00.png b/1.4/Textures/Fetus/~Dev/00.png new file mode 100644 index 0000000..cfb062c Binary files /dev/null and b/1.4/Textures/Fetus/~Dev/00.png differ diff --git a/1.4/Textures/Fetus/~Dev/01.png b/1.4/Textures/Fetus/~Dev/01.png new file mode 100644 index 0000000..240f177 Binary files /dev/null and b/1.4/Textures/Fetus/~Dev/01.png differ diff --git a/1.4/Textures/Fetus/~Dev/02.png b/1.4/Textures/Fetus/~Dev/02.png new file mode 100644 index 0000000..77fd712 Binary files /dev/null and b/1.4/Textures/Fetus/~Dev/02.png differ diff --git a/1.4/Textures/Fetus/~Dev/03.png b/1.4/Textures/Fetus/~Dev/03.png new file mode 100644 index 0000000..b20c79b Binary files /dev/null and b/1.4/Textures/Fetus/~Dev/03.png differ diff --git a/1.4/Textures/Fetus/~Dev/04.png b/1.4/Textures/Fetus/~Dev/04.png new file mode 100644 index 0000000..2c60c54 Binary files /dev/null and b/1.4/Textures/Fetus/~Dev/04.png differ diff --git a/1.4/Textures/Fetus/~Dev/05.png b/1.4/Textures/Fetus/~Dev/05.png new file mode 100644 index 0000000..38a4887 Binary files /dev/null and b/1.4/Textures/Fetus/~Dev/05.png differ diff --git a/1.4/Textures/Fetus/~Dev/~00.png b/1.4/Textures/Fetus/~Dev/~00.png new file mode 100644 index 0000000..7f49007 Binary files /dev/null and b/1.4/Textures/Fetus/~Dev/~00.png differ diff --git a/1.4/Textures/Genitals/Anal00.png b/1.4/Textures/Genitals/Anal00.png new file mode 100644 index 0000000..966cbf0 Binary files /dev/null and b/1.4/Textures/Genitals/Anal00.png differ diff --git a/1.4/Textures/Genitals/Anal01.png b/1.4/Textures/Genitals/Anal01.png new file mode 100644 index 0000000..d6376b8 Binary files /dev/null and b/1.4/Textures/Genitals/Anal01.png differ diff --git a/1.4/Textures/Genitals/Anal02.png b/1.4/Textures/Genitals/Anal02.png new file mode 100644 index 0000000..e258cb7 Binary files /dev/null and b/1.4/Textures/Genitals/Anal02.png differ diff --git a/1.4/Textures/Genitals/Anal03.png b/1.4/Textures/Genitals/Anal03.png new file mode 100644 index 0000000..6760051 Binary files /dev/null and b/1.4/Textures/Genitals/Anal03.png differ diff --git a/1.4/Textures/Genitals/Anal04.png b/1.4/Textures/Genitals/Anal04.png new file mode 100644 index 0000000..adb5acc Binary files /dev/null and b/1.4/Textures/Genitals/Anal04.png differ diff --git a/1.4/Textures/Genitals/Anal05.png b/1.4/Textures/Genitals/Anal05.png new file mode 100644 index 0000000..439966a Binary files /dev/null and b/1.4/Textures/Genitals/Anal05.png differ diff --git a/1.4/Textures/Genitals/BionicAnal00.png b/1.4/Textures/Genitals/BionicAnal00.png new file mode 100644 index 0000000..17d2aba Binary files /dev/null and b/1.4/Textures/Genitals/BionicAnal00.png differ diff --git a/1.4/Textures/Genitals/BionicAnal01.png b/1.4/Textures/Genitals/BionicAnal01.png new file mode 100644 index 0000000..1decaab Binary files /dev/null and b/1.4/Textures/Genitals/BionicAnal01.png differ diff --git a/1.4/Textures/Genitals/BionicAnal02.png b/1.4/Textures/Genitals/BionicAnal02.png new file mode 100644 index 0000000..b8c2398 Binary files /dev/null and b/1.4/Textures/Genitals/BionicAnal02.png differ diff --git a/1.4/Textures/Genitals/BionicAnal03.png b/1.4/Textures/Genitals/BionicAnal03.png new file mode 100644 index 0000000..b947669 Binary files /dev/null and b/1.4/Textures/Genitals/BionicAnal03.png differ diff --git a/1.4/Textures/Genitals/BionicAnal04.png b/1.4/Textures/Genitals/BionicAnal04.png new file mode 100644 index 0000000..973263f Binary files /dev/null and b/1.4/Textures/Genitals/BionicAnal04.png differ diff --git a/1.4/Textures/Genitals/BionicAnal05.png b/1.4/Textures/Genitals/BionicAnal05.png new file mode 100644 index 0000000..bd33d48 Binary files /dev/null and b/1.4/Textures/Genitals/BionicAnal05.png differ diff --git a/1.4/Textures/Genitals/BionicVagina00.png b/1.4/Textures/Genitals/BionicVagina00.png new file mode 100644 index 0000000..e433424 Binary files /dev/null and b/1.4/Textures/Genitals/BionicVagina00.png differ diff --git a/1.4/Textures/Genitals/BionicVagina01.png b/1.4/Textures/Genitals/BionicVagina01.png new file mode 100644 index 0000000..2cb7874 Binary files /dev/null and b/1.4/Textures/Genitals/BionicVagina01.png differ diff --git a/1.4/Textures/Genitals/BionicVagina02.png b/1.4/Textures/Genitals/BionicVagina02.png new file mode 100644 index 0000000..6ada1d1 Binary files /dev/null and b/1.4/Textures/Genitals/BionicVagina02.png differ diff --git a/1.4/Textures/Genitals/BionicVagina03.png b/1.4/Textures/Genitals/BionicVagina03.png new file mode 100644 index 0000000..3d4ee65 Binary files /dev/null and b/1.4/Textures/Genitals/BionicVagina03.png differ diff --git a/1.4/Textures/Genitals/BionicVagina04.png b/1.4/Textures/Genitals/BionicVagina04.png new file mode 100644 index 0000000..ece1957 Binary files /dev/null and b/1.4/Textures/Genitals/BionicVagina04.png differ diff --git a/1.4/Textures/Genitals/BionicVagina05.png b/1.4/Textures/Genitals/BionicVagina05.png new file mode 100644 index 0000000..7c53581 Binary files /dev/null and b/1.4/Textures/Genitals/BionicVagina05.png differ diff --git a/1.4/Textures/Genitals/BionicVagina06.png b/1.4/Textures/Genitals/BionicVagina06.png new file mode 100644 index 0000000..84ea205 Binary files /dev/null and b/1.4/Textures/Genitals/BionicVagina06.png differ diff --git a/1.4/Textures/Genitals/BionicVagina07.png b/1.4/Textures/Genitals/BionicVagina07.png new file mode 100644 index 0000000..c5d0208 Binary files /dev/null and b/1.4/Textures/Genitals/BionicVagina07.png differ diff --git a/1.4/Textures/Genitals/BionicVagina08.png b/1.4/Textures/Genitals/BionicVagina08.png new file mode 100644 index 0000000..0c9572d Binary files /dev/null and b/1.4/Textures/Genitals/BionicVagina08.png differ diff --git a/1.4/Textures/Genitals/BionicVagina09.png b/1.4/Textures/Genitals/BionicVagina09.png new file mode 100644 index 0000000..52dfd73 Binary files /dev/null and b/1.4/Textures/Genitals/BionicVagina09.png differ diff --git a/1.4/Textures/Genitals/BionicVagina10.png b/1.4/Textures/Genitals/BionicVagina10.png new file mode 100644 index 0000000..23f560c Binary files /dev/null and b/1.4/Textures/Genitals/BionicVagina10.png differ diff --git a/1.4/Textures/Genitals/BionicVagina11.png b/1.4/Textures/Genitals/BionicVagina11.png new file mode 100644 index 0000000..8ee5a5e Binary files /dev/null and b/1.4/Textures/Genitals/BionicVagina11.png differ diff --git a/1.4/Textures/Genitals/Genitals_Old.zip b/1.4/Textures/Genitals/Genitals_Old.zip new file mode 100644 index 0000000..bda9dd3 Binary files /dev/null and b/1.4/Textures/Genitals/Genitals_Old.zip differ diff --git a/1.4/Textures/Genitals/Vagina00.png b/1.4/Textures/Genitals/Vagina00.png new file mode 100644 index 0000000..3646007 Binary files /dev/null and b/1.4/Textures/Genitals/Vagina00.png differ diff --git a/1.4/Textures/Genitals/Vagina01.png b/1.4/Textures/Genitals/Vagina01.png new file mode 100644 index 0000000..4dd0549 Binary files /dev/null and b/1.4/Textures/Genitals/Vagina01.png differ diff --git a/1.4/Textures/Genitals/Vagina02.png b/1.4/Textures/Genitals/Vagina02.png new file mode 100644 index 0000000..549422a Binary files /dev/null and b/1.4/Textures/Genitals/Vagina02.png differ diff --git a/1.4/Textures/Genitals/Vagina03.png b/1.4/Textures/Genitals/Vagina03.png new file mode 100644 index 0000000..7876f2e Binary files /dev/null and b/1.4/Textures/Genitals/Vagina03.png differ diff --git a/1.4/Textures/Genitals/Vagina04.png b/1.4/Textures/Genitals/Vagina04.png new file mode 100644 index 0000000..e1f6f3b Binary files /dev/null and b/1.4/Textures/Genitals/Vagina04.png differ diff --git a/1.4/Textures/Genitals/Vagina05.png b/1.4/Textures/Genitals/Vagina05.png new file mode 100644 index 0000000..a86b146 Binary files /dev/null and b/1.4/Textures/Genitals/Vagina05.png differ diff --git a/1.4/Textures/Genitals/Vagina06.png b/1.4/Textures/Genitals/Vagina06.png new file mode 100644 index 0000000..29f103a Binary files /dev/null and b/1.4/Textures/Genitals/Vagina06.png differ diff --git a/1.4/Textures/Genitals/Vagina07.png b/1.4/Textures/Genitals/Vagina07.png new file mode 100644 index 0000000..d020b9f Binary files /dev/null and b/1.4/Textures/Genitals/Vagina07.png differ diff --git a/1.4/Textures/Genitals/Vagina08.png b/1.4/Textures/Genitals/Vagina08.png new file mode 100644 index 0000000..41a1e63 Binary files /dev/null and b/1.4/Textures/Genitals/Vagina08.png differ diff --git a/1.4/Textures/Genitals/Vagina09.png b/1.4/Textures/Genitals/Vagina09.png new file mode 100644 index 0000000..96bc301 Binary files /dev/null and b/1.4/Textures/Genitals/Vagina09.png differ diff --git a/1.4/Textures/Genitals/Vagina10.png b/1.4/Textures/Genitals/Vagina10.png new file mode 100644 index 0000000..fd5ab20 Binary files /dev/null and b/1.4/Textures/Genitals/Vagina10.png differ diff --git a/1.4/Textures/Genitals/Vagina11.png b/1.4/Textures/Genitals/Vagina11.png new file mode 100644 index 0000000..900e718 Binary files /dev/null and b/1.4/Textures/Genitals/Vagina11.png differ diff --git a/1.4/Textures/Milk/Milkbottle_Large.png b/1.4/Textures/Milk/Milkbottle_Large.png new file mode 100644 index 0000000..88a8899 Binary files /dev/null and b/1.4/Textures/Milk/Milkbottle_Large.png differ diff --git a/1.4/Textures/Milk/Milkbottle_Medium.png b/1.4/Textures/Milk/Milkbottle_Medium.png new file mode 100644 index 0000000..9fced73 Binary files /dev/null and b/1.4/Textures/Milk/Milkbottle_Medium.png differ diff --git a/1.4/Textures/Milk/Milkbottle_Small.png b/1.4/Textures/Milk/Milkbottle_Small.png new file mode 100644 index 0000000..c9ac05f Binary files /dev/null and b/1.4/Textures/Milk/Milkbottle_Small.png differ diff --git a/1.4/Textures/Ovaries/Ovary_00.png b/1.4/Textures/Ovaries/Ovary_00.png new file mode 100644 index 0000000..4e4ee2f Binary files /dev/null and b/1.4/Textures/Ovaries/Ovary_00.png differ diff --git a/1.4/Textures/Ovaries/Ovary_01.png b/1.4/Textures/Ovaries/Ovary_01.png new file mode 100644 index 0000000..1ab312a Binary files /dev/null and b/1.4/Textures/Ovaries/Ovary_01.png differ diff --git a/1.4/Textures/Ovaries/Ovary_02.png b/1.4/Textures/Ovaries/Ovary_02.png new file mode 100644 index 0000000..8307a66 Binary files /dev/null and b/1.4/Textures/Ovaries/Ovary_02.png differ diff --git a/1.4/Textures/Textures_old.7z b/1.4/Textures/Textures_old.7z new file mode 100644 index 0000000..a967dfb Binary files /dev/null and b/1.4/Textures/Textures_old.7z differ diff --git a/1.4/Textures/Things/Item/Cyclosporine/Cyclosporine_a.png b/1.4/Textures/Things/Item/Cyclosporine/Cyclosporine_a.png new file mode 100644 index 0000000..6b50437 Binary files /dev/null and b/1.4/Textures/Things/Item/Cyclosporine/Cyclosporine_a.png differ diff --git a/1.4/Textures/Things/Item/Cyclosporine/Cyclosporine_b.png b/1.4/Textures/Things/Item/Cyclosporine/Cyclosporine_b.png new file mode 100644 index 0000000..d66f763 Binary files /dev/null and b/1.4/Textures/Things/Item/Cyclosporine/Cyclosporine_b.png differ diff --git a/1.4/Textures/Things/Item/Milkbottle/Milkbottle_a.png b/1.4/Textures/Things/Item/Milkbottle/Milkbottle_a.png new file mode 100644 index 0000000..c9ac05f Binary files /dev/null and b/1.4/Textures/Things/Item/Milkbottle/Milkbottle_a.png differ diff --git a/1.4/Textures/Things/Item/Milkbottle/Milkbottle_b.png b/1.4/Textures/Things/Item/Milkbottle/Milkbottle_b.png new file mode 100644 index 0000000..9fced73 Binary files /dev/null and b/1.4/Textures/Things/Item/Milkbottle/Milkbottle_b.png differ diff --git a/1.4/Textures/Things/Item/Milkbottle/Milkbottle_c.png b/1.4/Textures/Things/Item/Milkbottle/Milkbottle_c.png new file mode 100644 index 0000000..88a8899 Binary files /dev/null and b/1.4/Textures/Things/Item/Milkbottle/Milkbottle_c.png differ diff --git a/1.4/Textures/Things/Item/ORPill/ORPill_a.png b/1.4/Textures/Things/Item/ORPill/ORPill_a.png new file mode 100644 index 0000000..b2eaeaa Binary files /dev/null and b/1.4/Textures/Things/Item/ORPill/ORPill_a.png differ diff --git a/1.4/Textures/Things/Item/ORPill/ORPill_b.png b/1.4/Textures/Things/Item/ORPill/ORPill_b.png new file mode 100644 index 0000000..b3f0dbd Binary files /dev/null and b/1.4/Textures/Things/Item/ORPill/ORPill_b.png differ diff --git a/1.4/Textures/Things/Item/Pad.png b/1.4/Textures/Things/Item/Pad.png new file mode 100644 index 0000000..e58d6d6 Binary files /dev/null and b/1.4/Textures/Things/Item/Pad.png differ diff --git a/1.4/Textures/Things/Item/PainReliever/PainReliever_a.png b/1.4/Textures/Things/Item/PainReliever/PainReliever_a.png new file mode 100644 index 0000000..bad8d0b Binary files /dev/null and b/1.4/Textures/Things/Item/PainReliever/PainReliever_a.png differ diff --git a/1.4/Textures/Things/Item/PainReliever/PainReliever_b.png b/1.4/Textures/Things/Item/PainReliever/PainReliever_b.png new file mode 100644 index 0000000..3e8d7c3 Binary files /dev/null and b/1.4/Textures/Things/Item/PainReliever/PainReliever_b.png differ diff --git a/1.4/Textures/Things/Item/SIA/SIA_a.png b/1.4/Textures/Things/Item/SIA/SIA_a.png new file mode 100644 index 0000000..8788c7f Binary files /dev/null and b/1.4/Textures/Things/Item/SIA/SIA_a.png differ diff --git a/1.4/Textures/Things/Item/SIA/SIA_b.png b/1.4/Textures/Things/Item/SIA/SIA_b.png new file mode 100644 index 0000000..b78ca67 Binary files /dev/null and b/1.4/Textures/Things/Item/SIA/SIA_b.png differ diff --git a/1.4/Textures/Things/Item/Tampon.png b/1.4/Textures/Things/Item/Tampon.png new file mode 100644 index 0000000..a2f10bd Binary files /dev/null and b/1.4/Textures/Things/Item/Tampon.png differ diff --git a/1.4/Textures/Things/Item/Tampon/Tampon_a.png b/1.4/Textures/Things/Item/Tampon/Tampon_a.png new file mode 100644 index 0000000..a2f10bd Binary files /dev/null and b/1.4/Textures/Things/Item/Tampon/Tampon_a.png differ diff --git a/1.4/Textures/Things/Item/Tampon/Tampon_b.png b/1.4/Textures/Things/Item/Tampon/Tampon_b.png new file mode 100644 index 0000000..6b5ed45 Binary files /dev/null and b/1.4/Textures/Things/Item/Tampon/Tampon_b.png differ diff --git a/1.4/Textures/UI/Icon/ToBucket.png b/1.4/Textures/UI/Icon/ToBucket.png new file mode 100644 index 0000000..b979db0 Binary files /dev/null and b/1.4/Textures/UI/Icon/ToBucket.png differ diff --git a/1.4/Textures/UI/Icon/ToPussy.png b/1.4/Textures/UI/Icon/ToPussy.png new file mode 100644 index 0000000..2e23632 Binary files /dev/null and b/1.4/Textures/UI/Icon/ToPussy.png differ diff --git a/1.4/Textures/Womb/Empty.png b/1.4/Textures/Womb/Empty.png new file mode 100644 index 0000000..1aa9036 Binary files /dev/null and b/1.4/Textures/Womb/Empty.png differ diff --git a/1.4/Textures/Womb/ImplantedEgg.png b/1.4/Textures/Womb/ImplantedEgg.png new file mode 100644 index 0000000..4858f77 Binary files /dev/null and b/1.4/Textures/Womb/ImplantedEgg.png differ diff --git a/1.4/Textures/Womb/ImplantedEgg_Multiplet_2.png b/1.4/Textures/Womb/ImplantedEgg_Multiplet_2.png new file mode 100644 index 0000000..abe3f63 Binary files /dev/null and b/1.4/Textures/Womb/ImplantedEgg_Multiplet_2.png differ diff --git a/1.4/Textures/Womb/ImplantedEgg_triplet_3.png b/1.4/Textures/Womb/ImplantedEgg_triplet_3.png new file mode 100644 index 0000000..e2573b2 Binary files /dev/null and b/1.4/Textures/Womb/ImplantedEgg_triplet_3.png differ diff --git a/1.4/Textures/Womb/Insect_Egged/Womb_Egged_1.png b/1.4/Textures/Womb/Insect_Egged/Womb_Egged_1.png new file mode 100644 index 0000000..1c6ac74 Binary files /dev/null and b/1.4/Textures/Womb/Insect_Egged/Womb_Egged_1.png differ diff --git a/1.4/Textures/Womb/Insect_Egged/Womb_Egged_2.png b/1.4/Textures/Womb/Insect_Egged/Womb_Egged_2.png new file mode 100644 index 0000000..e65723d Binary files /dev/null and b/1.4/Textures/Womb/Insect_Egged/Womb_Egged_2.png differ diff --git a/1.4/Textures/Womb/Insect_Egged/Womb_Egged_3.png b/1.4/Textures/Womb/Insect_Egged/Womb_Egged_3.png new file mode 100644 index 0000000..d67f3d0 Binary files /dev/null and b/1.4/Textures/Womb/Insect_Egged/Womb_Egged_3.png differ diff --git a/1.4/Textures/Womb/Insect_Egged/Womb_Egged_Large.png b/1.4/Textures/Womb/Insect_Egged/Womb_Egged_Large.png new file mode 100644 index 0000000..dbf41c1 Binary files /dev/null and b/1.4/Textures/Womb/Insect_Egged/Womb_Egged_Large.png differ diff --git a/1.4/Textures/Womb/Insect_Egged/Womb_Egged_Large_Stretched.png b/1.4/Textures/Womb/Insect_Egged/Womb_Egged_Large_Stretched.png new file mode 100644 index 0000000..8d7f546 Binary files /dev/null and b/1.4/Textures/Womb/Insect_Egged/Womb_Egged_Large_Stretched.png differ diff --git a/1.4/Textures/Womb/Insect_Egged/Womb_Egged_Many.png b/1.4/Textures/Womb/Insect_Egged/Womb_Egged_Many.png new file mode 100644 index 0000000..2665259 Binary files /dev/null and b/1.4/Textures/Womb/Insect_Egged/Womb_Egged_Many.png differ diff --git a/1.4/Textures/Womb/Insect_Egged/Womb_Egged_ManyMixed.png b/1.4/Textures/Womb/Insect_Egged/Womb_Egged_ManyMixed.png new file mode 100644 index 0000000..575203e Binary files /dev/null and b/1.4/Textures/Womb/Insect_Egged/Womb_Egged_ManyMixed.png differ diff --git a/1.4/Textures/Womb/Mechanoid_Fluid.png b/1.4/Textures/Womb/Mechanoid_Fluid.png new file mode 100644 index 0000000..5655052 Binary files /dev/null and b/1.4/Textures/Womb/Mechanoid_Fluid.png differ diff --git a/1.4/Textures/Womb/Womb.png b/1.4/Textures/Womb/Womb.png new file mode 100644 index 0000000..7f49007 Binary files /dev/null and b/1.4/Textures/Womb/Womb.png differ diff --git a/1.4/Textures/Womb/Womb.zip b/1.4/Textures/Womb/Womb.zip new file mode 100644 index 0000000..475b690 Binary files /dev/null and b/1.4/Textures/Womb/Womb.zip differ diff --git a/1.4/Textures/Womb/Womb_Bleeding.png b/1.4/Textures/Womb/Womb_Bleeding.png new file mode 100644 index 0000000..3b931ea Binary files /dev/null and b/1.4/Textures/Womb/Womb_Bleeding.png differ diff --git a/1.4/Textures/Womb/Womb_Cum_00.png b/1.4/Textures/Womb/Womb_Cum_00.png new file mode 100644 index 0000000..7a4361a Binary files /dev/null and b/1.4/Textures/Womb/Womb_Cum_00.png differ diff --git a/1.4/Textures/Womb/Womb_Cum_01.png b/1.4/Textures/Womb/Womb_Cum_01.png new file mode 100644 index 0000000..f753ae6 Binary files /dev/null and b/1.4/Textures/Womb/Womb_Cum_01.png differ diff --git a/1.4/Textures/Womb/Womb_Cum_02.png b/1.4/Textures/Womb/Womb_Cum_02.png new file mode 100644 index 0000000..1653f06 Binary files /dev/null and b/1.4/Textures/Womb/Womb_Cum_02.png differ diff --git a/1.4/Textures/Womb/Womb_Cum_03.png b/1.4/Textures/Womb/Womb_Cum_03.png new file mode 100644 index 0000000..000d517 Binary files /dev/null and b/1.4/Textures/Womb/Womb_Cum_03.png differ diff --git a/1.4/Textures/Womb/Womb_Cum_04.png b/1.4/Textures/Womb/Womb_Cum_04.png new file mode 100644 index 0000000..f3fdb37 Binary files /dev/null and b/1.4/Textures/Womb/Womb_Cum_04.png differ diff --git a/1.4/Textures/Womb/Womb_Cum_05.png b/1.4/Textures/Womb/Womb_Cum_05.png new file mode 100644 index 0000000..9f91d4d Binary files /dev/null and b/1.4/Textures/Womb/Womb_Cum_05.png differ diff --git a/1.4/Textures/Womb/Womb_Cum_06.png b/1.4/Textures/Womb/Womb_Cum_06.png new file mode 100644 index 0000000..a34b233 Binary files /dev/null and b/1.4/Textures/Womb/Womb_Cum_06.png differ diff --git a/1.4/Textures/Womb/Womb_Cum_07.png b/1.4/Textures/Womb/Womb_Cum_07.png new file mode 100644 index 0000000..9edb791 Binary files /dev/null and b/1.4/Textures/Womb/Womb_Cum_07.png differ diff --git a/1.4/Textures/Womb/Womb_Cum_08.png b/1.4/Textures/Womb/Womb_Cum_08.png new file mode 100644 index 0000000..5679e84 Binary files /dev/null and b/1.4/Textures/Womb/Womb_Cum_08.png differ diff --git a/1.4/Textures/Womb/Womb_Cum_09.png b/1.4/Textures/Womb/Womb_Cum_09.png new file mode 100644 index 0000000..c89a46e Binary files /dev/null and b/1.4/Textures/Womb/Womb_Cum_09.png differ diff --git a/1.4/Textures/Womb/Womb_Cum_10.png b/1.4/Textures/Womb/Womb_Cum_10.png new file mode 100644 index 0000000..7c4239c Binary files /dev/null and b/1.4/Textures/Womb/Womb_Cum_10.png differ diff --git a/1.4/Textures/Womb/Womb_Cum_11.png b/1.4/Textures/Womb/Womb_Cum_11.png new file mode 100644 index 0000000..52cd588 Binary files /dev/null and b/1.4/Textures/Womb/Womb_Cum_11.png differ diff --git a/1.4/Textures/Womb/Womb_Cum_12.png b/1.4/Textures/Womb/Womb_Cum_12.png new file mode 100644 index 0000000..6bd9215 Binary files /dev/null and b/1.4/Textures/Womb/Womb_Cum_12.png differ diff --git a/1.4/Textures/Womb/Womb_Cum_13.png b/1.4/Textures/Womb/Womb_Cum_13.png new file mode 100644 index 0000000..9a5a2ee Binary files /dev/null and b/1.4/Textures/Womb/Womb_Cum_13.png differ diff --git a/1.4/Textures/Womb/Womb_Cum_14.png b/1.4/Textures/Womb/Womb_Cum_14.png new file mode 100644 index 0000000..991af90 Binary files /dev/null and b/1.4/Textures/Womb/Womb_Cum_14.png differ diff --git a/1.4/Textures/Womb/Womb_Cum_15.png b/1.4/Textures/Womb/Womb_Cum_15.png new file mode 100644 index 0000000..fcc149e Binary files /dev/null and b/1.4/Textures/Womb/Womb_Cum_15.png differ diff --git a/1.4/Textures/Womb/Womb_Cum_16.png b/1.4/Textures/Womb/Womb_Cum_16.png new file mode 100644 index 0000000..3ff95ec Binary files /dev/null and b/1.4/Textures/Womb/Womb_Cum_16.png differ diff --git a/1.4/Textures/Womb/Womb_Cum_17.png b/1.4/Textures/Womb/Womb_Cum_17.png new file mode 100644 index 0000000..3da3ed4 Binary files /dev/null and b/1.4/Textures/Womb/Womb_Cum_17.png differ diff --git a/1.4/Textures/Womb/Womb_Implanted.png b/1.4/Textures/Womb/Womb_Implanted.png new file mode 100644 index 0000000..e570d37 Binary files /dev/null and b/1.4/Textures/Womb/Womb_Implanted.png differ diff --git a/1.4/Textures/Womb/Womb_Implanted_Multiplet_2.png b/1.4/Textures/Womb/Womb_Implanted_Multiplet_2.png new file mode 100644 index 0000000..638e68c Binary files /dev/null and b/1.4/Textures/Womb/Womb_Implanted_Multiplet_2.png differ diff --git a/1.4/Textures/Womb/Womb_Implanted_Multiplet_3.png b/1.4/Textures/Womb/Womb_Implanted_Multiplet_3.png new file mode 100644 index 0000000..2ce2c7f Binary files /dev/null and b/1.4/Textures/Womb/Womb_Implanted_Multiplet_3.png differ diff --git a/1.4/source/RJW_Menstruation/MilkModule/JobDriver_MilkSelf.cs b/1.4/source/RJW_Menstruation/MilkModule/JobDriver_MilkSelf.cs new file mode 100644 index 0000000..1a1cfd4 --- /dev/null +++ b/1.4/source/RJW_Menstruation/MilkModule/JobDriver_MilkSelf.cs @@ -0,0 +1,119 @@ +using Milk; +using RJW_Menstruation; +using Verse; + +namespace MilkModule +{ + public class JobDriver_MilkSelf_MC : JobDriver_MilkSelf + { + HumanCompHasGatherableBodyResource comp; + HediffComp_Breast breastcomp; + + protected override float Fullness + { + get + { + return comp?.Fullness ?? 0f; + } + } + + protected override void PreMakeNewToils() + { + comp = GetMilkComp(pawn); + breastcomp = pawn.GetBreastComp(); + } + + protected override void Gathered() + { + comp?.Gathered(pawn); + } + + protected override void PostTickAction() + { + breastcomp?.AdjustNippleProgress(Rand.Range(0.0f, 0.000005f) * Configurations.MaxNippleIncrementFactor); + } + + + public static HumanCompHasGatherableBodyResource GetMilkComp(Pawn pawn) + { + HumanCompHasGatherableBodyResource result; + if (pawn.health.hediffSet.HasHediff(VariousDefOf.Hediff_Heavy_Lactating_Permanent)) + { + result = pawn.TryGetComp(); + + } + else + { + result = pawn.TryGetComp(); + } + return result; + } + + + + } + + + //public class JobDriver_HumanMilkSelf : JobDriver + //{ + // const float milkingTime = 250f;//ticks - 120 = 2 real seconds, 3 in-game minutes + // + // public override bool TryMakePreToilReservations(bool errorOnFailed) + // { + // return pawn.Reserve(pawn, job, 1, -1, null, errorOnFailed); + // } + // + // protected override IEnumerable MakeNewToils() + // { + // + // HumanCompHasGatherableBodyResource Comp = GetMilkComp(pawn); + // HediffComp_Breast breastcomp = pawn.GetBreastComp(); + // this.FailOn(delegate + // { + // return !(Comp.Fullness > 0.01f); + // }); + // Toil milking = Toils_General.Wait((int)(50 + milkingTime * Comp.Fullness), TargetIndex.None);//duration of + // + // milking.WithProgressBarToilDelay(TargetIndex.A); + // milking.tickAction = delegate () + // { + // if (breastcomp != null) + // { + // breastcomp.AdjustAreolaSize(Rand.Range(0.0f,0.0001f * Configurations.NipplePermanentTransitionVariance)); + // breastcomp.AdjustNippleSize(Rand.Range(0.0f,0.0001f * Configurations.NipplePermanentTransitionVariance)); + // } + // + // }; + // yield return milking; + // yield return new Toil() + // { + // initAction = delegate () + // { + // Comp.Gathered(pawn); + // } + // }; + // //yield return excreting; + // yield break; + // + // } + // + // + // public static HumanCompHasGatherableBodyResource GetMilkComp(Pawn pawn) + // { + // HumanCompHasGatherableBodyResource result; + // if (pawn.health.hediffSet.HasHediff(VariousDefOf.Hediff_Heavy_Lactating_Permanent)) + // { + // result = pawn.TryGetComp(); + // } + // else + // { + // result = pawn.TryGetComp(); + // } + // return result; + // } + // + // + //} + + +} diff --git a/1.4/source/RJW_Menstruation/MilkModule/MilkModule.csproj b/1.4/source/RJW_Menstruation/MilkModule/MilkModule.csproj new file mode 100644 index 0000000..646ba34 --- /dev/null +++ b/1.4/source/RJW_Menstruation/MilkModule/MilkModule.csproj @@ -0,0 +1,104 @@ + + + + + Debug + AnyCPU + {3591B3C1-EB57-44BF-AB69-A613E097A7F8} + Library + Properties + MilkModule + MilkModule + v4.8 + 512 + true + + + + true + full + false + ..\..\..\MilkModule\Assemblies\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + ..\..\..\MilkModule\Assemblies\ + TRACE + prompt + 4 + + + + ..\..\..\..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll + False + + + ..\..\..\..\..\rjw-mc\1.3\Assemblies\Milk.dll + False + + + + + + + + + + + ..\..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.dll + False + + + ..\..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll + False + + + ..\..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.IMGUIModule.dll + False + + + ..\..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.TextCoreModule.dll + False + + + ..\..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.TextRenderingModule.dll + False + + + ..\..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.UI.dll + False + + + ..\..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.UIElementsModule.dll + False + + + ..\..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.UIModule.dll + False + + + + + + + + + + {eed2f3b9-8c20-4194-919e-8d151b29f70b} + RJW_Menstruation + False + + + + + 2.2.2 + runtime + compile; build; native; contentfiles; analyzers; buildtransitive + + + + \ No newline at end of file diff --git a/1.4/source/RJW_Menstruation/MilkModule/Milk_Patch.cs b/1.4/source/RJW_Menstruation/MilkModule/Milk_Patch.cs new file mode 100644 index 0000000..3167822 --- /dev/null +++ b/1.4/source/RJW_Menstruation/MilkModule/Milk_Patch.cs @@ -0,0 +1,28 @@ +using HarmonyLib; +using Milk; +using RJW_Menstruation; +using System.Reflection; +using Verse; + +namespace MilkModule +{ + internal static class First + { + static First() + { + Harmony har = new Harmony("RJW_Menstruation_MilkModule"); + har.PatchAll(Assembly.GetExecutingAssembly()); + } + } + + [HarmonyPatch(typeof(HumanCompHasGatherableBodyResource), nameof(HumanCompHasGatherableBodyResource.Gathered))] + public static class Milk_Patch + { + public static void Postfix(HumanCompHasGatherableBodyResource __instance) + { + if (__instance.parent is Pawn pawn) + pawn.GetBreastComp()?.AdjustNippleProgress(Rand.Range(0.0f, 0.005f) * Configurations.MaxNippleIncrementFactor); + } + + } +} diff --git a/1.4/source/RJW_Menstruation/MilkModule/Properties/AssemblyInfo.cs b/1.4/source/RJW_Menstruation/MilkModule/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..c526740 --- /dev/null +++ b/1.4/source/RJW_Menstruation/MilkModule/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해 +// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면 +// 이러한 특성 값을 변경하세요. +[assembly: AssemblyTitle("MilkModule")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("MilkModule")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에 +// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면 +// 해당 형식에 대해 ComVisible 특성을 true로 설정하세요. +[assembly: ComVisible(false)] + +// 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다. +[assembly: Guid("3591b3c1-eb57-44bf-ab69-a613e097a7f8")] + +// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다. +// +// 주 버전 +// 부 버전 +// 빌드 번호 +// 수정 버전 +// +// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를 +// 기본값으로 할 수 있습니다. +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/1.4/source/RJW_Menstruation/MilkModule/packages.config b/1.4/source/RJW_Menstruation/MilkModule/packages.config new file mode 100644 index 0000000..3299dfc --- /dev/null +++ b/1.4/source/RJW_Menstruation/MilkModule/packages.config @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation.sln b/1.4/source/RJW_Menstruation/RJW_Menstruation.sln new file mode 100644 index 0000000..701c76e --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32929.385 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RJW_Menstruation", "RJW_Menstruation\RJW_Menstruation.csproj", "{EED2F3B9-8C20-4194-919E-8D151B29F70B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MilkModule", "MilkModule\MilkModule.csproj", "{3591B3C1-EB57-44BF-AB69-A613E097A7F8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EED2F3B9-8C20-4194-919E-8D151B29F70B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EED2F3B9-8C20-4194-919E-8D151B29F70B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EED2F3B9-8C20-4194-919E-8D151B29F70B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EED2F3B9-8C20-4194-919E-8D151B29F70B}.Release|Any CPU.Build.0 = Release|Any CPU + {3591B3C1-EB57-44BF-AB69-A613E097A7F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3591B3C1-EB57-44BF-AB69-A613E097A7F8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3591B3C1-EB57-44BF-AB69-A613E097A7F8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3591B3C1-EB57-44BF-AB69-A613E097A7F8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0E4B1D09-2A81-4440-AC1E-32ACCECBEE0B} + EndGlobalSection +EndGlobal diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/App.config b/1.4/source/RJW_Menstruation/RJW_Menstruation/App.config new file mode 100644 index 0000000..4bfa005 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/App.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Compatibility/AnimalGeneticsCompatibility.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Compatibility/AnimalGeneticsCompatibility.cs new file mode 100644 index 0000000..1e7e50c --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Compatibility/AnimalGeneticsCompatibility.cs @@ -0,0 +1,42 @@ +#if false +using AnimalGenetics; +using RimWorld; +using System.Collections.Generic; +using Verse; + +namespace RJW_Menstruation +{ + public static class AnimalGeneticsCompatibility + { + public static void PreConception(Pawn mother, Pawn father) + { + GeneticInformation motherGeneticInformation = mother?.AnimalGenetics(); + GeneticInformation fatherGeneticInformation = father?.AnimalGenetics(); + + ParentReferences.Push(new ParentReferences.Record { Mother = motherGeneticInformation, Father = fatherGeneticInformation }); + } + + public static void PostConception() + { + ParentReferences.Pop(); + } + + public static void CopyGenes(Pawn baby, Pawn original) + { + Dictionary babyRecords = baby.AnimalGenetics()?.GeneRecords; + Dictionary originalRecords = original.AnimalGenetics()?.GeneRecords; + + if (babyRecords == null || originalRecords == null) return; + + foreach(KeyValuePair record in originalRecords) + { + GeneRecord originalRecord = record.Value; + if (!babyRecords.TryGetValue(record.Key, out GeneRecord babyRecord)) continue; // Shouldn't fail, but best to be safe + + babyRecord.Parent = originalRecord.Parent; + babyRecord.Value = originalRecord.Value; + } + } + } +} +#endif diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Compatibility/HARCompatibility.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Compatibility/HARCompatibility.cs new file mode 100644 index 0000000..7ef52c7 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Compatibility/HARCompatibility.cs @@ -0,0 +1,41 @@ +using AlienRace; +using System.Collections.Generic; +using UnityEngine; +using Verse; + +namespace RJW_Menstruation +{ + public static class HARCompatibility + { + + public static bool IsHAR(this Pawn pawn) + { + if (!Configurations.HARActivated) return false; + return pawn?.def is ThingDef_AlienRace; + } + + public static void CopyHARProperties(Pawn baby, Pawn original) + { + AlienPartGenerator.AlienComp babyHARComp = baby?.TryGetComp(); + AlienPartGenerator.AlienComp originalHARComp = original?.TryGetComp(); + if (babyHARComp == null || originalHARComp == null) return; + + foreach(KeyValuePair> channel in originalHARComp.ColorChannels) + { + babyHARComp.OverwriteColorChannel(channel.Key, channel.Value.first, channel.Value.second); + } + babyHARComp.headMaskVariant = originalHARComp.headMaskVariant; + babyHARComp.bodyMaskVariant = originalHARComp.bodyMaskVariant; + } + + // HAR doesn't populate variants until the graphics are called for, so this has to happen late + public static void CopyHARPropertiesPostBirth(Pawn baby, Pawn original) + { + AlienPartGenerator.AlienComp babyHARComp = baby?.TryGetComp(); + AlienPartGenerator.AlienComp originalHARComp = original?.TryGetComp(); + if (babyHARComp == null || originalHARComp == null) return; + if (originalHARComp.addonVariants != null) // Testing has shown that the addons are valid by this point, but it's better to be safe + babyHARComp.addonVariants = new List(originalHARComp.addonVariants); + } + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Configurations.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Configurations.cs new file mode 100644 index 0000000..31cfe5d --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Configurations.cs @@ -0,0 +1,494 @@ +using rjw; +using System; +using System.Collections.Generic; +using UnityEngine; +using Verse; + +namespace RJW_Menstruation +{ + public class Configurations : ModSettings + { + public const float ImplantationChanceDefault = 0.65f; + public const int ImplantationChanceAdjustDefault = 65; + public const float FertilizeChanceDefault = 0.15f; + public const int FertilizeChanceAdjustDefault = 150; + public const float CumDecayRatioDefault = 0.15f; + public const int CumDecayRatioAdjustDefault = 150; + public const float CumFertilityDecayRatioDefault = 0.05f; + public const int CumFertilityDecayRatioAdjustDefault = 50; + public const int CycleAccelerationDefault = 6; + public const float EnzygoticTwinsChanceDefault = 0.002f; + public const int EnzygoticTwinsChanceAdjustDefault = 2; + public const int MaxEnzygoticTwinsDefault = 9; + public const int BleedingAmountDefault = 50; + public const float MaxBreastIncrementFactorDefault = 1.0f; + public const float MaxBreastIncrementFactorMax = 2.5f; + public const float MaxNippleIncrementFactorDefault = 1.0f; + public const float MaxNippleIncrementFactorMax = 2.5f; + public const float PermanentNippleChangeDefault = 0.1f; + public const float PermanentNippleChangeMax = 0.25f; + public const float EggLifespanMultiplierDefault = 1.0f; + public const float VaginaMorphPowerDefault = 0.2f; + + public static DetailLevel infoDetail = DetailLevel.All; + + public static float ImplantationChance = ImplantationChanceDefault; + public static int ImplantationChanceAdjust = ImplantationChanceAdjustDefault; + public static float FertilizeChance = FertilizeChanceDefault; + public static int FertilizeChanceAdjust = FertilizeChanceAdjustDefault; + public static float CumDecayRatio = CumDecayRatioDefault; + public static int CumDecayRatioAdjust = CumDecayRatioAdjustDefault; + public static float CumFertilityDecayRatio = CumFertilityDecayRatioDefault; + public static int CumFertilityDecayRatioAdjust = CumFertilityDecayRatioAdjustDefault; + public static int CycleAcceleration = CycleAccelerationDefault; + public static bool EnableWombIcon = true; + public static bool EnableAnimalCycle = false; + public static bool DrawWombStatus = true; + public static bool DrawVaginaStatus = true; + public static bool DrawEggOverlay = true; + public static bool Debug = false; + public static bool EnableMenopause = true; + public static DetailLevel InfoDetail => infoDetail; + public static bool EstrusOverridesHookupSettings = false; + public static float EstrusFuckabilityToHookup = RJWHookupSettings.MinimumFuckabilityToHookup; + public static float EstrusAttractivenessToHookup = RJWHookupSettings.MinimumAttractivenessToHookup; + public static float EstrusRelationshipToHookup = RJWHookupSettings.MinimumRelationshipToHookup; + public static bool UseMultiplePregnancy = true; + public static bool EnableHeteroOvularTwins = true; + public static bool EnableEnzygoticTwins = true; + public static float EnzygoticTwinsChance = EnzygoticTwinsChanceDefault; + public static int EnzygoticTwinsChanceAdjust = EnzygoticTwinsChanceAdjustDefault; + public static int MaxEnzygoticTwins = MaxEnzygoticTwinsDefault; + public static int BleedingAmount = BleedingAmountDefault; + public static bool EnableButtonInHT = false; + public static bool EnableGatherCumGizmo = true; + public static PawnFlags ShowFlag = PawnFlags.Colonist | PawnFlags.Prisoner; + public static bool UseHybridExtention = true; + public static bool MotherFirst = false; + public static bool AllowShrinkIcon = false; + public static float EggLifespanMultiplier = EggLifespanMultiplierDefault; + public static bool EnableBirthVaginaMorph = false; + public static float VaginaMorphPower = VaginaMorphPowerDefault; + public static float MaxBreastIncrementFactor = MaxBreastIncrementFactorDefault; + public static float MaxNippleIncrementFactor = MaxNippleIncrementFactorDefault; + public static float PermanentNippleChange = PermanentNippleChangeDefault; + public static void SettoDefault() + { + ImplantationChanceAdjust = ImplantationChanceAdjustDefault; + FertilizeChanceAdjust = FertilizeChanceAdjustDefault; + CumDecayRatioAdjust = CumDecayRatioAdjustDefault; + CumFertilityDecayRatioAdjust = CumFertilityDecayRatioAdjustDefault; + EnableWombIcon = true; + EnableGatherCumGizmo = true; + EnableAnimalCycle = false; + CycleAcceleration = CycleAccelerationDefault; + EstrusOverridesHookupSettings = false; + EstrusFuckabilityToHookup = RJWHookupSettings.MinimumFuckabilityToHookup; + EstrusAttractivenessToHookup = RJWHookupSettings.MinimumAttractivenessToHookup; + EstrusRelationshipToHookup = RJWHookupSettings.MinimumRelationshipToHookup; + EnzygoticTwinsChanceAdjust = EnzygoticTwinsChanceAdjustDefault; + EnableEnzygoticTwins = true; + EnableHeteroOvularTwins = true; + UseMultiplePregnancy = true; + MaxEnzygoticTwins = MaxEnzygoticTwinsDefault; + BleedingAmount = BleedingAmountDefault; + MotherFirst = false; + MaxBreastIncrementFactor = MaxBreastIncrementFactorDefault; + MaxNippleIncrementFactor= MaxNippleIncrementFactorDefault; + PermanentNippleChange = PermanentNippleChangeDefault; + EggLifespanMultiplier = EggLifespanMultiplierDefault; + VaginaMorphPower = VaginaMorphPowerDefault; + } + + + public static List HybridOverride = new List(); + + + public static bool HARActivated = false; + public static bool AnimalGeneticsActivated = false; + + public enum DetailLevel + { + All, + OnReveal, + HideFetusInfo, + Hide + } + + public static string LevelString(DetailLevel level) + { + switch (level) + { + case DetailLevel.All: + return "All"; + case DetailLevel.OnReveal: + return "On reveal"; + case DetailLevel.HideFetusInfo: + return "Hide fetus info"; + case DetailLevel.Hide: + return "Hide"; + default: + return ""; + } + + + } + public static string HybridString(bool b) + { + if (b) return Translations.Option23_Label_1; + else return Translations.Option23_Label_2; + } + + public static bool IsOverrideExist(ThingDef def) + { + List removeList = new List(); + if (!HybridOverride.NullOrEmpty()) + foreach (HybridInformations o in HybridOverride) + { + if (o.IsNull) removeList.Add(o); + if (o.DefName == def.defName) return true; + } + foreach (HybridInformations o in removeList) + { + HybridOverride.Remove(o); + } + return false; + } + + [Flags] + public enum PawnFlags + { + None = 0, + Colonist = 1, + Prisoner = 2, + Ally = 4, + Neutral = 8, + Hostile = 16 + } + + public override void ExposeData() + { + Scribe_Values.Look(ref ImplantationChanceAdjust, "ImplantationChanceAdjust", ImplantationChanceAdjust, true); + Scribe_Values.Look(ref ImplantationChance, "ImplantationChance", ImplantationChance, true); + Scribe_Values.Look(ref FertilizeChanceAdjust, "FertilizeChanceAdjust", FertilizeChanceAdjust, true); + Scribe_Values.Look(ref FertilizeChance, "FertilizeChance", FertilizeChance, true); + Scribe_Values.Look(ref CumDecayRatioAdjust, "CumDecayRatioAdjust", CumDecayRatioAdjust, true); + Scribe_Values.Look(ref CumDecayRatio, "CumDecayRatio", CumDecayRatio, true); + Scribe_Values.Look(ref CumFertilityDecayRatioAdjust, "CumFertilityDecayRatioAdjust", CumFertilityDecayRatioAdjust, true); + Scribe_Values.Look(ref CumFertilityDecayRatio, "CumFertilityDecayRatio", CumFertilityDecayRatio, true); + Scribe_Values.Look(ref CycleAcceleration, "CycleAcceleration", CycleAcceleration, true); + Scribe_Values.Look(ref EnableWombIcon, "EnableWombIcon", EnableWombIcon, true); + Scribe_Values.Look(ref EnableAnimalCycle, "EnableAnimalCycle", EnableAnimalCycle, true); + Scribe_Values.Look(ref DrawWombStatus, "DrawWombStatus", DrawWombStatus, true); + Scribe_Values.Look(ref DrawVaginaStatus, "DrawVaginaStatus", DrawVaginaStatus, true); + Scribe_Values.Look(ref DrawEggOverlay, "DrawEggOvray", DrawEggOverlay, true); + Scribe_Values.Look(ref Debug, "Debug", Debug, true); + Scribe_Values.Look(ref infoDetail, "InfoDetail", infoDetail, true); + Scribe_Values.Look(ref EnableMenopause, "EnableMenopause", EnableMenopause, true); + Scribe_Values.Look(ref EstrusOverridesHookupSettings, "EstrusOverridesHookupSettings", EstrusOverridesHookupSettings, true); + Scribe_Values.Look(ref EstrusFuckabilityToHookup, "EstrusFuckabilityToHookup", EstrusFuckabilityToHookup, true); + Scribe_Values.Look(ref EstrusAttractivenessToHookup, "EstrusAttractivenessToHookup", EstrusAttractivenessToHookup, true); + Scribe_Values.Look(ref EstrusRelationshipToHookup, "EstrusRelationshipToHookup", EstrusRelationshipToHookup, true); + Scribe_Values.Look(ref UseMultiplePregnancy, "UseMultiplePregnancy", UseMultiplePregnancy, true); + Scribe_Values.Look(ref EnableHeteroOvularTwins, "EnableHeteroOvularTwins", EnableHeteroOvularTwins, true); + Scribe_Values.Look(ref EnableEnzygoticTwins, "EnableEnzygoticTwins", EnableEnzygoticTwins, true); + Scribe_Values.Look(ref EnzygoticTwinsChance, "EnzygoticTwinsChance", EnzygoticTwinsChance, true); + Scribe_Values.Look(ref EnzygoticTwinsChanceAdjust, "EnzygoticTwinsChanceAdjust", EnzygoticTwinsChanceAdjust, true); + Scribe_Values.Look(ref MaxEnzygoticTwins, "MaxEnzygoticTwins", MaxEnzygoticTwins, true); + Scribe_Values.Look(ref BleedingAmount, "BleedingAmount", BleedingAmount, true); + Scribe_Values.Look(ref EnableButtonInHT, "EnableButtonInHT", EnableButtonInHT, true); + Scribe_Values.Look(ref EnableGatherCumGizmo, "EnableGatherCumGizmo", true, true); + Scribe_Values.Look(ref ShowFlag, "ShowFlag", ShowFlag, true); + Scribe_Values.Look(ref UseHybridExtention, "UseHybridExtention", UseHybridExtention, true); + Scribe_Values.Look(ref MotherFirst, "MotherFirst", MotherFirst, true); + Scribe_Values.Look(ref MaxBreastIncrementFactor, "MaxBreastIncrementFactor", MaxBreastIncrementFactor, true); + Scribe_Values.Look(ref MaxNippleIncrementFactor, "MaxNippleIncrementFactor", MaxNippleIncrementFactor, true); + Scribe_Values.Look(ref PermanentNippleChange, "PermanentNippleChange", PermanentNippleChange, true); + Scribe_Values.Look(ref AllowShrinkIcon, "AllowShrinkIcon", AllowShrinkIcon, true); + Scribe_Values.Look(ref EggLifespanMultiplier, "EggLifespanMultiplier", EggLifespanMultiplier, true); + Scribe_Values.Look(ref EnableBirthVaginaMorph, "EnableBirthVaginaMorph", EnableBirthVaginaMorph, true); + Scribe_Values.Look(ref VaginaMorphPower, "VaginaMorphPower", VaginaMorphPower, true); + Scribe_Collections.Look(ref HybridOverride, saveDestroyedThings: true, label: "HybridOverride", lookMode: LookMode.Deep, ctorArgs: new object[0]); + base.ExposeData(); + } + + + + } + + + public class RJW_Menstruation : Mod + { + + private static Vector2 scroll; + + + + public static float EstimatedBleedingAmount + { + get + { + int days = VariousDefOf.HumanVaginaCompProperties.bleedingIntervalDays; + return days * 0.03f * Configurations.BleedingAmount * 6; + } + } + + public static float EstimatedBleedingAmountPerHour + { + get + { + return 0.03f * Configurations.BleedingAmount * Configurations.CycleAcceleration; + } + } + + + public RJW_Menstruation(ModContentPack content) : base(content) + { + GetSettings(); + Configurations.HARActivated = ModLister.GetActiveModWithIdentifier("erdelf.HumanoidAlienRaces") != null; + Configurations.AnimalGeneticsActivated = ModLister.GetActiveModWithIdentifier("Mlie.AnimalGenetics") != null; + } + + + + public override string SettingsCategory() + { + return Translations.Mod_Title; + } + + public override void DoSettingsWindowContents(Rect inRect) + { + Rect outRect = new Rect(0f, 30f, inRect.width, inRect.height - 30f); + float mainRectHeight = -3f + + (Configurations.EnableWombIcon || Configurations.EnableButtonInHT ? 400f : 0f) + + (Configurations.EstrusOverridesHookupSettings ? 144f : 0f) + + (Configurations.UseMultiplePregnancy ? (Configurations.EnableEnzygoticTwins ? 175f : 75f) : 0f) + + (Configurations.EnableBirthVaginaMorph ? 48f : 0f); + Rect mainRect = new Rect(0f, 0f, inRect.width - 30f, Math.Max(inRect.height + mainRectHeight, 1f)); + int Adjust; + Listing_Standard listmain = new Listing_Standard + { + maxOneColumn = true + }; + Widgets.BeginScrollView(outRect, ref scroll, mainRect); + listmain.Begin(mainRect); + listmain.Gap(20f); + Rect firstLine = listmain.GetRect(30f); + firstLine.SplitVertically(firstLine.width / 3, out Rect leftCell, out Rect middleAndRightCells); + Widgets.CheckboxLabeled(leftCell, Translations.Option1_Label_1, ref Configurations.EnableWombIcon, false, null, null, true); + Widgets.CheckboxLabeled(middleAndRightCells.LeftHalf(), Translations.Option1_Label_2, ref Configurations.EnableButtonInHT, false, null, null, true); + Widgets.CheckboxLabeled(middleAndRightCells.RightHalf(), Translations.Option_EnableGatherCumGizmo_Label, ref Configurations.EnableGatherCumGizmo, false, null, null, true); + if (Configurations.EnableWombIcon || Configurations.EnableButtonInHT) + { + Listing_Standard wombsection = listmain.BeginSection(350); + wombsection.CheckboxLabeled(Translations.Option9_Label, ref Configurations.DrawWombStatus, Translations.Option9_Desc); + if (Configurations.DrawWombStatus) + { + wombsection.CheckboxLabeled(Translations.Option18_Label, ref Configurations.DrawEggOverlay, Translations.Option18_Desc); + } + + wombsection.CheckboxLabeled(Translations.Option10_Label, ref Configurations.DrawVaginaStatus, Translations.Option10_Desc); + wombsection.CheckboxLabeled(Translations.Option29_Label, ref Configurations.AllowShrinkIcon, Translations.Option29_Desc); + if (wombsection.ButtonText(Translations.Option11_Label + ": " + Configurations.LevelString(Configurations.infoDetail))) + { + if (Configurations.infoDetail == Configurations.DetailLevel.Hide) Configurations.infoDetail = Configurations.DetailLevel.All; + else Configurations.infoDetail++; + } + switch (Configurations.infoDetail) + { + case Configurations.DetailLevel.All: + wombsection.Label(Translations.Option11_Desc_1); + break; + case Configurations.DetailLevel.OnReveal: + wombsection.Label(Translations.Option11_Desc_2); + break; + case Configurations.DetailLevel.HideFetusInfo: + wombsection.Label(Translations.Option11_Desc_3); + break; + case Configurations.DetailLevel.Hide: + wombsection.Label(Translations.Option11_Desc_4); + break; + } + wombsection.Label(Translations.Option21_Label + " " + Configurations.ShowFlag, -1, Translations.Option21_Desc); + Rect flagrect = wombsection.GetRect(30f); + Rect[] flagrects = new Rect[5]; + for (int i = 0; i < 5; i++) + { + flagrects[i] = new Rect(flagrect.x + (flagrect.width / 5) * i, flagrect.y, flagrect.width / 5, flagrect.height); + } + + if (Widgets.ButtonText(flagrects[0], Translations.Option20_Label_1 + ": " + Configurations.ShowFlag.HasFlag(Configurations.PawnFlags.Colonist))) + { + Configurations.ShowFlag ^= Configurations.PawnFlags.Colonist; + } + if (Widgets.ButtonText(flagrects[1], Translations.Option20_Label_2 + ": " + Configurations.ShowFlag.HasFlag(Configurations.PawnFlags.Prisoner))) + { + Configurations.ShowFlag ^= Configurations.PawnFlags.Prisoner; + } + if (Widgets.ButtonText(flagrects[2], Translations.Option20_Label_3 + ": " + Configurations.ShowFlag.HasFlag(Configurations.PawnFlags.Ally))) + { + Configurations.ShowFlag ^= Configurations.PawnFlags.Ally; + } + if (Widgets.ButtonText(flagrects[3], Translations.Option20_Label_4 + ": " + Configurations.ShowFlag.HasFlag(Configurations.PawnFlags.Neutral))) + { + Configurations.ShowFlag ^= Configurations.PawnFlags.Neutral; + } + if (Widgets.ButtonText(flagrects[4], Translations.Option20_Label_5 + ": " + Configurations.ShowFlag.HasFlag(Configurations.PawnFlags.Hostile))) + { + Configurations.ShowFlag ^= Configurations.PawnFlags.Hostile; + } + + Adjust = (int)(Configurations.MaxBreastIncrementFactor * 1000 / Configurations.MaxBreastIncrementFactorMax); + wombsection.Label(Translations.Option_MaxBreastIncrementFactor_Label + " " + Configurations.MaxBreastIncrementFactor * 100 + "%", -1, Translations.Option_MaxBreastIncrementFactor_Desc); + Adjust = (int)wombsection.Slider(Adjust, 0, 1000); + Configurations.MaxBreastIncrementFactor = (float)Adjust / (1000 / Configurations.MaxBreastIncrementFactorMax); + + Adjust = (int)(Configurations.MaxNippleIncrementFactor * 1000 / Configurations.MaxNippleIncrementFactorMax); + wombsection.Label(Translations.Option_MaxNippleIncrementFactor_Label + " " + Configurations.MaxNippleIncrementFactor * 100 + "%", -1, Translations.Option_MaxNippleIncrementFactor_Desc); + Adjust = (int)wombsection.Slider(Adjust, 0, 1000); + Configurations.MaxNippleIncrementFactor = (float)Adjust / (1000 / Configurations.MaxNippleIncrementFactorMax); + + Adjust = (int)(Configurations.PermanentNippleChange * 1000 / Configurations.PermanentNippleChangeMax); + wombsection.Label(Translations.Option_PermanentNippleChange_Label + " " + Configurations.PermanentNippleChange, -1, Translations.Option_PermanentNippleChange_Desc); + Adjust = (int)wombsection.Slider(Adjust, 0, 1000); + Configurations.PermanentNippleChange = (float)Adjust / (1000 / Configurations.PermanentNippleChangeMax); + + listmain.EndSection(wombsection); + } + + listmain.CheckboxLabeled(Translations.Option2_Label, ref Configurations.EnableAnimalCycle, Translations.Option2_Desc); + + listmain.CheckboxLabeled(Translations.Option12_Label, ref Configurations.EnableMenopause, Translations.Option12_Desc); + + listmain.Label(Translations.Option3_Label + " " + Configurations.ImplantationChance * 100 + "%", -1, Translations.Option3_Desc); + Configurations.ImplantationChanceAdjust = (int)listmain.Slider(Configurations.ImplantationChanceAdjust, 0, 1000); + Configurations.ImplantationChance = (float)Configurations.ImplantationChanceAdjust / 100; + + string tenMl = String.Format("10 ml: {0:0}%", (1.0f - Mathf.Pow(1.0f - Configurations.FertilizeChance, 10)) * 100f); + listmain.LabelDouble(Translations.Option4_Label + " " + Configurations.FertilizeChance * 100 + "%", tenMl, Translations.Option4_Desc); + Configurations.FertilizeChanceAdjust = (int)listmain.Slider(Configurations.FertilizeChanceAdjust, 0, 1000); + Configurations.FertilizeChance = (float)Configurations.FertilizeChanceAdjust / 1000; + + listmain.Label(Translations.Option5_Label + " " + Configurations.CumDecayRatio * 100 + "%", -1, Translations.Option5_Desc); + Configurations.CumDecayRatioAdjust = (int)listmain.Slider(Configurations.CumDecayRatioAdjust, 0, 1000); + Configurations.CumDecayRatio = (float)Configurations.CumDecayRatioAdjust / 1000; + + + Adjust = (int)(Configurations.EggLifespanMultiplier * 20); + float lifespan = (24f / Configurations.CycleAcceleration * Configurations.EggLifespanMultiplier); + listmain.LabelDouble(Translations.Option30_Label + " x" + Configurations.EggLifespanMultiplier, Translations.EstimatedEggLifespan + String.Format(": {0:0}h", (int)lifespan), Translations.Option30_Desc); + Adjust = (int)listmain.Slider(Adjust, 20, 1000); + Configurations.EggLifespanMultiplier = (float)Adjust / 20; + + + int semenlifespan = (int)(-5 / ((float)Math.Log10((1 - Configurations.CumFertilityDecayRatio) * (1 - Configurations.CumDecayRatio) * 10) - 1)) + 1; + string estimatedlifespan; + if (semenlifespan < 0) + { + estimatedlifespan = String.Format(": Infinite", semenlifespan); + } + else + { + estimatedlifespan = String.Format(": {0:0}h", semenlifespan); + } + listmain.LabelDouble(Translations.Option6_Label + " " + Configurations.CumFertilityDecayRatio * 100 + "%", Translations.EstimatedCumLifespan + estimatedlifespan, Translations.Option6_Desc); + Configurations.CumFertilityDecayRatioAdjust = (int)listmain.Slider(Configurations.CumFertilityDecayRatioAdjust, 0, 1000); + Configurations.CumFertilityDecayRatio = (float)Configurations.CumFertilityDecayRatioAdjust / 1000; + + listmain.Label(Translations.Option7_Label + " x" + Configurations.CycleAcceleration, -1, Translations.Option7_Desc); + Configurations.CycleAcceleration = (int)listmain.Slider(Configurations.CycleAcceleration, 1, 50); + + + float var2 = EstimatedBleedingAmountPerHour; + float var1 = Math.Max(EstimatedBleedingAmount, var2); + listmain.LabelDouble(Translations.Option19_Label_1, Translations.Option19_Label_2 + ": " + var1 + "ml, " + var2 + "ml/h", Translations.Option19_Desc); + Configurations.BleedingAmount = (int)listmain.Slider(Configurations.BleedingAmount, 0, 200); + + listmain.CheckboxLabeled(Translations.Option_EstrusOverride_Label, ref Configurations.EstrusOverridesHookupSettings, Translations.Option_EstrusOverride_Desc); + if (Configurations.EstrusOverridesHookupSettings) + { + listmain.Label(Translations.Option_EstrusFuckability_Label + ": " + (int)(Configurations.EstrusFuckabilityToHookup * 100) + "%"); + Configurations.EstrusFuckabilityToHookup = listmain.Slider(Configurations.EstrusFuckabilityToHookup, 0.1f, 1.0f); + listmain.Label(Translations.Option_EstrusAttractability_Label + ": " + (int)(Configurations.EstrusAttractivenessToHookup * 100) + "%"); + Configurations.EstrusAttractivenessToHookup = listmain.Slider(Configurations.EstrusAttractivenessToHookup, 0.0f, 1.0f); + listmain.Label(Translations.Option_EstrusRelationship_Label + ": " + Configurations.EstrusRelationshipToHookup); + Configurations.EstrusRelationshipToHookup = listmain.Slider((int)Configurations.EstrusRelationshipToHookup, -100f, 100f); + } + + listmain.CheckboxLabeled(Translations.Option13_Label, ref Configurations.UseMultiplePregnancy, Translations.Option13_Desc); + if (Configurations.UseMultiplePregnancy) + { + float sectionheight = 75f; + if (Configurations.EnableEnzygoticTwins) sectionheight += 100; + Listing_Standard twinsection = listmain.BeginSection(sectionheight); + Rect hybridrect = twinsection.GetRect(25); + Widgets.CheckboxLabeled(hybridrect.LeftHalf(), Translations.Option22_Label, ref Configurations.UseHybridExtention, false, null, null, true); + if (Widgets.ButtonText(hybridrect.RightHalf(), Translations.Option28_Label)) + { + Dialog_HybridCustom.ToggleWindow(); + //Configurations.MotherFirst = !Configurations.MotherFirst; + } + TooltipHandler.TipRegion(hybridrect, Translations.Option28_Tooltip); + + twinsection.CheckboxLabeled(Translations.Option14_Label, ref Configurations.EnableHeteroOvularTwins, Translations.Option14_Desc); + twinsection.CheckboxLabeled(Translations.Option15_Label, ref Configurations.EnableEnzygoticTwins, Translations.Option15_Desc); + if (Configurations.EnableEnzygoticTwins) + { + twinsection.Label(Translations.Option16_Label + " " + Configurations.EnzygoticTwinsChance * 100 + "%", -1, Translations.Option16_Desc); + Configurations.EnzygoticTwinsChanceAdjust = (int)twinsection.Slider(Configurations.EnzygoticTwinsChanceAdjust, 0, 1000); + Configurations.EnzygoticTwinsChance = (float)Configurations.EnzygoticTwinsChanceAdjust / 1000; + + twinsection.Label(Translations.Option17_Label + " " + Configurations.MaxEnzygoticTwins, -1, Translations.Option17_Desc); + Configurations.MaxEnzygoticTwins = (int)twinsection.Slider(Configurations.MaxEnzygoticTwins, 2, 100); + } + listmain.EndSection(twinsection); + } + + listmain.CheckboxLabeled(Translations.Option31_Label, ref Configurations.EnableBirthVaginaMorph, Translations.Option31_Desc); + if (Configurations.EnableBirthVaginaMorph) + { + float sectionheight = 48f; + Listing_Standard vmsection = listmain.BeginSection(sectionheight); + + LabelwithTextfield(vmsection.GetRect(24f), Translations.Option32_Label, Translations.Option32_Desc, ref Configurations.VaginaMorphPower, 0, 100f); + Adjust = (int)(Configurations.VaginaMorphPower * 1000); + Adjust = (int)vmsection.Slider(Adjust, 0, 1000); + Configurations.VaginaMorphPower = Adjust / 1000f; + + + listmain.EndSection(vmsection); + } + + + Widgets.EndScrollView(); + + listmain.CheckboxLabeled(Translations.Option8_Label, ref Configurations.Debug, Translations.Option8_Desc); + if (listmain.ButtonText(Translations.Button_ResetToDefault)) + { + Configurations.SettoDefault(); + + } + + listmain.End(); + + + } + + + public void LabelwithTextfield(Rect rect, string label, string tooltip, ref float value, float min, float max) + { + Rect textfieldRect = new Rect(rect.xMax - 100f, rect.y, 100f, rect.height); + string valuestr = value.ToString(); + Widgets.Label(rect, label); + Widgets.TextFieldNumeric(textfieldRect, ref value, ref valuestr, min, max); + Widgets.DrawHighlightIfMouseover(rect); + TooltipHandler.TipRegion(rect, tooltip); + } + + + } + + + + +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Cum.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Cum.cs new file mode 100644 index 0000000..c1f9931 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Cum.cs @@ -0,0 +1,278 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text; +using UnityEngine; +using Verse; + +namespace RJW_Menstruation +{ + public class Cum : IExposable + { + public Pawn pawn; + + protected float volume; // ml + public float fertility = 1.0f; + public bool notcum = false; // for other fluids + public string notcumLabel = ""; + protected bool useCustomColor = false; + protected float notcumthickness = 0; + protected float cumthickness = 1.0f; + protected Thing internalThing; + + public float Volume + { + get + { + return volume; + } + } + + public float FertVolume + { + get + { + return volume * fertility; + } + } + + public float CumThickness + { + get + { + return cumthickness; + } + } + + public float DecayResist + { + get + { + if (!notcum) return DNA.cumThickness; + else return notcumthickness; + } + set + { + notcumthickness = value; + } + } + protected Color customColor; + + public PawnDNAModExtension DNA + { + get + { + if (DNAcache != null) return DNAcache; + try + { + DNAcache = pawn.def.GetModExtension(); + } + catch (NullReferenceException) + { + DNAcache = ThingDefOf.Human.GetModExtension(); + } + if (DNAcache == null) + { + DNAcache = ThingDefOf.Human.GetModExtension(); + } + return DNAcache; + } + } + protected PawnDNAModExtension DNAcache = null; + public ThingDef FilthDef + { + get + { + if (filthDef == null) return VariousDefOf.CumFilth; + else return filthDef; + } + set + { + filthDef = value; + } + } + protected ThingDef filthDef = null; + public Color Color + { + get + { + if (!useCustomColor) return DNA.CumColor; + else return customColor; + } + + set + { + useCustomColor = true; + customColor = value; + } + } + + public Thing CumThing + { + get + { + if (internalThing == null) + { + internalThing = ThingMaker.MakeThing(VariousDefOf.CumFilth); + internalThing.stackCount = (int)volume; + } + internalThing.stackCount = (int)volume; + return internalThing; + } + } + + public Cum() { } + + public Cum(Pawn pawn) + { + this.pawn = pawn; + volume = 1.0f; + fertility = 1.0f; + } + + /// + /// Not Cum + /// + /// + /// + /// + /// + /// + public Cum(Pawn pawn, float volume, string notcumlabel, float decayresist = 0, ThingDef filthDef = null) + { + this.pawn = pawn; + this.volume = volume; + this.fertility = 0f; + this.notcum = true; + this.notcumLabel = notcumlabel; + this.notcumthickness = decayresist; + this.filthDef = filthDef; + } + + public Cum(Pawn pawn, float volume, float fertility, ThingDef filthDef = null) + { + this.pawn = pawn; + this.volume = volume; + this.fertility = fertility; + this.filthDef = filthDef; + } + + + + public virtual void ExposeData() + { + Scribe_References.Look(ref pawn, "pawn", true); + Scribe_Values.Look(ref volume, "volume", volume, true); + Scribe_Values.Look(ref fertility, "fertility", fertility, true); + Scribe_Values.Look(ref notcumthickness, "notcumthickness", notcumthickness, true); + Scribe_Values.Look(ref notcum, "notcum", notcum, true); + Scribe_Values.Look(ref notcumLabel, "notcumLabel", notcumLabel, true); + Scribe_Values.Look(ref useCustomColor, "useCustomColor", useCustomColor, true); + Scribe_Values.Look(ref customColor, "customColor", customColor, true); + Scribe_Defs.Look(ref filthDef, "filthDef"); + + } + + public void MakeThinner(int speed) + { + cumthickness = cumthickness.LerpMultiple(DecayResist, 0.3f, speed); + } + + public void MergeWithCum(float volumein, float fertility, ThingDef updatefilthDef = null) + { + if (updatefilthDef != null) filthDef = updatefilthDef; + volume += volumein; + this.fertility = (this.volume * this.fertility + volumein * fertility) / (this.volume + volumein); + cumthickness = Mathf.Lerp(cumthickness, 1.0f, volumein / volume); + } + + public void MergeWithFluid(float volumein, float thickness, ThingDef updatefilthDef = null) + { + if (updatefilthDef != null) filthDef = updatefilthDef; + volume += volumein; + fertility = volume * fertility / (volume + volumein); + notcumthickness = Mathf.Lerp(notcumthickness, thickness, volumein / volume); + } + + public bool ShouldRemove() + { + if ((notcum || FertVolume < 0.001f) && volume < 0.01f) return true; + return false; + } + + public float DismishNatural(float leakfactor, HediffComp_Menstruation comp, float antisperm = 0.0f) + { + // comp is used for Hydrogen's RJW Muscle Injury + float totalleak = volume; + volume *= Math.Max(0, (1 - (Configurations.CumDecayRatio * (1 - DecayResist)) * leakfactor)); + fertility *= Math.Max(0, 1 - (Configurations.CumFertilityDecayRatio * (1 - DecayResist) + antisperm)); + CutMinor(); + totalleak -= volume; + return totalleak; + } + + public float DismishForce(float portion, float leakfactor = 1.0f) + { + float totalleak = volume; + volume *= Math.Max(0, 1 - (portion * (1 - DecayResist / 10)) * leakfactor); + CutMinor(); + totalleak -= volume; + return totalleak; + } + + public void CumEffects(Pawn pawn) + { + if (notcum || DNA?.ingestionOutcomeDoers == null || volume < 1.0f) return; + + foreach (IngestionOutcomeDoer doer in DNA.ingestionOutcomeDoers) + doer.DoIngestionOutcome(pawn, CumThing); + } + + protected void CutMinor() + { + if (volume < 0.01f) volume = 0f; + } + } + + public class CumMixture : Cum + { + protected List cums; + public bool ispurecum = true; + public List Getingredients => cums; + + public CumMixture() + { + notcum = true; + cums = new List(); + } + + public CumMixture(Pawn pawn, float volume, List cums, Color color, ThingDef mixtureDef, bool pure) + { + this.pawn = pawn; + this.volume = volume; + this.cums = cums; + this.customColor = color; + this.useCustomColor = true; + ispurecum = pure; + } + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Collections.Look(ref cums, "cumslabel", LookMode.Value, new object[0]); + } + + public string GetIngredients() + { + StringBuilder res = new StringBuilder(); + + if (!cums.NullOrEmpty()) for (int i = 0; i < cums.Count; i++) + { + res.Append(cums[i]); + if (i < cums.Count - 1) res.Append(", "); + } + return res.ToString(); + } + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/DebugActions.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/DebugActions.cs new file mode 100644 index 0000000..3a8fdb5 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/DebugActions.cs @@ -0,0 +1,77 @@ +using RimWorld; +using Verse; + +#pragma warning disable IDE0051 // Remove unused private members +namespace RJW_Menstruation +{ + public static class DebugToolsMenstruation + { + [DebugAction("RJW Menstruation", "Set pawn's state to follicular", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)] + private static void SetFollicular(Pawn p) + { + foreach (HediffComp_Menstruation comp in p.GetMenstruationComps()) + comp.curStage = HediffComp_Menstruation.Stage.Follicular; + Messages.Message($"{p} is now follicular", p, MessageTypeDefOf.NeutralEvent, false); + } + + [DebugAction("RJW Menstruation", "Set pawn's state to ovulatory", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)] + private static void SetOvulatory(Pawn p) + { + foreach (HediffComp_Menstruation comp in p.GetMenstruationComps()) + comp.curStage = HediffComp_Menstruation.Stage.Ovulatory; + Messages.Message($"{p} is now ovulatory", p, MessageTypeDefOf.NeutralEvent, false); + } + + [DebugAction("RJW Menstruation", "Set pawn's state to luteal", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)] + private static void SetLuteal(Pawn p) + { + foreach (HediffComp_Menstruation comp in p.GetMenstruationComps()) + comp.curStage = HediffComp_Menstruation.Stage.Luteal; + Messages.Message($"{p} is now luteal", p, MessageTypeDefOf.NeutralEvent, false); + } + + [DebugAction("RJW Menstruation", "Set pawn's state to bleeding", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)] + private static void SetBleeding(Pawn p) + { + foreach (HediffComp_Menstruation comp in p.GetMenstruationComps()) + comp.curStage = HediffComp_Menstruation.Stage.Bleeding; + Messages.Message($"{p} is now bleeding", p, MessageTypeDefOf.NeutralEvent, false); + } + /* + [DebugAction("RJW Menstruation", "Set pawn's state to recovering", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)] + private static void setRecover(Pawn p) + { + p.GetMenstruationComp().curStage = HediffComp_Menstruation.Stage.Recover; + } + + [DebugAction("RJW Menstruation", "Set pawn's state to young", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)] + private static void setYoung(Pawn p) + { + p.GetMenstruationComp().curStage = HediffComp_Menstruation.Stage.Young; + } + */ + [DebugAction("RJW Menstruation", "Remove all cum from pawn's womb", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)] + private static void RemoveCums(Pawn p) + { + foreach (HediffComp_Menstruation comp in p.GetMenstruationComps()) + comp.RemoveAllCums(); + Messages.Message($"All cum removed from {p}'s womb", p, MessageTypeDefOf.NeutralEvent, false); + } + [DebugAction("RJW Menstruation", "Add egg to pawn's next ovulation", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)] + private static void AddEgg(Pawn p) + { + foreach (HediffComp_Menstruation comp in p.GetMenstruationComps()) + comp.eggstack++; + Messages.Message($"1 egg added to {p}'s next ovulation ({p.GetFirstMenstruationComp().eggstack})", p, MessageTypeDefOf.NeutralEvent, false); + } + + [DebugAction("RJW Menstruation", "Recalculate pawn's ovary power", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)] + private static void RecalculateOvaryPower(Pawn p) + { + foreach (HediffComp_Menstruation comp in p.GetMenstruationComps()) + comp.ovarypower = comp.GetOvaryPowerByAge(); + Messages.Message($"{p}'s ovarypower recalculated ({p.GetFirstMenstruationComp().ovarypower})", p, MessageTypeDefOf.NeutralEvent, false); + } + } +} +#pragma warning restore IDE0051 // Remove unused private members \ No newline at end of file diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/DrugOutcomeDoers.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/DrugOutcomeDoers.cs new file mode 100644 index 0000000..6e8c375 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/DrugOutcomeDoers.cs @@ -0,0 +1,96 @@ +using RimWorld; +using rjw; +using System.Collections.Generic; +using Verse; + +namespace RJW_Menstruation +{ + public class FertPillOutcomeDoer : IngestionOutcomeDoer + { + protected override void DoIngestionOutcomeSpecial(Pawn pawn, Thing ingested) + { + foreach (HediffComp_Menstruation comp in pawn.GetMenstruationComps()) + if (comp.curStage.Equals(HediffComp_Menstruation.Stage.Follicular) + || comp.curStage.Equals(HediffComp_Menstruation.Stage.Luteal) + || comp.curStage.Equals(HediffComp_Menstruation.Stage.Anestrus) + ) + { + comp.SetEstrus(); + comp.curStage = HediffComp_Menstruation.Stage.Ovulatory; + comp.ovarypower--; + } + } + } + + public class InduceOvulationOutcomeDoer : IngestionOutcomeDoer + { + protected override void DoIngestionOutcomeSpecial(Pawn pawn, Thing ingested) + { + foreach (HediffComp_Menstruation comp in pawn.GetMenstruationComps()) + if (comp.curStage.Equals(HediffComp_Menstruation.Stage.Follicular) + || comp.curStage.Equals(HediffComp_Menstruation.Stage.Anestrus) + ) + { + comp.SetEstrus(); + comp.curStage = HediffComp_Menstruation.Stage.Ovulatory; + comp.eggstack += ingested.stackCount - 1; + } + } + } + + public class IngestionOutcomeDoer_AdjustSeverity : IngestionOutcomeDoer + { + public HediffDef hediffDef; + public float severity; + + protected override void DoIngestionOutcomeSpecial(Pawn pawn, Thing ingested) + { + Hediff hediff = pawn.health.hediffSet.GetFirstHediffOfDef(hediffDef); + if (hediff != null) hediff.Severity += severity; + } + + } + + public class OvaryPillOutcomeDoer : IngestionOutcomeDoer + { + public float effectOffset; + + + protected override void DoIngestionOutcomeSpecial(Pawn pawn, Thing ingested) + { + foreach (HediffComp_Menstruation comp in pawn.GetMenstruationComps()) + if (Configurations.EnableMenopause) comp.RecoverOvary(1 + effectOffset); + } + } + + public class SuperOvulationOutcomeDoer : IngestionOutcomeDoer + { + protected override void DoIngestionOutcomeSpecial(Pawn pawn, Thing ingested) + { + foreach (HediffComp_Menstruation comp in pawn.GetMenstruationComps()) + comp.eggstack += Rand.Range(1, 4); + } + } + + public class ContraceptiveOutcomeDoer : IngestionOutcomeDoer + { + protected override void DoIngestionOutcomeSpecial(Pawn pawn, Thing ingested) + { + + List memories = pawn.needs?.mood?.thoughts?.memories?.Memories.FindAll( + x => + x.def == VariousDefOf.CameInsideF + || x.def == VariousDefOf.CameInsideFFetish + || x.def == VariousDefOf.HaterCameInsideF); + if (memories.NullOrEmpty()) return; + foreach (Thought_Memory m in memories) + { + if (m.def == VariousDefOf.HaterCameInsideF) m.moodPowerFactor = 0.5f; + else m.moodPowerFactor = 0.3f; + + } + if (pawn.Has(Quirk.Breeder)) pawn.needs.mood.thoughts.memories.TryGainMemoryFast(VariousDefOf.HateTookContraceptivePill); + else pawn.needs.mood.thoughts.memories.TryGainMemoryFast(VariousDefOf.TookContraceptivePill); + } + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/EstrusPartKindUsageRule.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/EstrusPartKindUsageRule.cs new file mode 100644 index 0000000..3062feb --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/EstrusPartKindUsageRule.cs @@ -0,0 +1,40 @@ +using rjw; +using rjw.Modules.Interactions.Contexts; +using rjw.Modules.Interactions.Enums; +using rjw.Modules.Interactions.Rules.PartKindUsageRules; +using rjw.Modules.Shared; +using System.Collections.Generic; +using Verse; + +namespace RJW_Menstruation.Interactions +{ + public class EstrusPartKindUsageRule : IPartPreferenceRule + { + private const float visible_estrus_multiplier = Multipliers.Doubled; + private const float concealed_estrus_multiplier = 1.1f; + + private bool WillingAndAble(Pawn fucker, Pawn fucked, bool visible) + { + return + fucked.IsInEstrus(visible) + && + PregnancyHelper.CanImpregnate(fucker, fucked); + } + + public IEnumerable> ModifiersForDominant(InteractionContext context) + { + if (WillingAndAble(context.Internals.Submissive.Pawn, context.Internals.Dominant.Pawn, true)) + yield return new Weighted(visible_estrus_multiplier, LewdablePartKind.Vagina); + else if (WillingAndAble(context.Internals.Submissive.Pawn, context.Internals.Dominant.Pawn, false)) + yield return new Weighted(concealed_estrus_multiplier, LewdablePartKind.Vagina); + } + + public IEnumerable> ModifiersForSubmissive(InteractionContext context) + { + if (WillingAndAble(context.Internals.Dominant.Pawn, context.Internals.Submissive.Pawn, true)) + yield return new Weighted(visible_estrus_multiplier, LewdablePartKind.Vagina); + else if (WillingAndAble(context.Internals.Dominant.Pawn, context.Internals.Submissive.Pawn, false)) + yield return new Weighted(concealed_estrus_multiplier, LewdablePartKind.Vagina); + } + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/FilthMaker_Colored.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/FilthMaker_Colored.cs new file mode 100644 index 0000000..a14e186 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/FilthMaker_Colored.cs @@ -0,0 +1,59 @@ +using RimWorld; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using Verse; + +namespace RJW_Menstruation +{ + public class FilthMaker_Colored + { + + public static bool TryMakeFilth(IntVec3 c, Map map, ThingDef filthDef, IEnumerable sources, Color color, bool shouldPropagate, FilthSourceFlags additionalFlags = FilthSourceFlags.None) + { + Filth_Colored filth = (Filth_Colored)(from t in c.GetThingList(map) + where t.def == filthDef + select t).FirstOrDefault(); + if (!c.Walkable(map) || (filth != null && !filth.CanBeThickened)) + { + if (shouldPropagate) + { + List list = GenAdj.AdjacentCells8WayRandomized(); + for (int i = 0; i < 8; i++) + { + IntVec3 c2 = c + list[i]; + if (c2.InBounds(map) && TryMakeFilth(c2, map, filthDef, sources, color, false, FilthSourceFlags.None)) + { + return true; + } + } + } + if (filth != null) + { + filth.AddSources(sources); + } + return false; + } + if (filth != null) + { + filth.ThickenFilth(); + filth.AddSources(sources); + } + else + { + if (!FilthMaker.CanMakeFilth(c, map, filthDef, additionalFlags)) + { + return false; + } + Filth_Colored filth2 = (Filth_Colored)ThingMaker.MakeThing(filthDef, null); + filth2.DrawColor = color; + filth2.AddSources(sources); + GenSpawn.Spawn(filth2, c, map, WipeMode.Vanish); + } + //FilthMonitor.Notify_FilthSpawned(); + return true; + } + + + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Breast.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Breast.cs new file mode 100644 index 0000000..6edeabe --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Breast.cs @@ -0,0 +1,388 @@ +using RimWorld; +using RimWorld.Planet; +using rjw; +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using Verse; + +namespace RJW_Menstruation +{ + public class CompProperties_Breast : HediffCompProperties + { + public static readonly ColorInt DefaultBlacknippleColor = new ColorInt(55, 20, 0); + public string BreastTex = "Breasts/Breast"; + public ColorInt BlacknippleColor = new ColorInt(55, 20, 0); + + + public Color BlackNippleColor + { + get + { + return BlacknippleColor.ToColor; + } + } + + + public CompProperties_Breast() + { + compClass = typeof(HediffComp_Breast); + } + } + + public class HediffComp_Breast : HediffComp + { + public const int tickInterval = GenDate.TicksPerHour * 3 / 2; + public const float breastGrowthStart = 1f / 6f; + public const float breastGrowthEnd = 1f / 3f; + public static readonly SimpleCurve nippleTransitions = new SimpleCurve() + { + new CurvePoint(0f,0f), + new CurvePoint(0.1f,0f), + new CurvePoint(0.333f,0.167f), + new CurvePoint(0.667f,0.833f), + new CurvePoint(1.0f,1.0f) + }; + public const float nippleChange = 0.2f; + + public CompProperties_Breast Props; + + protected long ageOfLastBirth = 0; + protected float maxBreastIncrement = -1f; + protected float breastSizeIncreased = 0f; + protected string debugGrowthStatus = "(Growth/shrink not yet calculated; run for 1.5h to update)"; + protected float nippleProgress = 0f; + protected float baseAlpha = -1f; // Will grow in response to pregnancy + protected float baseAreola = -1f; + protected float baseNipple = -1f; + protected float cachedAlpha = -1f; // Calculated dynamically instead of saved + protected float cachedAreola = -1f; // Actual size = these * breast size + protected float cachedNipple = -1f; + protected float babyHalfAge = -1f; + + protected Color cachedColor; + protected bool loaded = false; + + protected float BabyHalfAge + { + get + { + if (babyHalfAge > 0f) return babyHalfAge; + List ages = Pawn.def.race.lifeStageAges; + if (ages?.Count > 1) + babyHalfAge = ages[1].minAge / 2; + + if (babyHalfAge <= 0) babyHalfAge = 1.2f / 2; // Default to human + + if (RJWPregnancySettings.phantasy_pregnancy) + babyHalfAge /= GenDate.DaysPerYear; + + return babyHalfAge; + } + } + + protected void ShrinkBreasts() + { + // The natural rate will take them from full to empty during the second half of their child's babyhood + float shrinkRate = tickInterval * MaxBreastIncrement / (BabyHalfAge * GenDate.TicksPerYear); + float shrinkAmount = Mathf.Min(shrinkRate, breastSizeIncreased); + breastSizeIncreased -= shrinkAmount; + parent.Severity -= shrinkAmount; + } + + protected float MaxBreastIncrement + { + get + { + return maxBreastIncrement * Configurations.MaxBreastIncrementFactor; + } + } + + public Color NippleColor + { + get + { + return cachedColor; + } + } + public float Alpha + { + get + { + return cachedAlpha; + } + } + public float NippleSize + { + get + { + return cachedNipple * parent.Severity; + } + } + public float AreolaSize + { + get + { + return cachedAreola * parent.Severity; + } + } + + public float BreastSizeIncreased + { + get + { + return breastSizeIncreased; + } + } + + public override void CompExposeData() + { + base.CompExposeData(); + + Scribe_Values.Look(ref ageOfLastBirth, "ageOfLastBirth", ageOfLastBirth, true); + Scribe_Values.Look(ref maxBreastIncrement, "maxBreastIncrement", maxBreastIncrement, true); + Scribe_Values.Look(ref breastSizeIncreased, "breastSizeIncreased", breastSizeIncreased, true); + Scribe_Values.Look(ref nippleProgress, "nippleProgress", nippleProgress, true); + Scribe_Values.Look(ref baseAlpha, "baseAlpha", baseAlpha, true); + Scribe_Values.Look(ref baseAreola, "baseAreola", baseAreola, true); + Scribe_Values.Look(ref baseNipple, "baseNipple", baseNipple, true); + } + + public bool ShouldSimulate() + { + if (!Configurations.EnableAnimalCycle && Pawn.IsAnimal()) return false; + if (Pawn.Spawned || Pawn.IsCaravanMember() || PawnUtility.IsTravelingInTransportPodWorldObject(Pawn)) return true; + + return false; + } + + public override void CompPostTick(ref float severityAdjustment) + { + base.CompPostTick(ref severityAdjustment); + // If an exception makes it out, RW will remove the hediff, so catch it here + try + { + if ( + !Pawn.IsHashIntervalTick(tickInterval) || + !ShouldSimulate() + ) + { + return; + } + CalculateBreastSize(); + CalculateNipples(); + UpdateNipples(); + } + catch (Exception ex) + { + Log.Error($"Error processing breasts of {Pawn}: {ex}"); + } + + } + + public override void CompPostPostAdd(DamageInfo? dinfo) + { + if (!loaded) Initialize(); + if (ageOfLastBirth > Pawn.ageTracker.AgeChronologicalTicks) ageOfLastBirth = CalculateLastBirth(); // catch transplant issues + } + + public override void CompPostPostRemoved() + { + if (Pawn.health.hediffSet.hediffs.Contains(parent)) + { + Log.Warning($"Attempted to remove breast comp from wrong pawn ({Pawn})."); + return; + } + base.CompPostPostRemoved(); + } + + protected long CalculateLastBirth() + { + long youngestAge = (long)(BabyHalfAge * GenDate.TicksPerYear) * -2; // So a newborn isn't considered a new mother, either + + if ((Pawn.relations == null)) return youngestAge; + + List pregnancies = new List(); + Pawn.health.hediffSet.GetHediffs(ref pregnancies); + + bool hasChild = Pawn.relations.Children. + Where(child => !pregnancies.Any(preg => preg.babies.Contains(child))). // no fetuses + Where(child => child.GetMother() == Pawn). // not Dad + TryMinBy(child => child.ageTracker.AgeBiologicalTicks, out Pawn youngest); + + if (hasChild) youngestAge = Pawn.ageTracker.AgeBiologicalTicks - youngest.ageTracker.AgeBiologicalTicks; + + return youngestAge; + } + + public void Initialize() + { + Props = (CompProperties_Breast)props; + + if (maxBreastIncrement <= 0f) + { + maxBreastIncrement = Utility.RandGaussianLike(0.088f, 0.202f); + } + if (ageOfLastBirth == 0) + { + ageOfLastBirth = CalculateLastBirth(); + } + if (baseAlpha <= 0f) + { + baseAlpha = Utility.RandGaussianLike(0.0f, 0.3f) + Rand.Range(0.0f, 0.5f); + } + if (baseAreola <= 0f) + { + baseAreola = Utility.RandGaussianLike(0.0f, 1.0f); + } + if (baseNipple <= 0f) + { + baseNipple = Utility.RandGaussianLike(0.0f, 1.0f); + } + UpdateNipples(); + loaded = true; + } + + protected void CalculateBreastSize() + { + // Scenario A: the youngest child is less than halfway into babyhood: Full size + if (ageOfLastBirth + BabyHalfAge * GenDate.TicksPerYear > Pawn.ageTracker.AgeBiologicalTicks) + { + debugGrowthStatus = "Full size due to young child"; + if (breastSizeIncreased < MaxBreastIncrement) + { + parent.Severity += (MaxBreastIncrement - breastSizeIncreased); + breastSizeIncreased = MaxBreastIncrement; + } + } + // Scenario B: Pregnant, grow in the second half of first trimester + else if (Pawn.IsRJWPregnant()) + { + float pregnancySize = Mathf.InverseLerp(breastGrowthStart, breastGrowthEnd, Pawn.GetFarthestPregnancyProgress()) * MaxBreastIncrement; + if (breastSizeIncreased > pregnancySize) + { + debugGrowthStatus = "Shrinking due to being oversize for pregnancy"; + // Breasts still large from the last kid + ShrinkBreasts(); + } + else if (breastSizeIncreased < MaxBreastIncrement) + { + // Time to grow + float growAmount = pregnancySize - breastSizeIncreased; + if (growAmount != 0) + debugGrowthStatus = "Growing due to pregnancy"; + else + debugGrowthStatus = "Pregnant, but not time to grow"; + breastSizeIncreased += growAmount; + parent.Severity += growAmount; + } + else debugGrowthStatus = "Pregnant and full size"; + } + // Scenario C: Not (or very early) pregnant and youngest child nonexistent or more than halfway into babyhood, time to shrink + else if (breastSizeIncreased > 0) + { + debugGrowthStatus = "Shrinking due to no pregnancy nor young child"; + ShrinkBreasts(); + } + else debugGrowthStatus = "Base size"; + } + + protected void CalculateNipples() + { + float newNippleProgress; + if (ageOfLastBirth + BabyHalfAge * GenDate.TicksPerYear > Pawn.ageTracker.AgeBiologicalTicks) + newNippleProgress = 1f; + else if (Pawn.IsRJWPregnant()) + newNippleProgress = nippleTransitions.Evaluate(Pawn.GetFarthestPregnancyProgress()); + else + newNippleProgress = 0f; + + if (newNippleProgress < 0) newNippleProgress = 0; + + if (newNippleProgress == nippleProgress) return; // Nothing to change + else if (newNippleProgress > nippleProgress) + { + float progressDifference = newNippleProgress - nippleProgress; + // All nipple growth has a slight effect on the base + // Not mathematically precise in hitting the goal at the end of the term, but close enough + baseAlpha *= 1.0f + progressDifference * Configurations.PermanentNippleChange; + if (baseAlpha > 1.0f) baseAlpha = 1.0f; + baseAreola *= 1.0f + progressDifference * Configurations.PermanentNippleChange; + if (baseAreola > 1.0f) baseAreola = 1.0f; + baseNipple *= 1.0f + progressDifference * Configurations.PermanentNippleChange; + if (baseNipple > 1.0f) baseNipple = 1.0f; + nippleProgress = newNippleProgress; + } + else + { + nippleProgress -= tickInterval / (BabyHalfAge * GenDate.TicksPerYear); + if (nippleProgress < newNippleProgress) nippleProgress = newNippleProgress; + } + } + + public void GaveBirth() + { + ageOfLastBirth = Pawn.ageTracker.AgeBiologicalTicks; + } + + public void AdjustNippleProgress(float amount) + { + nippleProgress = Mathf.Clamp01(nippleProgress + amount); + UpdateNipples(); + } + + public void AdjustNippleSizeImmediately(float amount) + { + baseNipple = Mathf.Clamp01(baseNipple + amount); + UpdateNipples(); + } + + public void AdjustNippleColorImmediately(float amount) + { + baseAlpha = Mathf.Clamp01(baseAlpha + amount); + UpdateNipples(); + } + + public void AdjustAreolaSizeImmediately(float amount) + { + baseAreola = Mathf.Clamp01(baseAreola + amount); + UpdateNipples(); + } + + public void UpdateNipples() + { + cachedAlpha = baseAlpha + nippleProgress * nippleChange; + cachedAreola = baseAreola + nippleProgress * nippleChange; + cachedNipple = baseNipple + nippleProgress * nippleChange; + + // For some reason, Props can go null when RJW relocates the chest (e.g. some animals), so catch that + cachedColor = Colors.CMYKLerp(Pawn.story?.SkinColor ?? Color.white, (Props?.BlackNippleColor ?? CompProperties_Breast.DefaultBlacknippleColor.ToColor), Alpha); + } + + public void CopyBreastProperties(HediffComp_Breast original) + { + maxBreastIncrement = original.maxBreastIncrement; + baseAlpha = original.baseAlpha; + baseAreola = original.baseAreola; + baseNipple = original.baseNipple; + UpdateNipples(); + } + + public string DebugInfo() + { + return "Size: " + parent.Severity + + "\nIncrease: " + breastSizeIncreased + + "\n" + debugGrowthStatus + + "\nNipple progress: " + nippleProgress + + "\nBase alpha: " + baseAlpha + + "\nAlpha: " + cachedAlpha + + "\nBase areola: " + baseAreola + + "\nAreola: " + cachedAreola + + "\nDisplayed areola: " + AreolaSize + + "\nBase nipple: " + baseNipple + + "\nNipple: " + cachedNipple + + "\nDisplayed nipple: " + NippleSize; + } + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_InducedOvulator.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_InducedOvulator.cs new file mode 100644 index 0000000..a1ab09a --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_InducedOvulator.cs @@ -0,0 +1,102 @@ +using RimWorld; +using UnityEngine; +using Verse; + +namespace RJW_Menstruation +{ + public class CompProperties_InducedOvulator : CompProperties_Menstruation + { + public CompProperties_InducedOvulator() + { + compClass = typeof(HediffComp_InducedOvulator); + } + + } + + public class HediffComp_InducedOvulator : HediffComp_Menstruation + { + public override string GetCurStageDesc + { + get + { + switch (CurrentVisibleStage) + { + case Stage.Follicular: + return Translations.Stage_Follicular_Induced_Desc + (EggHealth < 1f ? Translations.Stage_Climacteric_Desc : ""); + default: + return base.GetCurStageDesc; + } + } + } + + // In an induced ovulator, about 65% of eggs ovulated will become pregnancies, so the expected lifetime supply + // is the number of pregnancies they could have, with some extra to be sure. + // An IUD or a poor fertility mate could run this down quicker. Oh well. + protected override float RaceCyclesPerYear() + { + // Don't bother with breeding season, since so much time is planned to be spent pregnant. + float pregnanciesPerYear = GenDate.DaysPerYear / Mathf.Max(1, Pawn.def.race.gestationPeriodDays); + + return 2 * pregnanciesPerYear / Configurations.ImplantationChanceDefault; + } + + // There's really no good way to estimate the number of times it's been induced, so this is all we can do + protected override int PawnEggsUsed(float pawnCyclesElapsed, float avglittersize) + { + return Mathf.CeilToInt((Pawn.relations?.ChildrenCount ?? 0) / Configurations.ImplantationChanceDefault); + } + + protected override void GoOvulatoryStage() + { + estrusflag = false; + GoNextStage(Stage.Luteal); + } + + protected override void AfterCumIn(Pawn cummer) + { + base.AfterCumIn(cummer); + switch (curStage) + { + case Stage.Follicular: + GoNextStage(Stage.Ovulatory); + break; + } + } + + public override bool IsDangerDay + { + get + { + if (Pawn.health.hediffSet.HasHediff(VariousDefOf.RJW_IUD)) return false; + + switch (curStage) + { + case Stage.Follicular: + case Stage.Ovulatory: + return true; + case Stage.Luteal: + return IsEggExist && curStageHrs < Props.eggLifespanDays * 24; + default: + return false; + } + } + } + + protected override bool ShouldBeInEstrus() + { + if (!loaded) + Initialize(); + switch (curStage) + { + case Stage.Follicular: + return curStageHrs > currentIntervalHours - Props.estrusDaysBeforeOvulation * 24; + case Stage.Ovulatory: + return true; + case Stage.Luteal: + return IsEggExist && curStageHrs < Props.eggLifespanDays * 24; + default: + return false; + } + } + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Menstruation.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Menstruation.cs new file mode 100644 index 0000000..4ebd3b4 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/HediffComp_Menstruation.cs @@ -0,0 +1,1845 @@ +using RimWorld; +using RimWorld.Planet; +using rjw; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; +using Verse; + +namespace RJW_Menstruation +{ + [Flags] + public enum SeasonalBreed + { + Always = 0, + Spring = 1, + Summer = 2, + Fall = 4, + Winter = 8, + FirstHalf = Spring | Summer, + SecondHalf = Fall | Winter + } + + + public class CompProperties_Menstruation : HediffCompProperties + { + public float maxCumCapacity; // ml + public float baseImplantationChanceFactor; + public float basefertilizationChanceFactor; + public int follicularIntervalDays = 14; //before ovulation including beginning of bleeding + public int lutealIntervalDays = 14; //after ovulation until bleeding + public int bleedingIntervalDays = 6; //must be less than folicularIntervalDays + public int recoveryIntervalDays = 10; //additional infertile days after gave birth + public int eggLifespanDays = 2; //fertiledays = ovaluationday - spermlifespan ~ ovaluationday + egglifespanday + public string wombTex = "Womb/Womb"; //fertiledays = ovaluationday - spermlifespan ~ ovaluationday + egglifespanday + public string vagTex = "Genitals/Vagina"; //fertiledays = ovaluationday - spermlifespan ~ ovaluationday + egglifespanday + public bool infertile = false; + public bool concealedEstrus = false; + public SeasonalBreed breedingSeason = SeasonalBreed.Always; + public int estrusDaysBeforeOvulation = 3; + public int eggMultiplier = 1; + + + public CompProperties_Menstruation() + { + + compClass = typeof(HediffComp_Menstruation); + } + } + + + public class CompProperties_Anus : HediffCompProperties + { + public string analTex = "Genitals/Anal"; + + public CompProperties_Anus() + { + compClass = typeof(HediffComp_Anus); + } + } + + public class HediffComp_Menstruation : HediffComp + { + const float minmakefilthvalue = 1.0f; + //const int ovarypowerthreshold = 72; + + const int tickInterval = GenDate.TicksPerHour; + const int maxImplantDelayHours = 30 * 24; + const int minImplantAgeHours = 3 * 24; + + public CompProperties_Menstruation Props; + public Stage curStage = Stage.Follicular; + public int curStageHrs = 0; + public bool loaded = false; + public bool initError = false; + public int ovarypower = -100000; + public int eggstack = 0; + public bool DoCleanWomb = false; + + public enum Stage + { + Follicular, + Ovulatory, + Luteal, + Bleeding, + Pregnant, + Recover, + None, + Infertile, + Anestrus + } + + public enum EstrusLevel + { + None, + Concealed, + Visible + } + + public static readonly Dictionary StageTexture = new Dictionary() + { + { Stage.Follicular, TextureCache.FollicularTexture }, + { Stage.Luteal, TextureCache.LutealTexture }, + { Stage.Bleeding, TextureCache.BleedingTexture }, + { Stage.Pregnant, TextureCache.PregnantTexture }, + { Stage.Recover, TextureCache.RecoverTexture } + }; + + + protected List cums; + protected List eggs; + protected float cycleSpeed = -1; + protected float cycleVariability = -1; + protected int currentIntervalHours = -1; + protected float crampPain = -1; + protected Need sexNeed = null; + protected string customwombtex = null; + protected string customvagtex = null; + protected bool estrusflag = false; + protected int opcache = -1; + protected float antisperm = 0.0f; + protected float? originvagsize = null; + // RJW pregnancy, or Biotech pregnancy/labor/laborpushing + protected Hediff pregnancy = null; + + private static readonly SimpleCurve SexFrequencyCurve = new SimpleCurve() + { + new CurvePoint(0.4f,0.05f), + new CurvePoint(0.6f,0.1f), + new CurvePoint(0.8f,0.25f), + new CurvePoint(1.0f,0.5f) + }; + + private static readonly SimpleCurve SexSatisfactionCurve = new SimpleCurve() + { + new CurvePoint(0.4f,0.5f), + new CurvePoint(0.6f,0.6f), + new CurvePoint(0.8f,0.7f), + new CurvePoint(1.0f,0.8f) + }; + + private static readonly SimpleCurve FertilityCurve = new SimpleCurve() + { + new CurvePoint(0.4f,0.01f), + new CurvePoint(0.6f,0.1f), + new CurvePoint(0.8f,0.25f), + new CurvePoint(1.0f,0.5f) + }; + + public Hediff Pregnancy { + get + { + if (pregnancy == null) return null; + else if (!Pawn.health.hediffSet.hediffs.Contains(pregnancy)) + { + pregnancy = null; + return null; + } + else return pregnancy; + } + set => pregnancy = value; + } + + public int OvaryPowerThreshold + { + get + { + if (opcache >= 0) return opcache; + float avglittersize; + try + { + avglittersize = Mathf.Max(Rand.ByCurveAverage(Pawn.def.race.litterSizeCurve), 1.0f); + } + catch + { + // Any exceptions in that will have been reported elsewhere in the code by now + avglittersize = 1.0f; + }; + const float yearsBeforeMenopause = 6.0f; + opcache = (int)(RaceCyclesPerYear() * + avglittersize * + yearsBeforeMenopause * + (Pawn.def.race.lifeExpectancy / ThingDefOf.Human.race.lifeExpectancy)); + return opcache; + } + } + + // >= 1: Normal cycles + // 1 - 0: Climacteric + // <= 0: Menopause + public float EggHealth + { + get + { + if (!Configurations.EnableMenopause || Props.infertile) return Mathf.Min(1.0f, ovarypower / OvaryPowerThreshold); + else return ovarypower / OvaryPowerThreshold; + } + } + + public float SexFrequencyModifier + { + get + { + float eggHealth = EggHealth; + if (eggHealth >= 1) return 1.0f; + else if (eggHealth <= 0) return 0.01f; + else return SexFrequencyCurve.Evaluate(eggHealth); + } + } + + public float SexSatisfactionModifier + { + get + { + float eggHealth = EggHealth; + if (eggHealth >= 1) return 1.0f; + else if (eggHealth <= 0) return 0.5f; + else return SexSatisfactionCurve.Evaluate(eggHealth); + } + } + + public float FertilityModifier + { + get + { + float eggHealth = EggHealth; + if (eggHealth >= 1) return 1.0f; + else if (eggHealth <= 0) return 0.0f; + else return FertilityCurve.Evaluate(eggHealth); + } + } + + public float TotalCum + { + get + { + return cums?.Sum(cum => cum.Volume) ?? 0; + } + } + public float TotalFertCum + { + get + { + return cums?.Sum(cum => cum.FertVolume) ?? 0; + } + } + public float TotalCumPercent + { + get + { + return cums?.Sum(cum => cum.Volume) / Props.maxCumCapacity ?? 0; + } + } + public float CumCapacity + { + get + { + float res = Props.maxCumCapacity * Pawn.BodySize; + if (curStage != Stage.Pregnant || (pregnancy?.Severity ?? 0f) < 0.175f) res *= 500f; + return res; + } + } + //make follicular interval into half and double egg lifespan + public float CycleFactor + { + get + { + if (xxx.has_quirk(Pawn, "Breeder")) return 0.5f; + + return 1.0f; + } + } + //effect on implant chance + public float ImplantFactor + { + get + { + float factor = 1.0f; + if (Pawn.Has(Quirk.Breeder)) factor = 10.0f; + return Pawn.health.capacities.GetLevel(xxx.reproduction) * Props.baseImplantationChanceFactor * FertilityModifier * factor; + } + } + public IEnumerable GetCumsInfo + { + get + { + if (cums.NullOrEmpty()) yield return Translations.Info_noCum; + else foreach (Cum cum in cums) + { + if (!cum.notcum) yield return string.Format("{0}: {1:0.##}ml", cum.pawn?.Label, cum.Volume); + else yield return string.Format("{0}: {1:0.##}ml", cum.notcumLabel, cum.Volume); + } + } + } + public Color GetCumMixtureColor + { + get + { + Color mixedcolor = Color.white; + + if (cums.NullOrEmpty()) return mixedcolor; + + float mixedsofar = 0; + foreach (Cum cum in cums) + { + if (cum.Volume > 0) + { + mixedcolor = Colors.CMYKLerp(mixedcolor, cum.Color, cum.Volume / (mixedsofar + cum.Volume)); + mixedsofar += cum.Volume; + } + } + return mixedcolor; + } + } + + public Stage CurrentVisibleStage + { + get + { + if (curStage == Stage.Pregnant) + { + if (Configurations.InfoDetail == Configurations.DetailLevel.All || (pregnancy?.Visible ?? false)) + return Stage.Pregnant; + else + return Stage.Luteal; + } + return curStage; + } + } + + public string GetCurStageLabel + { + get + { + switch (CurrentVisibleStage) + { + case Stage.Follicular: + return Translations.Stage_Follicular + (EggHealth < 1f ? Translations.Stage_Climacteric : ""); + case Stage.Ovulatory: + return Translations.Stage_Ovulatory + (EggHealth < 1f ? Translations.Stage_Climacteric : ""); + case Stage.Luteal: + return Translations.Stage_Luteal + (EggHealth < 1f ? Translations.Stage_Climacteric : ""); + case Stage.Bleeding: + return Translations.Stage_Bleeding + (EggHealth < 1f ? Translations.Stage_Climacteric : ""); + case Stage.Pregnant: + return Translations.Stage_Pregnant; + case Stage.Recover: + return Translations.Stage_Recover; + case Stage.None: + case Stage.Infertile: + if (EggHealth <= 0f) return Translations.Stage_Menopause; + else return Translations.Stage_None; + case Stage.Anestrus: + return Translations.Stage_Anestrus; + default: + return ""; + } + } + + } + public virtual string GetCurStageDesc + { + get + { + switch (CurrentVisibleStage) + { + case Stage.Follicular: + return Translations.Stage_Follicular_Desc + (EggHealth < 1f ? Translations.Stage_Climacteric_Desc : ""); + case Stage.Ovulatory: + return Translations.Stage_Ovulatory_Desc + (EggHealth < 1f ? Translations.Stage_Climacteric_Desc : ""); + case Stage.Luteal: + return Translations.Stage_Luteal_Desc + (EggHealth < 1f ? Translations.Stage_Climacteric_Desc : ""); + case Stage.Bleeding: + return Translations.Stage_Bleeding_Desc + (EggHealth < 1f ? Translations.Stage_Climacteric_Desc : ""); + case Stage.Pregnant: + return Translations.Stage_Pregnant_Desc; + case Stage.Recover: + return Translations.Stage_Recover_Desc; + case Stage.None: + case Stage.Infertile: + if (EggHealth <= 0f) return Translations.Stage_Menopause_Desc; + else return Translations.Stage_None_Desc; + case Stage.Anestrus: + return Translations.Stage_Anestrus_Desc; + default: + return ""; + } + } + } + + public string WombTex + { + get + { + return customwombtex ?? Props.wombTex; + } + set + { + customwombtex = value; + } + } + public string VagTex + { + get + { + return customvagtex ?? Props.vagTex; + } + set + { + customvagtex = value; + } + } + public string GetFertilizingInfo + { + get + { + if (eggs.NullOrEmpty()) return ""; + + StringBuilder res = new StringBuilder(); + int fertilized = eggs.Count(egg => egg.fertilized); + if (fertilized != 0) res.AppendFormat("{0} {1}", fertilized, Translations.Dialog_WombInfo05); + if (fertilized != 0 && eggs.Count - fertilized != 0) res.Append(", "); + if (cums.NullOrEmpty() || TotalFertCum == 0) + { + if (eggs.Count - fertilized != 0) res.AppendFormat("{0} {1}", eggs.Count - fertilized, Translations.Dialog_WombInfo07); + } + else + { + if (eggs.Count - fertilized != 0) res.AppendFormat("{0} {1}", eggs.Count - fertilized, Translations.Dialog_WombInfo06); + } + return res.ToString(); + } + } + public bool IsEggFertilizing + { + get + { + if (eggs.NullOrEmpty()) return false; + return cums?.Any(cum => cum.FertVolume > 0) ?? false; + } + } + /// + /// returns fertstage. if not fertilized returns -1 + /// + public int IsFertilized + { + get + { + if (eggs?.All(egg => !egg.fertilized) ?? true) return -1; + return eggs.Max(egg => egg.fertstage); + } + } + public IEnumerable GetCummersAndFertilizers() + { + if (!cums.NullOrEmpty()) + foreach (Cum cum in cums) + yield return cum.pawn; + if (!eggs.NullOrEmpty()) + foreach (Egg egg in eggs) + yield return egg.fertilizer; + } + public bool IsEggExist + { + get + { + return !eggs.NullOrEmpty(); + } + } + public virtual bool IsDangerDay + { + get + { + if (Pawn.health.hediffSet.HasHediff(VariousDefOf.RJW_IUD)) return false; + + switch (curStage) + { + case Stage.Follicular: + return curStageHrs > 0.7f * currentIntervalHours; + case Stage.Ovulatory: + return true; + case Stage.Luteal: + return curStageHrs < Props.eggLifespanDays * 24; + default: + return false; + } + } + } + public int GetNumOfEggs + { + get + { + return eggs?.Count ?? 0; + } + } + public Color BloodColor + { + get + { + try + { + Color c = Pawn.def.race.BloodDef.graphicData.color; + return c; + } + catch + { + return Colors.blood; + } + + } + } + + public float OriginVagSize + { + get + { + if (originvagsize == null) + { + originvagsize = parent.Severity; + } + return originvagsize ?? 0.1f; + } + set + { + originvagsize = value; + } + } + + public float CurStageIntervalHours + { + get + { + return currentIntervalHours; + } + } + + public float StageProgress + { + get + { + if (pregnancy == null) return Mathf.Clamp01(curStageHrs / CurStageIntervalHours); + bool is_discovered = false; + switch (pregnancy) + { + case Hediff_BasePregnancy rjw_preg: + is_discovered = rjw_preg.is_discovered; + break; + case Hediff_Pregnant vanilla_preg: + is_discovered = vanilla_preg.Visible; + break; + case Hediff_Labor _: + case Hediff_LaborPushing _: + return 1.0f; + } + + if (is_discovered || Configurations.infoDetail == Configurations.DetailLevel.All) return pregnancy.Severity; + + // Luteal will appear to progress, hitting the end of the phase when the pregnancy is discovered + float discoveryTime = 0.5f; + if (Pawn.story?.bodyType == BodyTypeDefOf.Thin) discoveryTime = 0.25f; + else if (Pawn.story?.bodyType == BodyTypeDefOf.Female) discoveryTime = 0.35f; + // Estimated; there's no way to get the exact value after the fact without writing it into the save + float lutealProgressWhenImplanted = Math.Min(0.5f, maxImplantDelayHours / (Props.lutealIntervalDays * 24)); + + return GenMath.LerpDouble(0, discoveryTime, lutealProgressWhenImplanted, 1.0f, pregnancy.Severity); + } + } + + public Texture2D GetStageTexture + { + get + { + if (!StageTexture.TryGetValue(CurrentVisibleStage, out Texture2D tex)) tex = TextureCache.PregnantTexture; + return tex; + } + } + + public override void CompExposeData() + { + base.CompExposeData(); + Scribe_Collections.Look(ref cums, saveDestroyedThings: true, label: "cums", lookMode: LookMode.Deep, ctorArgs: new object[0]); + Scribe_Collections.Look(ref eggs, saveDestroyedThings: true, label: "eggs", lookMode: LookMode.Deep, ctorArgs: new object[0]); + Scribe_Values.Look(ref curStage, "curStage", curStage, true); + Scribe_Values.Look(ref curStageHrs, "curStageHrs", curStageHrs, true); + Scribe_Values.Look(ref cycleSpeed, "cycleSpeed", cycleSpeed, true); + Scribe_Values.Look(ref cycleVariability, "cycleVariability", cycleVariability, true); + Scribe_Values.Look(ref currentIntervalHours, "currentIntervalHours", currentIntervalHours, true); + Scribe_Values.Look(ref crampPain, "crampPain", crampPain, true); + Scribe_Values.Look(ref ovarypower, "ovarypower", ovarypower, true); + Scribe_Values.Look(ref eggstack, "eggstack", eggstack, true); + Scribe_Values.Look(ref estrusflag, "estrusflag", estrusflag, true); + Scribe_Values.Look(ref originvagsize, "originvagsize", originvagsize, true); + Scribe_Values.Look(ref DoCleanWomb, "DoCleanWomb", DoCleanWomb, true); + Scribe_References.Look(ref pregnancy, "pregnancy"); + } + + + public override void CompPostPostAdd(DamageInfo? dinfo) + { + if (!loaded) + { + Initialize(); + } + } + + public bool ShouldSimulate() + { + if (!Configurations.EnableAnimalCycle && Pawn.IsAnimal()) return false; + if (Pawn.Spawned || Pawn.IsCaravanMember() || PawnUtility.IsTravelingInTransportPodWorldObject(Pawn)) return true; + + return false; + } + + public override void CompPostTick(ref float severityAdjustment) + { + base.CompPostTick(ref severityAdjustment); + // If an exception makes it out, RW will remove the hediff, so catch it here + try + { + if (!ShouldSimulate()) return; + + // Initialize immediately if needed, but if there's an error, then don't spam it every tick + if (!loaded && !initError) + { + Log.Warning($"{Pawn}'s womb is ticking, but was not initialized first"); + Initialize(); + } + + if (!Pawn.IsHashIntervalTick(tickInterval)) return; + + if (initError) Log.Warning($"Attempting to process {Pawn}'s womb uninitialized"); + + if (Pregnancy != null && curStage != Stage.Pregnant) + { + Log.Warning($"{Pawn}'s womb has a pregnancy, but was not in the pregnant stage"); + curStage = Stage.Pregnant; + } + + CumOut(); + + if (pregnancy == null && (Pawn.health.capacities.GetLevel(xxx.reproduction) <= 0) || EggHealth <= 0) curStage = Stage.Infertile; + switch (curStage) + { + case Stage.Follicular: + FollicularAction(); + break; + case Stage.Ovulatory: + OvulatoryAction(); + break; + case Stage.Luteal: + LutealAction(); + break; + case Stage.Bleeding: + BleedingAction(); + break; + case Stage.Pregnant: + PregnantAction(); + break; + case Stage.Recover: + RecoverAction(); + break; + case Stage.None: + break; + case Stage.Infertile: + InfertileAction(); + break; + case Stage.Anestrus: + AnestrusAction(); + break; + default: + GoNextStage(Stage.Follicular); + break; + } + AfterSimulator(); + } + catch (Exception ex) + { + Log.Error($"Error processing womb of {Pawn}: {ex}"); + } + } + + public override void CompPostPostRemoved() + { + // If a hediff is removed from a pawn that does not have it, CompPostPostRemoved is still called on the pawn that does. + // If it was a legitimate removal, then it won't be in this pawn's hediff list anymore, as that removal occurs first + if (Pawn.health.hediffSet.hediffs.Contains(parent)) + { + Log.Warning($"Attempted to remove menstruation comp from wrong pawn ({Pawn})."); + return; + } + switch (pregnancy) + { + case null: + case Hediff_MechanoidPregnancy _: + break; + case Hediff_BasePregnancy rjw_preg: + rjw_preg.Miscarry(); + break; + case Hediff_Pregnant vanilla_preg: + Pawn.health.RemoveHediff(vanilla_preg); + break; + } + + base.CompPostPostRemoved(); + } + + /// + /// Get fluid in womb that not a cum + /// + /// + /// + public Cum GetNotCum(string notcumlabel) + { + if (!cums.NullOrEmpty()) foreach (Cum cum in cums) + { + if (cum.notcum && cum.notcumLabel.Equals(notcumlabel)) return cum; + } + return null; + } + + /// + /// Get pawn's cum in womb + /// + /// + /// + public Cum GetCum(Pawn pawn) + { + return cums?.Find(cum => !cum.notcum && cum.pawn == pawn); + } + + /// + /// Inject pawn's cum into womb + /// + /// + /// + /// + /// + public void CumIn(Pawn pawn, float volume, float fertility = 1.0f, ThingDef filthdef = null) + { + if (volume <= 0) return; + if (Pawn.health.hediffSet.HasHediff(VariousDefOf.RJW_IUD)) fertility /= 100f; + float cumd = TotalCumPercent; + float tmp = TotalCum + volume; + if (tmp > CumCapacity) + { + float cumoutrate = 1 - (CumCapacity / tmp); + bool merged = false; + if (!cums.NullOrEmpty()) foreach (Cum cum in cums) + { + if (cum.pawn.Equals(pawn)) + { + cum.MergeWithCum(volume, fertility, filthdef); + merged = true; + } + cum.DismishForce(cumoutrate); + } + if (!merged) cums.Add(new Cum(pawn, volume * (1 - cumoutrate), fertility, filthdef)); + } + else + { + + bool merged = false; + if (!cums.NullOrEmpty()) foreach (Cum cum in cums) + { + if (cum.pawn.Equals(pawn)) + { + cum.MergeWithCum(volume, fertility, filthdef); + merged = true; + } + } + if (!merged) cums.Add(new Cum(pawn, volume, fertility, filthdef)); + } + cumd = TotalCumPercent - cumd; + + Pawn.records.AddTo(VariousDefOf.AmountofCreampied, volume); + AfterCumIn(pawn); + AfterFluidIn(cumd); + } + + /// + /// Inject pawn's fluid into womb + /// + /// + /// + /// + /// + /// + public void CumIn(Pawn pawn, float volume, string notcumlabel, float decayresist = 0, ThingDef filthdef = null) + { + if (volume <= 0) return; + float tmp = TotalCum + volume; + float cumd = TotalCumPercent; + if (tmp > CumCapacity) + { + float cumoutrate = 1 - (CumCapacity / tmp); + bool merged = false; + if (!cums.NullOrEmpty()) foreach (Cum cum in cums) + { + if (cum.notcum && cum.pawn.Equals(pawn) && cum.notcumLabel.Equals(notcumlabel)) + { + cum.MergeWithFluid(volume, decayresist, filthdef); + merged = true; + } + cum.DismishForce(cumoutrate); + } + if (!merged) cums.Add(new Cum(pawn, volume * (1 - cumoutrate), notcumlabel, decayresist, filthdef)); + } + else + { + + bool merged = false; + if (!cums.NullOrEmpty()) foreach (Cum cum in cums) + { + if (cum.notcum && cum.pawn.Equals(pawn) && cum.notcumLabel.Equals(notcumlabel)) + { + cum.MergeWithFluid(volume, decayresist, filthdef); + merged = true; + } + } + if (!merged) cums.Add(new Cum(pawn, volume, notcumlabel, decayresist, filthdef)); + } + cumd = TotalCumPercent - cumd; + AfterNotCumIn(); + AfterFluidIn(cumd); + } + + protected virtual void AfterCumIn(Pawn cummer) + { + ThoughtCumInside(cummer); + TaleCumInside(cummer); + } + + protected virtual void AfterNotCumIn() + { + + } + + /// + /// Action for both Cum and NotCum + /// + /// Fluid deviation + protected virtual void AfterFluidIn(float fd) + { + + + } + + + protected void BeforeCumOut(out Absorber absorber) + { + Hediff asa = Pawn.health.hediffSet.GetFirstHediffOfDef(VariousDefOf.Hediff_ASA); + float asafactor = asa?.Severity ?? 0f; + + if (Pawn.health.hediffSet.HasHediff(VariousDefOf.RJW_IUD)) antisperm = 0.70f + asafactor; + else antisperm = 0.0f + asafactor; + + absorber = (Absorber)Pawn.apparel?.WornApparel?.Find(x => x is Absorber); + if (absorber != null) + { + absorber.WearEffect(); + if (absorber.dirty && absorber.EffectAfterDirty) absorber.DirtyEffect(); + } + } + + /// + /// For natural leaking + /// + protected virtual void AfterCumOut() + { + Pawn.needs?.mood?.thoughts?.memories?.TryGainMemory(VariousDefOf.LeakingFluids); + } + + /// + /// For all type of leaking + /// + /// + protected virtual void AfterFluidOut(float fd) + { + + } + + + + + /// + /// Excrete cums in womb naturally + /// + public void CumOut() + { + float leakfactor = 1.0f; + float totalleak = 0f; + float cumd = TotalCumPercent; + List filthlabels = new List(); + BeforeCumOut(out Absorber absorber); + if (cums.NullOrEmpty()) return; + if (TotalCum > Props.maxCumCapacity * Pawn.BodySize) leakfactor = Math.Min(1 + (TotalCum - Props.maxCumCapacity * Pawn.BodySize) / 10, 2f); + if (absorber != null && absorber.dirty && !absorber.LeakAfterDirty) leakfactor = 0f; + if (Pawn.CurJobDef == xxx.knotted) leakfactor = 0f; + List removecums = new List(); + foreach (Cum cum in cums) + { + cum.CumEffects(Pawn); + float vd = cum.DismishNatural(leakfactor, this, antisperm); + cum.MakeThinner(Configurations.CycleAcceleration); + totalleak += AbsorbCum(vd, absorber); + string tmp = "FilthLabelWithSource".Translate(cum.FilthDef.label, cum.pawn?.LabelShort ?? "Unknown", 1.ToString()); + filthlabels.Add(tmp.Replace(" x1", "")); + if (cum.ShouldRemove()) removecums.Add(cum); + } + if (cums.Count > 1) MakeCumFilthMixture(totalleak, filthlabels); + else if (cums.Count == 1) MakeCumFilth(cums.First(), totalleak); + foreach (Cum cum in removecums) + { + cums.Remove(cum); + } + cumd = TotalCumPercent - cumd; + if (totalleak >= 1.0f) AfterCumOut(); + AfterFluidOut(cumd); + + } + + /// + /// Force excrete cums in womb and get excreted amount of specific cum. + /// + /// + /// + /// Amount of target cum + public float CumOut(Cum targetcum, float portion = 0.1f) + { + if (cums.NullOrEmpty()) return 0; + float totalleak = 0; + List filthlabels = new List(); + float outcum = 0; + float cumd = TotalCumPercent; + List removecums = new List(); + foreach (Cum cum in cums) + { + float vd = cum.DismishForce(portion); + if (cum.Equals(targetcum)) outcum = vd; + //MakeCumFilth(cum, vd - cum.volume); + string tmp = "FilthLabelWithSource".Translate(cum.FilthDef.label, cum.pawn?.LabelShort ?? "Unknown", 1.ToString()); + filthlabels.Add(tmp.Replace(" x1", "")); + totalleak += vd; + if (cum.ShouldRemove()) removecums.Add(cum); + } + if (cums.Count > 1) MakeCumFilthMixture(totalleak, filthlabels); + else if (cums.Count == 1) MakeCumFilth(cums.First(), totalleak); + foreach (Cum cum in removecums) + { + cums.Remove(cum); + } + cumd = TotalCumPercent - cumd; + AfterFluidOut(cumd); + return outcum; + } + + /// + /// Force excrete cums in womb and get mixture of cum. + /// + /// + /// + /// + public CumMixture MixtureOut(ThingDef mixtureDef, float portion = 0.1f) + { + if (cums.NullOrEmpty()) return null; + Color color = GetCumMixtureColor; + float totalleak = 0; + List cumlabels = new List(); + List removecums = new List(); + bool pure = true; + foreach (Cum cum in cums) + { + float vd = cum.DismishForce(portion); + string tmp = "FilthLabelWithSource".Translate(cum.FilthDef.label, cum.pawn?.LabelShort ?? "Unknown", 1.ToString()); + cumlabels.Add(tmp.Replace(" x1", "")); + totalleak += vd; + if (cum.ShouldRemove()) removecums.Add(cum); + if (cum.notcum) pure = false; + } + foreach (Cum cum in removecums) + { + cums.Remove(cum); + } + return new CumMixture(Pawn, totalleak, cumlabels, color, mixtureDef, pure); + } + + /// + /// Debug: Remove all cums from a womb + /// + /// + public void RemoveAllCums() + { + cums.Clear(); + } + + + /// + /// Fertilize eggs and return the result + /// + /// + protected void FertilizationCheck() + { + if (eggs.NullOrEmpty()) return; + foreach (Egg egg in eggs) + { + if (!egg.fertilized) egg.fertilizer = Fertilize(); + if (egg.fertilizer != null) + { + egg.fertilized = true; + } + } + } + + public void Initialize() + { + initError = true; + Props = (CompProperties_Menstruation)props; + + if (Props.infertile) + { + if (cums == null) cums = new List(); + curStage = Stage.None; + loaded = true; + initError = false; + return; + } + + if (cycleSpeed < 0f) cycleSpeed = Utility.RandGaussianLike(0.8f, 1.2f); + if (cycleVariability < 0f) cycleVariability = MenstruationUtility.RandomVariabilityPercent(); + if (currentIntervalHours < 0) + { + if (Pawn.health.capacities.GetLevel(xxx.reproduction) <= 0) curStage = Stage.Infertile; + else if (!IsBreedingSeason()) curStage = Stage.Anestrus; + else curStage = RandomStage(); + if (curStage == Stage.Follicular) + currentIntervalHours = PeriodRandomizer(Stage.Follicular) - PeriodRandomizer(Stage.Bleeding); + else + currentIntervalHours = PeriodRandomizer(curStage); + if (currentIntervalHours <= 0) currentIntervalHours = 1; + else if (currentIntervalHours < curStageHrs) curStageHrs = currentIntervalHours; + } + if (crampPain < 0) crampPain = PainRandomizer(); + if (cums == null) cums = new List(); + if (eggs == null) eggs = new List(); + + + InitOvary(); + TakeLoosePregnancy(); + + //Log.Message(Pawn.Label + " - Initialized menstruation comp"); + loaded = true; + initError = false; + } + + protected virtual float RaceCyclesPerYear() + { + int breedingSeasons = 0; + if (Props.breedingSeason == SeasonalBreed.Always) breedingSeasons = 4; + else + { + if ((Props.breedingSeason & SeasonalBreed.Spring) != 0) breedingSeasons++; + if ((Props.breedingSeason & SeasonalBreed.Summer) != 0) breedingSeasons++; + if ((Props.breedingSeason & SeasonalBreed.Fall) != 0) breedingSeasons++; + if ((Props.breedingSeason & SeasonalBreed.Winter) != 0) breedingSeasons++; + } + float breedingRatio = breedingSeasons / 4.0f; + return breedingRatio * GenDate.DaysPerYear / ((float)(Props.follicularIntervalDays + Props.lutealIntervalDays) / Configurations.CycleAccelerationDefault); + } + + protected virtual int PawnEggsUsed(float pawnCyclesElapsed, float avglittersize) + { + return (int)(pawnCyclesElapsed * avglittersize); + } + + public int GetOvaryPowerByAge() + { + float avglittersize; + try + { + avglittersize = Mathf.Max(Rand.ByCurveAverage(Pawn.def.race.litterSizeCurve), 1.0f); + } + catch (NullReferenceException) + { + avglittersize = 1.0f; + } + + float fertStartAge = Pawn.RaceProps.lifeStageAges?.Find(stage => stage.def.reproductive)?.minAge ?? 0.0f; + float fertEndAge = Pawn.RaceProps.lifeExpectancy * (Pawn.IsAnimal() ? RJWPregnancySettings.fertility_endage_female_animal : RJWPregnancySettings.fertility_endage_female_humanlike); + if (fertEndAge < fertStartAge) fertEndAge = fertStartAge; + + float raceCyclesPerYear = RaceCyclesPerYear(); + int lifetimeCycles = (int)(raceCyclesPerYear * (fertEndAge - fertStartAge)); + int lifetimeEggs = (int)(lifetimeCycles * avglittersize * Props.eggMultiplier * Utility.RandGaussianLike(0.70f, 1.30f, 5)); + + float pawnCyclesPerYear = raceCyclesPerYear * cycleSpeed; + float pawnCyclesElapsed = Mathf.Max((Pawn.ageTracker.AgeBiologicalYearsFloat - fertStartAge) * pawnCyclesPerYear, 0.0f); + int pawnEggsUsed = PawnEggsUsed(pawnCyclesElapsed, avglittersize); + + return Math.Max(lifetimeEggs - pawnEggsUsed, 0); + } + + protected void InitOvary() + { + if (ovarypower < -50000) + { + ovarypower = GetOvaryPowerByAge(); + if (Props.infertile) curStage = Stage.None; + else if (ovarypower < 1) + { + curStage = Stage.Infertile; + } + } + } + + public void RecoverOvary(float multiply = 1.2f) + { + ovarypower = Math.Max(0, (int)(ovarypower * multiply)); + } + + + protected void AfterSimulator() + { + if (EggHealth < 1f) + { + if (sexNeed == null) sexNeed = Pawn.needs.TryGetNeed(VariousDefOf.SexNeed); + if (sexNeed?.CurLevel < 0.5) sexNeed.CurLevel += 0.01f / Math.Max(1, Pawn.GetMenstruationComps().Count()); + } + } + + protected virtual bool ShouldBeInEstrus() + { + if (!loaded) + Initialize(); + switch (curStage) + { + case Stage.Follicular: + return curStageHrs > currentIntervalHours - Props.estrusDaysBeforeOvulation * 24; + case Stage.Ovulatory: + return true; + case Stage.Luteal: + return curStageHrs < Props.eggLifespanDays * 24; + default: + return false; + } + } + + public EstrusLevel GetEstrusLevel() + { + if (!ShouldBeInEstrus()) return EstrusLevel.None; + else return Props.concealedEstrus ? EstrusLevel.Concealed : EstrusLevel.Visible; + } + + public void SetEstrus() + { + Hediff hediff = HediffMaker.MakeHediff(Props.concealedEstrus ? VariousDefOf.Hediff_Estrus_Concealed : VariousDefOf.Hediff_Estrus, Pawn); + Pawn.health.AddHediff(hediff); + } + + public bool IsBreedingSeason() + { + if (Props.breedingSeason == SeasonalBreed.Always) return true; + + int tile = Pawn.Tile; + if (tile < 0) tile = Find.AnyPlayerHomeMap?.Tile ?? -1; + if (tile < 0) return true; + switch (GenLocalDate.Season(tile)) + { + case Season.Spring: + return (Props.breedingSeason & SeasonalBreed.Spring) != 0; + case Season.Summer: + case Season.PermanentSummer: + return (Props.breedingSeason & SeasonalBreed.Summer) != 0; + case Season.Fall: + return (Props.breedingSeason & SeasonalBreed.Fall) != 0; + case Season.Winter: + case Season.PermanentWinter: + return (Props.breedingSeason & SeasonalBreed.Winter) != 0; + default: + return false; + } + } + + protected Pawn Fertilize() + { + if (cums.NullOrEmpty()) return null; + List eligibleCum = cums.FindAll(cum => !cum.notcum && cum.FertVolume > 0 && cum.pawn != null && (RJWPregnancySettings.bestial_pregnancy_enabled || xxx.is_animal(Pawn) == xxx.is_animal(cum.pawn))); + if (eligibleCum.Count == 0) return null; + + float totalFertPower = eligibleCum.Sum(cum => cum.FertVolume); + + if (Rand.Range(0.0f, 1.0f) > 1.0f - Mathf.Pow(1.0f - Configurations.FertilizeChance, totalFertPower * Props.basefertilizationChanceFactor)) + return null; + + Pawn.records.AddTo(VariousDefOf.AmountofFertilizedEggs, 1); + float selection = Rand.Range(0.0f, totalFertPower); + + foreach (Cum cum in eligibleCum) + { + selection -= cum.FertVolume; + if (selection <= 0) return cum.pawn; + } + + // We shouldn't reach here, but floating point errors exist, so just to be sure, select whomever came the most + return eligibleCum.MaxBy(cum => cum.FertVolume).pawn; + } + + + protected bool Implant() + { + if (eggs.NullOrEmpty()) return false; + + List deadeggs = new List(); + bool pregnant = false; + foreach (Egg egg in eggs) + { + if (!egg.fertilized || + egg.fertstage < minImplantAgeHours || + egg.position < Math.Min(Props.lutealIntervalDays * 24 / 2, maxImplantDelayHours)) + continue; + else if (egg.fertilizer == null) + { + if (Configurations.Debug) Log.Message($"Could not implant {Pawn}'s egg due to null father"); + deadeggs.Add(egg); + continue; + } + else if (Pawn.health.hediffSet.GetFirstHediff() != null || pregnancy is Hediff_MechanoidPregnancy) + { + if (Configurations.Debug) Log.Message($"Could not implant {Pawn}'s egg due to insect or mechanoid pregnancy"); + deadeggs.Add(egg); + continue; + } + else if (Rand.Range(0.0f, 1.0f) <= Configurations.ImplantationChance * ImplantFactor * InterspeciesImplantFactor(egg.fertilizer)) + { + if (Configurations.Debug) Log.Message($"Implanting fertilized egg of {Pawn} into {parent}, father {egg.fertilizer}"); + if (pregnancy != null) + { + if (Configurations.UseMultiplePregnancy && Configurations.EnableHeteroOvularTwins) + { + if (pregnancy is Hediff_MultiplePregnancy h) + { + if (Configurations.Debug) Log.Message($"Adding to existing pregnancy {h}"); + h.AddNewBaby(Pawn, egg.fertilizer); + } + pregnant = true; + deadeggs.Add(egg); + } + else + { + pregnant = true; + break; + } + } + else + { + if (!Configurations.UseMultiplePregnancy) + { + if (Configurations.Debug) Log.Message($"Creating new base RJW pregnancy"); + PregnancyHelper.PregnancyDecider(Pawn, egg.fertilizer); + // I hate having to do this, but it gets the newest pregnancy + List pregnancies = new List(); + Pawn.health.hediffSet.GetHediffs(ref pregnancies); + pregnancy = pregnancies.MaxBy(hediff => hediff.loadID); + pregnant = true; + break; + } + else + { + if (Configurations.Debug) Log.Message($"Creating new menstruation pregnancy"); + pregnancy = Hediff_BasePregnancy.Create(Pawn, egg.fertilizer); + pregnant = true; + deadeggs.Add(egg); + } + if (pregnancy is Hediff_BasePregnancy rjw_preg) + { + rjw_preg.p_start_tick -= egg.fertstage / Configurations.CycleAcceleration * GenDate.TicksPerHour; + rjw_preg.p_end_tick -= egg.fertstage / Configurations.CycleAcceleration * GenDate.TicksPerHour; + } + // TODO: advance biotech pregnancy + } + + } + else + { + if (Configurations.Debug) Log.Message($"Fertilized egg of {Pawn} failed to implant (father {egg.fertilizer})"); + deadeggs.Add(egg); + } + } + + if (pregnant && (!Configurations.UseMultiplePregnancy || !Configurations.EnableHeteroOvularTwins)) + { + eggs.Clear(); + return true; + } + else + { + foreach (Egg egg in deadeggs) + { + eggs.Remove(egg); + } + } + return pregnant; + } + + protected void BleedOut() + { + CumIn(Pawn, Rand.Range(0.02f * Configurations.BleedingAmount, 0.04f * Configurations.BleedingAmount), Translations.Menstrual_Blood, -5.0f, Pawn.def.race?.BloodDef ?? ThingDefOf.Filth_Blood); + Cum blood = GetNotCum(Translations.Menstrual_Blood); + if (blood != null) blood.Color = BloodColor; + } + + /// + /// Make filth ignoring absorber + /// + /// + /// + protected void MakeCumFilth(Cum cum, float amount) + { + if (Pawn.Map == null) return; + if (amount >= minmakefilthvalue) FilthMaker.TryMakeFilth(Pawn.Position, Pawn.Map, cum.FilthDef, cum.pawn?.LabelShort ?? "Unknown"); + } + + /// + /// Absorb cum and return leaked amount + /// + /// + /// + /// + /// + protected float AbsorbCum(float amount, Absorber absorber) + { + + if (absorber == null) + { + //if (amount >= minmakefilthvalue) FilthMaker.TryMakeFilth(Pawn.Position, Pawn.Map, cum.FilthDef, cum.pawn.LabelShort); + return amount; + } + + float absorbable = absorber.GetStatValue(VariousDefOf.MaxAbsorbable); + absorber.SetColor(Colors.CMYKLerp(GetCumMixtureColor, absorber.DrawColor, 1f - amount / absorbable)); + if (absorber.dirty) + { + //if (absorber.LeakAfterDirty) FilthMaker.TryMakeFilth(Pawn.Position, Pawn.Map, cum.FilthDef, cum.pawn.LabelShort); + return amount; + } + absorber.absorbedfluids += amount; + if (absorber.absorbedfluids > absorbable && !Pawn.apparel.IsLocked(absorber)) + { + absorber.def = absorber.DirtyDef; + //absorber.fluidColor = GetCumMixtureColor; + absorber.dirty = true; + } + return 0; + } + + protected float MakeCumFilthMixture(float amount, List cumlabels) + { + if (Pawn.Map == null) return 0; + if (amount >= minmakefilthvalue) + { + FilthMaker_Colored.TryMakeFilth(Pawn.Position, Pawn.Map, VariousDefOf.FilthMixture, cumlabels, GetCumMixtureColor, false); + } + return amount; + } + + + + + protected void EggDecay() + { + List deadeggs = new List(); + foreach (Egg egg in eggs) + { + egg.position += Configurations.CycleAcceleration; + if (egg.fertilized) egg.fertstage += Configurations.CycleAcceleration; + else + { + egg.lifespanhrs -= Configurations.CycleAcceleration; + if (egg.lifespanhrs < 0) deadeggs.Add(egg); + } + } + foreach (Egg egg in deadeggs) + { + eggs.Remove(egg); + } + } + + protected void AddCrampPain() + { + Hediff hediff = HediffMaker.MakeHediff(VariousDefOf.Hediff_MenstrualCramp, Pawn); + hediff.Severity = crampPain * Rand.Range(0.9f, 1.1f); + HediffCompProperties_SeverityPerDay Prop = (HediffCompProperties_SeverityPerDay)hediff.TryGetComp().props; + Prop.severityPerDay = -hediff.Severity / (currentIntervalHours / 24) * Configurations.CycleAcceleration; + Pawn.health.AddHediff(hediff, Genital_Helper.get_genitalsBPR(Pawn)); + } + + protected virtual void FollicularAction() + { + if (!IsBreedingSeason()) + { + estrusflag = false; + GoNextStage(Stage.Anestrus); + return; + } + else if (curStageHrs >= currentIntervalHours) + { + GoOvulatoryStage(); + } + else + { + curStageHrs += Configurations.CycleAcceleration; + if (!estrusflag && curStageHrs > currentIntervalHours - Props.estrusDaysBeforeOvulation * 24) + { + estrusflag = true; + SetEstrus(); + } + StayCurrentStage(); + } + } + + protected virtual void OvulatoryAction() + { + estrusflag = false; + int eggnum; + try + { + eggnum = Math.Max((int)Rand.ByCurve(Pawn.def.race.litterSizeCurve), 1); + } + catch (NullReferenceException) + { + eggnum = 1; + } + catch (ArgumentException e) + { + Log.Warning($"Invalid litterSizeCurve for {Pawn.def}: {e}"); + eggnum = 1; + } + eggnum += eggstack; + + for (int i = 0; i < eggnum; i++) + eggs.Add(new Egg((int)(Props.eggLifespanDays * 24 / CycleFactor))); + ovarypower -= eggnum; + + eggstack = 0; + if (EggHealth <= 0) + { + eggs.Clear(); + ovarypower = 0; + GoNextStage(Stage.Infertile); + } + else + { + GoNextStage(Stage.Luteal); + } + } + + protected virtual void LutealAction() + { + if (curStageHrs > currentIntervalHours) + { + eggs.Clear(); + if (EggHealth < 1f / 4f || (EggHealth < 1f / 3f && Rand.Range(0.0f, 1.0f) < 0.3f)) //skips bleeding + { + GoNextStage(Stage.Follicular); + } + else + { + GoFollicularOrBleeding(); + } + } + else if (!eggs.NullOrEmpty()) + { + FertilizationCheck(); + EggDecay(); + if (Implant()) + { + GoNextStage(Stage.Pregnant); + } + else + { + curStageHrs += Configurations.CycleAcceleration; + StayCurrentStage(); + } + } + else + { + curStageHrs += Configurations.CycleAcceleration; + StayCurrentStage(); + } + + } + + protected virtual void BleedingAction() + { + if (curStageHrs >= currentIntervalHours) + { + Hediff hediff = Pawn.health.hediffSet.GetFirstHediffOfDef(VariousDefOf.Hediff_MenstrualCramp); + if (hediff != null) Pawn.health.RemoveHediff(hediff); + int totalFollicularHours = PeriodRandomizer(Stage.Follicular); // The total amount of time for both bleeding and follicular + if (totalFollicularHours <= currentIntervalHours) // We've bled for so long that we completely missed the follicular phase + GoOvulatoryStage(); + else + { + currentIntervalHours = totalFollicularHours - currentIntervalHours; // I.e., the remaining follicular hours equals the total minus the bleeding hours elapsed + GoNextStage(Stage.Follicular, false); + } + } + else + { + if (curStageHrs < currentIntervalHours / 4) for (int i = 0; i < Configurations.CycleAcceleration; i++) BleedOut(); + curStageHrs += Configurations.CycleAcceleration; + StayCurrentStage(); + } + } + + protected virtual void PregnantAction() + { + if (!eggs.NullOrEmpty()) + { + FertilizationCheck(); + EggDecay(); + Implant(); + } + + if (pregnancy != null && Pawn.health.hediffSet.hediffs.Contains(pregnancy)) + { + curStageHrs += 1; + StayCurrentStageConst(Stage.Pregnant); + } + else + { + if (pregnancy != null) pregnancy = null; + GoNextStage(Stage.Recover); + } + } + + protected virtual void RecoverAction() + { + if (curStageHrs >= currentIntervalHours) + { + if (Pawn.health.capacities.GetLevel(xxx.reproduction) == 0 || EggHealth <= 0) + { + GoNextStage(Stage.Infertile); + } + else if (!IsBreedingSeason()) + { + GoNextStage(Stage.Anestrus); + } + else + { + GoNextStage(Stage.Follicular); + } + } + else + { + curStageHrs += Configurations.CycleAcceleration; + StayCurrentStage(); + } + } + + protected virtual void InfertileAction() + { + if (Pawn.health.capacities.GetLevel(xxx.reproduction) <= 0 || EggHealth <= 0) + { + StayCurrentStageConst(Stage.Infertile); + } + else + { + bool breedingSeason = IsBreedingSeason(); + GoNextStage(breedingSeason ? Stage.Follicular : Stage.Anestrus, breedingSeason); + } + } + + protected virtual void AnestrusAction() + { + if (IsBreedingSeason()) + { + GoFollicularOrBleeding(); + } + else + { + StayCurrentStage(); + } + } + + protected virtual void ThoughtCumInside(Pawn cummer) + { + if (!xxx.is_human(Pawn) || !xxx.is_human(cummer)) return; + + if ((cummer.Has(Quirk.Teratophile) != (Pawn.GetStatValue(StatDefOf.PawnBeauty) >= 0)) || + cummer.Has(Quirk.ImpregnationFetish) || + cummer.Has(Quirk.Breeder)) + { + if (cummer.relations.OpinionOf(Pawn) <= -25) + { + cummer.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.HaterCameInsideM, Pawn); + } + else + { + cummer.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.CameInsideM, Pawn); + } + } + + if (IsDangerDay) + { + if (Pawn.Has(Quirk.Breeder) || Pawn.Has(Quirk.ImpregnationFetish)) + { + Pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.CameInsideFFetish, cummer); + } + else if (Pawn.relations.OpinionOf(cummer) <= -5) + { + Pawn.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(VariousDefOf.CameInsideF, cummer); + Pawn.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(VariousDefOf.HaterCameInsideFEstrus, cummer); + Pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.HaterCameInsideF, cummer); + } + else if (Pawn.IsInEstrus() && Pawn.relations.OpinionOf(cummer) < RJWHookupSettings.MinimumRelationshipToHookup) + { + Pawn.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(VariousDefOf.CameInsideF, cummer); + Pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.HaterCameInsideFEstrus, cummer); + } + else if (!Pawn.relations.DirectRelationExists(PawnRelationDefOf.Spouse, cummer) && !Pawn.relations.DirectRelationExists(PawnRelationDefOf.Fiance, cummer)) + { + if (Pawn.health.capacities.GetLevel(xxx.reproduction) < 0.50f) Pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.CameInsideFLowFert, cummer); + else Pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.CameInsideF, cummer); + } + } + else + { + if (Pawn.Has(Quirk.Breeder) || Pawn.Has(Quirk.ImpregnationFetish)) + { + Pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.CameInsideFFetishSafe, cummer); + } + else if (Pawn.relations.OpinionOf(cummer) <= -5) + { + Pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.HaterCameInsideFSafe, cummer); + } + } + } + + protected virtual void TaleCumInside(Pawn cummer) + { + // Only make the tale for human-on-human, consentual sex. Otherwise the art just gets too hard to phrase properly + if (!xxx.is_human(Pawn) || !xxx.is_human(cummer) || Pawn == cummer) return; + if (Pawn.CurJobDef != xxx.casual_sex && Pawn.CurJobDef != xxx.gettin_loved) return; + if (!(Pawn.IsColonist || Pawn.IsPrisonerOfColony) && !(cummer.IsColonist || cummer.IsPrisonerOfColony)) return; + if (!IsDangerDay) return; + TaleRecorder.RecordTale(VariousDefOf.TaleCameInside, new object[] { cummer, Pawn }); + } + + protected void GoNextStage(Stage nextstage, bool calculateHours = true) + { + curStageHrs = 0; + if (calculateHours) currentIntervalHours = PeriodRandomizer(nextstage); + curStage = nextstage; + } + + protected virtual void GoOvulatoryStage() + { + if (EggHealth < 1.0f / 3.0f && Rand.Range(0.0f, 1.0f) < 0.2f) // Skip ovulation if deep into climacteric + { + estrusflag = false; + GoNextStage(Stage.Luteal); + } + else GoNextStage(Stage.Ovulatory); + } + + //stage can be interrupted in other reasons + protected void StayCurrentStage() + { + } + + //stage never changes + protected void StayCurrentStageConst(Stage curstage) + { + } + + protected void GoFollicularOrBleeding() + { + if (Props.bleedingIntervalDays == 0) + { + GoNextStage(Stage.Follicular); + } + else + { + GoNextStage(Stage.Bleeding); + if (crampPain >= 0.05f) + { + AddCrampPain(); + } + } + } + + protected int PeriodRandomizer(Stage stage) + { + float variabilityFactor = (EggHealth < 1.0f) ? 6.0f : 1.0f; + // Most cycle lengthening or shortening occurs in the follicular phase, so weight towards that + switch (stage) + { + case Stage.Follicular: + return (int)(Props.follicularIntervalDays * 24 * (1 + Rand.Range(-cycleVariability, cycleVariability) * 1.5f * variabilityFactor) / (1 + (cycleSpeed - 1) * 1.5f)); + case Stage.Luteal: + return (int)(Props.lutealIntervalDays * 24 * (1 + Rand.Range(-cycleVariability, cycleVariability) * 0.5f * variabilityFactor) / (1 + (cycleSpeed - 1) * 0.5f)); + case Stage.Bleeding: + return (int)(Props.bleedingIntervalDays * 24 * (1 + Rand.Range(-cycleVariability, cycleVariability) * 0.5f * variabilityFactor) / (1 + (cycleSpeed - 1) * 0.5f)); + case Stage.Recover: + return (int)(Props.recoveryIntervalDays * 24 * Rand.Range(0.95f, 1.05f)); + case Stage.Pregnant: + return (int)MenstruationUtility.GestationHours(pregnancy); + default: // Often unused + return 1; + } + } + + protected float InterspeciesImplantFactor(Pawn fertilizer) + { + if (fertilizer.def.defName == Pawn.def.defName) return 1.0f; + else + { + if (RJWPregnancySettings.complex_interspecies) return SexUtility.BodySimilarity(Pawn, fertilizer); + else return RJWPregnancySettings.interspecies_impregnation_modifier; + } + } + + protected float PainRandomizer() + { + float rand = Rand.Range(0.0f, 1.0f); + if (rand < 0.01f) return Rand.Range(0.0f, 0.2f); + else if (rand < 0.2f) return Rand.Range(0.1f, 0.2f); + else if (rand < 0.8f) return Rand.Range(0.2f, 0.4f); + else if (rand < 0.95f) return Rand.Range(0.4f, 0.6f); + else return Rand.Range(0.6f, 1.0f); + } + + protected Stage RandomStage() + { + Stage stage = Rand.ElementByWeight( + Stage.Follicular, Props.follicularIntervalDays - Props.bleedingIntervalDays, + Stage.Luteal, Props.lutealIntervalDays, + Stage.Bleeding, Props.bleedingIntervalDays); + + switch (stage) + { + case Stage.Follicular: + curStageHrs = Rand.Range(0, (Props.follicularIntervalDays - Props.bleedingIntervalDays) * 24); + break; + case Stage.Luteal: + curStageHrs = Rand.Range(0, Props.lutealIntervalDays * 24); + break; + case Stage.Bleeding: + curStageHrs = Rand.Range(0, Props.bleedingIntervalDays * 24); + break; + } + return stage; + } + + // Searches for a pregnancy unclaimed by any womb and put it in this one + public void TakeLoosePregnancy() + { + if (pregnancy != null) return; + + IEnumerable pregnancies = Pawn.health.hediffSet.hediffs.Where(hediff => + hediff is Hediff_BasePregnancy || + hediff is Hediff_Pregnant || + hediff is Hediff_Labor || + hediff is Hediff_LaborPushing); + + pregnancy = + pregnancies.Except( + Pawn.GetMenstruationComps().Select(comp => comp.pregnancy).Where(preg => preg != null) + ).FirstOrDefault(); + if (pregnancy != null) + GoNextStage(Stage.Pregnant); + } + + public void CopyCycleProperties(HediffComp_Menstruation original) + { + cycleSpeed = original.cycleSpeed; + cycleVariability = original.cycleVariability; + ovarypower = original.ovarypower; + crampPain = original.crampPain; + } + + public class Egg : IExposable + { + public bool fertilized; + public int lifespanhrs; + public Pawn fertilizer; + public int position; + public int fertstage = 0; + + public Egg() + { + fertilized = false; + lifespanhrs = (int)(96 * Configurations.EggLifespanMultiplier); + fertilizer = null; + position = 0; + } + + public Egg(int lifespanhrs) + { + fertilized = false; + this.lifespanhrs = (int)(lifespanhrs * Configurations.EggLifespanMultiplier); + fertilizer = null; + position = 0; + } + + public void ExposeData() + { + Scribe_References.Look(ref fertilizer, "fertilizer", true); + Scribe_Values.Look(ref fertilized, "fertilized", fertilized, true); + Scribe_Values.Look(ref lifespanhrs, "lifespanhrs", lifespanhrs, true); + Scribe_Values.Look(ref position, "position", position, true); + Scribe_Values.Look(ref fertstage, "fertstage", fertstage, true); + } + } + + + } + + public class HediffComp_Anus : HediffComp + { + protected float? originanussize; + + public float OriginAnusSize + { + get + { + if (originanussize == null) + { + originanussize = parent.Severity; + } + return originanussize ?? 0.1f; + } + } + + public override void CompExposeData() + { + base.CompExposeData(); + Scribe_Values.Look(ref originanussize, "originanussize", originanussize, true); + } + + public override void CompPostTick(ref float severityAdjustment) + { + } + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/MenstruationUtility.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/MenstruationUtility.cs new file mode 100644 index 0000000..a243f52 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/HediffComps/MenstruationUtility.cs @@ -0,0 +1,361 @@ +using RimWorld; +using rjw; +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using Verse; +using Verse.AI; + +namespace RJW_Menstruation +{ + public static class MenstruationUtility + { + [Obsolete("This method is obsolete. Use GetMenstruationComps or a related function instead", false)] + public static HediffComp_Menstruation GetMenstruationComp(this Pawn pawn) + { + return pawn.GetFirstMenstruationComp(); + } + + public static IEnumerable GetMenstruationComps(this Pawn pawn) + { + List hedifflist = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn))?.FindAll(h => VariousDefOf.AllVaginas.Contains(h.def)); + if (hedifflist == null) yield break; + foreach (Hediff hediff in hedifflist) + { + HediffComp_Menstruation result = hediff.TryGetComp(); + if (result != null) yield return result; + } + } + + public static HediffComp_Menstruation GetFirstMenstruationComp(this Pawn pawn) + { + return pawn.GetMenstruationComps().FirstOrDefault(); + } + + public static HediffComp_Menstruation GetRandomMenstruationComp(this Pawn pawn) + { + return pawn.GetMenstruationComps().RandomElementWithFallback(); + } + + public static HediffComp_Menstruation GetFertileMenstruationComp(this Pawn pawn) + { + List comps = pawn.GetMenstruationComps().ToList(); + return comps.Where(c => c.IsDangerDay).RandomElementWithFallback() ?? comps.RandomElementWithFallback(); + } + + public static HediffComp_Menstruation GetMenstruationCompFromVagina(this Hediff vagina) + { + if (VariousDefOf.AllVaginas.Contains(vagina?.def)) + { + return vagina.TryGetComp(); + } + return null; + } + + public static HediffComp_Menstruation GetMenstruationCompFromPregnancy(this Hediff pregnancy) + { + return pregnancy?.pawn.GetMenstruationComps().FirstOrDefault(comp => comp.Pregnancy == pregnancy); + } + + public static HediffComp_Anus GetAnusComp(this Pawn pawn) + { + List hedifflist = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn))?.FindAll((Hediff h) => h.def.defName.ToLower().Contains("anus")); + HediffComp_Anus result; + if (!hedifflist.NullOrEmpty()) + { + foreach (Hediff h in hedifflist) + { + result = h.TryGetComp(); + if (result != null) return result; + } + } + return null; + } + + public static HediffComp_Anus GetAnusComp(this Hediff hediff) + { + if (hediff is Hediff_PartBaseNatural || hediff is Hediff_PartBaseArtifical) + { + return hediff.TryGetComp(); + } + return null; + } + + public static float GetFertilityChance(this HediffComp_Menstruation comp) + { + return 1.0f - Mathf.Pow(1.0f - Configurations.FertilizeChance, comp.TotalFertCum * comp.Props.basefertilizationChanceFactor); + } + + public static Texture2D GetPregnancyIcon(this HediffComp_Menstruation comp, Hediff hediff) + { + if (hediff is Hediff_MechanoidPregnancy) + return ContentFinder.Get(("Womb/Mechanoid_Fluid"), true); + + string icon = "Fetus/Slime_Abomi02"; + string fetustex = "Fetus/Fetus_Default"; + ThingDef babydef = comp.Pawn.def; // TODO: Pregenerated babies + + float gestationProgress = comp.StageProgress; + int babycount = hediff is Hediff_BasePregnancy preg ? preg.babies.Count : 1; + + if (hediff is Hediff_BasePregnancy h) + { + babydef = h.babies?.FirstOrDefault()?.def ?? ThingDefOf.Human; + } + + fetustex = babydef.GetModExtension()?.fetusTexPath ?? "Fetus/Fetus_Default"; + if (gestationProgress < 0.2f) icon = comp.WombTex + "_Implanted"; + else if (gestationProgress < 0.3f) + { + if (babydef.race?.FleshType == FleshTypeDefOf.Insectoid) icon = "Fetus/Insects/Insect_Early00"; + else icon = "Fetus/Fetus_Early00"; + } + else if (gestationProgress < 0.4f) icon = fetustex + "00"; + else if (gestationProgress < 0.5f) icon = fetustex + "01"; + else if (gestationProgress < 0.6f) icon = fetustex + "02"; + else if (gestationProgress < 0.7f) icon = fetustex + "03"; + else if (gestationProgress < 0.8f) icon = fetustex + "04"; + else icon = fetustex + "05"; + + Texture2D result = TryGetTwinsIcon(icon, babycount); + + if (result == null) result = ContentFinder.Get((icon), true); + return result; + } + + public static Texture2D TryGetTwinsIcon(string path, int babycount) + { + for (int i = babycount; i > 1; i--) + { + Texture2D result = ContentFinder.Get(path + "_Multiplet_" + i, false); + if (result != null) return result; + } + return null; + } + + public static Texture2D GetCumIcon(this HediffComp_Menstruation comp) + { + string icon = comp.WombTex; + float cumpercent = comp.TotalCumPercent; + if (cumpercent < 0.001f) return ContentFinder.Get("Womb/Empty", true); + else if (cumpercent < 0.01f) icon += "_Cum_00"; + else if (cumpercent < 0.05f) icon += "_Cum_01"; + else if (cumpercent < 0.11f) icon += "_Cum_02"; + else if (cumpercent < 0.17f) icon += "_Cum_03"; + else if (cumpercent < 0.23f) icon += "_Cum_04"; + else if (cumpercent < 0.29f) icon += "_Cum_05"; + else if (cumpercent < 0.35f) icon += "_Cum_06"; + else if (cumpercent < 0.41f) icon += "_Cum_07"; + else if (cumpercent < 0.47f) icon += "_Cum_08"; + else if (cumpercent < 0.53f) icon += "_Cum_09"; + else if (cumpercent < 0.59f) icon += "_Cum_10"; + else if (cumpercent < 0.65f) icon += "_Cum_11"; + else if (cumpercent < 0.71f) icon += "_Cum_12"; + else if (cumpercent < 0.77f) icon += "_Cum_13"; + else if (cumpercent < 0.83f) icon += "_Cum_14"; + else if (cumpercent < 0.89f) icon += "_Cum_15"; + else if (cumpercent < 0.95f) icon += "_Cum_16"; + else icon += "_Cum_17"; + Texture2D cumtex = ContentFinder.Get((icon), true); + return cumtex; + } + public static Texture2D GetInsectEggedIcon(this HediffComp_Menstruation comp) + { + List hediffs = new List(); + comp.Pawn.health.hediffSet.GetHediffs(ref hediffs); + + if (hediffs.NullOrEmpty()) return null; + string path = "Womb/Insect_Egged/"; + if (hediffs.Max(hediff => hediff.eggssize) > 0.3) // The threshold for "large egg" in the debug + { + if (hediffs.Count == 1) return ContentFinder.Get(path + "Womb_Egged_Large", true); + else return ContentFinder.Get(path + "Womb_Egged_ManyMixed", true); + } + Texture2D result = ContentFinder.Get(path + "Womb_Egged_" + hediffs.Count(), false); + if (result == null) result = ContentFinder.Get(path + "Womb_Egged_Many", true); + + return result; + } + public static Texture2D GetWombIcon(this HediffComp_Menstruation comp) + { + Texture2D wombtex = comp.GetInsectEggedIcon(); + if (wombtex != null) return wombtex; + string icon = comp.WombTex; + HediffComp_Menstruation.Stage stage = comp.curStage; + if (stage == HediffComp_Menstruation.Stage.Bleeding) icon += "_Bleeding"; + + wombtex = ContentFinder.Get(icon, true); + + return wombtex; + } + public static Texture2D GetEggIcon(this HediffComp_Menstruation comp, bool includeOvary) + { + switch (comp.CurrentVisibleStage) + { + case HediffComp_Menstruation.Stage.Follicular: + if (!includeOvary) break; + if (comp is HediffComp_InducedOvulator) + { + if (comp.Pawn.jobs.curDriver is JobDriver_Sex job && + job.Sexprops != null && + !job.Sexprops.usedCondom && + (job.Sexprops.sexType == xxx.rjwSextype.Vaginal || job.Sexprops.sexType == xxx.rjwSextype.DoublePenetration)) + return ContentFinder.Get("Ovaries/Ovary_01", true); + else break; + } + if (comp.curStageHrs > comp.CurStageIntervalHours - 30) // Approximate time for ovulation to occur + return ContentFinder.Get("Ovaries/Ovary_01", true); + else break; + case HediffComp_Menstruation.Stage.Ovulatory: + if (!includeOvary) break; + return ContentFinder.Get("Ovaries/Ovary_02", true); + case HediffComp_Menstruation.Stage.Luteal: + if (!comp.IsEggExist) break; + int fertstage = comp.IsFertilized; + if (fertstage >= 0) + { + if (fertstage <= Configurations.CycleAcceleration) return ContentFinder.Get("Eggs/Egg_Fertilizing02", true); + else if (fertstage <= 18) return ContentFinder.Get("Eggs/Egg_Fertilized00", true); + else if (fertstage <= 54) return ContentFinder.Get("Eggs/Egg_Fertilized01", true); + else return ContentFinder.Get("Eggs/Egg_Fertilized02", true); + } + else if (comp.IsEggFertilizing) + { + if (comp.GetFertilityChance() < 0.5f) + return ContentFinder.Get("Eggs/Egg_Fertilizing00", true); + else + return ContentFinder.Get("Eggs/Egg_Fertilizing01", true); + } + else return ContentFinder.Get("Eggs/Egg", true); + case HediffComp_Menstruation.Stage.Pregnant: + if (comp.Pregnancy is Hediff_MechanoidPregnancy) break; + else if (comp.GetPregnancyProgress() < 0.2f) return ContentFinder.Get("Eggs/Egg_Implanted00", true); + else break; + } + return ContentFinder.Get("Womb/Empty", true); + } + + public static void DrawEggOverlay(this HediffComp_Menstruation comp, Rect wombRect, bool includeOvary) + { + Rect rect = new Rect(wombRect.xMax - wombRect.width / 3, wombRect.y, wombRect.width / 3, wombRect.width / 3); + GUI.color = Color.white; + GUI.DrawTexture(rect, comp.GetEggIcon(includeOvary), ScaleMode.ScaleToFit); + } + + + public static Texture2D GetGenitalIcon(this Pawn pawn, HediffComp_Menstruation comp, bool drawOrigin = false) + { + Hediff hediff = comp?.parent; + if (hediff == null) return ContentFinder.Get("Genitals/Vagina00", true); + //HediffComp_Menstruation comp = hediff.GetMenstruationComp(); + string icon; + float severity; + if (drawOrigin) severity = comp.OriginVagSize; + else severity = hediff.Severity; + if (comp != null) icon = comp.VagTex; + else icon = "Genitals/Vagina"; + + if (severity < 0.20f) icon += "00"; //micro + else if (severity < 0.30f) icon += "01"; //tight + else if (severity < 0.40f) icon += "02"; //tight + else if (severity < 0.47f) icon += "03"; //average + else if (severity < 0.53f) icon += "04"; //average + else if (severity < 0.60f) icon += "05"; //average + else if (severity < 0.70f) icon += "06"; //accomodating + else if (severity < 0.80f) icon += "07"; //accomodating + else if (severity < 0.87f) icon += "08"; //cavernous + else if (severity < 0.94f) icon += "09"; //cavernous + else if (severity < 1.01f) icon += "10"; //cavernous + else icon += "11"; //abyssal + + return ContentFinder.Get((icon), true); + } + + public static Texture2D GetAnalIcon(this Pawn pawn, bool drawOrigin = false) + { + Hediff hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_anusBPR(pawn)).FirstOrDefault(h => VariousDefOf.AllAnuses.Contains(h.def)); + if (hediff == null) hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_anusBPR(pawn)).FirstOrDefault(h => h.def.defName.ToLower().Contains("anus")); + if (hediff == null) return ContentFinder.Get(("Genitals/Anal00"), true); + + string icon; + float severity; + HediffComp_Anus comp = hediff.GetAnusComp(); + if (comp != null) + { + CompProperties_Anus Props = (CompProperties_Anus)comp.props; + icon = Props.analTex ?? "Genitals/Anal"; + if (drawOrigin) severity = comp.OriginAnusSize; + else severity = hediff.Severity; + } + else + { + icon = "Genitals/Anal"; + severity = hediff.Severity; + } + if (severity < 0.20f) icon += "00"; //micro + else if (severity < 0.40f) icon += "01"; //tight + else if (severity < 0.60f) icon += "02"; //average + else if (severity < 0.80f) icon += "03"; //accomodating + else if (severity < 1.01f) icon += "04"; //cavernous + else icon += "05"; //abyssal + + return ContentFinder.Get((icon), true); + } + + public static float GestationHours(this Hediff hediff) + { + if (hediff == null) + { + Log.Error("Tried to get gestation length without a pregnancy."); + return 1f; + } + else if (hediff is Hediff_BasePregnancy rjw_preg) + return (rjw_preg.p_end_tick - rjw_preg.p_start_tick) / GenDate.TicksPerHour; + // TODO: Biotech pregnancy + else return hediff.pawn.def.race.gestationPeriodDays * GenDate.HoursPerDay; + } + + public static float RandomVariabilityPercent(int recursion = 0) + { + // Humans, in days + const float mean = 1.635f; + const float stddev = 0.9138f; + const float lambda = 0.234f; + if (recursion >= 10) return mean / (28 * 2); + + float variability = Rand.Gaussian(mean, stddev) - Mathf.Log(Rand.Value) / lambda; + variability /= 28 * 2; // Convert to percentage + + if (variability < 0 || variability > 0.35f) return RandomVariabilityPercent(recursion + 1); // ~2% chance, about the limit on how far variability can go before things start to break + else return variability; + } + + public static bool IsInEstrus(this Pawn pawn, bool visible = true) + { + if (pawn.Dead) return false; + return pawn.health?.hediffSet?.HasHediff(visible ? VariousDefOf.Hediff_Estrus : VariousDefOf.Hediff_Estrus_Concealed) ?? false; + } + + public static HediffComp_Menstruation.EstrusLevel HighestEstrus(this Pawn pawn) + { + HediffComp_Menstruation.EstrusLevel res = HediffComp_Menstruation.EstrusLevel.None; + + foreach(HediffComp_Menstruation comp in pawn.GetMenstruationComps()) + { + switch (comp.GetEstrusLevel()) + { + case HediffComp_Menstruation.EstrusLevel.None: + break; + case HediffComp_Menstruation.EstrusLevel.Concealed: + res = HediffComp_Menstruation.EstrusLevel.Concealed; + break; + case HediffComp_Menstruation.EstrusLevel.Visible: + return HediffComp_Menstruation.EstrusLevel.Visible; + } + } + + return res; + } + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Hediff_Estrus.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Hediff_Estrus.cs new file mode 100644 index 0000000..6c7f462 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Hediff_Estrus.cs @@ -0,0 +1,79 @@ +using RimWorld; +using System.Collections.Generic; +using System.Linq; +using Verse; + +namespace RJW_Menstruation +{ + public class Hediff_Estrus : HediffWithComps + { + const int checkInterval = GenTicks.TickRareInterval; + private bool shouldRemove = false; + + public override bool ShouldRemove + { + get + { + return shouldRemove || base.ShouldRemove; + } + } + + protected bool IsVisible + { + get + { + return def == VariousDefOf.Hediff_Estrus; + } + } + + public override void PostAdd(DamageInfo? dinfo) + { + base.PostAdd(dinfo); + if (IsVisible) + { + List removals = pawn.health.hediffSet.hediffs.Where(hediff => hediff.def == VariousDefOf.Hediff_Estrus_Concealed).ToList(); + foreach (Hediff concealedEstrus in removals) + { + pawn.health.RemoveHediff(concealedEstrus); + } + } + } + + public override void PostTick() + { + base.PostTick(); + if (!pawn.IsHashIntervalTick(checkInterval)) return; + + if (IsVisible) + { + switch (pawn.HighestEstrus()) + { + case HediffComp_Menstruation.EstrusLevel.None: + shouldRemove = true; + break; + case HediffComp_Menstruation.EstrusLevel.Concealed: + shouldRemove = true; + pawn.health.AddHediff(VariousDefOf.Hediff_Estrus_Concealed); + break; + case HediffComp_Menstruation.EstrusLevel.Visible: + break; + } + } + else + { + // Adding a visible will remove this one, so we don't have to check it here + if (pawn.HighestEstrus() == HediffComp_Menstruation.EstrusLevel.None) shouldRemove = true; + } + } + + public override bool TryMergeWith(Hediff other) + { + if (!(other is Hediff_Estrus otherEstrus)) return false; + + if (this.def == otherEstrus.def) return true; + else if (!this.IsVisible && otherEstrus.IsVisible && !otherEstrus.shouldRemove) return true; // A concealed estrus won't be added if there's a visible + // This is a visible estrus overwriting a concealed. + else return false; // Since this is being added while hediffs are being looped through, it's not safe to remove the concealed yet. Do it in PostAdd. + } + } +} \ No newline at end of file diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs new file mode 100644 index 0000000..8abaf18 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Hediff_MultiplePregnancy.cs @@ -0,0 +1,807 @@ +using RimWorld; +using rjw; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; +using Verse; + +namespace RJW_Menstruation +{ + public class Hediff_MultiplePregnancy : Hediff_BasePregnancy + { + protected Dictionary enzygoticSiblings; // Each pawn and who they split from + + public override void DiscoverPregnancy() + { + PregnancyThought(); + base.DiscoverPregnancy(); + } + + protected void PregnancyThought() + { + if (is_discovered || + !xxx.is_human(pawn) || + pawn.Has(Quirk.Breeder) || + (pawn.relations?.DirectRelations?.Find(x => x.def.Equals(PawnRelationDefOf.Spouse) || + x.def.Equals(PawnRelationDefOf.Fiance))) != null) + return; + if (pawn.Has(Quirk.ImpregnationFetish) || pawn.relations?.DirectRelations?.Find(x => x.def.Equals(PawnRelationDefOf.Lover)) != null) + { + pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.UnwantedPregnancyMild); + } + else + { + pawn.needs.mood.thoughts.memories.TryGainMemory(VariousDefOf.UnwantedPregnancy); + } + } + + public override void Miscarry() + { + this.GetMenstruationCompFromPregnancy().Pregnancy = null; + base.Miscarry(); + } + + public override void GiveBirth() + { + + if (babies.NullOrEmpty()) + { + ModLog.Warning(" no babies (debug?) " + this.GetType().Name); + if (father == null) + { + father = Trytogetfather(ref pawn); + } + Initialize(pawn, father); + } + + foreach (Pawn baby in babies) + { + if (xxx.is_animal(baby)) + { + BestialBirth(baby); + } + else + { + HumanlikeBirth(baby); + } + + baby.ageTracker.AgeChronologicalTicks = 0; + } + + pawn.health.RemoveHediff(this); + HediffComp_Menstruation comp = this.GetMenstruationCompFromPregnancy(); + if(comp != null) comp.Pregnancy = null; + HediffComp_Breast breastcomp = pawn.GetBreastComp(); + if (ModsConfig.BiotechActive && xxx.is_human(pawn) && breastcomp != null) + pawn.health.AddHediff(HediffDefOf.Lactating); + breastcomp?.GaveBirth(); + } + + public string GetBabyInfo() + { + if (babies.NullOrEmpty()) + return "Null"; + + StringBuilder res = new StringBuilder(); + + IEnumerable babiesdistinct = babies.Distinct(new RaceComparer()); + int iteration = 0; + foreach (Pawn baby in babiesdistinct) + { + int num = babies.Where(x => x.def.Equals(baby.def)).Count(); + if (iteration > 0) res.Append(", "); + res.AppendFormat("{0} {1}", num, baby.def.label); + iteration++; + } + res.AppendFormat(" {0}", Translations.Dialog_WombInfo02); + return res.ToString(); + } + + public string GetFatherInfo() + { + if (babies.NullOrEmpty()) + return "Null"; + + StringBuilder res = new StringBuilder(); + res.AppendFormat("{0}: ", Translations.Dialog_WombInfo03); + + if (!is_parent_known && Configurations.InfoDetail != Configurations.DetailLevel.All) + return res.Append(Translations.Dialog_FatherUnknown).ToString(); + + IEnumerable babiesdistinct = babies.Distinct(new FatherComparer(pawn)); + int iteration = 0; + foreach (Pawn baby in babiesdistinct) + { + if (iteration > 0) res.Append(", "); + res.Append(Utility.GetFather(baby, pawn)?.LabelShort ?? Translations.Dialog_FatherUnknown); + iteration++; + } + return res.ToString(); + } + + private void HumanlikeBirth(Pawn baby) + { + Pawn mother = pawn; Pawn father = Utility.GetFather(baby, pawn); + //backup melanin, LastName for when baby reset by other mod on spawn/backstorychange + //var skin_whiteness = baby.story.melanin; + //var last_name = baby.story.birthLastName; + + PawnUtility.TrySpawnHatchedOrBornPawn(baby, mother); + + Need_Sex sex_need = mother.needs?.TryGetNeed(); + if (mother.Faction != null && !(mother.Faction?.IsPlayer ?? false) && sex_need != null) + { + sex_need.CurLevel = 1.0f; + } + if (mother.Faction != null) + { + if (mother.Faction != baby.Faction) + baby.SetFaction(mother.Faction); + } + if (mother.IsSlaveOfColony) + { + if (mother.SlaveFaction != null) + baby.SetFaction(mother.SlaveFaction); + else if (mother.HomeFaction != null) + baby.SetFaction(mother.HomeFaction); + else if (mother.Faction != null) + baby.SetFaction(mother.Faction); + else + baby.SetFaction(Faction.OfPlayer); + baby.guest.SetGuestStatus(Faction.OfPlayer, GuestStatus.Slave); + } + else if (mother.IsPrisonerOfColony) + { + if (mother.HomeFaction != null) + baby.SetFaction(mother.HomeFaction); + baby.guest.SetGuestStatus(Faction.OfPlayer, GuestStatus.Prisoner); + } + + if (xxx.is_human(mother)) TaleRecorder.RecordTale(TaleDefOf.GaveBirth, new object[] { mother, baby }); + + PostBirth(mother, father, baby); + } + + + private void BestialBirth(Pawn baby) + { + Pawn mother = pawn; Pawn father = Utility.GetFather(baby, pawn); + //backup melanin, LastName for when baby reset by other mod on spawn/backstorychange + //var skin_whiteness = baby.story.melanin; + //var last_name = baby.story.birthLastName; + + PawnUtility.TrySpawnHatchedOrBornPawn(baby, mother); + + Need_Sex sex_need = mother.needs?.TryGetNeed(); + if (mother.Faction != null && !(mother.Faction?.IsPlayer ?? false) && sex_need != null) + { + sex_need.CurLevel = 1.0f; + } + if (mother.Faction != null) + { + if (mother.Faction != baby.Faction) + baby.SetFaction(mother.Faction); + } + + Train(baby, mother); + + PostBirth(mother, father, baby); + + //restore melanin, LastName for when baby reset by other mod on spawn/backstorychange + //baby.story.melanin = skin_whiteness; + //baby.story.birthLastName = last_name; + } + + protected void CopyBodyPartProperties(Hediff part, Hediff originalPart) + { + CompHediffBodyPart comp = part.TryGetComp(); + CompHediffBodyPart originalComp = originalPart.TryGetComp(); + + if (comp != null && originalComp != null) + { + // the string properties should be the same between both pawns anyways, besides the name of the owner + part.Severity = originalPart.Severity; + comp.SizeBase = originalComp.SizeBase; + comp.SizeOwner = originalComp.SizeOwner; + comp.EffSize = originalComp.EffSize; + comp.FluidAmmount = originalComp.FluidAmmount; + comp.FluidModifier = originalComp.FluidModifier; + } + + HediffComp_Menstruation originalMenstruationComp = originalPart.GetMenstruationCompFromVagina(); + if (originalMenstruationComp != null) + { + part.GetMenstruationCompFromVagina()?.CopyCycleProperties(originalMenstruationComp); + } + HediffComp_Breast originalBreastComp = originalPart.GetBreastComp(); + if (originalBreastComp != null) + { + part.GetBreastComp()?.CopyBreastProperties(originalBreastComp); + } + } + + protected void CopyBodyPartRecord(Pawn baby, Pawn original, BodyPartRecord babyBPR, BodyPartRecord originalBPR) + { + if (babyBPR == null || originalBPR == null) return; + + RemoveBabyParts(baby, Genital_Helper.get_PartsHediffList(baby, babyBPR)); + foreach (Hediff originalPart in Genital_Helper.get_PartsHediffList(original, originalBPR)) + { + Hediff part = SexPartAdder.MakePart(originalPart.def, baby, babyBPR); + CopyBodyPartProperties(part, originalPart); + baby.health.AddHediff(part, babyBPR); + } + } + + // Baby is the sibling to be changed, original is the first of the set and the one to copy to the rest. + public virtual void ProcessIdenticalSibling(Pawn baby, Pawn original) + { + // They'll be the same pawnkind, which lets us make a lot of useful assumptions + // However, some RNG might still be involved in genital generation (e.g. futas), so the easiest method is to clear out and re-generate + // A bit wasteful since Hediff_BasePregnancy.PostBirth already redid the genitals + CopyBodyPartRecord(baby, original, Genital_Helper.get_genitalsBPR(baby), Genital_Helper.get_genitalsBPR(original)); + CopyBodyPartRecord(baby, original, Genital_Helper.get_breastsBPR(baby), Genital_Helper.get_breastsBPR(original)); + CopyBodyPartRecord(baby, original, Genital_Helper.get_uddersBPR(baby), Genital_Helper.get_uddersBPR(original)); + CopyBodyPartRecord(baby, original, Genital_Helper.get_anusBPR(baby), Genital_Helper.get_anusBPR(original)); + if (baby.IsHAR()) + HARCompatibility.CopyHARPropertiesPostBirth(baby, original); + } + + public override void PostBirth(Pawn mother, Pawn father, Pawn baby) + { + base.PostBirth(mother, father, baby); + // Has to happen on birth since RJW redoes the genitals at birth + if (!enzygoticSiblings.NullOrEmpty() && enzygoticSiblings.TryGetValue(baby, out Pawn original) && baby != original) + ProcessIdenticalSibling(baby, original); + } + + // From RJW's trait code + protected List GetInheritableTraits(Pawn mother, Pawn father) + { + List traitpool = new List(); + List momtraits = new List(); + List poptraits = new List(); + List traits_to_inherit = new List(); + float max_num_momtraits_inherited = RJWPregnancySettings.max_num_momtraits_inherited; + float max_num_poptraits_inherited = RJWPregnancySettings.max_num_poptraits_inherited; + float max_num_traits_inherited = max_num_momtraits_inherited + max_num_poptraits_inherited; + int i = 1; + int j = 1; + if (xxx.has_traits(mother) && mother.RaceProps.Humanlike) + { + foreach (Trait momtrait in mother.story.traits.allTraits) + { + if (!non_genetic_traits.Contains(momtrait.def.defName) && !momtrait.ScenForced) + momtraits.Add(momtrait); + } + } + if (father != null && xxx.has_traits(father) && father.RaceProps.Humanlike) + { + foreach (Trait poptrait in father.story.traits.allTraits) + { + if (!non_genetic_traits.Contains(poptrait.def.defName) && !poptrait.ScenForced) + poptraits.Add(poptrait); + } + } + int rand_trait_index; + if (!momtraits.NullOrEmpty()) + { + i = 1; + while (momtraits.Count > 0 && i <= max_num_momtraits_inherited) + { + rand_trait_index = Rand.Range(0, momtraits.Count); + traits_to_inherit.Add(momtraits[rand_trait_index]); + momtraits.RemoveAt(rand_trait_index); + } + } + if (!poptraits.NullOrEmpty()) + { + j = 1; + while (poptraits.Count > 0 && j <= max_num_poptraits_inherited) + { + rand_trait_index = Rand.Range(0, poptraits.Count); + traits_to_inherit.Add(poptraits[rand_trait_index]); + poptraits.RemoveAt(rand_trait_index); + } + } + + if (poptraits.NullOrEmpty() || momtraits.NullOrEmpty()) + { + foreach (Trait traits in traits_to_inherit) + { + traitpool.Add(traits); + } + } + else + { + if (traits_to_inherit.Count() != max_num_traits_inherited) + { + if (momtraits.Count != 0 && i != max_num_momtraits_inherited) + { + while (poptraits != null && momtraits.Count() > 0 && i <= max_num_momtraits_inherited) + { + rand_trait_index = Rand.Range(0, momtraits.Count); + if (!traits_to_inherit.Contains(momtraits[rand_trait_index])) + { + traits_to_inherit.Add(momtraits[rand_trait_index]); + } + momtraits.RemoveAt(rand_trait_index); + } + } + if (poptraits != null && poptraits.Count != 0 && j != max_num_poptraits_inherited) + { + while (poptraits.Count > 0 && i < max_num_poptraits_inherited) + { + rand_trait_index = Rand.Range(0, poptraits.Count); + if (!traits_to_inherit.Contains(poptraits[rand_trait_index])) + { + traits_to_inherit.Add(poptraits[rand_trait_index]); + } + poptraits.RemoveAt(rand_trait_index); + } + } + } + foreach (Trait traits in traits_to_inherit) + { + traitpool.Add(traits); + } + } + return traitpool; + } + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Collections.Look(ref enzygoticSiblings, "enzygoticSiblings", keyLookMode: LookMode.Reference, valueLookMode: LookMode.Reference); + } + + protected override void GenerateBabies() + { + AddNewBaby(pawn, father); + } + + protected void Train(Pawn baby, Pawn mother) + { + if (xxx.is_human(baby) || baby.Faction != Faction.OfPlayer) return; + + if (xxx.is_human(mother) && baby.Faction == Faction.OfPlayer && baby.training.CanAssignToTrain(TrainableDefOf.Obedience, out _).Accepted) + { + baby.training.Train(TrainableDefOf.Obedience, mother); + } + if (xxx.is_human(mother) && baby.Faction == Faction.OfPlayer && baby.training.CanAssignToTrain(TrainableDefOf.Tameness, out _).Accepted) + { + baby.training.Train(TrainableDefOf.Tameness, mother); + } + } + + + public bool AddNewBaby(Pawn mother, Pawn father) + { + //float melanin; + string lastname; + if (xxx.is_human(mother)) + { + if (xxx.is_human(father)) + { + //melanin = ChildRelationUtility.GetRandomChildSkinColor(father.story?.melanin ?? 0f, mother.story?.melanin ?? 0f); + //melanin = (mother.story?.melanin ?? 0f + father.story?.melanin ?? 0f) / 2; + } + else + { + //melanin = mother.story?.melanin ?? 0f; + } + lastname = NameTriple.FromString(mother.Name.ToStringFull).Last; + } + else if (xxx.is_human(father)) + { + //melanin = father.story?.melanin ?? 0f; + lastname = NameTriple.FromString(father.Name.ToStringFull).Last; + } + else + { + //melanin = Rand.Range(0, 1.0f); + lastname = ""; + } + + PawnGenerationRequest request = new PawnGenerationRequest( + developmentalStages: DevelopmentalStage.Newborn, + allowDowned: true, + faction: mother.Faction, + canGeneratePawnRelations: false, + forceGenerateNewPawn: true, + colonistRelationChanceFactor: 0, + allowFood: false, + allowAddictions: false, + relationWithExtraPawnChanceFactor: 0, + fixedLastName: lastname, + kind: BabyPawnKindDecider(mother, father), + //fixedIdeo: mother.Ideo, + forbidAnyTitle: true, + forceNoBackstory: true, + forcedEndogenes: PregnancyUtility.GetInheritedGenes(father, mother) + ); + + int division = 1; + Pawn firstbaby = null; + //string firstheadpath = null; + int traitSeed = Rand.Int; + List parentTraits = GetInheritableTraits(mother, father); + while (Rand.Chance(Configurations.EnzygoticTwinsChance) && division < Configurations.MaxEnzygoticTwins) division++; + for (int i = 0; i < division; i++) + { + Pawn baby = GenerateBaby(request, mother, father, parentTraits, traitSeed); + if (baby == null) break; + if (division > 1) + { + if (i == 0) + { + firstbaby = baby; + request.FixedGender = baby.gender; + request.ForcedEndogenes = baby.genes?.Endogenes.Select(gene => gene.def).ToList(); + } + else + { + enzygoticSiblings?.Add(baby, firstbaby); + + if (baby.story != null) + { + baby.story.headType = firstbaby.story.headType; + baby.story.hairDef = firstbaby.story.hairDef; + baby.story.bodyType = firstbaby.story.bodyType; + } + + if (baby.IsHAR()) + HARCompatibility.CopyHARProperties(baby, firstbaby); + //if (Configurations.AnimalGeneticsActivated) + //AnimalGeneticsCompatibility.CopyGenes(baby, firstbaby); + } + } + babies.Add(baby); + } + + return true; + + } + + public Pawn GenerateBaby(PawnGenerationRequest request, Pawn mother, Pawn father, List parentTraits, int traitSeed) + { + //if (Configurations.AnimalGeneticsActivated) AnimalGeneticsCompatibility.PreConception(mother, father); + Pawn baby = PawnGenerator.GeneratePawn(request); + //if (Configurations.AnimalGeneticsActivated) AnimalGeneticsCompatibility.PostConception(); + if (baby == null) + { + Log.Error("Baby not generated. Request: " + request.ToString()); + return null; + } + if (xxx.is_human(baby) || (baby.relations != null && !RJWSettings.Disable_bestiality_pregnancy_relations)) + { + baby.SetMother(mother); + if (mother != father) + { + if (father.gender != Gender.Female) baby.SetFather(father); + else baby.relations.AddDirectRelation(PawnRelationDefOf.Parent, father); + } + } + if (xxx.is_human(baby)) + { + // Ensure the same inherited traits are chosen each run + // Has to happen right here so GeneratePawn up there still gets unique results + Rand.PushState(traitSeed); // With a seed just to make sure that fraternal twins *don't* get trait-duped + UpdateTraits(baby, parentTraits); + Rand.PopState(); + } + return baby; + } + + /// + /// Decide pawnkind from mother and father + /// Come from RJW + /// + /// + /// + /// + public PawnKindDef BabyPawnKindDecider(Pawn mother, Pawn father) + { + PawnKindDef motherKindDef = Utility.GetRacesPawnKind(mother); + PawnKindDef fatherKindDef = Utility.GetRacesPawnKind(father); + + PawnKindDef spawn_kind_def = motherKindDef; + + int flag = 0; + if (xxx.is_human(mother)) flag += 2; + if (xxx.is_human(father)) flag += 1; + //Mother - Father = Flag + //Human - Human = 3 + //Human - Animal = 2 + //Animal - Human = 1 + //Animal - Animal = 0 + + switch (flag) + { + case 3: + if (!Rand.Chance(RJWPregnancySettings.humanlike_DNA_from_mother)) spawn_kind_def = fatherKindDef; + break; + case 2: + if (RJWPregnancySettings.bestiality_DNA_inheritance == 0f) spawn_kind_def = fatherKindDef; + else if (!Rand.Chance(RJWPregnancySettings.bestial_DNA_from_mother)) spawn_kind_def = fatherKindDef; + break; + case 1: + if (RJWPregnancySettings.bestiality_DNA_inheritance == 1f) spawn_kind_def = fatherKindDef; + else if (!Rand.Chance(RJWPregnancySettings.bestial_DNA_from_mother)) spawn_kind_def = fatherKindDef; + break; + case 0: + if (!Rand.Chance(RJWPregnancySettings.bestial_DNA_from_mother)) spawn_kind_def = fatherKindDef; + break; + } + + bool IsAndroidmother = AndroidsCompatibility.IsAndroid(mother); + bool IsAndroidfather = AndroidsCompatibility.IsAndroid(father); + if (IsAndroidmother && !IsAndroidfather) + { + spawn_kind_def = fatherKindDef; + } + else if (!IsAndroidmother && IsAndroidfather) + { + spawn_kind_def = motherKindDef; + } + + string MotherRaceName = ""; + string FatherRaceName = ""; + MotherRaceName = motherKindDef?.race?.defName; + PawnKindDef non_hybrid_kind_def = spawn_kind_def; + if (father != null) + FatherRaceName = fatherKindDef?.race?.defName; + + + if (FatherRaceName != "" && Configurations.UseHybridExtention) + { + spawn_kind_def = GetHybrid(father, mother); + //Log.Message("pawnkind: " + spawn_kind_def?.defName); + } + + if (MotherRaceName != FatherRaceName && FatherRaceName != "") + { + if (!Configurations.UseHybridExtention || spawn_kind_def == null) + { + spawn_kind_def = non_hybrid_kind_def; + IEnumerable groups = DefDatabase.AllDefs.Where(x => !(x.hybridRaceParents.NullOrEmpty() || x.hybridChildKindDef.NullOrEmpty())); + + + //ModLog.Message(" found custom RaceGroupDefs " + groups.Count()); + foreach (RaceGroupDef t in groups) + { + if ((t.hybridRaceParents.Contains(MotherRaceName) && t.hybridRaceParents.Contains(FatherRaceName)) + || (t.hybridRaceParents.Contains("Any") && (t.hybridRaceParents.Contains(MotherRaceName) || t.hybridRaceParents.Contains(FatherRaceName)))) + { + //ModLog.Message(" has hybridRaceParents"); + if (t.hybridChildKindDef.Contains("MotherKindDef")) + spawn_kind_def = motherKindDef; + else if (t.hybridChildKindDef.Contains("FatherKindDef") && father != null) + spawn_kind_def = fatherKindDef; + else + { + //ModLog.Message(" trying hybridChildKindDef " + t.defName); + List child_kind_def_list = new List(); + child_kind_def_list.AddRange(DefDatabase.AllDefs.Where(x => t.hybridChildKindDef.Contains(x.defName))); + + //ModLog.Message(" found custom hybridChildKindDefs " + t.hybridChildKindDef.Count); + if (!child_kind_def_list.NullOrEmpty()) + spawn_kind_def = child_kind_def_list.RandomElement(); + } + } + } + } + + } + else if (!Configurations.UseHybridExtention || spawn_kind_def == null) + { + spawn_kind_def = mother.RaceProps?.AnyPawnKind ?? motherKindDef; + } + + if (spawn_kind_def.defName.Contains("Nymph")) + { + //child is nymph, try to find other PawnKindDef + List spawn_kind_def_list = new List(); + spawn_kind_def_list.AddRange(DefDatabase.AllDefs.Where(x => x.race == spawn_kind_def.race && !x.defName.Contains("Nymph"))); + //no other PawnKindDef found try mother + if (spawn_kind_def_list.NullOrEmpty()) + spawn_kind_def_list.AddRange(DefDatabase.AllDefs.Where(x => x.race == motherKindDef.race && !x.defName.Contains("Nymph"))); + //no other PawnKindDef found try father + if (spawn_kind_def_list.NullOrEmpty() && father != null) + spawn_kind_def_list.AddRange(DefDatabase.AllDefs.Where(x => x.race == fatherKindDef.race && !x.defName.Contains("Nymph"))); + //no other PawnKindDef found fallback to generic colonist + if (spawn_kind_def_list.NullOrEmpty()) + spawn_kind_def = PawnKindDefOf.Colonist; + + if (!spawn_kind_def_list.NullOrEmpty()) spawn_kind_def = spawn_kind_def_list.RandomElement(); + } + + return spawn_kind_def; + + } + + public PawnKindDef GetHybrid(Pawn first, Pawn second) + { + PawnKindDef res = null; + Pawn opposite = second; + HybridInformations info = null; + + + if (!Configurations.HybridOverride.NullOrEmpty()) + { + info = Configurations.HybridOverride.FirstOrDefault(x => x.DefName == first.def?.defName && (x.hybridExtension?.Exists(y => y.DefName == second.def?.defName) ?? false)); + if (info == null) + { + info = Configurations.HybridOverride.FirstOrDefault(x => x.DefName == second.def?.defName && (x.hybridExtension?.Exists(y => y.DefName == first.def?.defName) ?? false)); + opposite = first; + } + } + + if (info != null) + { + res = info.GetHybridWith(opposite.def.defName) ?? null; + } + if (res != null) return res; + + + PawnDNAModExtension dna; + dna = first.def.GetModExtension(); + if (dna != null) + { + res = dna.GetHybridWith(second.def.defName) ?? null; + } + else + { + dna = second.def.GetModExtension(); + if (dna != null) + { + res = dna.GetHybridWith(first.def.defName) ?? null; + } + } + return res; + } + + /// + /// Copy from RJW + /// + /// + /// + /// + public void UpdateTraits(Pawn pawn, List parentTraits) + { + if (pawn?.story?.traits == null) + { + return; + } + + int traitLimit = pawn.story.traits.allTraits.Count; + + //Personal pool + List personalTraitPool = new List(pawn.story.traits.allTraits); + //Parents + List parentTraitPool = new List(parentTraits); + parentTraitPool.RemoveAll(x => x.ScenForced); + int numberInherited; + if (parentTraitPool != null) + numberInherited = System.Math.Min(parentTraitPool.Count(), Rand.RangeInclusive(0, 2)); // Not 3; give a better chance for a natural trait to appear + else + numberInherited = 0; + + //Game suggested traits. + IEnumerable forcedTraits = personalTraitPool + .Where(x => x.ScenForced) + .Distinct(new TraitComparer(ignoreDegree: true)); // result can be a mess, because game allows this mess to be created in scenario editor + + List selectedTraits = new List(); + TraitComparer comparer = new TraitComparer(); // trait comparision implementation, because without game compares traits *by reference*, makeing them all unique. + selectedTraits.AddRange(forcedTraits); // enforcing scenario forced traits + for (int i = 0; i < numberInherited; i++) // add parent traits first + { + int index = Rand.Range(0, parentTraitPool.Count); + Trait trait = parentTraitPool[index]; + parentTraitPool.RemoveAt(index); + if (!selectedTraits.Any(x => comparer.Equals(x, trait) || + x.def.ConflictsWith(trait))) + selectedTraits.Add(new Trait(trait.def, trait.Degree, false)); + } + + while (selectedTraits.Count < traitLimit && personalTraitPool.Count > 0) + { + int index = Rand.Range(0, personalTraitPool.Count); // getting trait and removing from the pull + Trait trait = personalTraitPool[index]; + personalTraitPool.RemoveAt(index); + + if (!selectedTraits.Any(x => comparer.Equals(x, trait) || // skipping traits conflicting with already added + x.def.ConflictsWith(trait))) + selectedTraits.Add(new Trait(trait.def, trait.Degree, false)); + + } + + pawn.story.traits.allTraits = selectedTraits; + } + + public override void Initialize(Pawn mother, Pawn dad) + { + enzygoticSiblings = new Dictionary(); + base.Initialize(mother, dad); + } + + public string DueDate() + { + if (pawn.Tile == -1) return ""; + return GenDate.DateFullStringWithHourAt(GenDate.TickGameToAbs((int)p_end_tick), Find.WorldGrid.LongLatOf(pawn.Tile)); + } + + public override bool TryMergeWith(Hediff other) + { + return false; + } + } + + /// + /// Copy from RJW + /// + public class TraitComparer : IEqualityComparer + { + readonly bool ignoreForced; + readonly bool ignoreDegree; + + public TraitComparer(bool ignoreDegree = false, bool ignoreForced = true) + { + this.ignoreDegree = ignoreDegree; + this.ignoreForced = ignoreForced; + } + + public bool Equals(Trait x, Trait y) + { + return + x.def == y.def && + (ignoreDegree || (x.Degree == y.Degree)) && + (ignoreForced || (x.ScenForced == y.ScenForced)); + } + + public int GetHashCode(Trait obj) + { + return + (obj.def.GetHashCode() << 5) + + (ignoreDegree ? 0 : obj.Degree) + + ((ignoreForced || obj.ScenForced) ? 0 : 0x10); + } + } + + public class RaceComparer : IEqualityComparer + { + public bool Equals(Pawn x, Pawn y) + { + return x.def.Equals(y.def); + } + + public int GetHashCode(Pawn obj) + { + return obj.def.GetHashCode(); + } + } + + public class FatherComparer : IEqualityComparer + { + readonly Pawn mother; + + public FatherComparer(Pawn mother) + { + this.mother = mother; + } + + public bool Equals(Pawn x, Pawn y) + { + if (Utility.GetFather(x, mother) == null && Utility.GetFather(y, mother) == null) return true; + return Utility.GetFather(x, mother)?.Label.Equals(Utility.GetFather(y, mother)?.Label) ?? false; + } + + public int GetHashCode(Pawn obj) + { + return obj.def.GetHashCode(); + } + } + +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/IngestionOutcomeDoers.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/IngestionOutcomeDoers.cs new file mode 100644 index 0000000..0ebf299 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/IngestionOutcomeDoers.cs @@ -0,0 +1,19 @@ +using RimWorld; +using Verse; + +namespace RJW_Menstruation +{ + public class IngestionOutcomeDoer_GiveHediff_StackCount : IngestionOutcomeDoer_GiveHediff + { + protected override void DoIngestionOutcomeSpecial(Pawn pawn, Thing ingested) + { + Hediff hediff = HediffMaker.MakeHediff(hediffDef, pawn); + float effect = ((!(severity > 0f)) ? hediffDef.initialSeverity : severity) * ingested.stackCount; + AddictionUtility.ModifyChemicalEffectForToleranceAndBodySize(pawn, toleranceChemical, ref effect); + hediff.Severity = effect; + pawn.health.AddHediff(hediff); + } + + + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/JobDrivers.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/JobDrivers.cs new file mode 100644 index 0000000..99cae05 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/JobDrivers.cs @@ -0,0 +1,125 @@ +using RimWorld; +using System.Collections.Generic; +using System.Linq; +using Verse; +using Verse.AI; + +namespace RJW_Menstruation +{ + public class JobDriver_VaginaWashing : JobDriver + { + const int excretingTime = 300;//ticks - 120 = 2 real seconds, 3 in-game minutes + + public override bool TryMakePreToilReservations(bool errorOnFailed) + { + return pawn.Reserve(pawn, job, 1, -1, null, errorOnFailed); + } + + protected override IEnumerable MakeNewToils() + { + List comps = pawn.GetMenstruationComps().ToList(); + this.FailOn(delegate + { + return comps.All(comp => comp.TotalCumPercent < 0.001); + }); + Toil excreting = Toils_General.Wait(excretingTime, TargetIndex.None);//duration of + + excreting.WithProgressBarToilDelay(TargetIndex.A); + yield return excreting; + yield return new Toil() + { + initAction = delegate () + { + foreach (HediffComp_Menstruation comp in comps) + comp.CumOut(null, 0.5f); + if (comps.Any(comp => comp.TotalCumPercent > 0.001)) JumpToToil(excreting); + } + }; + //yield return excreting; + yield break; + } + } + + public class JobDriver_MilkSelf : JobDriver + { + protected float progress = 0; + protected float MilkingTime + { + get + { + return 250f * Fullness + 50f; + } + } + protected virtual float Fullness + { + get + { + return comp?.Fullness ?? 0; + } + } + + private CompMilkable comp; + + public override bool TryMakePreToilReservations(bool errorOnFailed) + { + return pawn.Reserve(pawn, job, 1, -1, null, errorOnFailed); + } + + protected virtual void PreMakeNewToils() + { + comp = pawn.GetComp(); + } + + protected override IEnumerable MakeNewToils() + { + PreMakeNewToils(); + this.FailOnDespawnedNullOrForbidden(TargetIndex.A); + this.FailOnNotCasualInterruptible(TargetIndex.A); + Toil milking = new Toil + { + initAction = delegate () + { + pawn.pather.StopDead(); + }, + tickAction = MilkingTick + }; + milking.AddFinishAction(Finish); + milking.defaultCompleteMode = ToilCompleteMode.Never; + milking.WithProgressBar(TargetIndex.A, () => progress / MilkingTime); + yield return milking; + yield break; + } + + protected void MilkingTick() + { + progress += pawn.GetStatValue(StatDefOf.AnimalGatherSpeed); + if (progress > MilkingTime) + { + Gathered(); + pawn.jobs.EndCurrentJob(JobCondition.Succeeded); + } + PostTickAction(); + } + + protected virtual void Gathered() + { + pawn.GetComp().Gathered(pawn); + } + + protected virtual void Finish() + { + if (pawn.CurJobDef == JobDefOf.Wait_MaintainPosture) + { + pawn.jobs.EndCurrentJob(JobCondition.InterruptForced); + } + } + + protected virtual void PostTickAction() + { + } + + + } + + +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/GC_Patch.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/GC_Patch.cs new file mode 100644 index 0000000..79e7be5 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/GC_Patch.cs @@ -0,0 +1,37 @@ +using HarmonyLib; +using RimWorld; +using RimWorld.Planet; +using System.Collections.Generic; +using System.Linq; +using Verse; + +namespace RJW_Menstruation.Patch +{ + [HarmonyPatch(typeof(WorldPawnGC), "GetCriticalPawnReason")] + public static class GetCriticalPawnReason_Patch + { + readonly public static HashSet cummedPawns = new HashSet(); + + public static void Postfix(ref string __result, Pawn pawn) + { + if (!__result.NullOrEmpty()) return; + if (cummedPawns.Contains(pawn)) + __result = "Has cum or fertilized egg in a womb"; + } + } + + [HarmonyPatch(typeof(WorldPawnGC), "AccumulatePawnGCData")] + public static class AccumulatePawnGCData_Patch + { + public static void Prefix() + { + GetCriticalPawnReason_Patch.cummedPawns.Clear(); + // foreach(Pawn p in PawnsFinder.All_AliveOrDead) + foreach (Pawn p in PawnsFinder.AllMapsCaravansAndTravelingTransportPods_Alive_OfPlayerFaction.Union(PawnsFinder.AllMapsCaravansAndTravelingTransportPods_Alive_PrisonersOfColony)) + { + foreach (HediffComp_Menstruation comp in p.GetMenstruationComps()) + GetCriticalPawnReason_Patch.cummedPawns.UnionWith(comp.GetCummersAndFertilizers()); + } + } + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/GetGizmos.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/GetGizmos.cs new file mode 100644 index 0000000..e640659 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/GetGizmos.cs @@ -0,0 +1,123 @@ +using HarmonyLib; +using rjw; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; +using Verse; + +namespace RJW_Menstruation +{ + [HarmonyPatch(typeof(Pawn), nameof(Pawn.GetGizmos))] + public class Pawn_GetGizmos + { + public static void Postfix(ref IEnumerable __result, Pawn __instance) + { + if (!__instance.ShowStatus()) + { + return; + } + + if (__instance.ShouldShowWombGizmo()) + { + __result = AddWombGizmos(__instance, __result); + } + } + + private static IEnumerable AddWombGizmos(Pawn __instance, IEnumerable gizmos) + { + foreach (Gizmo gizmo in gizmos) + yield return gizmo; + + foreach (HediffComp_Menstruation comp in __instance.GetMenstruationComps()) + foreach (Gizmo gizmo in GetMenstruationGizmos(__instance, comp)) + yield return gizmo; + } + + public static List GetMenstruationGizmos(Pawn pawn, HediffComp_Menstruation comp) + { + return new List() { CreateGizmo_WombStatus(pawn, comp) }; + } + + + private static Gizmo CreateGizmo_WombStatus(Pawn pawn, HediffComp_Menstruation comp) + { + Texture2D icon, icon_overay; + StringBuilder description = new StringBuilder(); + if (Configurations.Debug) + { + description + .AppendFormat("{0}: {1}\n", comp.curStage, comp.curStageHrs); + if (comp.Pregnancy is Hediff_MultiplePregnancy preg) description + .AppendFormat("due: {0}\n", preg.DueDate()); + description + .AppendFormat("fertcums: {0}\n" + + "ovarypower: {1}\n" + + "eggs: {2}\n", + comp.TotalFertCum, comp.ovarypower, comp.GetNumOfEggs); + } + else description.AppendFormat("{0}\n", comp.GetCurStageLabel); + if (pawn.IsRJWPregnant() || pawn.IsBiotechPregnant()) + { + Hediff hediff = comp.Pregnancy; + if (hediff != null && Utility.ShowFetusImage(hediff)) + { + icon = comp.GetPregnancyIcon(hediff); + float gestationProgress = comp.StageProgress; + if (hediff is Hediff_BasePregnancy || hediff is HediffWithParents) + { + if (gestationProgress < 0.2f) icon_overay = comp.GetCumIcon(); + else icon_overay = ContentFinder.Get(("Womb/Empty"), true); + } + else icon_overay = ContentFinder.Get(("Womb/Empty"), true); + } + else + { + icon = comp.GetWombIcon(); + icon_overay = comp.GetCumIcon(); + } + } + else + { + Hediff hediff = pawn.health.hediffSet.GetFirstHediff(); + if (hediff != null) + { + icon = MenstruationUtility.GetInsectEggedIcon(comp); + } + else + { + icon = comp.GetWombIcon(); + } + icon_overay = comp.GetCumIcon(); + + } + foreach (string s in comp.GetCumsInfo) description.AppendFormat("{0}\n", s); + + Color c = comp.GetCumMixtureColor; + + return new Gizmo_Womb + { + defaultLabel = pawn.LabelShort, + defaultDesc = description.ToString(), + icon = icon, + icon_overay = icon_overay, + shrinkable = Configurations.AllowShrinkIcon, + cumcolor = c, + comp = comp, + //order = 100, + hotKey = comp == pawn.GetFirstMenstruationComp() ? VariousDefOf.OpenStatusWindowKey : null, + groupKey = 0, + action = delegate + { + Dialog_WombStatus.ToggleWindow(pawn, comp); + } + }; + } + } + + + + + + +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Harmony.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Harmony.cs new file mode 100644 index 0000000..d701d49 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Harmony.cs @@ -0,0 +1,31 @@ +using HarmonyLib; +using rjw; +using rjw.Modules.Interactions.Internals.Implementation; +using rjw.Modules.Interactions.Rules.PartKindUsageRules; +using rjw.Modules.Shared.Logs; +using System.Collections.Generic; +using System.Reflection; +using Verse; + +namespace RJW_Menstruation +{ + [StaticConstructorOnStartup] + internal static class First + { + static First() + { + Harmony har = new Harmony("RJW_Menstruation"); + har.PatchAll(Assembly.GetExecutingAssembly()); + + InjectIntoRjwInteractionServices(); + } + private static void InjectIntoRjwInteractionServices() + { + ILog log = LogManager.GetLogger("StaticConstructorOnStartup"); + + List partKindUsageRules = Unprivater.GetProtectedValue>("_partKindUsageRules", typeof(PartPreferenceDetectorService)); + partKindUsageRules.Add(new Interactions.EstrusPartKindUsageRule()); + log.Message("Added 1 rule to PartPreferenceDetectorService._partKindUsageRules"); + } + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Pawn_Patch.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Pawn_Patch.cs new file mode 100644 index 0000000..97cb9c4 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/Pawn_Patch.cs @@ -0,0 +1,166 @@ +using HarmonyLib; +using RimWorld; +using System.Collections.Generic; +using UnityEngine; +using Verse; + +namespace RJW_Menstruation +{ + + [HarmonyPatch(typeof(Pawn), nameof(Pawn.SpawnSetup))] + public class Pawn_Patch + { + public static void Postfix(Pawn __instance) + { + //Log.Message("Initialize on spawnsetup"); + foreach (HediffComp_Menstruation comp in __instance.GetMenstruationComps()) + { + comp.Initialize(); + } + + HediffComp_Breast bcomp = __instance.GetBreastComp(); + if (bcomp != null) + { + bcomp.Initialize(); + } + } + } + + [HarmonyPatch(typeof(FloatMenuMakerMap), "AddHumanlikeOrders")] + public class HumanlikeOrder_Patch + { + public static void Postfix(Vector3 clickPos, Pawn pawn, List opts) + { + IEnumerable selftargets = GenUI.TargetsAt(clickPos, TargetingParameters.ForSelf(pawn)); + + foreach (LocalTargetInfo t in selftargets) + { + if (t.Pawn == pawn && pawn.HasMenstruationComp()) opts.AddDistinct(MakeSelfMenu(pawn, t)); + break; + } + + + + + } + + public static FloatMenuOption MakeSelfMenu(Pawn pawn, LocalTargetInfo target) + { + FloatMenuOption option = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(Translations.FloatMenu_CleanSelf, delegate () + { + pawn.jobs.TryTakeOrderedJob(new Verse.AI.Job(VariousDefOf.VaginaWashing, null, null, target.Cell)); + }, MenuOptionPriority.Low), pawn, target); + + return option; + } + } + + //[HarmonyPatch(typeof(HealthCardUtility), "DrawHediffListing")] + //public class DrawHediffListing_Patch + //{ + // public const float buttonWidth = 80f; + // public const float buttonHeight = 20f; + // + // public static void Postfix(Rect rect, Pawn pawn, bool showBloodLoss) + // { + // if (Configurations.EnableButtonInHT && pawn.HasMenstruationComp()) + // { + // Rect buttonrect = new Rect(rect.xMax - buttonWidth, rect.yMax - buttonHeight, buttonWidth, buttonHeight); + // if (Widgets.ButtonText(buttonrect, "Status")) + // { + // Dialog_WombStatus.ToggleWindow(pawn,pawn.GetMenstruationComp()); + // } + // } + // + // + // } + //} + + [HarmonyPatch(typeof(HealthCardUtility), "DrawHediffRow")] + public class DrawHediffRow_Patch + { + public const float buttonWidth = 50f; + public const float buttonHeight = 20f; + + private static HediffComp_Menstruation GetFirstMenstruation(IEnumerable diffs) + { + foreach (Hediff diff in diffs) + { + HediffComp_Menstruation comp = diff.GetMenstruationCompFromVagina(); + if (comp != null) return comp; + } + return null; + } + + public static void Prefix(Rect rect, Pawn pawn, IEnumerable diffs, ref float curY) + { + if (Configurations.EnableButtonInHT && pawn.ShowStatus()) + { + HediffComp_Menstruation comp = GetFirstMenstruation(diffs); + if (comp != null) + { + Rect buttonrect = new Rect((rect.xMax) / 2 - 5f, curY + 2f, buttonWidth, buttonHeight); + if (Widgets.ButtonText(buttonrect, Translations.Button_HealthTab)) + { + Dialog_WombStatus.ToggleWindow(pawn, comp); + } + } + } + + } + + } + + + //Merged to RJW + //[HarmonyPatch(typeof(PawnColumnWorker_Pregnant), "GetIconFor")] + //public class PawnColumnWorker_Patch_Icon + //{ + // public static void Postfix(Pawn pawn, ref Texture2D __result) + // { + // if (pawn.IsVisiblyPregnant()) __result = ContentFinder.Get("UI/Icons/Animal/Pregnant", true); + // } + // + //} + // + //[HarmonyPatch(typeof(PawnColumnWorker_Pregnant), "GetTooltipText")] + //public class PawnColumnWorker_Patch_Tooltip + //{ + // public static bool Prefix(Pawn pawn, ref string __result) + // { + // float gestationProgress = PregnancyHelper.GetPregnancy(pawn).Severity; + // int num = (int)(pawn.RaceProps.gestationPeriodDays * 60000f); + // int numTicks = (int)(gestationProgress * (float)num); + // __result = "PregnantIconDesc".Translate(numTicks.ToStringTicksToDays("F0"), num.ToStringTicksToDays("F0")); + // return false; + // } + // + //} + // + //[HarmonyPatch(typeof(TransferableUIUtility), "DoExtraAnimalIcons")] + //public class TransferableUIUtility_Patch_Icon + //{ + // //private static readonly Texture2D PregnantIcon = ContentFinder.Get("UI/Icons/Animal/Pregnant", true); + // + // + // + // public static void Postfix(Transferable trad, Rect rect, ref float curX, Texture2D ___PregnantIcon) + // { + // Pawn pawn = trad.AnyThing as Pawn; + // if (pawn?.health?.hediffSet != null && pawn.IsVisiblyPregnant()) + // { + // Rect rect3 = new Rect(curX - 24f, (rect.height - 24f) / 2f, 24f, 24f); + // curX -= 24f; + // if (Mouse.IsOver(rect3)) + // { + // TooltipHandler.TipRegion(rect3, PawnColumnWorker_Pregnant.GetTooltipText(pawn)); + // } + // GUI.DrawTexture(rect3, ___PregnantIcon); + // } + // } + //} + + + + +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/RJW_Patch.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/RJW_Patch.cs new file mode 100644 index 0000000..18931b3 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Patch/RJW_Patch.cs @@ -0,0 +1,346 @@ +using HarmonyLib; +using rjw; +using rjw.Modules.Interactions.Enums; +using rjw.Modules.Interactions.Objects; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using UnityEngine; +using Verse; + +namespace RJW_Menstruation +{ + + [HarmonyPatch(typeof(PregnancyHelper), nameof(PregnancyHelper.impregnate))] + public static class Impregnate_Patch + { + public static bool Prefix(SexProps props) + { + xxx.rjwSextype sextype = props.sexType; + Pawn pawn = props.pawn; + Pawn partner = props.partner; + + if (sextype != xxx.rjwSextype.Vaginal && sextype != xxx.rjwSextype.DoublePenetration) return true; + + if (partner.IsAnimal() && !Configurations.EnableAnimalCycle) return true; + + if (!InteractionCanCausePregnancy(props)) return false; + + List pawnparts = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn)); + + HediffComp_Menstruation comp; + if (pawn.Has(Quirk.ImpregnationFetish) || partner.Has(Quirk.ImpregnationFetish) || partner.IsInEstrus()) + comp = partner.GetFertileMenstruationComp(); + else comp = partner.GetRandomMenstruationComp(); + if (comp == null) return true; + + if (Genital_Helper.has_penis_fertile(pawn, pawnparts) && PregnancyHelper.CanImpregnate(pawn, partner, sextype)) + { + PregnancyHelper.Doimpregnate(pawn, partner); + return false; + } + else if (Genital_Helper.has_ovipositorM(pawn, pawnparts)) + { + comp.CumIn(pawn, Rand.Range(0.75f, 4.5f) * pawn.BodySize, 1.0f); + } + else comp.CumIn(pawn, pawn.GetCumVolume(pawnparts), 0); + + return true; + } + + public static void Postfix(SexProps props) + { + Pawn pawn = props.partner; + + if (props.sexType != xxx.rjwSextype.MechImplant && pawn.health.hediffSet.GetFirstHediff() == null) return; + + // The existing pregnancies might have been destroyed, so go through see if any new mech pregnancies need to be picked up + foreach (HediffComp_Menstruation comp in pawn.GetMenstruationComps()) + { + _ = comp.Pregnancy; // get_Pregnancy will do any removals + comp.TakeLoosePregnancy(); + } + } + + /// + /// Checks if pregnancy can happen based on the interaction def + /// This is needed for futanari sex, but should work for everyone + /// + /// + /// Interaction can result in pregnancy + private static bool InteractionCanCausePregnancy(SexProps props) + { + InteractionWithExtension interaction = rjw.Modules.Interactions.Helpers.InteractionHelper.GetWithExtension(props.dictionaryKey); + + if (!interaction.HasInteractionTag(InteractionTag.Fertilization)) + return false; + + bool usesPawnsPenis; + bool usesPartnersVagina; + + if (!props.isReceiver) + { + usesPawnsPenis = interaction.DominantHasTag(GenitalTag.CanPenetrate); + usesPartnersVagina = interaction.SubmissiveHasFamily(GenitalFamily.Vagina); + } + else + { + usesPawnsPenis = interaction.SubmissiveHasTag(GenitalTag.CanPenetrate); + usesPartnersVagina = interaction.DominantHasFamily(GenitalFamily.Vagina); + } + + return usesPawnsPenis && usesPartnersVagina; + } + } + + [HarmonyPatch(typeof(PregnancyHelper), nameof(PregnancyHelper.Doimpregnate))] + public static class Doimpregnate_Patch + { + public static bool Prefix(Pawn pawn, Pawn partner) // partner has vagina + { + if (partner.IsAnimal() && !Configurations.EnableAnimalCycle) return true; + HediffComp_Menstruation comp; + if (pawn.Has(Quirk.ImpregnationFetish) || partner.Has(Quirk.ImpregnationFetish) || partner.IsInEstrus()) + comp = partner.GetFertileMenstruationComp(); + else comp = partner.GetRandomMenstruationComp(); + if (comp == null) + { + if (Configurations.Debug) ModLog.Message("used original rjw method: Comp missing"); + return true; + } + else if (AndroidsCompatibility.IsAndroid(pawn) && !AndroidsCompatibility.AndroidPenisFertility(pawn)) + { + comp.CumIn(pawn, pawn.GetCumVolume(), 0); + return false; + } + else comp.CumIn(pawn, pawn.GetCumVolume(), pawn.health.capacities.GetLevel(xxx.reproduction)); + return false; + } + } + + [HarmonyPatch(typeof(PregnancyHelper), nameof(PregnancyHelper.CanImpregnate))] + public static class CanImpregnate_Patch + { + private static bool PregnancyBlocksImpregnation(this Pawn pawn, bool _) + { + if (!Configurations.EnableAnimalCycle && pawn.IsAnimal()) return pawn.IsPregnant(); + else if (pawn.GetMenstruationComps().Any()) return false; + else return pawn.IsPregnant(); + } + private static readonly MethodInfo IsPregnant = AccessTools.Method(typeof(PawnExtensions), nameof(PawnExtensions.IsPregnant), new System.Type[] {typeof(Pawn), typeof(bool)}); + public static IEnumerable Transpiler(IEnumerable instructions) + { + if (IsPregnant == null) throw new System.InvalidOperationException("IsPregnant not found"); + foreach(CodeInstruction instruction in instructions) + { + if (instruction.Calls(IsPregnant)) + yield return CodeInstruction.Call(typeof(CanImpregnate_Patch), nameof(PregnancyBlocksImpregnation)); + else yield return instruction; + } + } + } + + [HarmonyPatch(typeof(Hediff_BasePregnancy), nameof(Hediff_BasePregnancy.PostBirth))] + public static class RJW_Patch_PostBirth + { + public static void Postfix(Hediff_BasePregnancy __instance, Pawn mother, Pawn baby) + { + if (Configurations.EnableBirthVaginaMorph) + { + // The comp still has the pregnancy attached at this point in the process + Hediff vagina = __instance.GetMenstruationCompFromPregnancy()?.parent; + if (vagina == null) vagina = mother.health.hediffSet.hediffs.FirstOrFallback(x => VariousDefOf.AllVaginas.Contains(x.def)); + if (vagina == null) return; + float morph = Mathf.Max(baby.BodySize - Mathf.Pow(vagina.Severity * mother.BodySize, 2), 0f); + vagina.Severity += morph * Configurations.VaginaMorphPower; + } + } + } + + [HarmonyPatch(typeof(Quirk), nameof(Quirk.IsSatisfiedBy))] + public static class IsSatisfiedBy_Patch + { + public static void Postfix(Quirk __instance, ref bool __result, Pawn pawn, Pawn partner) + { + // This is stricter than can_impregnate, so quickly filter out scenarios that are negative anyways. + if (__result == false || __instance != Quirk.ImpregnationFetish) return; + __result = + (PregnancyHelper.CanImpregnate(pawn, partner) && (partner.GetMenstruationComps()?.Any(comp => comp.IsDangerDay) ?? true)) + || + (PregnancyHelper.CanImpregnate(partner, pawn) && (pawn.GetMenstruationComps()?.Any(comp => comp.IsDangerDay) ?? true)); + } + } + + [HarmonyPatch(typeof(Quirk), nameof(Quirk.CountSatisfiedQuirks))] + public static class CountSatisfiedQuirks_Patch + { + public static void Postfix(ref int __result, SexProps props) + { + // Awkward, but it'll have to do + Pawn pawn = props.pawn; + if (__result == 0 || !pawn.Has(Quirk.ImpregnationFetish) || !props.hasPartner()) return; + + // Check if the existing code would have added the count + Pawn partner = props.partner; + if (!(PregnancyHelper.CanImpregnate(pawn, partner, props.sexType) || PregnancyHelper.CanImpregnate(partner, pawn, props.sexType))) return; + else __result--; + + if ( + (PregnancyHelper.CanImpregnate(pawn, partner, props.sexType) && (partner.GetMenstruationComps()?.Any(comp => comp.IsDangerDay) ?? true)) + || + (PregnancyHelper.CanImpregnate(partner, pawn, props.sexType) && (pawn.GetMenstruationComps()?.Any(comp => comp.IsDangerDay) ?? true))) + __result++; + } + } + + [HarmonyPatch(typeof(SexAppraiser), "GetBodyFactor")] + public static class GetBodyFactor_Patch + { + private static float GetNetFertility(Pawn fucker, Pawn fucked) + { + float fert = fucked.health.capacities.GetLevel(xxx.reproduction); + if (fucker.def.defName != fucked.def.defName) + { + if (RJWPregnancySettings.complex_interspecies) + fert *= SexUtility.BodySimilarity(fucker, fucked); + else + fert *= RJWPregnancySettings.interspecies_impregnation_modifier; + } + return fert; + } + public static void Postfix(ref float __result, Pawn fucker, Pawn fucked) + { + if (fucker.IsInEstrus(true) && PregnancyHelper.CanImpregnate(fucked, fucker)) + { + __result *= (1f + GetNetFertility(fucker, fucked) / 4); + } + else if (fucker.IsInEstrus(false) && PregnancyHelper.CanImpregnate(fucked, fucker)) + { + __result *= (1f + GetNetFertility(fucker, fucked) / 40); + } + else if (xxx.is_animal(fucker) && fucked.IsInEstrus(true) && PregnancyHelper.CanImpregnate(fucker, fucked)) + { + __result *= 1.25f; + } + } + } + + [HarmonyPatch(typeof(CasualSex_Helper), nameof(CasualSex_Helper.roll_to_skip))] + public static class Roll_To_Skip_Patch + { + private static float FuckabilityThreshold(Pawn pawn, Pawn partner) + { + return (Configurations.EstrusOverridesHookupSettings && pawn.IsInEstrus() && PregnancyHelper.CanImpregnate(partner, pawn)) + ? Configurations.EstrusFuckabilityToHookup : RJWHookupSettings.MinimumFuckabilityToHookup; + } + + private static readonly FieldInfo MinimumFuckabilityToHookup = AccessTools.Field(typeof(RJWHookupSettings), nameof(RJWHookupSettings.MinimumFuckabilityToHookup)); + public static IEnumerable Transpiler(IEnumerable instructions) + { + if (MinimumFuckabilityToHookup == null) throw new System.InvalidOperationException("MinimumFuckabilityToHookup not found"); + bool first_fuckability = true; + foreach (CodeInstruction instruction in instructions) + { + if (instruction.LoadsField(MinimumFuckabilityToHookup)) + { + // The first load will be for the estrus-haver considering a partner, the second for a pawn considering the estrus-haver + yield return new CodeInstruction(first_fuckability ? OpCodes.Ldarg_0 : OpCodes.Ldarg_1); + yield return new CodeInstruction(first_fuckability ? OpCodes.Ldarg_1 : OpCodes.Ldarg_0); + + yield return CodeInstruction.Call(typeof(Roll_To_Skip_Patch), nameof(FuckabilityThreshold)); + first_fuckability = false; + } + else yield return instruction; + } + } + } + + [HarmonyPatch(typeof(CasualSex_Helper), nameof(CasualSex_Helper.FindBestPartner))] + public static class FindBestPartner_Patch + { + private static float AttractivenessThreshold(Pawn pawn, Pawn partner) + { + return (Configurations.EstrusOverridesHookupSettings && pawn.IsInEstrus() && PregnancyHelper.CanImpregnate(partner, pawn)) + ? Configurations.EstrusAttractivenessToHookup : RJWHookupSettings.MinimumAttractivenessToHookup; + } + private static float RelationshipThreshold(Pawn pawn, Pawn partner) + { + return (Configurations.EstrusOverridesHookupSettings && pawn.IsInEstrus() && PregnancyHelper.CanImpregnate(partner, pawn)) + ? Configurations.EstrusRelationshipToHookup : RJWHookupSettings.MinimumRelationshipToHookup; + } + + private static readonly FieldInfo MinimumAttractivenessToHookup = AccessTools.Field(typeof(RJWHookupSettings), nameof(RJWHookupSettings.MinimumAttractivenessToHookup)); + private static readonly FieldInfo MinimumRelationshipToHookup = AccessTools.Field(typeof(RJWHookupSettings), nameof(RJWHookupSettings.MinimumRelationshipToHookup)); + public static IEnumerable Transpiler(IEnumerable instructions) + { + if (MinimumAttractivenessToHookup == null) throw new System.InvalidOperationException("MinimumAttractivenessToHookup not found"); + if (MinimumRelationshipToHookup == null) throw new System.InvalidOperationException("MinimumRelationshipToHookup not found"); + LocalBuilder pawn_index = null; + // Like in the last one, we switch the arguments around for the second load + bool first_attractiveness = true; + bool first_relationship = true; + foreach (CodeInstruction instruction in instructions) + { + // Get where the compiler decided to index the pawn at + if (pawn_index == null && instruction.opcode == OpCodes.Stloc_S) // the first stloc.s in the IL is the pawn being loaded out of the list + { // a future RJW or compiler update might change this, or maybe another mod's patch + pawn_index = (LocalBuilder)instruction.operand; + yield return instruction; + } + else if (instruction.LoadsField(MinimumAttractivenessToHookup)) + { + if (pawn_index?.LocalType != typeof(Pawn)) + throw new System.InvalidOperationException($"pawn_index is not a Pawn ({pawn_index?.LocalType})"); + + yield return first_attractiveness ? new CodeInstruction(OpCodes.Ldarg_0) : new CodeInstruction(OpCodes.Ldloc_S, pawn_index); + yield return first_attractiveness ? new CodeInstruction(OpCodes.Ldloc_S, pawn_index) : new CodeInstruction(OpCodes.Ldarg_0); + + yield return CodeInstruction.Call(typeof(FindBestPartner_Patch), nameof(AttractivenessThreshold)); + first_attractiveness = false; + } + else if (instruction.LoadsField(MinimumRelationshipToHookup)) + { + if (pawn_index?.LocalType != typeof(Pawn)) + throw new System.InvalidOperationException($"pawn_index is not a Pawn ({pawn_index?.LocalType})"); + + yield return first_relationship ? new CodeInstruction(OpCodes.Ldarg_0) : new CodeInstruction(OpCodes.Ldloc_S, pawn_index); + yield return first_relationship ? new CodeInstruction(OpCodes.Ldloc_S, pawn_index) : new CodeInstruction(OpCodes.Ldarg_0); + + yield return CodeInstruction.Call(typeof(FindBestPartner_Patch), nameof(RelationshipThreshold)); + first_relationship = false; + } + else yield return instruction; + } + } + } + + [HarmonyPatch(typeof(JobDriver_Sex), nameof(JobDriver_Sex.PlayCumSound))] + public static class Orgasm_Patch + { + public static void Postfix(JobDriver_Sex __instance) + { +#if false + Pawn pawn = __instance.pawn; + foreach (HediffComp_Menstruation comp in pawn.GetMenstruationComps()) + { + comp.CumIn(pawn, (comp.parent.Severity / 10) * Rand.Range(0.75f, 1.25f), pawn.Label, -5.0f, VariousDefOf.GirlCumFilth); + } +#endif + } + } + + [HarmonyPatch(typeof(CompHediffBodyPart), nameof(CompHediffBodyPart.updatesize))] + public static class Updatesize_Patch + { + public static void Postfix(CompHediffBodyPart __instance) + { + HediffComp_Breast comp = __instance.parent.GetBreastComp(); + if (comp != null) + { + __instance.parent.Severity += comp.BreastSizeIncreased; + } + + } + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/RJW_Menstruation.csproj b/1.4/source/RJW_Menstruation/RJW_Menstruation/RJW_Menstruation.csproj new file mode 100644 index 0000000..35f0a1c --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/RJW_Menstruation.csproj @@ -0,0 +1,176 @@ + + + + + Debug + AnyCPU + {EED2F3B9-8C20-4194-919E-8D151B29F70B} + Library + RJW_Menstruation + RJW_Menstruation + v4.8 + 512 + true + true + 게시\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + + AnyCPU + true + full + false + ..\..\..\Assemblies\ + DEBUG;TRACE + prompt + 4 + false + + + AnyCPU + pdbonly + true + ..\..\..\Assemblies\ + TRACE + prompt + 4 + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ..\..\..\..\..\..\..\..\workshop\content\294100\839005762\1.4\Assemblies\AlienRace.dll + False + + + ..\..\..\..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll + False + + + ..\..\..\..\..\rjw\1.4\Assemblies\RJW.dll + False + + + + + ..\..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.dll + False + + + ..\..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll + False + + + ..\..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.IMGUIModule.dll + False + + + ..\..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.InputLegacyModule.dll + False + + + ..\..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.InputModule.dll + False + + + ..\..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.TextCoreModule.dll + False + + + ..\..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.TextRenderingModule.dll + False + + + ..\..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.UI.dll + False + + + ..\..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.UIElementsModule.dll + False + + + ..\..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.UIModule.dll + False + + + + + False + Microsoft .NET Framework 4.7.2%28x86 및 x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + + 2.2.2 + runtime + compile; build; native; contentfiles; analyzers; buildtransitive + + + + + changelogs.txt + + + + \ No newline at end of file diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Recipe_Surgery.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Recipe_Surgery.cs new file mode 100644 index 0000000..6473ac4 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Recipe_Surgery.cs @@ -0,0 +1,88 @@ +using RimWorld; +using rjw; +using System.Collections.Generic; +using Verse; + + +namespace RJW_Menstruation +{ + public class Recipe_BreastSurgery : Recipe_Surgery + { + public override IEnumerable GetPartsToApplyOn(Pawn pawn, RecipeDef recipe) + { + BodyPartRecord part = Genital_Helper.get_breastsBPR(pawn) ?? Genital_Helper.get_uddersBPR(pawn); + if (part != null) + { + + if (pawn.GetBreastComp() != null) yield return part; + } + } + + public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List ingredients, Bill bill) + { + HediffComp_Breast breast = pawn.GetBreastComp(); + if (billDoer != null && breast != null) + { + TaleRecorder.RecordTale(TaleDefOf.DidSurgery, new object[] + { + billDoer, + pawn + }); + SurgeryResult(breast); + } + } + + protected virtual void SurgeryResult(HediffComp_Breast breast) + { + } + } + + + public class Recipe_ExpandAreola : Recipe_BreastSurgery + { + protected override void SurgeryResult(HediffComp_Breast breast) + { + breast.AdjustAreolaSizeImmediately(0.2f); + } + } + + public class Recipe_ContractAreola : Recipe_BreastSurgery + { + protected override void SurgeryResult(HediffComp_Breast breast) + { + breast.AdjustAreolaSizeImmediately(-0.2f); + } + } + + public class Recipe_ExpandNipple : Recipe_BreastSurgery + { + protected override void SurgeryResult(HediffComp_Breast breast) + { + breast.AdjustNippleSizeImmediately(0.2f); + } + } + + public class Recipe_ContractNipple : Recipe_BreastSurgery + { + protected override void SurgeryResult(HediffComp_Breast breast) + { + breast.AdjustNippleSizeImmediately(-0.2f); + } + } + + public class Recipe_DarkenNipple : Recipe_BreastSurgery + { + protected override void SurgeryResult(HediffComp_Breast breast) + { + breast.AdjustNippleColorImmediately(0.2f); + } + } + + public class Recipe_LightenNipple : Recipe_BreastSurgery + { + protected override void SurgeryResult(HediffComp_Breast breast) + { + breast.AdjustNippleColorImmediately(-0.2f); + } + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Reflect.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Reflect.cs new file mode 100644 index 0000000..8df18e6 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Reflect.cs @@ -0,0 +1,58 @@ +using System; +using System.Reflection; + +namespace RJW_Menstruation +{ + public static class Reflector + { + public static object GetMemberValue(this Type type, string name) + { + BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; + FieldInfo fieldInfo = type?.GetField(name, flags); + return fieldInfo?.GetValue(null); + } + + public static object GetMemberValue(this object obj, string name) + { + BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + FieldInfo fieldInfo = obj?.GetType().GetField(name, flags); + return fieldInfo?.GetValue(obj); + } + + public static object GetPropertyValue(this Type type, string name) + { + BindingFlags flags = BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + PropertyInfo propertyInfo = type?.GetProperty(name, flags); + return propertyInfo?.GetValue(null); + } + + public static object GetPropertyValue(this object obj, string name) + { + BindingFlags flags = BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + PropertyInfo propertyInfo = obj?.GetType().GetProperty(name, flags); + return propertyInfo?.GetValue(obj); + } + + public static void SetMemberValue(this Type type, string name, object value) + { + BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; + FieldInfo fieldInfo = type?.GetField(name, flags); + if (fieldInfo != null) + { + fieldInfo.SetValue(null, value); + } + } + + public static void SetMemberValue(this object obj, string name, object value) + { + BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + FieldInfo fieldInfo = obj?.GetType().GetField(name, flags); + if (fieldInfo != null) + { + fieldInfo.SetValue(obj, value); + } + } + + + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/StatParts.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/StatParts.cs new file mode 100644 index 0000000..6028377 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/StatParts.cs @@ -0,0 +1,90 @@ +using RimWorld; +using System.Collections.Generic; +using System.Linq; +using Verse; + +namespace RJW_Menstruation +{ + public abstract class StatPart_Menstruation_Effects : StatPart + { + public override void TransformValue(StatRequest req, ref float val) + { + if (req.Thing is Pawn pawn && ApplicableComps(pawn).Any()) + val *= GetFactor(pawn); + } + protected abstract IEnumerable ApplicableComps(Pawn pawn); + + protected IEnumerable AllComps(Pawn pawn) + { + return pawn.GetMenstruationComps(); + } + + protected abstract float GetFactor(Pawn pawn); + } + + public abstract class StatPart_Climacteric_Effects : StatPart_Menstruation_Effects + { + public override string ExplanationPart(StatRequest req) + { + if (req.Thing is Pawn pawn && ApplicableComps(pawn).Any()) + { + return $"{Translations.Stage_Climacteric.CapitalizeFirst()}: x{GetFactor(pawn).ToStringPercent()}"; + } + else return null; + } + + protected override IEnumerable ApplicableComps(Pawn pawn) + { + return pawn.GetMenstruationComps().Where(comp => comp.EggHealth < 1f && comp.EggHealth > 0f); + } + } + + public abstract class StatPart_Menopause_Effects : StatPart_Menstruation_Effects + { + public override string ExplanationPart(StatRequest req) + { + if (req.Thing is Pawn pawn && ApplicableComps(pawn).Any()) + { + return $"{Translations.Stage_Menopause.CapitalizeFirst()}: x{GetFactor(pawn).ToStringPercent()}"; + } + else return null; + } + + protected override IEnumerable ApplicableComps(Pawn pawn) + { + return pawn.GetMenstruationComps().Where(comp => comp.EggHealth <= 0f); + } + } + + public class StatPart_Climacteric_SexFrequency : StatPart_Climacteric_Effects + { + protected override float GetFactor(Pawn pawn) + { + return AllComps(pawn).Average(comp => comp.SexFrequencyModifier); + } + } + + public class StatPart_Climacteric_SexSatisfaction : StatPart_Climacteric_Effects + { + protected override float GetFactor(Pawn pawn) + { + return AllComps(pawn).Average(comp => comp.SexSatisfactionModifier); + } + } + + public class StatPart_Menopause_SexFrequency : StatPart_Menopause_Effects + { + protected override float GetFactor(Pawn pawn) + { + return AllComps(pawn).Average(comp => comp.SexFrequencyModifier); + } + } + + public class StatPart_Menopause_SexSatisfaction : StatPart_Menopause_Effects + { + protected override float GetFactor(Pawn pawn) + { + return AllComps(pawn).Average(comp => comp.SexSatisfactionModifier); + } + } +} \ No newline at end of file diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/TextureCache.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/TextureCache.cs new file mode 100644 index 0000000..b1c3853 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/TextureCache.cs @@ -0,0 +1,110 @@ +using UnityEngine; +using Verse; + +namespace RJW_Menstruation +{ + [StaticConstructorOnStartup] + public static class TextureCache + { + // Milk bars + public static Texture2D MilkTexture + { + get + { + if (milktexturecache == null) milktexturecache = SolidColorMaterials.NewSolidColorTexture(0.992f, 1.0f, 0.960f, 1.0f); + return milktexturecache; + } + } + // Sex drive + public static Texture2D SexDriveTexture + { + get + { + if (sexdrivetexturecache == null) sexdrivetexturecache = SolidColorMaterials.NewSolidColorTexture(0.686f, 0.062f, 0.698f, 1.0f); + return sexdrivetexturecache; + } + } + // Bleeding, vulnerability + public static Texture2D BleedingTexture + { + get + { + if (bleedingtexturecache == null) bleedingtexturecache = SolidColorMaterials.NewSolidColorTexture(0.415f, 0.0f, 0.003f, 1.0f); + return bleedingtexturecache; + } + } + // Pregnant, default, formerly sex ability + public static Texture2D PregnantTexture + { + get + { + if (pregnanttexturecache == null) pregnanttexturecache = SolidColorMaterials.NewSolidColorTexture(0.082f, 0.453f, 0.6f, 1.0f); + return pregnanttexturecache; + } + } + // Recover, count of egg births + public static Texture2D RecoverTexture + { + get + { + if (recovertexturecache == null) recovertexturecache = SolidColorMaterials.NewSolidColorTexture(0.6f, 0.83f, 0.35f, 1.0f); + return recovertexturecache; + } + } + // Follicular, count of humanlike births + public static Texture2D FollicularTexture + { + get + { + if (folliculartexturecache == null) folliculartexturecache = SolidColorMaterials.NewSolidColorTexture(0.878f, 0.674f, 0.411f, 1.0f); + return folliculartexturecache; + } + } + // Count of animal births + public static Texture2D AnimalTexture + { + get + { + if (animaltexturecache == null) animaltexturecache = SolidColorMaterials.NewSolidColorTexture(0.411f, 0.521f, 0.878f, 1.0f); + return animaltexturecache; + } + } + // Luteal, fertility + public static Texture2D LutealTexture + { + get + { + if (lutealtexturecache == null) lutealtexturecache = SolidColorMaterials.NewSolidColorTexture(0.843f, 0.474f, 0.6f, 1.0f); + return lutealtexturecache; + } + } + // Unused, formerly count of whored + public static Texture2D WhoredTexture + { + get + { + if (whoredtexturecache == null) whoredtexturecache = SolidColorMaterials.NewSolidColorTexture(0.7f, 0.7f, 0.0f, 1.0f); + return whoredtexturecache; + } + } + + public static readonly Texture2D FertChanceTex = SolidColorMaterials.NewSolidColorTexture(new Color(1f, 1f, 1f, 0.4f)); + public static readonly Texture2D GatherCum_Bucket = ContentFinder.Get("UI/Icon/ToBucket"); + public static readonly Texture2D GatherCum_Pussy = ContentFinder.Get("UI/Icon/ToPussy"); + + private static Texture2D milktexturecache = SolidColorMaterials.NewSolidColorTexture(0.992f, 1.0f, 0.960f, 1.0f); + private static Texture2D sexdrivetexturecache = SolidColorMaterials.NewSolidColorTexture(0.686f, 0.062f, 0.698f, 1.0f); + private static Texture2D bleedingtexturecache = SolidColorMaterials.NewSolidColorTexture(0.415f, 0.0f, 0.003f, 1.0f); + private static Texture2D pregnanttexturecache = SolidColorMaterials.NewSolidColorTexture(0.082f, 0.453f, 0.6f, 1.0f); + private static Texture2D recovertexturecache = SolidColorMaterials.NewSolidColorTexture(0.6f, 0.83f, 0.35f, 1.0f); + private static Texture2D folliculartexturecache = SolidColorMaterials.NewSolidColorTexture(0.878f, 0.674f, 0.411f, 1.0f); + private static Texture2D animaltexturecache = SolidColorMaterials.NewSolidColorTexture(0.411f, 0.521f, 0.878f, 1.0f); + private static Texture2D lutealtexturecache = SolidColorMaterials.NewSolidColorTexture(0.843f, 0.474f, 0.6f, 1.0f); + private static Texture2D whoredtexturecache = SolidColorMaterials.NewSolidColorTexture(0.7f, 0.7f, 0.0f, 1.0f); + + + + + + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Things.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Things.cs new file mode 100644 index 0000000..e427e0f --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Things.cs @@ -0,0 +1,284 @@ +using RimWorld; +using rjw; +using System.Collections.Generic; +using System.Xml; +using UnityEngine; +using Verse; + +namespace RJW_Menstruation +{ + public class PawnDNAModExtension : DefModExtension + { + public string fetusTexPath; + public ColorInt cumColor; + public Color CumColor => cumColor.ToColor; + public float cumThickness = 0f; + public List hybridExtension; + public List ingestionOutcomeDoers; + + public HybridExtension GetHybridExtension(string race) + { + if (hybridExtension.NullOrEmpty()) return null; + else return hybridExtension.Find(x => x.thingDef.defName.Equals(race)); + } + + public PawnKindDef GetHybridWith(string race) + { + return GetHybridExtension(race)?.ChooseOne() ?? null; + } + } + + public class HybridExtension + { + + public Dictionary hybridInfo = new Dictionary(); + public ThingDef thingDef; + + public HybridExtension() { } + + + public PawnKindDef ChooseOne() + { + + if (hybridInfo.EnumerableNullOrEmpty()) return null; + PawnKindDef res = null; + do + { + string key = hybridInfo.RandomElementByWeight(x => x.Value).Key; + res = DefDatabase.GetNamedSilentFail(key); + if (res == null) res = DefDatabase.GetNamedSilentFail(key)?.race?.AnyPawnKind; + + if (res == null) + { + Log.Warning($"Could not find pawnKind or race {key}, removing hybrid definition"); + hybridInfo.Remove(key); + } + } while (res == null && !hybridInfo.EnumerableNullOrEmpty()); + + return res; + } + + + public void LoadDataFromXmlCustom(XmlNode xmlRoot) + { + DirectXmlCrossRefLoader.RegisterObjectWantsCrossRef(this, "thingDef", xmlRoot.Name); + XmlNodeList childNodes = xmlRoot.ChildNodes; + + if (childNodes.Count >= 1) foreach (XmlNode node in childNodes) + { +#if DEBUG + Log.Message(xmlRoot.Name + "HybridInfo: " + node.Name + " " + node.InnerText); +#endif + hybridInfo.Add(node.Name, ParseHelper.FromString(node.InnerText)); + } + } + } + + public class HybridInformations : IExposable + { + public List hybridExtension = new List(); + + private ThingDef thingDef; + private string thingDefName; + + public string DefName + { + get + { + return thingDefName; + } + } + public bool IsNull + { + get + { + return (thingDefName?.Length ?? 0) < 1; + } + } + public ThingDef GetDef + { + get + { + if (thingDef != null) return thingDef; + else + { + thingDef = DefDatabase.GetNamedSilentFail(thingDefName); + return thingDef; + } + } + } + + public HybridInformations() { } + + public HybridInformations(ThingDef def) + { + thingDef = def; + thingDefName = def.defName; + } + + public HybridExtensionExposable GetHybridExtension(string race) + { + if (hybridExtension.NullOrEmpty()) return null; + else + { + return hybridExtension.Find(x => x.GetDef?.defName?.Equals(race) ?? false); + } + } + + public PawnKindDef GetHybridWith(string race) + { + return GetHybridExtension(race)?.ChooseOne() ?? null; + } + + public void ExposeData() + { + Scribe_Values.Look(ref thingDefName, "thingDefName"); + Scribe_Collections.Look(ref hybridExtension, "hybridExtension", LookMode.Deep, new object[0]); + } + } + + public class HybridExtensionExposable : HybridExtension, IExposable + { + private string thingDefName; + + public string DefName + { + get + { + return thingDefName; + } + } + public bool IsNull + { + get + { + return (thingDefName?.Length ?? 0) < 1; + } + } + public ThingDef GetDef + { + get + { + if (thingDef != null) return thingDef; + else + { + thingDef = DefDatabase.GetNamedSilentFail(thingDefName); + return thingDef; + } + } + } + + public HybridExtensionExposable() { } + + public HybridExtensionExposable(ThingDef def) + { + thingDef = def; + thingDefName = def.defName; + hybridInfo = new Dictionary(); + } + + public void ExposeData() + { + Scribe_Values.Look(ref thingDefName, "thingDefName"); + Scribe_Collections.Look(ref hybridInfo, "hybridInfo", LookMode.Value, LookMode.Value); + + } + } + public class AbsorberModExtension : DefModExtension + { + public bool leakAfterDirty = false; + public bool effectsAfterDirty = false; + public ThingDef dirtyDef = null; + public int minHourstoDirtyEffect = 0; + } + + public class Absorber : Apparel + { + + public float absorbedfluids = 0; + public bool dirty = false; + public int wearhours = 0; + public virtual bool LeakAfterDirty => def.GetModExtension().leakAfterDirty; + public virtual bool EffectAfterDirty => def.GetModExtension().effectsAfterDirty; + public virtual ThingDef DirtyDef => def.GetModExtension().dirtyDef; + public virtual int MinHrstoDirtyEffect => def.GetModExtension().minHourstoDirtyEffect; + + public Color fluidColor = Color.white; + + public virtual void DirtyEffect() { } + + public virtual void WearEffect() + { + absorbedfluids += 0.1f; + if (dirty) wearhours++; + } + + public override Color DrawColorTwo => fluidColor; + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Values.Look(ref absorbedfluids, "absorbedfluids", absorbedfluids, true); + Scribe_Values.Look(ref dirty, "dirty", dirty, true); + Scribe_Values.Look(ref wearhours, "wearhours", wearhours, true); + Scribe_Values.Look(ref fluidColor, "fluidColor", fluidColor, true); + } + + } + + public class Absorber_Tampon : Absorber + { + + public override void WearEffect() + { + if (dirty) wearhours++; + absorbedfluids += 0.5f; + } + + public override void DirtyEffect() + { + if (wearhours > MinHrstoDirtyEffect && Rand.Chance(0.01f) && !Wearer.apparel.IsLocked(this)) + { + Wearer.health.AddHediff(HediffDefOf.WoundInfection, Genital_Helper.get_genitalsBPR(Wearer)); + } + } + + } + + + public class Filth_Colored : Filth + { + + private Color color = Color.white; + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Values.Look(ref color, "color", color, true); + } + + public override Color DrawColor + { + get + { + if (color != Color.white) + { + return color; + } + if (Stuff != null) + { + return def.GetColorForStuff(Stuff); + } + if (def.graphicData != null) + { + return def.graphicData.color; + } + return color; + } + set + { + color = value; + } + } + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Translations.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Translations.cs new file mode 100644 index 0000000..8f0de67 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Translations.cs @@ -0,0 +1,139 @@ +using Verse; + +namespace RJW_Menstruation +{ + public static class Translations + { + public static readonly string Mod_Title = "Mod_Title".Translate(); + public static readonly string Info_noCum = "Info_noCum".Translate(); + public static readonly string Menstrual_Blood = "Menstrual_Blood".Translate(); + public static readonly string Stage_Follicular = "Stage_Follicular".Translate(); + public static readonly string Stage_Ovulatory = "Stage_Ovulatory".Translate(); + public static readonly string Stage_Luteal = "Stage_Luteal".Translate(); + public static readonly string Stage_Bleeding = "Stage_Bleeding".Translate(); + public static readonly string Stage_Pregnant = "Stage_Pregnant".Translate(); + public static readonly string Stage_Recover = "Stage_Recover".Translate(); + public static readonly string Stage_None = "Stage_None".Translate(); + public static readonly string Stage_Climacteric = "Stage_Climacteric".Translate(); + public static readonly string Stage_Menopause = "Stage_Menopause".Translate(); + public static readonly string Stage_Anestrus = "Stage_Anestrus".Translate(); + public static readonly string Stage_Follicular_Desc = "Stage_Follicular_Desc".Translate(); + public static readonly string Stage_Follicular_Induced_Desc = "Stage_Follicular_Induced_Desc".Translate(); + public static readonly string Stage_Ovulatory_Desc = "Stage_Ovulatory_Desc".Translate(); + public static readonly string Stage_Luteal_Desc = "Stage_Luteal_Desc".Translate(); + public static readonly string Stage_Bleeding_Desc = "Stage_Bleeding_Desc".Translate(); + public static readonly string Stage_Pregnant_Desc = "Stage_Pregnant_Desc".Translate(); + public static readonly string Stage_Recover_Desc = "Stage_Recover_Desc".Translate(); + public static readonly string Stage_None_Desc = "Stage_None_Desc".Translate(); + public static readonly string Stage_Menopause_Desc = "Stage_Menopause_Desc".Translate(); + public static readonly string Stage_Climacteric_Desc = "Stage_Climacteric_Desc".Translate(); + public static readonly string Stage_Anestrus_Desc = "Stage_Anestrus_Desc".Translate(); + public static readonly string Button_HealthTab = "Button_HealthTab".Translate(); + public static readonly string Button_MilkTooltip = "Button_MilkTooltip".Translate(); + public static readonly string Dialog_DoCleanWomb_Tooltip = "Dialog_DoCleanWomb_Tooltip".Translate(); + public static readonly string Dialog_DontCleanWomb_Tooltip = "Dialog_DontCleanWomb_Tooltip".Translate(); + public static readonly string Dialog_FatherUnknown = "Dialog_FatherUnknown".Translate(); + + public static readonly string Dialog_WombInfo01 = "Dialog_WombInfo01".Translate(); + public static readonly string Dialog_WombInfo02 = "Dialog_WombInfo02".Translate(); + public static readonly string Dialog_WombInfo03 = "Dialog_WombInfo03".Translate(); + public static readonly string Dialog_WombInfo04 = "Dialog_WombInfo04".Translate(); + public static readonly string Dialog_WombInfo05 = "Dialog_WombInfo05".Translate(); + public static readonly string Dialog_WombInfo06 = "Dialog_WombInfo06".Translate(); + public static readonly string Dialog_WombInfo07 = "Dialog_WombInfo07".Translate(); + public static readonly string Dialog_WombInfo08 = "Dialog_WombInfo08".Translate(); + public static readonly string Dialog_WombInfo09 = "Dialog_WombInfo09".Translate(); + public static readonly string Dialog_WombInfo10 = "Dialog_WombInfo10".Translate(); + + + public static readonly string Option1_Label_1 = "Option1_Label_1".Translate(); + public static readonly string Option1_Label_2 = "Option1_Label_2".Translate(); + public static readonly string Option2_Label = "Option2_Label".Translate(); + public static readonly string Option2_Desc = "Option2_Desc".Translate(); + public static readonly string Option3_Label = "Option3_Label".Translate(); + public static readonly string Option3_Desc = "Option3_Desc".Translate(); + public static readonly string Option4_Label = "Option4_Label".Translate(); + public static readonly string Option4_Desc = "Option4_Desc".Translate(); + public static readonly string Option5_Label = "Option5_Label".Translate(); + public static readonly string Option5_Desc = "Option5_Desc".Translate(); + public static readonly string Option6_Label = "Option6_Label".Translate(); + public static readonly string Option6_Desc = "Option6_Desc".Translate(); + public static readonly string Option7_Label = "Option7_Label".Translate(); + public static readonly string Option7_Desc = "Option7_Desc".Translate(); + public static readonly string Option8_Label = "Option8_Label".Translate(); + public static readonly string Option8_Desc = "Option8_Desc".Translate(); + public static readonly string Option9_Label = "Option9_Label".Translate(); + public static readonly string Option9_Desc = "Option9_Desc".Translate(); + public static readonly string Option10_Label = "Option10_Label".Translate(); + public static readonly string Option10_Desc = "Option10_Desc".Translate(); + public static readonly string Option11_Label = "Option11_Label".Translate(); + public static readonly string Option11_Desc_1 = "Option11_Desc_1".Translate(); + public static readonly string Option11_Desc_2 = "Option11_Desc_2".Translate(); + public static readonly string Option11_Desc_3 = "Option11_Desc_3".Translate(); + public static readonly string Option11_Desc_4 = "Option11_Desc_4".Translate(); + public static readonly string Option12_Label = "Option12_Label".Translate(); + public static readonly string Option12_Desc = "Option12_Desc".Translate(); + public static readonly string Option13_Label = "Option13_Label".Translate(); + public static readonly string Option13_Desc = "Option13_Desc".Translate(); + public static readonly string Option14_Label = "Option14_Label".Translate(); + public static readonly string Option14_Desc = "Option14_Desc".Translate(); + public static readonly string Option15_Label = "Option15_Label".Translate(); + public static readonly string Option15_Desc = "Option15_Desc".Translate(); + public static readonly string Option16_Label = "Option16_Label".Translate(); + public static readonly string Option16_Desc = "Option16_Desc".Translate(); + public static readonly string Option17_Label = "Option17_Label".Translate(); + public static readonly string Option17_Desc = "Option17_Desc".Translate(); + public static readonly string Option18_Label = "Option18_Label".Translate(); + public static readonly string Option18_Desc = "Option18_Desc".Translate(); + public static readonly string Option19_Label_1 = "Option19_Label_1".Translate(); + public static readonly string Option19_Label_2 = "Option19_Label_2".Translate(); + public static readonly string Option19_Desc = "Option19_Desc".Translate(); + public static readonly string Option20_Label_1 = "Option20_Label_1".Translate(); + public static readonly string Option20_Label_2 = "Option20_Label_2".Translate(); + public static readonly string Option20_Label_3 = "Option20_Label_3".Translate(); + public static readonly string Option20_Label_4 = "Option20_Label_4".Translate(); + public static readonly string Option20_Label_5 = "Option20_Label_5".Translate(); + public static readonly string Option21_Label = "Option21_Label".Translate(); + public static readonly string Option21_Desc = "Option21_Desc".Translate(); + public static readonly string Option22_Label = "Option22_Label".Translate(); + public static readonly string Option22_Desc = "Option22_Desc".Translate(); + public static readonly string Option23_Label = "Option23_Label".Translate(); + public static readonly string Option23_Label_1 = "Option23_Label_1".Translate(); + public static readonly string Option23_Label_2 = "Option23_Label_2".Translate(); + public static readonly string Option28_Label = "Option28_Label".Translate(); + public static readonly string Option28_Tooltip = "Option28_Tooltip".Translate(); + public static readonly string Option29_Label = "Option29_Label".Translate(); + public static readonly string Option29_Desc = "Option29_Desc".Translate(); + public static readonly string Option30_Label = "Option30_Label".Translate(); + public static readonly string Option30_Desc = "Option30_Desc".Translate(); + public static readonly string Option31_Label = "Option31_Label".Translate(); + public static readonly string Option31_Desc = "Option31_Desc".Translate(); + public static readonly string Option32_Label = "Option32_Label".Translate(); + public static readonly string Option32_Desc = "Option32_Desc".Translate(); + public static readonly string Option_MaxBreastIncrementFactor_Label = "Option_MaxBreastIncrementFactor_Label".Translate(); + public static readonly string Option_MaxBreastIncrementFactor_Desc = "Option_MaxBreastIncrementFactor_Desc".Translate(); + public static readonly string Option_MaxNippleIncrementFactor_Label = "Option_MaxNippleIncrementFactor_Label".Translate(); + public static readonly string Option_MaxNippleIncrementFactor_Desc = "Option_MaxNippleIncrementFactor_Desc".Translate(); + public static readonly string Option_PermanentNippleChange_Label = "Option_PermanentNippleChange_Label".Translate(); + public static readonly string Option_PermanentNippleChange_Desc = "Option_PermanentNippleChange_Desc".Translate(); + public static readonly string Option_EnableGatherCumGizmo_Label = "Option_EnableGatherCumGizmo_Label".Translate(); + public static readonly string Option_EstrusOverride_Label = "Option_EstrusOverride_Label".Translate(); + public static readonly string Option_EstrusOverride_Desc = "Option_EstrusOverride_Desc".Translate(); + public static readonly string Option_EstrusFuckability_Label = "Option_EstrusFuckability_Label".Translate(); + public static readonly string Option_EstrusAttractability_Label = "Option_EstrusAttractability_Label".Translate(); + public static readonly string Option_EstrusRelationship_Label = "Option_EstrusRelationship_Label".Translate(); + + public static readonly string Button_ResetToDefault = "Button_ResetToDefault".Translate(); + + public static readonly string EstimatedCumLifespan = "EstimatedCumLifespan".Translate(); + public static readonly string EstimatedEggLifespan = "EstimatedEggLifespan".Translate(); + public static string FertilityDesc(string value) => "FertilityDesc".Translate(value); + + public static readonly string Gizmo_GatherCum = "Gizmo_GatherCum".Translate(); + public static readonly string FloatMenu_CleanSelf = "FloatMenu_CleanSelf".Translate(); + + public static readonly string CustomHybrid_List_Title = "CustomHybrid_List_Title".Translate(); + static public string CustomHybrid_Title(string label) { return TranslatorFormattedStringExtensions.Translate("CustomHybrid_Title", label); } + static public string CustomHybrid_Tooltip(string label, string breedee, string baby, string chance) { return TranslatorFormattedStringExtensions.Translate("CustomHybrid_Tooltip", label, breedee, baby, chance); } + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_HybridCustom.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_HybridCustom.cs new file mode 100644 index 0000000..e61af20 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_HybridCustom.cs @@ -0,0 +1,474 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using Verse; +using Verse.Sound; + +namespace RJW_Menstruation +{ + public class Dialog_HybridCustom : Window + { + private static Vector2 scroll; + private const float windowMargin = 20f; + private static readonly List raceList = new List(); + private static readonly List removeList = new List(); + + public Dialog_HybridCustom() + { + BuildRaceList(); + } + + public void BuildRaceList() + { + raceList.Clear(); + if (!VariousDefOf.AllRaces.NullOrEmpty()) + foreach (ThingDef def in VariousDefOf.AllRaces) + { + if (def.race == null || Configurations.IsOverrideExist(def)) continue; + raceList.Add(new FloatMenuOption(def.label, delegate { AddHybridOverride(def); }, def.uiIcon, Color.white)); + } + raceList.SortBy(x => x.Label); + } + + public void AddHybridOverride(ThingDef def) + { + FloatMenuOption option = raceList.FirstOrDefault(x => x.Label.Equals(def?.label)); + if (option == null) return; + raceList.Remove(option); + if (Configurations.HybridOverride.NullOrEmpty()) + { + Configurations.HybridOverride = new List(); + } + Configurations.HybridOverride.Add(new HybridInformations(def)); + Configurations.HybridOverride.SortBy(x => x.GetDef?.label ?? "Undefined"); + + } + + public override Vector2 InitialSize + { + get + { + float width = 480f; + float height = 640f; + return new Vector2(width, height); + } + } + + + public override void DoWindowContents(Rect inRect) + { + soundClose = SoundDefOf.CommsWindow_Close; + //closeOnClickedOutside = true; + absorbInputAroundWindow = false; + forcePause = false; + preventCameraMotion = false; + draggable = true; + //resizeable = true; + + if (Event.current.type == EventType.KeyDown && (Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.Escape)) + { + Event.current.Use(); + } + + Rect windowRect = inRect.ContractedBy(windowMargin); + Rect mainRect = new Rect(windowRect.x, windowRect.y, windowRect.width, windowRect.height); + Rect closeRect = new Rect(windowRect.xMax, 0f, 20f, 20f); + + DoMainContents(mainRect); + + if (Widgets.CloseButtonFor(closeRect)) + { + Close(); + } + } + + public override void PostClose() + { + base.PostClose(); + if (!removeList.NullOrEmpty()) + { + foreach (HybridInformations extension in removeList) + { + Configurations.HybridOverride.Remove(extension); + } + raceList.SortBy(x => x.Label); + } + removeList.Clear(); + } + + protected void DoMainContents(Rect inRect) + { + Rect buttonRect = new Rect(inRect.xMax - 120, 0, 100, 30); + Rect titleRect = new Rect(inRect.x, 0, 200, 30); + Widgets.Label(titleRect, Translations.CustomHybrid_List_Title); + Widgets.DrawLineHorizontal(titleRect.x, titleRect.yMax + 12f, inRect.width); + if (Widgets.ButtonText(buttonRect, "Add")) + { + if (!raceList.NullOrEmpty()) Find.WindowStack.Add(new FloatMenu(raceList)); + } + if (!removeList.NullOrEmpty()) + { + buttonRect.x -= 100; + if (Widgets.ButtonText(buttonRect, "Undo")) + { + HybridInformations element = removeList.Last(); + Configurations.HybridOverride.Add(element); + Configurations.HybridOverride.SortBy(x => x.GetDef?.label ?? "Undefined"); + removeList.Remove(element); + } + + foreach (HybridInformations extension in removeList) + { + Configurations.HybridOverride.Remove(extension); + } + raceList.SortBy(x => x.Label); + } + + + + Rect outRect = new Rect(inRect.x, inRect.y + 30f, inRect.width, inRect.height - 30f); + Rect mainRect = new Rect(inRect.x, inRect.y + 30f, inRect.width - 30f, Math.Max(24f * Configurations.HybridOverride?.Count() ?? 1, 10f)); + Listing_Standard listmain = new Listing_Standard(); + + Widgets.BeginScrollView(outRect, ref scroll, mainRect); + listmain.Begin(mainRect); + if (!Configurations.HybridOverride.NullOrEmpty()) + foreach (HybridInformations extension in Configurations.HybridOverride) + { + if (extension.GetDef != null) DoRow(listmain.GetRect(24f), extension); + } + Widgets.EndScrollView(); + listmain.End(); + + + } + + protected void DoRow(Rect rect, HybridInformations extension) + { + Rect buttonRect = new Rect(rect.xMax - 90f, rect.y, 80f, rect.height); + Widgets.Label(rect, extension.GetDef?.label ?? "Undefined"); + if (Widgets.ButtonText(buttonRect, "Delete")) + { + removeList.Add(extension); + //raceList.Add(new FloatMenuOption(extension.GetDef.label, delegate { AddHybridOverride(extension.GetDef); })); + } + buttonRect.x -= 80f; + if (Widgets.ButtonText(buttonRect, "Edit")) + { + Dialog_EditHybrid.OpenWindow(extension); + } + + + Widgets.DrawHighlightIfMouseover(rect); + } + + + public static void ToggleWindow() + { + Dialog_HybridCustom window = (Dialog_HybridCustom)Find.WindowStack.Windows.FirstOrDefault(x => x.GetType().Equals(typeof(Dialog_HybridCustom))); + if (window != null) + { + Find.WindowStack.TryRemove(typeof(Dialog_HybridCustom), true); + } + else + { + SoundDefOf.CommsWindow_Open.PlayOneShotOnCamera(); + Find.WindowStack.Add(new Dialog_HybridCustom()); + } + + + } + + } + + public class Dialog_EditHybrid : Window + { + private const float windowMargin = 20f; + private const float rowH = 24f; + private HybridInformations info; + private Vector2 scroll; + protected List raceList = new List(); + protected List removeList = new List(); + protected float totalWeight = 0; + + public Dialog_EditHybrid(HybridInformations info) + { + this.info = info; + BuildRaceList(); + } + + + + public override Vector2 InitialSize + { + get + { + float width = 840f; + float height = 640f; + return new Vector2(width, height); + } + } + + + public override void DoWindowContents(Rect inRect) + { + soundClose = SoundDefOf.CommsWindow_Close; + //closeOnClickedOutside = true; + absorbInputAroundWindow = false; + forcePause = false; + preventCameraMotion = false; + draggable = true; + //resizeable = true; + + if (Event.current.type == EventType.KeyDown && (Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.Escape)) + { + Event.current.Use(); + } + + Rect windowRect = inRect.ContractedBy(windowMargin); + Rect mainRect = new Rect(windowRect.x, windowRect.y, windowRect.width, windowRect.height); + Rect closeRect = new Rect(windowRect.xMax, 0f, 20f, 20f); + + DoMainContents(mainRect); + + if (Widgets.CloseButtonFor(closeRect)) + { + Close(); + } + } + + public static void OpenWindow(HybridInformations info) + { + Dialog_EditHybrid window = (Dialog_EditHybrid)Find.WindowStack.Windows.FirstOrDefault(x => x.GetType().Equals(typeof(Dialog_EditHybrid))); + if (window != null) + { + if (window.info != info) + { + SoundDefOf.TabOpen.PlayOneShotOnCamera(); + window.ChangeExtension(info); + } + } + else + { + SoundDefOf.TabClose.PlayOneShotOnCamera(); + Find.WindowStack.Add(new Dialog_EditHybrid(info)); + } + + + } + + protected void ChangeExtension(HybridInformations info) + { + this.info = info; + BuildRaceList(); + } + + protected void BuildRaceList() + { + raceList.Clear(); + if (VariousDefOf.AllRaces.NullOrEmpty()) return; + + foreach (ThingDef def in VariousDefOf.AllRaces) + { + if (def.race != null) + { + if (info.hybridExtension.Exists(x => x.DefName == def.defName)) continue; + else + { + raceList.Add(new FloatMenuOption(def.label, delegate { AddHybridInfo(def); }, Widgets.GetIconFor(def), Color.white)); + } + } + } + raceList.SortBy(x => x.Label); + } + + protected void AddHybridInfo(ThingDef def) + { + FloatMenuOption option = raceList.FirstOrDefault(x => x.Label == def.label); + if (option != null) + { + raceList.Remove(option); + } + info.hybridExtension.Add(new HybridExtensionExposable(def)); + } + + protected void DoMainContents(Rect inRect) + { + Rect labelRect = new Rect(inRect.xMin, inRect.yMin, 300, 24); + Rect buttonRect = new Rect(inRect.xMax - 120, 0, 100, 30); + + Widgets.Label(labelRect, Translations.CustomHybrid_Title(info.GetDef?.label ?? "Undefined")); + Widgets.DrawLineHorizontal(inRect.x, labelRect.yMax, inRect.width); + if (Widgets.ButtonText(buttonRect, "Add")) + { + if (!raceList.NullOrEmpty()) Find.WindowStack.Add(new FloatMenu(raceList)); + } + if (!removeList.EnumerableNullOrEmpty()) + { + buttonRect.x -= 100; + if (Widgets.ButtonText(buttonRect, "Undo")) + { + HybridExtensionExposable element = removeList.Last(); + info.hybridExtension.Add(element); + removeList.Remove(element); + } + + foreach (HybridExtensionExposable element in removeList) + { + info.hybridExtension.Remove(element); + } + } + + + float additionalHeight = 0f; + if (!info.hybridExtension.NullOrEmpty()) foreach (HybridExtensionExposable e in info.hybridExtension) + { + additionalHeight += (e.hybridInfo?.Count() ?? 1) * rowH; + } + + + Rect outRect = new Rect(inRect.x, inRect.y + 30f, inRect.width, inRect.height - 30f); + Rect mainRect = new Rect(inRect.x, inRect.y + 30f, inRect.width - 30f, rowH * (info.hybridExtension?.Count() ?? 1) + additionalHeight); + Listing_Standard listmain = new Listing_Standard(); + + Widgets.BeginScrollView(outRect, ref scroll, mainRect); + listmain.Begin(mainRect); + + if (!info.hybridExtension.NullOrEmpty()) + { + foreach (HybridExtensionExposable extension in info.hybridExtension) + { + DoRow(listmain.GetRect(rowH + rowH * (extension.hybridInfo?.Count() ?? 1)), extension); + } + + } + + + + Widgets.EndScrollView(); + listmain.End(); + } + + protected void DoRow(Rect rect, HybridExtensionExposable extension) + { + Rect mainRect = new Rect(rect.x, rect.y, rect.width, rowH); + Rect subRect = new Rect(rect.x, rect.y + rowH, rect.width, rect.height - rowH); + Rect buttonRect = new Rect(rect.xMax - 90f, rect.y, 80f, rowH); + Widgets.Label(mainRect, extension.GetDef?.label ?? "Undefined"); + + if (Widgets.ButtonText(buttonRect, "Delete")) + { + removeList.Add(extension); + } + buttonRect.x -= 80f; + if (Widgets.ButtonText(buttonRect, "Add")) + { + List list = new List(); + if (!VariousDefOf.AllRaces.NullOrEmpty()) foreach (ThingDef def in VariousDefOf.AllRaces) + { + if (def.race != null) + { + if (extension.hybridInfo.ContainsKey(def.defName)) continue; + else + { + list.Add(new FloatMenuOption(def.label, delegate { extension.hybridInfo.Add(def.defName, 1.0f); }, Widgets.GetIconFor(def), Color.white)); + } + } + } + if (!list.NullOrEmpty()) + { + list.SortBy(x => x.Label); + Find.WindowStack.Add(new FloatMenu(list)); + } + + } + buttonRect.x -= 80f; + + Listing_Standard sublist = new Listing_Standard(); + sublist.Begin(subRect); + + List removeelements = new List(); + if (!extension.hybridInfo.EnumerableNullOrEmpty()) + { + totalWeight = 0; + foreach (KeyValuePair element in extension.hybridInfo) + { + totalWeight += element.Value; + } + + List keys = new List(extension.hybridInfo.Keys); + foreach (string key in keys) + { + DoSubRow(sublist.GetRect(rowH), key, extension, removeelements); + } + } + foreach (string key in removeelements) + extension.hybridInfo.Remove(key); + + sublist.End(); + Widgets.DrawHighlightIfMouseover(rect); + + + } + + protected void DoSubRow(Rect rect, string key, HybridExtensionExposable extension, List removeelements) + { + bool isPawnKind = false; + int value = (int)extension.hybridInfo.TryGetValue(key); + string valuestr = value.ToString(); + string label = null; + label = DefDatabase.GetNamedSilentFail(key)?.label; + if (label == null) + { + label = DefDatabase.GetNamedSilentFail(key)?.label ?? "Undefined"; + isPawnKind = true; + } + Rect buttonRect = new Rect(rect.xMax - 90f, rect.y, 80f, rect.height); + if (Widgets.ButtonText(buttonRect, "Delete")) + { + removeelements.Add(key); + } + buttonRect.x -= 80f; + if (!isPawnKind) + { + if (Widgets.ButtonText(buttonRect, "PawnKind")) + { + List list = new List(); + if (!VariousDefOf.AllKinds.NullOrEmpty()) foreach (PawnKindDef def in VariousDefOf.AllKinds) + { + if (def.race.defName == key) + { + if (extension.hybridInfo.ContainsKey(def.defName)) continue; + else + { + list.Add(new FloatMenuOption(def.label, delegate { extension.hybridInfo.Add(def.defName, 1.0f); }, Widgets.GetIconFor(def.race), Color.white)); + } + } + } + if (!list.NullOrEmpty()) Find.WindowStack.Add(new FloatMenu(list)); + else SoundDefOf.ClickReject.PlayOneShotOnCamera(); + } + buttonRect.x -= 80f; + } + else + { + Widgets.Label(buttonRect, " PawnKind"); + buttonRect.x -= 80f; + } + label += ": " + key; + Widgets.Label(rect, " - " + label); + Widgets.TextFieldNumeric(buttonRect, ref value, ref valuestr, 0, 9999999); + extension.hybridInfo.SetOrAdd(key, value); + buttonRect.x -= 80f; + Widgets.Label(buttonRect, String.Format("{0,0:P2}", value / totalWeight)); + Widgets.DrawHighlightIfMouseover(rect); + TooltipHandler.TipRegion(rect, Translations.CustomHybrid_Tooltip(info.GetDef?.label ?? "Undefined", extension.GetDef?.label ?? "Undefined", label, String.Format("{0,0:0.########%}", value / totalWeight))); + } + + + } + + +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_WombStatus.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_WombStatus.cs new file mode 100644 index 0000000..e90643b --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Dialog_WombStatus.cs @@ -0,0 +1,456 @@ +using RimWorld; +using rjw; +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using Verse; +using Verse.Sound; + +namespace RJW_Menstruation +{ + public class Dialog_WombStatus : Window + { + public Pawn pawn; + private HediffComp_Menstruation comp; + private const float windowMargin = 20f; + private const float pawnRectWidth = 150f; + private const float pawnRectHeight = 150f; + private const float wombRectHeight = 300f; + private const float wombRectWidth = 300f; + private const float fontheight = 30; + private const float genitalRectWidth = 102; + private const float genitalRectHeight = 140; + private const float breastRectWidth = 102; + private const float breastRectHeight = 100; + + private static bool naked = false; + + private Texture2D womb; + private Texture2D cum; + private Texture2D vagina; + private Texture2D anal; + private Color cumcolor; + + private static GUIStyle fontstylecenter = null; + private static GUIStyle fontstyleright = null; + private static GUIStyle fontstyleleft = null; + private static GUIStyle boxstyle = null; + private static GUIStyle buttonstyle = null; + + public Pawn Pawn + { + get + { + return pawn; + } + } + public HediffComp_Menstruation Comp + { + get + { + return comp; + } + } + + + public override Vector2 InitialSize + { + get + { + float width = 450f + 2 * windowMargin; + float height = 780f + 2 * windowMargin; + if (!Configurations.DrawWombStatus) height -= wombRectHeight; + if (!Configurations.DrawVaginaStatus || pawn.IsAnimal()) width -= 150f; + return new Vector2(width, height); + } + } + + public Dialog_WombStatus(Pawn pawn, HediffComp_Menstruation comp) + { + this.pawn = pawn; + this.comp = comp; + } + + public void ChangePawn(Pawn pawn, HediffComp_Menstruation comp) + { + + if (this.pawn.IsAnimal() && !pawn.IsAnimal()) windowRect.width += 150f; + else if (!this.pawn.IsAnimal() && pawn.IsAnimal()) windowRect.width -= 150f; + this.pawn = pawn; + this.comp = comp; + } + + public static void ToggleWindow(Pawn pawn, HediffComp_Menstruation comp) + { + Dialog_WombStatus window = (Dialog_WombStatus)Find.WindowStack.Windows.FirstOrDefault(x => x.GetType().Equals(typeof(Dialog_WombStatus))); + if (window != null) + { + List pawns = Find.Selector.SelectedPawns.FindAll(x => x.ShouldShowWombGizmo()); + if (Input.GetKey(VariousDefOf.OpenStatusWindowKey.MainKey) && !pawns.NullOrEmpty() && pawns.Count > 1) + { + int index = pawns.IndexOf(window.pawn); + SoundDefOf.TabOpen.PlayOneShotOnCamera(); + Pawn newpawn = pawns[(index + 1) % pawns.Count]; + window.ChangePawn(newpawn, newpawn.GetFirstMenstruationComp()); + } + else if (window.pawn != pawn) + { + SoundDefOf.TabOpen.PlayOneShotOnCamera(); + window.ChangePawn(pawn, comp); + } + else Find.WindowStack.TryRemove(typeof(Dialog_WombStatus), true); + } + else + { + SoundDefOf.InfoCard_Open.PlayOneShotOnCamera(); + Find.WindowStack.Add(new Dialog_WombStatus(pawn, comp)); + } + + + } + + public override void DoWindowContents(Rect inRect) + { + soundClose = SoundDefOf.InfoCard_Close; + //closeOnClickedOutside = true; + absorbInputAroundWindow = false; + forcePause = false; + preventCameraMotion = false; + draggable = true; + //resizeable = true; + + if (Event.current.type == EventType.KeyDown && (Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.Escape)) + { + Event.current.Use(); + } + + Rect windowRect = inRect.ContractedBy(windowMargin); + Rect mainRect = new Rect(windowRect.x, windowRect.y, windowRect.width, windowRect.height); + Rect closeRect = new Rect(windowRect.xMax, 0f, 20f, 20f); + MainContents(mainRect); + if (Widgets.CloseButtonFor(closeRect)) + { + Close(); + } + closeRect.x -= 20f; + + } + + public override void PreOpen() + { + base.PreOpen(); + if (fontstylecenter == null) fontstylecenter = new GUIStyle() { alignment = TextAnchor.MiddleCenter }; + if (fontstyleright == null) fontstyleright = new GUIStyle() { alignment = TextAnchor.MiddleRight }; + if (fontstyleleft == null) fontstyleleft = new GUIStyle() { alignment = TextAnchor.MiddleLeft }; + if (boxstyle == null) boxstyle = new GUIStyle(GUI.skin.textArea); + if (buttonstyle == null) buttonstyle = new GUIStyle(GUI.skin.button); + } + + private void MainContents(Rect mainRect) + { + + boxstyle.hover = boxstyle.normal; + boxstyle.onHover = boxstyle.normal; + boxstyle.onNormal = boxstyle.normal; + + buttonstyle.onHover = buttonstyle.onNormal; + buttonstyle.hover = buttonstyle.normal; + boxstyle.border.left = 4; boxstyle.border.right = 4; boxstyle.border.bottom = 4; boxstyle.border.top = 4; + + fontstyleleft.normal.textColor = Color.white; + + float preginfoheight = 0f; + Hediff hediff = comp.Pregnancy; + if (hediff != null && Utility.ShowFetusImage(hediff)) + { + womb = comp.GetPregnancyIcon(hediff); + if (hediff is Hediff_MultiplePregnancy m) + { + if (m.GestationProgress < 0.2f) cum = comp.GetCumIcon(); + else cum = ContentFinder.Get(("Womb/Empty"), true); + Pawn fetus = comp.GetFetus(); + if (fetus != null && Utility.ShowFetusInfo()) + { + string feinfo = m.GetBabyInfo(); + string fainfo = m.GetFatherInfo() + " "; + if (feinfo.Length + fainfo.Length > 45) + { + preginfoheight = fontheight + 2; + buttonstyle.alignment = TextAnchor.UpperLeft; + fontstyleright.alignment = TextAnchor.LowerRight; + } + else + { + preginfoheight = fontheight; + buttonstyle.alignment = TextAnchor.MiddleLeft; + + } + Rect preginfo = new Rect(0f, mainRect.yMax - wombRectHeight - 2, wombRectWidth, preginfoheight); + fontstyleright.normal.textColor = Color.white; + GUI.Box(preginfo, feinfo, buttonstyle); + GUI.Label(preginfo, fainfo, fontstyleright); + } + + } + else if (hediff is Hediff_BasePregnancy b) + { + if (b.GestationProgress < 0.2f) cum = comp.GetCumIcon(); + else cum = ContentFinder.Get(("Womb/Empty"), true); + Pawn fetus = comp.GetFetus(); + if (fetus != null && Utility.ShowFetusInfo()) + { + preginfoheight = fontheight; + Rect preginfo = new Rect(0f, mainRect.yMax - wombRectHeight - 2, wombRectWidth, preginfoheight); + fontstyleright.normal.textColor = Color.white; + fontstyleright.alignment = TextAnchor.MiddleRight; + buttonstyle.alignment = TextAnchor.MiddleLeft; + + string father; + + if (!b.is_parent_known && Configurations.InfoDetail != Configurations.DetailLevel.All) + father = Translations.Dialog_FatherUnknown; + else + father = b.father.LabelShort; + + GUI.Box(preginfo, b.babies.Count + " " + fetus.def.label + " " + Translations.Dialog_WombInfo02, buttonstyle); + GUI.Label(preginfo, Translations.Dialog_WombInfo03 + ": " + father + " ", fontstyleright); + } + } + else if (hediff is HediffWithParents p) + { + if (p is Hediff_Pregnant hp && hp.Severity < 0.2f) cum = comp.GetCumIcon(); + else cum = ContentFinder.Get("Womb/Empty", true); + // TODO: Pregenerated babies (base on multiplepregnancy) + if (Utility.ShowFetusInfo()) + { + preginfoheight = fontheight; + Rect preginfo = new Rect(0f, mainRect.yMax - wombRectHeight - 2, wombRectWidth, preginfoheight); + fontstyleright.normal.textColor = Color.white; + fontstyleright.alignment = TextAnchor.MiddleRight; + buttonstyle.alignment = TextAnchor.MiddleLeft; + + string father = p.Father.LabelShort; + + GUI.Box(preginfo, "1 " + p.Mother.def.label + " " + Translations.Dialog_WombInfo02, buttonstyle); + GUI.Label(preginfo, Translations.Dialog_WombInfo03 + ": " + father + " ", fontstyleright); + } + } + else cum = ContentFinder.Get(("Womb/Empty"), true); + } + else + { + womb = comp.GetWombIcon(); + cum = comp.GetCumIcon(); + } + + + Rect pawnRect = new Rect(0, 0, pawnRectWidth, pawnRectHeight); + Widgets.DrawTextureFitted(pawnRect, PortraitsCache.Get(pawn, pawnRect.size, Rot4.South, default, 1, true, true, false, !naked), 1.0f); + if (Widgets.ButtonInvisible(pawnRect)) + { + naked = !naked; + } + Rect pawnLabelRect = new Rect(0, pawnRectHeight, pawnRectWidth, fontheight - 10); + Rect pawnLabel2Rect = new Rect(0, pawnRectHeight + fontheight - 10, pawnRectWidth, fontheight - 10); + fontstylecenter.normal.textColor = pawn.DrawColor; + GUI.Label(pawnLabelRect, pawn.Name?.ToStringFull ?? pawn.Label, fontstylecenter); + if (pawn.story != null) GUI.Label(pawnLabel2Rect, pawn.ageTracker.AgeBiologicalYears + ", " + pawn.story.Title, fontstylecenter); + GUI.color = Color.white; + + + float wombrecth = 0; + if (Configurations.DrawWombStatus) + { + wombrecth = wombRectHeight; + cumcolor = comp.GetCumMixtureColor; + Rect wombRect = new Rect(0f, mainRect.yMax - wombRectHeight + preginfoheight, wombRectWidth, wombRectWidth * 0.9f); + DrawWomb(wombRect); + + + if (Configurations.DrawEggOverlay) + { + comp.DrawEggOverlay(wombRect, true); + } + + + } + + Rect wombInfoRect = new Rect(0f, mainRect.yMax - wombrecth - fontheight - 2, wombRectWidth, fontheight - 4f); + Rect progressRect = new Rect(wombInfoRect.x, wombInfoRect.yMax, wombRectWidth, 4f); + buttonstyle.normal.textColor = Color.white; + //boxstyle.normal.background = Texture2D.whiteTexture; + buttonstyle.alignment = TextAnchor.MiddleLeft; + GUI.backgroundColor = new Color(0.24f, 0.29f, 0.35f, 1); + GUI.Box(wombInfoRect, Translations.Dialog_WombInfo01 + ": " + comp.GetCurStageLabel, buttonstyle); + Widgets.FillableBar(progressRect, comp.StageProgress, comp.GetStageTexture); + GUI.color = Color.white; + TooltipHandler.TipRegion(wombInfoRect, comp.GetCurStageDesc); + + + fontstyleright.normal.textColor = Color.red; + fontstyleright.alignment = TextAnchor.MiddleRight; + //if (comp.GetFertilization) GUI.Label(wombInfoRect, Translations.Dialog_WombInfo05 + " ", fontstyleright); + //else if (comp.GetEggFertilizing) GUI.Label(wombInfoRect, Translations.Dialog_WombInfo06 + " ", fontstyleright); + //else if (comp.GetEgg) GUI.Label(wombInfoRect, Translations.Dialog_WombInfo07 + " ", fontstyleright); + GUI.Label(wombInfoRect, comp.GetFertilizingInfo + " ", fontstyleright); + + + //Widgets.Label(wombInfoRect,Translations.Dialog_WombInfo01 + ": " + comp.GetCurStageLabel); + + Rect cumlistTitle, cumlistRect; + if (Configurations.DrawVaginaStatus && !pawn.IsAnimal()) + { + Rect genitalRect = new Rect(pawnRectWidth + 24, pawnRectHeight + 2 * fontheight, genitalRectWidth, genitalRectHeight + fontheight * 2); + Rect breastRect = new Rect(pawnRectWidth + 24, 40f, breastRectWidth, breastRectHeight + fontheight); + DrawVagina(genitalRect, comp); + DrawBreast(breastRect); + cumlistTitle = new Rect(wombRectWidth + 4f, 0, 150f, fontheight); + cumlistRect = new Rect(wombRectWidth + 4f, fontheight, 150f, mainRect.yMax - fontheight + preginfoheight + 3); + } + else + { + cumlistTitle = new Rect(pawnRectWidth, 0, 150f, fontheight); + cumlistRect = new Rect(pawnRectWidth, fontheight, 150f, mainRect.yMax - wombRectHeight - fontheight); + } + + Rect infoRect = new Rect(0, pawnRectHeight + 2 * fontheight, pawnRectWidth, pawnRect.yMax + 2 * fontheight - wombInfoRect.y); + DrawInfos(infoRect); + + + + GUI.Label(cumlistTitle, Translations.Dialog_WombInfo04); + DrawCumlist(cumlistRect); + + + + + + } + + + + + private void DrawCumlist(Rect rect) + { + Listing_Standard cumlist = new Listing_Standard + { + maxOneColumn = true, + ColumnWidth = wombRectWidth - pawnRectWidth + }; + cumlist.Begin(rect); + Listing_Standard cumlistsection = cumlist.BeginSection(rect.height - fontheight - 12f); + foreach (string s in comp.GetCumsInfo) + { + cumlistsection.Label(s); + } + cumlist.EndSection(cumlistsection); + cumlist.End(); + } + + private void DrawWomb(Rect rect) + { + GUI.color = new Color(1.00f, 0.47f, 0.47f, 1); + GUI.Box(rect, "", boxstyle); + //GUI.color = Color.white; + //Widgets.DrawTextureFitted(wombRect, womb,1.0f); + //GUI.color = cumcolor; + //Widgets.DrawTextureFitted(wombRect, cum,1.0f); + GUI.DrawTexture(rect, womb, ScaleMode.ScaleToFit, true, 0, Color.white, 0, 0); + GUI.DrawTexture(rect, cum, ScaleMode.ScaleToFit, true, 0, cumcolor, 0, 0); + + GUI.color = Color.white; + + + } + + + + private void DrawVagina(Rect rect, HediffComp_Menstruation comp) + { + Rect genitalIconRect = new Rect(rect.x, rect.y + fontheight, genitalRectWidth, genitalRectHeight); + Rect genitalVaginaLabelRect = new Rect(rect.x, rect.y + 10f, genitalRectWidth, fontheight); + Rect genitalAnusLabelRect = new Rect(rect.x, rect.y + fontheight + genitalRectHeight, genitalRectWidth, fontheight); + bool showOrigin = Mouse.IsOver(genitalIconRect) && Input.GetMouseButton(0); + + vagina = pawn.GetGenitalIcon(comp, showOrigin); + anal = pawn.GetAnalIcon(showOrigin); + GUI.color = new Color(1.00f, 0.47f, 0.47f, 1); + GUI.Box(rect, "", boxstyle); + GUI.color = pawn.story.SkinColor; + //Widgets.DrawTextureFitted(genitalIconRect, anal, 1.0f); + //Widgets.DrawTextureFitted(genitalIconRect, vagina, 1.0f); + GUI.DrawTexture(genitalIconRect, anal, ScaleMode.ScaleToFit); + GUI.DrawTexture(genitalIconRect, vagina, ScaleMode.ScaleToFit); + + GUI.color = Color.white; + GUI.Label(genitalVaginaLabelRect, pawn.GetVaginaLabel(), fontstylecenter); + GUI.Label(genitalAnusLabelRect, pawn.GetAnusLabel(), fontstylecenter); + } + + private void DrawBreast(Rect rect) + { + Rect BreastIconRect = new Rect(rect.x, rect.y + fontheight, breastRectWidth, breastRectHeight); + Rect BreastLabelRect = new Rect(rect.x, rect.y, breastRectWidth, fontheight); + Rect MilkGaugeRect = new Rect(rect.x, rect.yMax, breastRectWidth, 20f); + + GUI.color = new Color(1.00f, 0.47f, 0.47f, 1); + GUI.Box(rect, "", boxstyle); + + + + pawn.DrawBreastIcon(BreastIconRect); + + + GUI.color = Color.white; + GUI.Label(BreastLabelRect, pawn.GetBreastLabel(), fontstylecenter); + + pawn.DrawMilkBars(MilkGaugeRect); + + + } + + private void DrawInfos(Rect rect) + { + Rect lineRect = new Rect(rect.x, rect.y, rect.width, 20f); + float statvalue; + const float height = 24f; + statvalue = pawn.GetStatValue(xxx.sex_drive_stat); + FillableBarLabeled(lineRect, " " + xxx.sex_drive_stat.LabelCap.CapitalizeFirst() + " " + statvalue.ToStringPercent(), statvalue / 2, TextureCache.SexDriveTexture, Texture2D.blackTexture, xxx.sex_drive_stat.description); + lineRect.y += height; + + statvalue = pawn.GetStatValue(xxx.vulnerability_stat); + FillableBarLabeled(lineRect, " " + xxx.vulnerability_stat.LabelCap.CapitalizeFirst() + " " + statvalue.ToStringPercent(), statvalue / 2, TextureCache.BleedingTexture, Texture2D.blackTexture, xxx.vulnerability_stat.description); + lineRect.y += height; + + statvalue = pawn.records.GetValue(xxx.CountOfBirthHuman); + FillableBarLabeled(lineRect, " " + xxx.CountOfBirthHuman.LabelCap.CapitalizeFirst() + " " + statvalue, statvalue / 10, TextureCache.FollicularTexture, Texture2D.blackTexture, xxx.CountOfBirthHuman.description); + lineRect.y += height; + + statvalue = pawn.records.GetValue(xxx.CountOfBirthAnimal); + FillableBarLabeled(lineRect, " " + xxx.CountOfBirthAnimal.LabelCap.CapitalizeFirst() + " " + statvalue, statvalue / 20, TextureCache.AnimalTexture, Texture2D.blackTexture, xxx.CountOfBirthAnimal.description); + lineRect.y += height; + + statvalue = pawn.records.GetValue(xxx.CountOfBirthEgg); + FillableBarLabeled(lineRect, " " + xxx.CountOfBirthEgg.LabelCap.CapitalizeFirst() + " " + statvalue, statvalue / 100, TextureCache.RecoverTexture, Texture2D.blackTexture, xxx.CountOfBirthEgg.description); + lineRect.y += height * 4; + + statvalue = Configurations.ImplantationChance * comp.ImplantFactor; + float fertchance = comp.GetFertilityChance(); + FillableBarLabeled(lineRect, " " + xxx.reproduction.LabelCap.CapitalizeFirst() + " " + statvalue.ToStringPercent(), statvalue, TextureCache.LutealTexture, Texture2D.blackTexture, Translations.FertilityDesc(String.Format("{0:0.##}", fertchance * 100))); + Rect overayRect = new Rect(lineRect.x, lineRect.y, lineRect.width * Math.Min(1.0f, fertchance), lineRect.height); + GUI.DrawTexture(overayRect, TextureCache.FertChanceTex); + lineRect.y += height; + } + + private void FillableBarLabeled(Rect rect, string label, float fillPercent, Texture2D filltexture, Texture2D bgtexture, string tooltip = null) + { + Widgets.FillableBar(rect, Math.Min(fillPercent, 1.0f), filltexture, bgtexture, true); + GUI.Label(rect, label, fontstyleleft); + Widgets.DrawHighlightIfMouseover(rect); + if (tooltip != null) TooltipHandler.TipRegion(rect, tooltip); + } + + + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Gizmo_Womb.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Gizmo_Womb.cs new file mode 100644 index 0000000..c303d4e --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/UI/Gizmo_Womb.cs @@ -0,0 +1,48 @@ +using UnityEngine; +using Verse; + +namespace RJW_Menstruation +{ + public class Gizmo_Womb : Command_Action + { + public Texture2D icon_overay; + public Color cumcolor; + public HediffComp_Menstruation comp; + + public const float progressbarHeight = 2f; + + public override void DrawIcon(Rect rect, Material buttonMat, GizmoRenderParms parms) + { + Texture badTex = icon; + Texture2D overay = icon_overay; + Color color = cumcolor; + + if (badTex == null) + { + badTex = BaseContent.BadTex; + } + if (overay == null) + { + overay = BaseContent.BadTex; + } + if (color == null) color = Color.white; + rect.position += new Vector2(iconOffset.x * rect.size.x, iconOffset.y * rect.size.y); + GUI.color = IconDrawColor; + Widgets.DrawTextureFitted(rect, badTex, this.iconDrawScale * 0.85f, this.iconProportions, this.iconTexCoords, this.iconAngle, buttonMat); + GUI.color = color; + Widgets.DrawTextureFitted(rect, overay, iconDrawScale * 0.85f, iconProportions, iconTexCoords, iconAngle, buttonMat); + GUI.color = Color.white; + if (Configurations.DrawEggOverlay) comp.DrawEggOverlay(rect, false); + Rect progressRect = new Rect(rect.x + 2f, rect.y, rect.width - 4f, progressbarHeight); + Widgets.FillableBar(progressRect, comp.StageProgress, comp.GetStageTexture); + + } + + public override bool GroupsWith(Gizmo other) + { + if (other is Gizmo_Womb womb && womb.comp != this.comp) return false; + else return base.GroupsWith(other); + } + + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/Utility.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/Utility.cs new file mode 100644 index 0000000..aefa4c2 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/Utility.cs @@ -0,0 +1,455 @@ +using RimWorld; +using rjw; +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using Verse; +using Verse.Sound; + + +namespace RJW_Menstruation +{ + public static class Colors + { + public static Color blood = new Color(0.78f, 0, 0); + //public static Color nippleblack = new Color(0.215f, 0.078f, 0); // 81,20,0 + public static ColorInt white = new ColorInt(255, 255, 255, 255); + + + + public static Color CMYKLerp(Color a, Color b, float t) + { + RGBtoCMYK(a, out float ac, out float am, out float ay, out float ak); + RGBtoCMYK(b, out float bc, out float bm, out float by, out float bk); + + return CMYKtoRGB(Mathf.Lerp(ac, bc, t), Mathf.Lerp(am, bm, t), Mathf.Lerp(ay, by, t), Mathf.Lerp(ak, bk, t)); + } + + public static void RGBtoCMYK(Color rgb, out float c, out float m, out float y, out float k) + { + k = 1 - Math.Max(rgb.r, Math.Max(rgb.g, rgb.b)); + c = (1 - rgb.r - k) / (1 - k); + m = (1 - rgb.g - k) / (1 - k); + y = (1 - rgb.b - k) / (1 - k); + + } + + public static Color CMYKtoRGB(float c, float m, float y, float k) + { + return new Color((1 - c) * (1 - k), (1 - m) * (1 - k), (1 - y) * (1 - k)); + } + + + + } + + + public static class Utility + { + public static PawnKindDef GetRacesPawnKind(Pawn pawn) + { + if (pawn == null) return null; + if (pawn.kindDef?.race == pawn.def) return pawn.kindDef; + return VariousDefOf.AllKinds.Find(kind => kind.race == pawn.def && kind.defName.Contains("Colonist")) ?? + VariousDefOf.AllKinds.Find(kind => kind.race == pawn.def) ?? + pawn.def.race?.AnyPawnKind ?? + pawn.kindDef; + } + + public static float GetCumVolume(this Pawn pawn) + { + List hediffs = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn)); + if (hediffs.NullOrEmpty()) return 0; + else return pawn.GetCumVolume(hediffs); + } + + public static float GetCumVolume(this Pawn pawn, List hediffs) + { + CompHediffBodyPart part = hediffs?.FindAll((Hediff hed) => hed.def.defName.ToLower().Contains("penis")).InRandomOrder().FirstOrDefault()?.TryGetComp(); + if (part == null) part = hediffs?.FindAll((Hediff hed) => hed.def.defName.ToLower().Contains("ovipositorf")).InRandomOrder().FirstOrDefault()?.TryGetComp(); + if (part == null) part = hediffs?.FindAll((Hediff hed) => hed.def.defName.ToLower().Contains("ovipositorm")).InRandomOrder().FirstOrDefault()?.TryGetComp(); + if (part == null) part = hediffs?.FindAll((Hediff hed) => hed.def.defName.ToLower().Contains("tentacle")).InRandomOrder().FirstOrDefault()?.TryGetComp(); + + + return pawn.GetCumVolume(part); + } + + + public static float GetCumVolume(this Pawn pawn, CompHediffBodyPart part) + { + float res; + + try + { + res = part.FluidAmmount * part.FluidModifier * pawn.BodySize / pawn.RaceProps.baseBodySize * Rand.Range(0.8f, 1.2f); + } + catch (NullReferenceException) + { + res = 0.0f; + } + if (pawn.Has(Quirk.Messy)) res *= Rand.Range(4.0f, 8.0f); + + return res; + } + + + + public static HediffComp_Breast GetBreastComp(this Pawn pawn) + { + List hedifflist = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_breastsBPR(pawn))?.FindAll(h => VariousDefOf.AllBreasts.Contains(h.def)); + if (hedifflist.NullOrEmpty()) hedifflist = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_uddersBPR(pawn))?.FindAll(h => VariousDefOf.AllBreasts.Contains(h.def)); + if (hedifflist.NullOrEmpty()) return null; + HediffComp_Breast result; + foreach (Hediff h in hedifflist) + { + result = h.TryGetComp(); + if (result != null) return result; + } + return null; + } + + public static HediffComp_Breast GetBreastComp(this Hediff hediff) + { + if (hediff is Hediff_PartBaseNatural) + { + return hediff.TryGetComp(); + } + return null; + } + + public static List GetMilkComps(this Pawn pawn) + { + List milkcomp = pawn.AllComps.FindAll(x => x is CompMilkable || x.GetType().ToString().ToLower().Contains("milkable")); + return milkcomp; + } + + public static bool HasMenstruationComp(this Pawn pawn) + { + return pawn.GetMenstruationComps().Any(); + } + + public static bool HasMenstruationComp(this Hediff hediff) + { + if ((hediff is Hediff_PartBaseNatural || hediff is Hediff_PartBaseArtifical) && hediff.TryGetComp() != null) + return true; + else return false; + } + + public static bool IsRJWPregnant(this Pawn pawn) + { + return pawn.health.hediffSet.GetFirstHediff() != null; + } + + public static bool IsBiotechPregnant(this Pawn pawn) + { + if (!ModsConfig.BiotechActive) return false; + foreach (HediffDef def in pawn.health.hediffSet.hediffs.Select(hediff => hediff.def)) + { + if (def == HediffDefOf.PregnantHuman || def == HediffDefOf.PregnancyLabor || def == HediffDefOf.PregnancyLaborPushing) + return true; + } + return false; + } + + public static float GetFarthestPregnancyProgress(this Pawn pawn) + { + if (ModsConfig.BiotechActive) + { + foreach (Hediff hediff in pawn.health.hediffSet.hediffs) + { + if (hediff.def == HediffDefOf.PregnancyLabor || hediff.def == HediffDefOf.PregnancyLaborPushing) + return 1.0f; + if (hediff.def == HediffDefOf.PregnantHuman) + return hediff.Severity; + } + } + List pregnancies = new List(); + pawn.health.hediffSet.GetHediffs(ref pregnancies); + return pregnancies.MaxByWithFallback(hediff => hediff.GestationProgress)?.GestationProgress ?? 0; + } + + public static float GetPregnancyProgress(this HediffComp_Menstruation comp) + { + if (comp.Pregnancy == null) return 0; + else return comp.StageProgress; + } + + public static Pawn GetFetus(this HediffComp_Menstruation comp) + { + if (comp.Pregnancy == null) return null; + if (comp.Pregnancy is Hediff_BasePregnancy rjw_preg) + { + if (!rjw_preg.babies.NullOrEmpty()) return rjw_preg.babies.First(); + else + { + Log.Error("Baby not exist: baby was not created or removed. Remove pregnancy."); + rjw_preg.Miscarry(); + return null; + } + } + // TODO: Biotech pregenerated babies + return null; + } + + public static void DrawBreastIcon(this Pawn pawn, Rect rect) + { + Hediff hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_breastsBPR(pawn)).FirstOrDefault(h => VariousDefOf.AllBreasts.Contains(h.def)); + if (hediff == null) + hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_uddersBPR(pawn)).FirstOrDefault(h => VariousDefOf.AllBreasts.Contains(h.def)); + Texture2D breast, nipple, areola; + if (hediff != null) + { + HediffComp_Breast comp = hediff.TryGetComp(); + string icon; + if (comp != null) icon = comp.Props?.BreastTex ?? "Breasts/Breast_Breast"; + else + { + breast = ContentFinder.Get("Breasts/Breast_Breast00", false); + nipple = ContentFinder.Get("Breasts/Breast_Breast00_Nipple00", false); + areola = ContentFinder.Get("Breasts/Breast_Breast00_Areola00", false); + + GUI.color = pawn.story?.SkinColor ?? Color.white; + GUI.DrawTexture(rect, breast, ScaleMode.ScaleToFit); + GUI.color = Color.white; + GUI.DrawTexture(rect, areola, ScaleMode.ScaleToFit); + GUI.DrawTexture(rect, nipple, ScaleMode.ScaleToFit); + return; + } + + if (hediff.Severity < 0.20f) icon += "_Breast00"; + else if (hediff.Severity < 0.40f) icon += "_Breast01"; + else if (hediff.Severity < 0.60f) icon += "_Breast02"; + else if (hediff.Severity < 0.80f) icon += "_Breast03"; + else if (hediff.Severity < 1.00f) icon += "_Breast04"; + else icon += "_Breast05"; + + string nippleicon, areolaicon; + float nipplesize, areolasize; + nipplesize = comp.NippleSize; + areolasize = comp.AreolaSize; + + nippleicon = icon + "_Nipple0" + GetNippleIndex(nipplesize); + areolaicon = icon + "_Areola0" + GetAreolaIndex(areolasize); + + + breast = ContentFinder.Get(icon, false); + areola = ContentFinder.Get(areolaicon, false); + nipple = ContentFinder.Get(nippleicon, false); + GUI.color = pawn.story.SkinColor; + GUI.DrawTexture(rect, breast, ScaleMode.ScaleToFit); + + GUI.color = comp.NippleColor; + + GUI.DrawTexture(rect, areola, ScaleMode.ScaleToFit); + + GUI.DrawTexture(rect, nipple, ScaleMode.ScaleToFit); + + + if (Configurations.Debug) TooltipHandler.TipRegion(rect, comp.DebugInfo()); + + } + else + { + breast = ContentFinder.Get("Breasts/Breast_Breast00", false); + nipple = ContentFinder.Get("Breasts/Breast_Breast00_Nipple00", false); + areola = ContentFinder.Get("Breasts/Breast_Breast00_Areola00", false); + + GUI.color = pawn.story.SkinColor; + GUI.DrawTexture(rect, breast, ScaleMode.ScaleToFit); + GUI.color = Color.white; + GUI.DrawTexture(rect, areola, ScaleMode.ScaleToFit); + GUI.DrawTexture(rect, nipple, ScaleMode.ScaleToFit); + } + + + } + + public static int GetNippleIndex(float nipplesize) + { + if (nipplesize < 0.25f) return 0; + else if (nipplesize < 0.50f) return 1; + else if (nipplesize < 0.75f) return 2; + else return 3; + } + + public static int GetAreolaIndex(float nipplesize) + { + if (nipplesize < 0.15f) return 0; + else if (nipplesize < 0.30f) return 1; + else if (nipplesize < 0.45f) return 2; + else if (nipplesize < 0.70f) return 3; + else return 4; + } + + public static void DrawMilkBars(this Pawn pawn, Rect rect) + { + //List milkcomp = pawn.AllComps.FindAll(x => x is CompMilkable || x.GetType().ToString().ToLower().Contains("milkable")); + ThingComp milkcomp = null; + float res = 0; + if (VariousDefOf.Hediff_Heavy_Lactating_Permanent != null) + { + if (pawn.health.hediffSet.HasHediff(VariousDefOf.Hediff_Heavy_Lactating_Permanent)) milkcomp = pawn.AllComps.FirstOrDefault(x => x.GetType().ToString().ToLower().Contains("hypermilkable")); + else milkcomp = pawn.AllComps.FirstOrDefault(x => x.GetType().ToString().ToLower().Contains("milkable")); + } + else + { + milkcomp = pawn.GetComp(); + } + + if (milkcomp == null) return; + if (milkcomp is CompMilkable milkable) + { + bool active = (bool)milkcomp.GetPropertyValue("Active"); + if (active) + { + CompMilkable m = milkable; + res = Math.Max(m.Fullness, res); + Widgets.FillableBar(rect, Math.Min(res, 1.0f), TextureCache.MilkTexture, Texture2D.blackTexture, true); + DrawMilkBottle(rect, pawn, VariousDefOf.Job_LactateSelf, m.Fullness); + } + } + else + { + bool active = (bool)milkcomp.GetPropertyValue("Active"); + if (active) + { + float fullness = (float)milkcomp.GetMemberValue("fullness"); + res = Math.Max(fullness, res); + Widgets.FillableBar(rect, Math.Min(res, 1.0f), TextureCache.MilkTexture, Texture2D.blackTexture, true); + DrawMilkBottle(rect, pawn, VariousDefOf.Job_LactateSelf_MC, fullness); + } + } + } + + public static void DrawMilkBottle(Rect rect, Pawn pawn, JobDef milkjob, float fullness) + { + Texture2D texture; + Rect buttonrect = new Rect(rect.x, rect.y, rect.height, rect.height); + if (fullness <= 0.0f) return; + + if (fullness < 0.3f) texture = ContentFinder.Get("Milk/Milkbottle_Small", false); + else if (fullness < 0.7f) texture = ContentFinder.Get("Milk/Milkbottle_Medium", false); + else texture = ContentFinder.Get("Milk/Milkbottle_Large", false); + GUIContent icon = new GUIContent(texture); + GUIStyle style = GUIStyle.none; + style.normal.background = texture; + string tooltip = Translations.Button_MilkTooltip; + + TooltipHandler.TipRegion(buttonrect, tooltip); + if (GUI.Button(buttonrect, icon, style)) + { + if (fullness < 0.1f + || !pawn.IsColonistPlayerControlled + || pawn.Downed) SoundDefOf.ClickReject.PlayOneShotOnCamera(); + else + { + SoundDefOf.Click.PlayOneShotOnCamera(); + pawn.jobs.TryTakeOrderedJob(new Verse.AI.Job(milkjob, pawn)); + } + } + Widgets.DrawHighlightIfMouseover(buttonrect); + } + + + public static string GetVaginaLabel(this Pawn pawn) + { + Hediff hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn)).Find(h => VariousDefOf.AllVaginas.Contains(h.def)); + return hediff.LabelBase.CapitalizeFirst() + "\n(" + hediff.LabelInBrackets + ")" + "\n" + xxx.CountOfSex.LabelCap.CapitalizeFirst() + ": " + pawn.records.GetAsInt(xxx.CountOfSex); + } + public static string GetAnusLabel(this Pawn pawn) + { + Hediff hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_anusBPR(pawn)).FirstOrDefault(h => VariousDefOf.AllAnuses.Contains(h.def)); + if (hediff == null) hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_anusBPR(pawn)).FirstOrDefault(h => h.def.defName.ToLower().Contains("anus")); + if (hediff != null) return hediff.LabelBase.CapitalizeFirst() + "\n(" + hediff.LabelInBrackets + ")"; + else return ""; + } + public static string GetBreastLabel(this Pawn pawn) + { + Hediff hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_breastsBPR(pawn)).FirstOrDefault(h => VariousDefOf.AllBreasts.Contains(h.def)); + if (hediff == null) hediff = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_uddersBPR(pawn)).FirstOrDefault(h => VariousDefOf.AllBreasts.Contains(h.def)); + if (hediff != null) return hediff.LabelBase.CapitalizeFirst() + "\n(" + hediff.LabelInBrackets + ")"; + else return ""; + } + + + public static bool ShowFetusImage(this Hediff hediff) + { + if (Configurations.InfoDetail == Configurations.DetailLevel.All) return true; + else if (Configurations.InfoDetail == Configurations.DetailLevel.Hide) return false; + else if (hediff.Visible) return true; + else return false; + } + + public static bool ShowFetusInfo() + { + if (Configurations.InfoDetail == Configurations.DetailLevel.All || Configurations.InfoDetail == Configurations.DetailLevel.OnReveal) return true; + else return false; + } + + public static bool ShowStatus(this Pawn pawn) + { + if (pawn.Faction != null && Configurations.ShowFlag != Configurations.PawnFlags.None) + { + if (pawn.Faction.IsPlayer) + { + if ((Configurations.ShowFlag & Configurations.PawnFlags.Colonist) != 0) return true; + } + else if (pawn.IsPrisonerOfColony) + { + if ((Configurations.ShowFlag & Configurations.PawnFlags.Prisoner) != 0) return true; + } + else if (pawn.Faction.PlayerRelationKind == FactionRelationKind.Ally) + { + if ((Configurations.ShowFlag & Configurations.PawnFlags.Ally) != 0) return true; + } + else if (pawn.Faction.PlayerRelationKind == FactionRelationKind.Hostile) + { + if ((Configurations.ShowFlag & Configurations.PawnFlags.Hostile) != 0) return true; + } + else if ((Configurations.ShowFlag & Configurations.PawnFlags.Neutral) != 0) return true; + else return false; + } + else if ((Configurations.ShowFlag & Configurations.PawnFlags.Neutral) != 0) return true; + + return false; + } + + public static Pawn GetFather(Pawn pawn, Pawn mother) + { + Pawn res = pawn.GetFather(); + if (res != null) return res; + else res = pawn.relations?.GetFirstDirectRelationPawn(PawnRelationDefOf.Parent, x => x != mother) ?? null; + return res; + } + + public static float RandGaussianLike(float min, float max, int iterations = 3) + { + float res = 0; + for (int i = 0; i < iterations; i++) + { + res += Rand.Value; + } + res /= iterations; + + return res * (max - min) + min; + + } + + public static float LerpMultiple(this float a, float b, float t, int num) + { + float tmult = Mathf.Pow(1 - t, num); + return tmult * a + (1 - tmult) * b; + } + + public static float VariationRange(this float num, float variant) + { + return num * Rand.Range(1.0f - variant, 1.0f + variant); + } + + public static bool ShouldShowWombGizmo(this Pawn pawn) + { + return Configurations.EnableWombIcon && (!pawn.IsAnimal() || Configurations.EnableAnimalCycle); + } + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/VariousDefOf.cs b/1.4/source/RJW_Menstruation/RJW_Menstruation/VariousDefOf.cs new file mode 100644 index 0000000..5e00858 --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/VariousDefOf.cs @@ -0,0 +1,155 @@ +using RimWorld; +using rjw; +using rjw.Modules.Interactions.Rules.PartKindUsageRules.Implementation; +using System; +using System.Collections.Generic; +using System.Linq; +using Verse; + +namespace RJW_Menstruation +{ + public static class VariousDefOf + { + + public static readonly ThingDef CumFilth = DefDatabase.GetNamed("FilthCum"); + public static readonly ThingDef GirlCumFilth = DefDatabase.GetNamed("FilthGirlCum"); + public static readonly ThingDef Tampon = DefDatabase.GetNamed("Absorber_Tampon"); + public static readonly ThingDef Tampon_Dirty = DefDatabase.GetNamed("Absorber_Tampon_Dirty"); + public static readonly ThingDef FilthMixture = DefDatabase.GetNamed("FilthMixture"); + public static readonly HediffDef RJW_IUD = DefDatabase.GetNamed("RJW_IUD"); + public static readonly HediffDef Hediff_MenstrualCramp = DefDatabase.GetNamed("Hediff_MenstrualCramp"); + public static readonly HediffDef Hediff_Estrus = DefDatabase.GetNamed("Hediff_Estrus"); + public static readonly HediffDef Hediff_Estrus_Concealed = DefDatabase.GetNamed("Hediff_Estrus_Concealed"); + public static readonly HediffDef Hediff_ASA = DefDatabase.GetNamed("Hediff_ASA"); + public static readonly StatDef MaxAbsorbable = DefDatabase.GetNamed("MaxAbsorbable"); + public static readonly NeedDef SexNeed = DefDatabase.GetNamed("Sex"); + public static readonly JobDef VaginaWashing = DefDatabase.GetNamed("VaginaWashing"); + public static readonly JobDef Job_LactateSelf = DefDatabase.GetNamed("LactateSelf"); + public static readonly ThoughtDef LeakingFluids = DefDatabase.GetNamed("LeakingFluids"); + public static readonly ThoughtDef CameInsideF = DefDatabase.GetNamed("CameInsideF"); + public static readonly ThoughtDef CameInsideFLowFert = DefDatabase.GetNamed("CameInsideFLowFert"); + public static readonly ThoughtDef CameInsideFFetish = DefDatabase.GetNamed("CameInsideFFetish"); + public static readonly ThoughtDef CameInsideFFetishSafe = DefDatabase.GetNamed("CameInsideFFetishSafe"); + public static readonly ThoughtDef HaterCameInsideFSafe = DefDatabase.GetNamed("HaterCameInsideFSafe"); + public static readonly ThoughtDef HaterCameInsideF = DefDatabase.GetNamed("HaterCameInsideF"); + public static readonly ThoughtDef HaterCameInsideFEstrus = DefDatabase.GetNamed("HaterCameInsideFEstrus"); + public static readonly ThoughtDef CameInsideM = DefDatabase.GetNamed("CameInsideM"); + public static readonly ThoughtDef HaterCameInsideM = DefDatabase.GetNamed("HaterCameInsideM"); + public static readonly ThoughtDef UnwantedPregnancy = DefDatabase.GetNamed("UnwantedPregnancy"); + public static readonly ThoughtDef UnwantedPregnancyMild = DefDatabase.GetNamed("UnwantedPregnancyMild"); + public static readonly ThoughtDef TookContraceptivePill = DefDatabase.GetNamed("TookContraceptivePill"); + public static readonly ThoughtDef HateTookContraceptivePill = DefDatabase.GetNamed("HateTookContraceptivePill"); + public static readonly CompProperties_Menstruation HumanVaginaCompProperties = (CompProperties_Menstruation)Genital_Helper.average_vagina.comps.FirstOrDefault(x => x is CompProperties_Menstruation); + public static readonly KeyBindingDef OpenStatusWindowKey = DefDatabase.GetNamed("OpenStatusWindow"); + public static readonly RecordDef AmountofCreampied = DefDatabase.GetNamed("AmountofCreampied"); + public static readonly RecordDef AmountofFertilizedEggs = DefDatabase.GetNamed("AmountofFertilizedEggs"); + public static readonly TaleDef TaleCameInside = DefDatabase.GetNamed("CameInside"); + + + + private static List allraces = null; + private static List allkinds = null; + private static HashSet allvaginas = null; + private static HashSet allanuses = null; + private static HashSet allbreasts = null; + + public static List AllRaces + { + get + { + if (allraces != null) return allraces; + + List allThings = DefDatabase.AllDefsListForReading; + allraces = allThings.FindAll(x => x.race != null && x.race.IsFlesh); + return allraces; + } + } + public static List AllKinds + { + get + { + if (allkinds != null) return allkinds; + + List allKinds = DefDatabase.AllDefsListForReading; + allkinds = allKinds.FindAll(x => x.race != null); + return allkinds; + } + } + public static HashSet AllVaginas + { + get + { + if (allvaginas != null) return allvaginas; + allvaginas = new HashSet(); + + foreach(HediffDef hediffDef in DefDatabase.AllDefsListForReading) + { + if (hediffDef.comps.NullOrEmpty()) continue; + foreach (HediffCompProperties comp in hediffDef.comps) + { + if (comp.compClass == typeof(HediffComp_Menstruation) || (comp.compClass?.IsSubclassOf(typeof(HediffComp_Menstruation)) ?? false)) + { + allvaginas.Add(hediffDef); + break; + } + } + } + + return allvaginas; + } + } + public static HashSet AllAnuses + { + get + { + if (allanuses != null) return allanuses; + allanuses = new HashSet(); + + foreach (HediffDef hediffDef in DefDatabase.AllDefsListForReading) + { + if (hediffDef.comps.NullOrEmpty()) continue; + foreach (HediffCompProperties comp in hediffDef.comps) + { + if (comp.compClass == typeof(HediffComp_Anus) || (comp.compClass?.IsSubclassOf(typeof(HediffComp_Anus)) ?? false)) + { + allanuses.Add(hediffDef); + break; + } + } + } + + return allanuses; + } + } + public static HashSet AllBreasts + { + get + { + if (allbreasts != null) return allbreasts; + allbreasts = new HashSet(); + + foreach(HediffDef hediffDef in DefDatabase.AllDefsListForReading) + { + if (hediffDef.comps.NullOrEmpty()) continue; + foreach(HediffCompProperties comp in hediffDef.comps) + { + if (comp.compClass == typeof(HediffComp_Breast) || (comp.compClass?.IsSubclassOf(typeof(HediffComp_Breast)) ?? false)) + { + allbreasts.Add(hediffDef); + break; + } + } + } + + return allbreasts; + } + } + + // Defs from Milkable Colonists + public static readonly HediffDef Hediff_Lactating_Drug = DefDatabase.GetNamedSilentFail("Lactating_Drug"); + public static readonly HediffDef Hediff_Lactating_Natural = DefDatabase.GetNamedSilentFail("Lactating_Natural"); + public static readonly HediffDef Hediff_Lactating_Permanent = DefDatabase.GetNamedSilentFail("Lactating_Permanent"); + public static readonly HediffDef Hediff_Heavy_Lactating_Permanent = DefDatabase.GetNamedSilentFail("Heavy_Lactating_Permanent"); + public static readonly JobDef Job_LactateSelf_MC = DefDatabase.GetNamedSilentFail("LactateSelf_MC"); + } +} diff --git a/1.4/source/RJW_Menstruation/RJW_Menstruation/packages.config b/1.4/source/RJW_Menstruation/RJW_Menstruation/packages.config new file mode 100644 index 0000000..3299dfc --- /dev/null +++ b/1.4/source/RJW_Menstruation/RJW_Menstruation/packages.config @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/About/About.xml b/About/About.xml index 3c8c3c6..9c10224 100644 --- a/About/About.xml +++ b/About/About.xml @@ -5,6 +5,7 @@
  • 1.2
  • 1.3
  • +
  • 1.4
  • @@ -26,8 +27,6 @@
  • rim.job.world
  • Abraxas.RJW.RaceSupport
  • rjw.milk.humanoid
  • -
  • rjw.sexperience
  • -
  • rjw.cum
  • rjw.menstruation Adds menstruation mechanics to vaginas: diff --git a/About/Manifest.xml b/About/Manifest.xml index e6a19ed..b1bb3ff 100644 --- a/About/Manifest.xml +++ b/About/Manifest.xml @@ -1,7 +1,7 @@ RJW Menstruation - 1.0.7.5 + 1.0.8.0 @@ -11,8 +11,6 @@
  • rim.job.world
  • Abraxas.RJW.RaceSupport
  • rjw.milk.humanoid
  • -
  • rjw.sexperience
  • -
  • rjw.cum
  • diff --git a/LoadFolders.xml b/LoadFolders.xml index c2d3849..4179abb 100644 --- a/LoadFolders.xml +++ b/LoadFolders.xml @@ -11,4 +11,9 @@
  • 1.3/MilkModule
  • + +
  • 1.4
  • +
  • 1.4/RJW Menstruation Race Support
  • + +
    \ No newline at end of file diff --git a/changelogs.txt b/changelogs.txt index 666f85f..1ab4156 100644 --- a/changelogs.txt +++ b/changelogs.txt @@ -1,3 +1,10 @@ +Version 1.0.8.0 + - Support for RimWorld 1.4. All future changes to Menstruation will only be for Rimworld 1.4. + - Existing Biotech pregnancies will appear in a womb, but no support yet for starting a Biotech pregnancy. + - Identical twins will have identical genes. + - Biotech: A human will lactate upon giving birth with multiple pregnancy. + - Updated Traditional Chinese translation by Hydrogen. + Version 1.0.7.5 - Requires RJW 5.2.2. - High resolution graphics and new fetus graphics provided by Glux.