commit 1761f030481646ca8fc6d8c41323a093fe9d313e Author: leboeuf <39616-leboeuf@users.noreply.gitgud.io> Date: Wed Jan 4 17:00:19 2023 -0500 1.0 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e4e587 --- /dev/null +++ b/.gitignore @@ -0,0 +1,261 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +project.fragment.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +#*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc +/cp_new_asm.ps1 +/1.4/Assemblies/RJW.dll +/1.4/Assemblies/HarmonyMod.dll +/1.4/Assemblies/0MultiplayerAPI.dll +/1.4/Assemblies/0Harmony.dll diff --git a/1.4/Assemblies/LewdBiotech.dll b/1.4/Assemblies/LewdBiotech.dll new file mode 100644 index 0000000..f8b7ad2 Binary files /dev/null and b/1.4/Assemblies/LewdBiotech.dll differ diff --git a/1.4/Defs/GeneDefs/LitteredBirths.xml b/1.4/Defs/GeneDefs/LitteredBirths.xml new file mode 100644 index 0000000..94f6076 --- /dev/null +++ b/1.4/Defs/GeneDefs/LitteredBirths.xml @@ -0,0 +1,15 @@ + + + + + LitteredBirths + + Female carriers of this gene birth litters instead of just one baby, with a chance of having two to four babies per pregnancy. + Icons/Genes/Gene_LitteredBirths + + 110 + 1.25 + -1 + 1 + + \ No newline at end of file diff --git a/1.4/Defs/HediffDefs/Bioscaffold.xml b/1.4/Defs/HediffDefs/Bioscaffold.xml new file mode 100644 index 0000000..0b94e23 --- /dev/null +++ b/1.4/Defs/HediffDefs/Bioscaffold.xml @@ -0,0 +1,21 @@ + + + + + Bioscaffold + HediffWithComps + + This woman has an bioscaffold mesh within her womb, providing an enriching environment for an unborn baby to grow more quickly. + + Bioscaffold + + 0.001 + false + + + \ No newline at end of file diff --git a/1.4/Defs/HediffDefs/LimbicStimulator.xml b/1.4/Defs/HediffDefs/LimbicStimulator.xml new file mode 100644 index 0000000..e3073fd --- /dev/null +++ b/1.4/Defs/HediffDefs/LimbicStimulator.xml @@ -0,0 +1,23 @@ + + + + LimbicStimulator + HediffWithComps + + limbic stimulator + An installed limbic stimulator. + + Scrambler + + (1.0, 0.6, 0.7) + +
  • + 0 + + -1.0 + 6.0 + +
  • +
    +
    +
    \ No newline at end of file diff --git a/1.4/Defs/HediffDefs/OvaryAgitator.xml b/1.4/Defs/HediffDefs/OvaryAgitator.xml new file mode 100644 index 0000000..916b122 --- /dev/null +++ b/1.4/Defs/HediffDefs/OvaryAgitator.xml @@ -0,0 +1,119 @@ + + + + + OvaryAgitator + + An installed ovary agitator. + + OvaryAgitator + + HediffWithComps + 0.0001 + +
  • + +
  • + RJW_Fertility + 0.50 +
  • + + +
  • + 0.1 + +
  • + RJW_Fertility + 0.22 +
  • + + +
  • + 0.2 + +
  • + RJW_Fertility + 0 +
  • + + +
  • + 0.3 + +
  • + RJW_Fertility + -0.17 +
  • + + +
  • + 0.4 + +
  • + RJW_Fertility + -0.32 +
  • + + +
  • + 0.5 + +
  • + RJW_Fertility + -0.48 +
  • + + +
  • + 0.6 + +
  • + RJW_Fertility + -0.54 +
  • + + +
  • + 0.7 + +
  • + RJW_Fertility + -0.63 +
  • + + +
  • + 0.8 + +
  • + RJW_Fertility + -0.69 +
  • + + +
  • + 0.9 + +
  • + RJW_Fertility + -0.75 +
  • + + +
  • + 1 + +
  • + RJW_Fertility + -100 +
  • + + +
    + +
  • + 0.0045 +
  • +
    +
    +
    \ No newline at end of file diff --git a/1.4/Defs/HediffDefs/Scrambler.xml b/1.4/Defs/HediffDefs/Scrambler.xml new file mode 100644 index 0000000..5db5c4a --- /dev/null +++ b/1.4/Defs/HediffDefs/Scrambler.xml @@ -0,0 +1,32 @@ + + + + Scrambler + + scrambler + An installed scrambler. + + Scrambler + + (0.9, 0.5, 1.0) + +
  • + 0 + + 0.40 + 3.0 + + +
  • + Consciousness + 0.6 +
  • +
  • + Talking + 0.2 +
  • + + +
    +
    +
    \ No newline at end of file diff --git a/1.4/Defs/LetterDefs/AnotherBaby.xml b/1.4/Defs/LetterDefs/AnotherBaby.xml new file mode 100644 index 0000000..d8f7c17 --- /dev/null +++ b/1.4/Defs/LetterDefs/AnotherBaby.xml @@ -0,0 +1,11 @@ + + + + AnotherBaby + (120, 176, 216) + (106, 179, 231) + 40 + LetterArrive_Good + MajorThreat + + \ No newline at end of file diff --git a/1.4/Defs/RecipeDefs/Bioscaffold.xml b/1.4/Defs/RecipeDefs/Bioscaffold.xml new file mode 100644 index 0000000..aef67a4 --- /dev/null +++ b/1.4/Defs/RecipeDefs/Bioscaffold.xml @@ -0,0 +1,33 @@ + + + + + InstallBioscaffold + + Install a bioscaffold. + + Bioscaffold + Bioscaffold + + Installing bioscaffold. + +
  • + + +
  • Bioscaffold
  • + + + 1 + +
    + + +
  • Bioscaffold
  • +
    +
    + + Bioscaffold +
    +
    \ No newline at end of file diff --git a/1.4/Defs/RecipeDefs/LimbicStimulator.xml b/1.4/Defs/RecipeDefs/LimbicStimulator.xml new file mode 100644 index 0000000..b824041 --- /dev/null +++ b/1.4/Defs/RecipeDefs/LimbicStimulator.xml @@ -0,0 +1,33 @@ + + + + + InstallLimbicStimulator + + Install a limbic stimulator. + + LimbicStimulator + LimbicStimulator + + Installing limbic stimulator. + +
  • + + +
  • LimbicStimulator
  • + + + 1 + +
    + + +
  • LimbicStimulator
  • +
    +
    + +
  • Brain
  • +
    + LimbicStimulator +
    +
    \ No newline at end of file diff --git a/1.4/Defs/RecipeDefs/OvaryAgitator.xml b/1.4/Defs/RecipeDefs/OvaryAgitator.xml new file mode 100644 index 0000000..2d2523f --- /dev/null +++ b/1.4/Defs/RecipeDefs/OvaryAgitator.xml @@ -0,0 +1,35 @@ + + + + + InstallOvaryAgitator + + Install an ovary agitator. + + OvaryAgitator + OvaryAgitator + + Recipe_InstallImplant + Installing ovary agitator. + true + +
  • + + +
  • OvaryAgitator
  • + + + 1 + +
    + + +
  • OvaryAgitator
  • +
    +
    + +
  • Torso
  • +
    + OvaryAgitator +
    +
    \ No newline at end of file diff --git a/1.4/Defs/RecipeDefs/Scrambler.xml b/1.4/Defs/RecipeDefs/Scrambler.xml new file mode 100644 index 0000000..5479d91 --- /dev/null +++ b/1.4/Defs/RecipeDefs/Scrambler.xml @@ -0,0 +1,35 @@ + + + + + InstallScrambler + + Install a scrambler. + + Scrambler + Scrambler + + Recipe_InstallImplant + Installing scrambler. + true + +
  • + + +
  • Scrambler
  • + + + 1 + +
    + + +
  • Scrambler
  • +
    +
    + +
  • Brain
  • +
    + Scrambler +
    +
    \ No newline at end of file diff --git a/1.4/Defs/ThingDefs/Bioscaffold.xml b/1.4/Defs/ThingDefs/Bioscaffold.xml new file mode 100644 index 0000000..4d585ba --- /dev/null +++ b/1.4/Defs/ThingDefs/Bioscaffold.xml @@ -0,0 +1,53 @@ + + + + + Bioscaffold + + A single-use nanite-constructed lattice of organic mesh material meant to be installed inside a woman's womb prior to pregnancy. It provides an enriching environment for an unborn baby to grow more quickly. + + InstallBioscaffold + + Spacer + Rare + true + 25 + false + + 30 + 350 + 0.15 + 1.3 + 6 + 800 + + +
  • + 5 + true +
  • +
    + + 5 + 10 + 1 + 1 + + + DrugSynthesisSpeed + Intellectual + +
  • DrugLab
  • +
    + + 6 + 4 + + FertilityProcedures + 4 +
    + +
  • ExoticMisc
  • +
    +
    +
    \ No newline at end of file diff --git a/1.4/Defs/ThingDefs/LimbicStimulator.xml b/1.4/Defs/ThingDefs/LimbicStimulator.xml new file mode 100644 index 0000000..a4e6aab --- /dev/null +++ b/1.4/Defs/ThingDefs/LimbicStimulator.xml @@ -0,0 +1,20 @@ + + + + + LimbicStimulator + + A perpetual slow-release chemical stimulation implant that is embedded deep within the reward center of the brain, greatly increasing the need for lovin'. The need is said to become so strong that it can drive people to force themselves onto others, even if they wouldn't otherwise. Post-lovin' clarity will leave the implanted in a state of bliss, but they may also feel a sense of regret if they steal lovin' if they normally wouldn't - at least until they become used to doing it. + + InstallLimbicStimulator + + + 30 + 4 + 1 + + + BrainWiring + + + \ No newline at end of file diff --git a/1.4/Defs/ThingDefs/OvaryAgitator.xml b/1.4/Defs/ThingDefs/OvaryAgitator.xml new file mode 100644 index 0000000..256f69c --- /dev/null +++ b/1.4/Defs/ThingDefs/OvaryAgitator.xml @@ -0,0 +1,20 @@ + + + + + OvaryAgitator + + A crude slaver implant used to increase the number of eggs released during ovulation, increasing the likelihood of having multiple children per pregnancy. Their use is largely limited to rimworlds lacking in cloning infrastructure as most civilized and unified worlds have outlawed them.\n\nWhile it provides an initial boost in fertility, the implant will slowly deplete the victims's ovaries over several years until they're infertile. Allies of implanted victims will be angered. + + InstallOvaryAgitator + + + 10 + 1 + 6 + + + FertilityProcedures + + + \ No newline at end of file diff --git a/1.4/Defs/ThingDefs/Scrambler.xml b/1.4/Defs/ThingDefs/Scrambler.xml new file mode 100644 index 0000000..0b13726 --- /dev/null +++ b/1.4/Defs/ThingDefs/Scrambler.xml @@ -0,0 +1,21 @@ + + + + + Scrambler + + A slaver implant, made from a modified mindscrew, that can inject disorienting mind imagery directly into the visual cortex of the brain through a complex network of nanoelectrodes. Victims of scrambler implantation tend to socially withdraw to minimize additional stimulation. As a consequence of their confusion, they also become physically meek, making them easy to impose upon. Allies of implanted victims will be angered. + InstallScrambler + + 50 + + + 1 + 1 + 1 + + + BrainWiring + + + \ No newline at end of file diff --git a/1.4/Defs/ThoughtDefs/Thoughts_Memories.xml b/1.4/Defs/ThoughtDefs/Thoughts_Memories.xml new file mode 100644 index 0000000..5b9bc5c --- /dev/null +++ b/1.4/Defs/ThoughtDefs/Thoughts_Memories.xml @@ -0,0 +1,18 @@ + + + + + RegretsStealingLovin + Thought_Memory + 1.5 + 3 + 0.4 + +
  • + + I don't remember how or why, but I violated someone. It felt good in the moment, but it felt so wrong afterward. My cravings from my implant are just too strong! + -5 +
  • +
    +
    +
    \ No newline at end of file diff --git a/1.4/Languages/English/Keyed/SettingsKeys.xml b/1.4/Languages/English/Keyed/SettingsKeys.xml new file mode 100644 index 0000000..732bf1a --- /dev/null +++ b/1.4/Languages/English/Keyed/SettingsKeys.xml @@ -0,0 +1,8 @@ + + + Lewd Biotech + Enable development logging + When enabled, this setting provides additional Lewd Biotech related logging in the development mode log. + Disable "Regrets stealing lovin'" thought + By default, the limbic stimulator implant allows for pawns without the Rapist trait to steal lovin'. When this occurs, the non-rapist pawn will receive a -5 mood negative thought that stacks up to 3 times. When enabled, this setting disables generation of that thought. + \ No newline at end of file diff --git a/1.4/Textures/Icons/Genes/Gene_LitteredBirths.png b/1.4/Textures/Icons/Genes/Gene_LitteredBirths.png new file mode 100644 index 0000000..5b5a09e Binary files /dev/null and b/1.4/Textures/Icons/Genes/Gene_LitteredBirths.png differ diff --git a/About/About.xml b/About/About.xml new file mode 100644 index 0000000..304ab8b --- /dev/null +++ b/About/About.xml @@ -0,0 +1,51 @@ + + Lewd Biotech + leboeuf + leboeuf.lewdbiotech + +
  • 1.4
  • +
    + +
  • + rim.job.world + RimJobWorld + https://gitgud.io/Ed86/rjw +
  • +
    + + +
  • rim.job.world
  • +
    + +Lewd Biotech is a small RimWorld: Biotech compatible expansion for RimJobWorld. This mod provides several new, unique ways to interact with pawns using existing RimJobWorld features, like vulnerability and sex need stats, while also providing some of its own features: + +Features: + + • Biotech pregnancy compatible multibirth system, allowing + pawns to have random twins with a default 1-in-100 chance. + • Littered births gene, where pawns can have guaranteed + litters of multiple babies. + • Bioscaffolds: craftable glittertech that can significantly + increase the speed of Biotech pregnancies. + • Limbic stimulators and scramblers: brain implants that + can make pawns ravenous with sexual need, or confused and + highly vulnerable. + • Ovary agitators: crude, permanent slave implants that can + artificially incease the chance of having multiple babies - + at the cost of eventual early infertility. + +Many additional features are planned, including: + + • Milkable Colonist integration and/or new human milk system + and lactation expansion + • New, well-integrated serum system similar to Licentia Labs + • More new and unique implants + • Lewd specialist mechanoids + • Genes/xenohumans for sci-fi succubi/incubi that fit + RimWorld's lore + • ... and more! + +For all feature requests and bugs/issues: + https://gitgud.io/leboeuf/lewd-biotech/-/issues + +
    \ No newline at end of file diff --git a/About/Preview.png b/About/Preview.png new file mode 100644 index 0000000..52aed81 Binary files /dev/null and b/About/Preview.png differ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f19aaa6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,14 @@ +MIT No Attribution + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/LewdBiotech.sln b/LewdBiotech.sln new file mode 100644 index 0000000..1e7f9bf --- /dev/null +++ b/LewdBiotech.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31205.134 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LewdBiotech", "Source\LewdBiotech.csproj", "{D7D21B4A-1DA7-41D8-B202-C58CA8FA62AA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D7D21B4A-1DA7-41D8-B202-C58CA8FA62AA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D7D21B4A-1DA7-41D8-B202-C58CA8FA62AA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {28CF9A73-5333-4EB3-BFCC-3FBEDDA19200} + EndGlobalSection +EndGlobal diff --git a/README.md b/README.md new file mode 100644 index 0000000..cf3c4a9 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# Lewd Biotech + +**Lewd Biotech** is a RimWorld mod set to add additional features to RimWorld's new Biotech expansion and RimJobWorld. New features include: + +### Features +* A new vanilla-friendly, Biotech-compatible multibirth system enabling colonists to have random chance twins, implant and gene-assisted triplets, and more that properly inherit genes +* New implants and genes that enhance the new multibirth system +* New implants that can change pawn vulnerability and sex need + +### Planned features +* Milkable Colonists integration and/or new human milk system and lactation expansion +** As of 3 Jan 2023: thanks to ongoing work by onslort in making Milkable Colonists compatible with Biotech, a new system may not be needed - stay tuned. +* New, well-integrated serum system similar to Licentia Labs +* More new and unique implants +* Lewd specialist mechanoids +* Genes/xenohumans for sci-fi succubi/incubi that fit RimWorld's lore +* ... and more! + +### Issues and bugs +Please report all bugs to the mod's issue tracker on the gitgud.io repo (https://gitgud.io/leboeuf/lewd-biotech/-/issues) +Please don't report bugs anywhere else. Having a single place to view latest bug reports shortens the time it takes to find and resolve them. +Please provide a log and (if possible) your full current modlist when reporting issues. + +### Contributing +The project is currently set up to be built directly from within your "RimWorld/Mods" folder, which is usually under "steamapps/common" on Steam installs. Working from any other location may require some additional Visual Studio project fiddling. DM laboeuf if you want to help, but are having build issues. diff --git a/Source/DefOf/GeneDefOf.cs b/Source/DefOf/GeneDefOf.cs new file mode 100644 index 0000000..35e15a0 --- /dev/null +++ b/Source/DefOf/GeneDefOf.cs @@ -0,0 +1,11 @@ +using RimWorld; +using Verse; + +namespace LewdBiotech +{ + [RimWorld.DefOf] + public static class GeneDefOf + { + public static GeneDef LitteredBirths; + } +} \ No newline at end of file diff --git a/Source/DefOf/HediffDefOf.cs b/Source/DefOf/HediffDefOf.cs new file mode 100644 index 0000000..33c6a87 --- /dev/null +++ b/Source/DefOf/HediffDefOf.cs @@ -0,0 +1,14 @@ +using RimWorld; +using Verse; + +namespace LewdBiotech +{ + [RimWorld.DefOf] + public static class HediffDefOf + { + // public static HediffDef Infatuo; + // public static HediffDef InfatuoCalibrating; + public static HediffDef OvaryAgitator; + public static HediffDef Bioscaffold; + } +} \ No newline at end of file diff --git a/Source/DefOf/LetterDefOf.cs b/Source/DefOf/LetterDefOf.cs new file mode 100644 index 0000000..ab671c8 --- /dev/null +++ b/Source/DefOf/LetterDefOf.cs @@ -0,0 +1,11 @@ +using RimWorld; +using Verse; + +namespace LewdBiotech +{ + [RimWorld.DefOf] + public static class LetterDefOf + { + public static LetterDef AnotherBaby; + } +} diff --git a/Source/Hediffs/Infatuo.cs b/Source/Hediffs/Infatuo.cs new file mode 100644 index 0000000..dbffd71 --- /dev/null +++ b/Source/Hediffs/Infatuo.cs @@ -0,0 +1,57 @@ +// FOR ANYONE (THAT ISN"T ME (BOEUF)) THAT CARES +// ===================== +// This is an idea for an implant that I had that basically forces a pawn to romantically obsess about another pawn, but I'm taking a break from working on it +// because I'm too smoothbrain to work out relation defs and making custom relations, and the multibirth stuff was taking up my time as is +// If you want to mess with it, this code is here for shits and gigs - modify it, throw it out, make something new, idgaf + +/*using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LewdBiotech.Hediffs +{ + class Infatuo + { + public class PawnRelationWorker_InfatuoInfatuated : PawnRelationWorker + { + // BaseGenerationChanceFactor - should NEVER autogenerate on pawns (for now, anyway) + new public float BaseGenerationChanceFactor(Pawn generated, Pawn other, PawnGenerationRequest request) + { + return 0.0f; + } + + // CreateRelation - shouldn't be needed for now since we're not autogenerating infatuo relations, but may be used in future + public override void CreateRelation(Pawn generated, Pawn other, ref PawnGenerationRequest request) + { + return; + } + + // GenerationChance - should NEVER autogenerate on pawns (for now, anyway) + public override float GenerationChance(Pawn generated, Pawn other, PawnGenerationRequest request) + { + return 0.0f; + } + + public override bool InRelation(Pawn me, Pawn other) + { + return (me.health.hediffSet.GetFirstHediff().target == other); + } + } + + public class Hediff_Infatuo : Hediff + { + public Hediff_Infatuo(Pawn intTarget) + { + target = intTarget; + } + public Pawn target; + } + + public class Hediff_InfatuoCalibrating : Hediff + { + + } + } +}*/ diff --git a/Source/Helpers/LBTLogger.cs b/Source/Helpers/LBTLogger.cs new file mode 100644 index 0000000..c25ad7c --- /dev/null +++ b/Source/Helpers/LBTLogger.cs @@ -0,0 +1,35 @@ +using Verse; + +namespace LewdBiotech.Helpers +{ + public static class LBTLogger + { + public static void Message(string message) + { + Log.Message("[INFO][LewdBT] - " + message); + } + + public static void Warning(string message) + { + Log.Message("[WARN][LewdBT] - " + message); + } + + public static void Error(string message) + { + Log.Message("[ ERR][LewdBT] - " + message); + } + + public static void MessageGroupHead(string message) + { + Log.Message("[INFO][LewdBT]╦═ " + message); + } + public static void MessageGroupBody(string message) + { + Log.Message("[INFO][LewdBT]╠═══ " + message); + } + public static void MessageGroupFoot(string message) + { + Log.Message("[INFO][LewdBT]╚═══ " + message); + } + } +} diff --git a/Source/Helpers/LaborState.cs b/Source/Helpers/LaborState.cs new file mode 100644 index 0000000..740fcb3 --- /dev/null +++ b/Source/Helpers/LaborState.cs @@ -0,0 +1,28 @@ +using System; +using RimWorld; +using Verse; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LewdBiotech +{ + class LaborState + { + public Pawn pawn; + public int birthTotal = 0; + public int birthCount = 1; + public bool hasOvaryAgitator = false; + public bool hasBioscaffold = false; + + public LaborState(Pawn pawn, int birthTotal) + { + this.pawn = pawn; + this.birthTotal = birthTotal; + this.birthCount = 0; + this.hasOvaryAgitator = pawn.health.hediffSet.HasHediff(HediffDef.Named("OvaryAgitator")); + this.hasBioscaffold = pawn.health.hediffSet.HasHediff(HediffDef.Named("OvaryAgitator")); + } + } +} diff --git a/Source/LewdBiotech.cs b/Source/LewdBiotech.cs new file mode 100644 index 0000000..cbd0b2f --- /dev/null +++ b/Source/LewdBiotech.cs @@ -0,0 +1,255 @@ +using HarmonyLib; +using RimWorld; +using rjw; +using LewdBiotech.Helpers; +using System.Collections.Generic; +using Verse; + +namespace LewdBiotech +{ + [StaticConstructorOnStartup] + public class LewdBiotechMod + { + public static readonly ThoughtDef regretsStealingLovin = DefDatabase.GetNamed("RegretsStealingLovin"); + public static readonly ThoughtDef stoleSomeLovin = DefDatabase.GetNamed("StoleSomeLovin"); + public static readonly ThoughtDef bloodlustStoleSomeLovin = DefDatabase.GetNamed("BloodlustStoleSomeLovin"); + public static readonly TraitDef rapist = DefDatabase.GetNamed("Rapist"); + static Dictionary laborStateMap = new Dictionary(); + + static LewdBiotechMod() + { + Harmony harmony = new Harmony(id: "rimworld.leboeuf.lewdbiotech"); + + // Non-rapist would_rape bypass for limbic stimulator - may be unused + harmony.Patch(AccessTools.Method(typeof(SexAppraiser), nameof(SexAppraiser.would_rape)), + postfix: new HarmonyMethod(typeof(LewdBiotechMod), nameof(would_rape_PostFix))); + + // Non-rapist is_rapist bypass for limbic stimulator + harmony.Patch(AccessTools.Method(typeof(xxx), nameof(xxx.is_rapist)), + postfix: new HarmonyMethod(typeof(LewdBiotechMod), nameof(is_rapist_PostFix))); + + // Non-Rapist trait rape thoughts + harmony.Patch(AccessTools.Method(typeof(AfterSexUtility), nameof(AfterSexUtility.think_about_sex_Rapist)), + postfix: new HarmonyMethod(typeof(LewdBiotechMod), nameof(think_about_sex_Rapist_PostFix))); + + // Bioscaffold double gestation speed tick + harmony.Patch(AccessTools.Method(typeof(Hediff_Pregnant), nameof(Hediff_Pregnant.Tick)), + postfix: new HarmonyMethod(typeof(LewdBiotechMod), nameof(Hediff_Pregnant_TickPostFix))); + + // Hediff_Labor state capture + harmony.Patch(AccessTools.Method(typeof(Hediff_Labor), nameof(Hediff_Labor.PostRemoved)), + postfix: new HarmonyMethod(typeof(LewdBiotechMod), nameof(Hediff_Labor_PostRemovedPostFix))); + + // OvaryAgitator/Gene_LitteredBirths multibirth logic + harmony.Patch(AccessTools.Method(typeof(Hediff_LaborPushing), nameof(Hediff_LaborPushing.PostRemoved)), + postfix: new HarmonyMethod(typeof(LewdBiotechMod), nameof(Hediff_LaborPushing_PostRemovedPostFix))); + + // ================================================================================================= + // Future content - Infatuo implant (possibly - don't know if I'm going to finish it; mixed feelings + /* harmony.Patch(AccessTools.Method(typeof(InteractionUtility), nameof(InteractionWorker.Interacted)), + postfix: new HarmonyMethod(typeof(LewdBiotech), nameof(InteractionWorker_InteractedPostfix)));*/ + // ================================================================================================= + + LBTLogger.Message("Lewd Biotech started successfully."); + + if (LBTSettings.devMode) + { + LBTLogger.Message("Notice: Developer logging for Lewd Biotech is currently active - it can be disabled in the mod settings."); + } + } + + // Is this even used??? I haven't seen it be hit in debug logs yet ... + // Keeping it here for now, I suppose. + static void would_rape_PostFix(ref bool __result, Pawn rapist) + { + if (rapist.health.hediffSet.HasHediff(HediffDef.Named("LimbicStimulator"))) + { + if (LBTSettings.devMode) + { + LBTLogger.MessageGroupHead("Found LimbicStimulator hediff during xxx.would_rape check"); + LBTLogger.MessageGroupBody("Pawn: " + rapist.NameShortColored + " (" + rapist.ThingID + ")"); + LBTLogger.MessageGroupBody("__result (Before roll): " + __result); + } + __result = Rand.Chance(0.95f); + if (LBTSettings.devMode) + { + LBTLogger.MessageGroupFoot("__result (After roll): " + __result); + } + } + } + + static void is_rapist_PostFix(ref bool __result, Pawn pawn) + { + if (pawn.health.hediffSet.HasHediff(HediffDef.Named("LimbicStimulator"))) + { + if (LBTSettings.devMode) + { + LBTLogger.Message("Found LimbicStimulator hediff during xxx.is_rapist check for " + pawn.NameShortColored + " (" + pawn.ThingID + ")" + " with __result = " + __result + " - forcing to true"); + __result = true; + } + } + } + + static void think_about_sex_Rapist_PostFix(ref ThoughtDef __result, Pawn pawn) + { + if (LBTSettings.regretStealingLovinThoughtDisabled) return; + + if (pawn.health.hediffSet.HasHediff(HediffDef.Named("LimbicStimulator")) && (__result == stoleSomeLovin || __result == bloodlustStoleSomeLovin) && !pawn.story.traits.HasTrait(rapist)) + { + __result = regretsStealingLovin; + } + } + + static void Hediff_Pregnant_TickPostFix(ref Hediff_Pregnant __instance) + { + // 60000 = 1 day ticks + // 0.055 = severity/gestation per day + // 0.000000916 (repeating) = target for "2x pregnancy speed"-ish + // Note for posterity: my original calucation ousted me as COMICALLY bad at math + // I also need to do a performance analysis on this - having this run every pregnant tick with multiple pawns on a map may be super expensive + if (__instance.pawn.health.hediffSet.HasHediff(HediffDef.Named("Bioscaffold")) && __instance.pawn.health.hediffSet.HasHediff(HediffDef.Named("PregnantHuman"))) + { + __instance.Severity = __instance.Severity + 0.000000916f; + } + } + + // Notes about Hediff_Labor_PostRemovedPostFix + // =========================================== + // Alright, didn't really want to make a patch for Labor as well as LaborPushing, but I have to because otherwise there's + // no way to assign a doctor on second/third/etc births if I only use LaborPushing, which can disproportionately cause + // more stillbirths than you might normally have + // + // I TRIED to modify the ChildBirth lord job and ritual code to allow the first doctor that was assigned and any childbirth + // attendees to just autoreassign themselves to the next births, but it wasn't working - for now, I'm not happy with how I'm + // doing this because multiple births now require: + // 1. (potentially several) forced pauses with letters telling the player to reassign a doctor to the mother who's giving birth to another child + // 2. A LOT of state carrying (that I likely overengineered :v) ) between hediff removes and adds + // + // I've got a dictionary now for storing state across hediffs and on multiple pawns, instead of what I was originally doing, which was using + // severity as a way of tracking state. LaborState class should help keep things a little more organized. + // + // I'll revisit this in the future (probably). Thanks for coming to my TED talk + static void Hediff_Labor_PostRemovedPostFix(ref Hediff_Labor __instance) + { + bool randomTwinsRoll; + int totalBirths; + bool laborStateIsNull = !laborStateMap.ContainsKey(__instance.pawn.ThingID); + bool hasLitteredBirthsGene = __instance.pawn.genes.HasGene(LewdBiotech.GeneDefOf.LitteredBirths); + + // we'll never do additional processing if this is the guaranteed last birth (eg birth #4) + if (!laborStateIsNull && laborStateMap.TryGetValue(__instance.pawn.ThingID).birthCount == 4) + { + return; + } + + // For now, littered birth overrides ovary agitator and twin calculations, so if a LaborState already exists + // with littered births gene, move on + if (!laborStateIsNull && hasLitteredBirthsGene) + { + if (LBTSettings.devMode) + { + LBTLogger.MessageGroupHead("Found active LaborState and LitteredBirths gene - skipping additional Hediff_Labor_PostRemovedPostFix work"); + LBTLogger.MessageGroupBody("Pawn: " + __instance.pawn.NameShortColored + " (" + __instance.pawn.ThingID + ")"); + LBTLogger.MessageGroupFoot("birthCount: " + laborStateMap.TryGetValue(__instance.pawn.ThingID).birthCount); + } + + return; + } + + // Make a new LaborState for the null case with littered births + if (laborStateIsNull && hasLitteredBirthsGene) + { + LBTLogger.Message("Found littered births gene"); + int litteredBirthsTotalRoll = Rand.RangeInclusive(2, 4); + laborStateMap.SetOrAdd(__instance.pawn.ThingID, new LaborState(__instance.pawn, litteredBirthsTotalRoll)); + return; + } + + // Finally, regardless of littered births gene, we only want new state creation on + // pawns that don't already have state, so return if state is !null (STATE SHOULD ALWAYS BE CLEANED IN LABORPUSHING POSTFIX) + if (!laborStateIsNull) + { + if (LBTSettings.devMode) + { + LBTLogger.Warning("Labor state for pawn " + __instance.pawn.NameShortColored + " (" + __instance.pawn.ThingID + ") is not null despite all checks passing for determining first instance of Hediff_Labor - this warning should never occur, and may indicate a bug in Hediff_LaborPushing of lingering labor state from a previous pregnancy"); + } + return; + } + + // For everything else, we do random twin and OvaryAgitator handling + // ------- + // If we fail a base chance twins roll, return without any additional processing and proceed with vanilla childbirth + // Notes on rolls: + // -> Chance without OvaryAgitator to have twins: 1% + // -> Chance with OvaryAgitator to have twins: Guaranteed + // ---> Chance with OvaryAgitator to have triplets (MUST HAVE SUCCEEDED TWINS ROLL): 50% + // ---> Chance with OvaryAgitator to have quadruplets (MUST HAVE SUCCEEDED TRIPLETS ROLL): 10% + // -> Chance with Littered Births gene: random between 2 and 4 (inclusive) + randomTwinsRoll = Rand.Chance(0.01f); + bool hasAgitator = __instance.pawn.health.hediffSet.HasHediff(HediffDef.Named("OvaryAgitator")); + if (!randomTwinsRoll && !hasAgitator) + { + // We failed rolls, and we don't have an agitator - no additional processing, do vanilla single baby birth + if (LBTSettings.devMode) + { + LBTLogger.MessageGroupHead("Inside Hediff_Labor_PostRemovedPostFix random twins check fail"); + LBTLogger.MessageGroupBody("Pawn: " + __instance.pawn.NameShortColored); + LBTLogger.MessageGroupBody("Random twins roll outcome: " + randomTwinsRoll); + LBTLogger.MessageGroupFoot("Has OvaryAgitator: " + hasAgitator); + } + return; + } + + // Beyond this point, we can assume the pawn has an agitator + totalBirths = 2; + bool agitatorTriplets = Rand.Chance(0.5f); + bool agitatorQuadruplets = Rand.Chance(0.1f); + if (hasAgitator) + { + if (agitatorTriplets) totalBirths = 3; + if (agitatorTriplets && agitatorQuadruplets) totalBirths = 4; + } + + // Set new LaborState + laborStateMap.Add(__instance.pawn.ThingID, new LaborState(__instance.pawn, totalBirths)); + } + + static void Hediff_LaborPushing_PostRemovedPostFix(ref Hediff_LaborPushing __instance) + { + bool hasAgitator = __instance.pawn.health.hediffSet.HasHediff(HediffDef.Named("OvaryAgitator")); + bool hasLitteredBirthsGene = __instance.pawn.genes.HasGene(LewdBiotech.GeneDefOf.LitteredBirths); + bool laborStateIsNull = !laborStateMap.ContainsKey(__instance.pawn.ThingID); + LaborState currentLaborState; + laborStateMap.TryGetValue(__instance.pawn.ThingID, out currentLaborState); + + if (laborStateIsNull) + { + return; + } + + if (currentLaborState.birthTotal == currentLaborState.birthCount) + { + laborStateMap.Remove(__instance.pawn.ThingID); + if (__instance.pawn.health.hediffSet.HasHediff(HediffDef.Named("Bioscaffold"))) { + __instance.pawn.health.RemoveHediff(__instance.pawn.health.hediffSet.GetFirstHediffOfDef(LewdBiotech.HediffDefOf.Bioscaffold)); + } + return; + } + + ((Hediff_Labor)__instance.pawn.health.AddHediff(RimWorld.HediffDefOf.PregnancyLabor)).SetParents(__instance.pawn, __instance.Father, PregnancyUtility.GetInheritedGeneSet(__instance.Father, __instance.pawn)); + currentLaborState.birthCount++; + + if (!hasAgitator && !hasLitteredBirthsGene) + { + if (LBTSettings.devMode) + { + LBTLogger.Message("Pawn " + __instance.pawn.NameShortColored + " (" + __instance.pawn.ThingID + ") is having random twins"); + } + Find.LetterStack.ReceiveLetter("Twins!", __instance.pawn.NameShortColored + " is still in labor and is having twins!\n\nBe sure to gather your doctor and additional friends and family to ensure the other baby is also born healthy!", LewdBiotech.LetterDefOf.AnotherBaby, __instance.pawn); + return; + } + + Find.LetterStack.ReceiveLetter("Another baby!", __instance.pawn.NameShortColored + " is still in labor and is having another baby!\n\nBe sure to gather your doctor and additional friends and family to ensure the next baby is also born healthy!", LewdBiotech.LetterDefOf.AnotherBaby, __instance.pawn); + } + } +} \ No newline at end of file diff --git a/Source/LewdBiotech.csproj b/Source/LewdBiotech.csproj new file mode 100644 index 0000000..9a0475b --- /dev/null +++ b/Source/LewdBiotech.csproj @@ -0,0 +1,77 @@ + + + + + Debug + AnyCPU + {D7D21B4A-1DA7-41D8-B202-C58CA8FA62AA} + Library + Properties + LewdBiotech + LewdBiotech + v4.7.2 + 512 + + + + none + true + ..\1.4\Assemblies\ + prompt + 4 + false + + + Always + + + + ..\..\..\..\..\workshop\content\294100\2009463077\Current\Assemblies\0Harmony.dll + + + ..\..\rjw\1.4\Assemblies\0MultiplayerAPI.dll + + + ..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll + False + + + ..\..\..\..\..\workshop\content\294100\2009463077\Current\Assemblies\HarmonyMod.dll + + + ..\..\rjw\1.4\Assemblies\RJW.dll + + + + + + + + + ..\..\..\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll + False + + + + + + + + + + + + + + + + + + + + + copy "$(SolutionDir)Source\obj\Release\$(SolutionName).dll" "$(SolutionDir)1.4\Assemblies" +$(SolutionDir)..\..\RimWorldWin64.exe + + + \ No newline at end of file diff --git a/Source/Properties/AssemblyInfo.cs b/Source/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..cbf0e3d --- /dev/null +++ b/Source/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("LewdBiotech")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("LewdBiotech")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("d7d21b4a-1da7-41d8-b202-c58ca8fa62aa")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Source/Settings/LBTSettings.cs b/Source/Settings/LBTSettings.cs new file mode 100644 index 0000000..cf874b9 --- /dev/null +++ b/Source/Settings/LBTSettings.cs @@ -0,0 +1,54 @@ +using UnityEngine; +using Verse; + +// If it isn't blatantly obvious, I unabashedly ripped this settings template from RJW, minus the fact that +// I won't be (personally) supporting multiplayer, and it's all in one file - but I digress ... +namespace LewdBiotech +{ + class LBTSettingsController : Mod + { + public LBTSettingsController(ModContentPack content) : base(content) + { + GetSettings(); + } + + public override string SettingsCategory() + { + return "LBTSettings".Translate(); + } + + public override void DoSettingsWindowContents(Rect inRect) + { + LBTSettings.DoWindowContents(inRect); + } + } + + public class LBTSettings : ModSettings + { + // For my own sanity, all now and future settings will have a default disabled/false state (at least, that's the plan), and + // the settings name and description should reflect that (not that I'm going to add that many settings, mind you) + public static bool devMode = false; + public static bool regretStealingLovinThoughtDisabled = false; + + public static void DoWindowContents(Rect inRect) + { + // Shrink the settings window a bit - don't need to be that w i d e + inRect.width = inRect.width - 400; + inRect.x = inRect.x + 200; + Listing_Standard listingStandard = new Listing_Standard(); + listingStandard.Begin(inRect); + listingStandard.Gap(4f); + listingStandard.CheckboxLabeled("EnableLBTDevLogging".Translate(), ref devMode, "EnableLBTDevLoggingDesc".Translate()); + listingStandard.Gap(4f); + listingStandard.CheckboxLabeled("RegretStealingLovinThoughtDisabled".Translate(), ref regretStealingLovinThoughtDisabled, "RegretStealingLovinThoughtDisabledDesc".Translate()); + listingStandard.End(); + } + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Values.Look(ref devMode, "EnableLBTDevLogging", devMode, true); + Scribe_Values.Look(ref regretStealingLovinThoughtDisabled, "regretStealingLovinThoughtDisabled", regretStealingLovinThoughtDisabled, true); + } + } +}