From 7ea74813b3fd4da6050eda487cf15cacb71cbedc Mon Sep 17 00:00:00 2001 From: Ed86 Date: Wed, 13 Jul 2022 15:13:21 +0300 Subject: [PATCH] 1.0 --- .gitattributes | 63 ++ .gitignore | 340 ++++++++++ 1.3/Assemblies/RimJobWorldCum.dll | Bin 0 -> 40960 bytes 1.3/Defs/HediffsDef/Hediff_CumController.xml | 49 ++ 1.3/Defs/HediffsDef/Hediffs_Cum.xml | 72 ++ 1.3/Defs/JobDefs/Jobs_CleanSelf.xml | 10 + .../WorkGiverDefs/WorkGivers_CleanSelf.xml | 16 + 1.3/Languages/English/Keyed/Cum.xml | 15 + 1.3/Patches/FacialAnimation_compatibility.xml | 20 + 1.3/Source/Mod/CumBase.cs | 53 ++ 1.3/Source/Mod/CumHelper.cs | 620 ++++++++++++++++++ 1.3/Source/Mod/DefOf/HediffDefOf.cs | 17 + 1.3/Source/Mod/DefOf/JobDefOf.cs | 11 + 1.3/Source/Mod/Hediffs/Hediff_Cum.cs | 155 +++++ .../Mod/Hediffs/Hediff_CumController.cs | 272 ++++++++ .../Mod/JobDrivers/JobDriver_CleanSelf.cs | 53 ++ 1.3/Source/Mod/Patch_AddCumOnOrgasm.cs | 65 ++ 1.3/Source/Mod/Patch_AddGizmo.cs | 68 ++ .../Mod/Patch_JobDriver_DubsBadHygiene.cs | 85 +++ 1.3/Source/Mod/Patch_RenderOverBody.cs | 52 ++ 1.3/Source/Mod/RimJobWorldCum.csproj | 80 +++ 1.3/Source/Mod/Textures.cs | 58 ++ .../Mod/WorkGivers/WorkGiver_CleanSelf.cs | 76 +++ 1.3/Source/Mod/packages.config | 4 + 1.3/Source/Properties/AssemblyInfo.cs | 32 + 1.3/Source/mod.sln | 25 + 1.3/Textures/CumIcon_drenched.png | Bin 0 -> 419 bytes 1.3/Textures/CumIcon_dripping.png | Bin 0 -> 385 bytes 1.3/Textures/CumIcon_little.png | Bin 0 -> 226 bytes 1.3/Textures/CumIcon_some.png | Bin 0 -> 265 bytes 1.3/Textures/splatch_1.png | Bin 0 -> 3417 bytes 1.3/Textures/splatch_2.png | Bin 0 -> 3027 bytes 1.3/Textures/splatch_3.png | Bin 0 -> 2976 bytes 1.3/Textures/splatch_4.png | Bin 0 -> 2965 bytes 1.3/Textures/splatch_5.png | Bin 0 -> 2990 bytes 1.3/Textures/splatch_6.png | Bin 0 -> 3463 bytes 1.3/Textures/splatch_7.png | Bin 0 -> 2226 bytes 1.3/Textures/splatch_8.png | Bin 0 -> 2480 bytes 1.3/Textures/splatch_9.png | Bin 0 -> 3066 bytes About/About.xml | 43 ++ About/Manifest.xml | 13 + README.md | 101 +-- 42 files changed, 2381 insertions(+), 87 deletions(-) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 1.3/Assemblies/RimJobWorldCum.dll create mode 100644 1.3/Defs/HediffsDef/Hediff_CumController.xml create mode 100644 1.3/Defs/HediffsDef/Hediffs_Cum.xml create mode 100644 1.3/Defs/JobDefs/Jobs_CleanSelf.xml create mode 100644 1.3/Defs/WorkGiverDefs/WorkGivers_CleanSelf.xml create mode 100644 1.3/Languages/English/Keyed/Cum.xml create mode 100644 1.3/Patches/FacialAnimation_compatibility.xml create mode 100644 1.3/Source/Mod/CumBase.cs create mode 100644 1.3/Source/Mod/CumHelper.cs create mode 100644 1.3/Source/Mod/DefOf/HediffDefOf.cs create mode 100644 1.3/Source/Mod/DefOf/JobDefOf.cs create mode 100644 1.3/Source/Mod/Hediffs/Hediff_Cum.cs create mode 100644 1.3/Source/Mod/Hediffs/Hediff_CumController.cs create mode 100644 1.3/Source/Mod/JobDrivers/JobDriver_CleanSelf.cs create mode 100644 1.3/Source/Mod/Patch_AddCumOnOrgasm.cs create mode 100644 1.3/Source/Mod/Patch_AddGizmo.cs create mode 100644 1.3/Source/Mod/Patch_JobDriver_DubsBadHygiene.cs create mode 100644 1.3/Source/Mod/Patch_RenderOverBody.cs create mode 100644 1.3/Source/Mod/RimJobWorldCum.csproj create mode 100644 1.3/Source/Mod/Textures.cs create mode 100644 1.3/Source/Mod/WorkGivers/WorkGiver_CleanSelf.cs create mode 100644 1.3/Source/Mod/packages.config create mode 100644 1.3/Source/Properties/AssemblyInfo.cs create mode 100644 1.3/Source/mod.sln create mode 100644 1.3/Textures/CumIcon_drenched.png create mode 100644 1.3/Textures/CumIcon_dripping.png create mode 100644 1.3/Textures/CumIcon_little.png create mode 100644 1.3/Textures/CumIcon_some.png create mode 100644 1.3/Textures/splatch_1.png create mode 100644 1.3/Textures/splatch_2.png create mode 100644 1.3/Textures/splatch_3.png create mode 100644 1.3/Textures/splatch_4.png create mode 100644 1.3/Textures/splatch_5.png create mode 100644 1.3/Textures/splatch_6.png create mode 100644 1.3/Textures/splatch_7.png create mode 100644 1.3/Textures/splatch_8.png create mode 100644 1.3/Textures/splatch_9.png create mode 100644 About/About.xml create mode 100644 About/Manifest.xml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4ce6fdd --- /dev/null +++ b/.gitignore @@ -0,0 +1,340 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# 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 + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.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 + +# Visual Studio Trace Files +*.e2e + +# 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 + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# 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 +# Note: 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 +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable 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 +*.appx + +# 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 +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# 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 +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- Backup*.rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# 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 personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb \ No newline at end of file diff --git a/1.3/Assemblies/RimJobWorldCum.dll b/1.3/Assemblies/RimJobWorldCum.dll new file mode 100644 index 0000000000000000000000000000000000000000..3223fd470ebbc5461f2f8a68cee38dc7ddc2b02b GIT binary patch literal 40960 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 literal 0 HcmV?d00001 diff --git a/1.3/Defs/HediffsDef/Hediff_CumController.xml b/1.3/Defs/HediffsDef/Hediff_CumController.xml new file mode 100644 index 0000000..854f8e0 --- /dev/null +++ b/1.3/Defs/HediffsDef/Hediff_CumController.xml @@ -0,0 +1,49 @@ + + + + + Hediff_CumController + rjwcum.Hediff_CumController + + Covered in cum. + false + 0.01 + 1 + + + + + false + false + +
  • + + false +
  • +
  • + 0.3 + + + 0.2 + -0.1 + +
  • +
  • + 0.6 + + + 0.3 + -0.3 + +
  • +
  • + 0.8 + + + -0.1 + -0.5 + +
  • +
    +
    +
    \ No newline at end of file diff --git a/1.3/Defs/HediffsDef/Hediffs_Cum.xml b/1.3/Defs/HediffsDef/Hediffs_Cum.xml new file mode 100644 index 0000000..3a77e61 --- /dev/null +++ b/1.3/Defs/HediffsDef/Hediffs_Cum.xml @@ -0,0 +1,72 @@ + + + + rjwcum.Hediff_Cum + Hediff_Cum + + cum + cum. + cum on {1} + (0.95,0.95,0.95) + false + false + false + false + 1 + 0.001 + + true + + +
  • + +
  • +
  • + 0.25 + +
  • +
  • + 0.5 + +
  • +
  • + 0.8 + +
  • +
    + +
  • + + 1800 + 0.01 +
  • +
    +
    + + + Hediff_Cum + + cum + cum + cum on {1} + (0.95,0.95,0.95) + + + + Hediff_InsectSpunk + Insect spunk. + + insect spunk + insect spunk on {1} + (0.6,0.83,0.35) + + + + Hediff_MechaFluids + Mechanoid fluids. + + mechanoid fluids + mecha fluids on {1} + (0.37,0.71,0.82) + +
    \ No newline at end of file diff --git a/1.3/Defs/JobDefs/Jobs_CleanSelf.xml b/1.3/Defs/JobDefs/Jobs_CleanSelf.xml new file mode 100644 index 0000000..12ae606 --- /dev/null +++ b/1.3/Defs/JobDefs/Jobs_CleanSelf.xml @@ -0,0 +1,10 @@ + + + + + CleanSelf + rjwcum.JobDriver_CleanSelf + cleaning self + true + + \ No newline at end of file diff --git a/1.3/Defs/WorkGiverDefs/WorkGivers_CleanSelf.xml b/1.3/Defs/WorkGiverDefs/WorkGivers_CleanSelf.xml new file mode 100644 index 0000000..62b7637 --- /dev/null +++ b/1.3/Defs/WorkGiverDefs/WorkGivers_CleanSelf.xml @@ -0,0 +1,16 @@ + + + + CleanSelf + + rjwcum.WorkGiver_CleanSelf + Cleaning + clean self + cleaning self + false + 11 + +
  • Manipulation
  • +
    +
    +
    \ No newline at end of file diff --git a/1.3/Languages/English/Keyed/Cum.xml b/1.3/Languages/English/Keyed/Cum.xml new file mode 100644 index 0000000..54ce568 --- /dev/null +++ b/1.3/Languages/English/Keyed/Cum.xml @@ -0,0 +1,15 @@ + + + Debug + + Enable cum on body (Hediffs) + Enables cum hediffs in health tab. + Adjust cum amount on body + All cum applied to pawn bodies will be multiplied by this amount. + Enable cum overlays (Visuals) + Enables cum overlay for pawn drawer(may have conflicts with mods that change pawn appearance and other issues).\nRequires Cum on body option enabled. + Hero manual CleanSelf + Hero pawn will only clean cum from body if manually told so. + DubsBadHygiene block CleanSelf + If DubsBadHygiene installed, pawns will only clean cum from body in buckets, showers, baths, hottubs etc. + \ No newline at end of file diff --git a/1.3/Patches/FacialAnimation_compatibility.xml b/1.3/Patches/FacialAnimation_compatibility.xml new file mode 100644 index 0000000..7a6b70e --- /dev/null +++ b/1.3/Patches/FacialAnimation_compatibility.xml @@ -0,0 +1,20 @@ + + + + +
  • [NL] Facial Animation - WIP
  • +
    + + Always + +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="Wear" or defName="Wear2" or defName="Wear3"]/targetJobs + Always + +
  • CleanSelf
  • + + +
    +
    +
    +
    \ No newline at end of file diff --git a/1.3/Source/Mod/CumBase.cs b/1.3/Source/Mod/CumBase.cs new file mode 100644 index 0000000..78cea32 --- /dev/null +++ b/1.3/Source/Mod/CumBase.cs @@ -0,0 +1,53 @@ +using System; +using HugsLib; +using HugsLib.Settings; +using Verse; + +namespace rjwcum +{ + public class CumBase : ModBase + { + public override string ModIdentifier + { + get + { + return "RJW_Cum"; + } + } + + public static SettingHandle debug; + public static SettingHandle cum_on_body; + public static SettingHandle cum_overlays; + public static SettingHandle cum_on_body_amount; + public static SettingHandle manual_hero_CleanSelf; + public static SettingHandle dubsDBH_block_CleanSelf; + + public override void DefsLoaded() + { + cum_on_body = Settings.GetHandle("debug", + Translator.Translate("debug"), + Translator.Translate("debug_desc"), + false); + cum_on_body = Settings.GetHandle("cum_on_body", + Translator.Translate("cum_on_body"), + Translator.Translate("cum_on_body_desc"), + true); + cum_overlays = Settings.GetHandle("cum_overlays", + Translator.Translate("cum_overlays"), + Translator.Translate("cum_overlays_desc"), + true); + cum_on_body_amount = Settings.GetHandle("cum_on_body_amount", + Translator.Translate("cum_on_body_amount"), + Translator.Translate("cum_on_body_amount_desc"), + 1.0f); + manual_hero_CleanSelf = Settings.GetHandle("manual_hero_CleanSelf", + Translator.Translate("manual_hero_CleanSelf"), + Translator.Translate("manual_hero_CleanSelf_desc"), + true); + dubsDBH_block_CleanSelf = Settings.GetHandle("dubsDBH_block_CleanSelf", + Translator.Translate("dubsDBH_block_CleanSelf"), + Translator.Translate("dubsDBH_block_CleanSelf_desc"), + true); + } + } +} diff --git a/1.3/Source/Mod/CumHelper.cs b/1.3/Source/Mod/CumHelper.cs new file mode 100644 index 0000000..9de0f69 --- /dev/null +++ b/1.3/Source/Mod/CumHelper.cs @@ -0,0 +1,620 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using RimWorld; +using Verse; +using HarmonyLib; +using UnityEngine; +//using Multiplayer.API; +using rjw; + +namespace rjwcum +{ + [StaticConstructorOnStartup] + public static class CumHelper + { + /* + contains many important functions of use to the other classes + */ + + //amount of cum per sex act: + + public static readonly Dictionary splatchAdjust;//saves x (horizontal) and z (vertical) adjustments of texture positiion for each unique combination of bodyType and bodyPart + public static readonly Dictionary layerAdjust;//saves y adjustments (drawing plane) for left/right appendages + bodyPart combinations to hide spunk if pawn looks in the wrong direction + + //structs are used to pack related variables together - used as keys for the dictionaries + public struct key//allows to save all unique combinations of bodyType and bodyPart + { + public readonly BodyTypeDef bodyType; + public readonly BodyPartDef bodyPart; + public key(BodyTypeDef bodyType, BodyPartDef bodyPart) + { + this.bodyType = bodyType; + this.bodyPart = bodyPart; + } + } + + //for the 4 directions, use arrays to store the different adjust for north, east, south, west (in that order) + public struct values + { + public readonly float[] x; + public readonly float[] z; + //public readonly bool over_clothing;//on gentials: hide when clothes are worn - in case of the other body parts it can't be said (for now) if it was added on the clothing or not + public values(float[] xAdjust, float[] zAdjust) + { + x = xAdjust; + z = zAdjust; + //this.over_clothing = over_clothing; + } + } + + + public struct key_layer//used to save left/right appendage + bodyPart combinations + { + public readonly bool left_side; + public readonly BodyPartDef bodyPart; + + public key_layer(bool left_side, BodyPartDef bodyPart) + { + this.left_side = left_side; + this.bodyPart = bodyPart; + } + } + + public struct values_layer//saves the y-adjustments for different body parts and sides -> e.g. allows hiding spunk on the right arm if pawn is looking to the left (aka west) + { + public readonly float[] y; + + public values_layer(float[] yAdjust) + { + y = yAdjust; + } + } + + //get defs of the rjw parts + public static BodyPartDef genitalsDef = BodyDefOf.Human.AllParts.Find(bpr => string.Equals(bpr.def.defName, "Genitals")).def; + public static BodyPartDef anusDef = BodyDefOf.Human.AllParts.Find(bpr => string.Equals(bpr.def.defName, "Anus")).def; + public static BodyPartDef chestDef = BodyDefOf.Human.AllParts.Find(bpr => string.Equals(bpr.def.defName, "Chest")).def; + + + static CumHelper() + { + splatchAdjust = new Dictionary(); + //maybe there is a more elegant way to save and load this data, but I don't know about it + + //structure explained: + //1) key: struct consisting of bodyType + bodyPart (= unique key for every combination of bodyType + part) + //2) values: struct containing positioning information (xAdjust: horizontal positioning, yAdjust: vertical positioning, zAdjust: whether to draw above or below pawn + //note: arms, hands, and legs (which are only visible from one direction) values need not be inverted between west and east + + //BodyType Thin + splatchAdjust.Add(new key(BodyTypeDefOf.Thin, BodyPartDefOf.Arm), new values(new float[] { -0.13f, 0.05f, 0.13f, 0.05f }, new float[] { 0f, 0f, 0f, 0f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Thin, BodyPartDefOf.Hand), new values(new float[] { -0.12f, 0.15f, 0.12f, 0.15f }, new float[] { -0.25f, -0.25f, -0.25f, -0.25f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Thin, BodyPartDefOf.Head), new values(new float[] { 0f, -0.23f, 0f, 0.23f }, new float[] { 0.37f, 0.35f, 0.33f, 0.35f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Thin, BodyPartDefOf.Jaw), new values(new float[] { 0f, -0.19f, 0f, 0.19f }, new float[] { 0.15f, 0.15f, 0.15f, 0.15f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Thin, BodyPartDefOf.Leg), new values(new float[] { -0.1f, 0.1f, 0.1f, 0.1f }, new float[] { -0.4f, -0.4f, -0.4f, -0.4f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Thin, BodyPartDefOf.Neck), new values(new float[] { 0f, -0.07f, 0f, 0.07f }, new float[] { 0.06f, 0.06f, 0.06f, 0.06f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Thin, BodyPartDefOf.Torso), new values(new float[] { 0f, 0f, 0f, 0f }, new float[] { -0.18f, -0.20f, -0.25f, -0.25f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Thin, genitalsDef), new values(new float[] { 0f, 0.01f, 0f, -0.01f }, new float[] { 0, -0.35f, -0.35f, -0.35f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Thin, anusDef), new values(new float[] { 0, 0.18f, 0, -0.18f }, new float[] { -0.42f, -0.35f, 0, -0.35f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Thin, chestDef), new values(new float[] { 0f, -0.1f, 0f, 0.1f }, new float[] { -0.06f, -0.05f, -0.06f, -0.05f })); + + //BodyType Female + splatchAdjust.Add(new key(BodyTypeDefOf.Female, BodyPartDefOf.Arm), new values(new float[] { -0.17f, 0f, 0.17f, 0f }, new float[] { 0f, 0f, 0f, 0f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Female, BodyPartDefOf.Hand), new values(new float[] { -0.17f, 0.1f, 0.17f, 0.1f }, new float[] { -0.25f, -0.25f, -0.25f, -0.25f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Female, BodyPartDefOf.Head), new values(new float[] { 0f, -0.23f, 0f, 0.23f }, new float[] { 0.37f, 0.35f, 0.33f, 0.35f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Female, BodyPartDefOf.Jaw), new values(new float[] { 0f, -0.19f, 0f, 0.19f }, new float[] { 0.15f, 0.15f, 0.15f, 0.15f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Female, BodyPartDefOf.Leg), new values(new float[] { -0.2f, 0.1f, 0.2f, 0.1f }, new float[] { -0.4f, -0.4f, -0.4f, -0.4f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Female, BodyPartDefOf.Neck), new values(new float[] { 0f, -0.07f, 0f, 0.07f }, new float[] { 0.06f, 0.06f, 0.06f, 0.06f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Female, BodyPartDefOf.Torso), new values(new float[] { 0f, -0.05f, 0f, 0.05f }, new float[] { -0.20f, -0.25f, -0.25f, -0.25f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Female, genitalsDef), new values(new float[] { 0f, -0.10f, 0f, 0.10f }, new float[] { 0, -0.42f, -0.45f, -0.42f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Female, anusDef), new values(new float[] { 0, 0.26f, 0, -0.26f }, new float[] { -0.42f, -0.35f, 0, -0.35f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Female, chestDef), new values(new float[] { 0f, -0.12f, 0f, 0.12f }, new float[] { -0.06f, -0.05f, -0.06f, -0.05f })); + + //BodyType Male + splatchAdjust.Add(new key(BodyTypeDefOf.Male, BodyPartDefOf.Arm), new values(new float[] { -0.21f, 0.05f, 0.21f, 0.05f }, new float[] { 0f, -0.02f, 0f, -0.02f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Male, BodyPartDefOf.Hand), new values(new float[] { -0.17f, 0.07f, 0.17f, 0.07f }, new float[] { -0.25f, -0.25f, -0.25f, -0.25f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Male, BodyPartDefOf.Head), new values(new float[] { 0f, -0.23f, 0f, 0.23f }, new float[] { 0.37f, 0.35f, 0.33f, 0.35f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Male, BodyPartDefOf.Jaw), new values(new float[] { 0f, -0.19f, 0f, 0.19f }, new float[] { 0.15f, 0.15f, 0.15f, 0.15f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Male, BodyPartDefOf.Leg), new values(new float[] { -0.17f, 0.07f, 0.17f, 0.07f }, new float[] { -0.4f, -0.4f, -0.4f, -0.4f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Male, BodyPartDefOf.Neck), new values(new float[] { 0f, -0.07f, 0f, 0.07f }, new float[] { 0.06f, 0.06f, 0.06f, 0.06f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Male, BodyPartDefOf.Torso), new values(new float[] { 0f, -0.05f, 0f, 0.05f }, new float[] { -0.20f, -0.25f, -0.25f, -0.25f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Male, genitalsDef), new values(new float[] { 0f, -0.07f, 0f, 0.07f }, new float[] { 0, -0.35f, -0.42f, -0.35f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Male, anusDef), new values(new float[] { 0, 0.17f, 0, -0.17f }, new float[] { -0.42f, -0.35f, 0, -0.35f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Male, chestDef), new values(new float[] { 0f, -0.16f, 0f, 0.16f }, new float[] { -0.06f, -0.05f, -0.06f, -0.05f })); + + //BodyType Hulk + splatchAdjust.Add(new key(BodyTypeDefOf.Hulk, BodyPartDefOf.Arm), new values(new float[] { -0.3f, 0.05f, 0.3f, 0.05f }, new float[] { 0f, -0.02f, 0f, -0.02f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Hulk, BodyPartDefOf.Hand), new values(new float[] { -0.22f, 0.07f, 0.22f, 0.07f }, new float[] { -0.28f, -0.28f, -0.28f, -0.28f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Hulk, BodyPartDefOf.Head), new values(new float[] { 0f, -0.23f, 0f, 0.23f }, new float[] { 0.37f, 0.35f, 0.33f, 0.35f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Hulk, BodyPartDefOf.Jaw), new values(new float[] { 0f, -0.19f, 0f, 0.19f }, new float[] { 0.15f, 0.15f, 0.15f, 0.15f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Hulk, BodyPartDefOf.Leg), new values(new float[] { -0.17f, 0.07f, 0.17f, 0.07f }, new float[] { -0.5f, -0.5f, -0.5f, -0.5f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Hulk, BodyPartDefOf.Neck), new values(new float[] { 0f, -0.07f, 0f, 0.07f }, new float[] { 0.06f, 0.06f, 0.06f, 0.06f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Hulk, BodyPartDefOf.Torso), new values(new float[] { 0f, -0.05f, 0f, 0.05f }, new float[] { -0.20f, -0.3f, -0.3f, -0.3f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Hulk, genitalsDef), new values(new float[] { 0f, -0.02f, 0f, 0.02f }, new float[] { 0, -0.55f, -0.55f, -0.55f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Hulk, anusDef), new values(new float[] { 0, 0.35f, 0, -0.35f }, new float[] { -0.5f, -0.5f, 0, -0.5f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Hulk, chestDef), new values(new float[] { 0f, -0.22f, 0f, 0.22f }, new float[] { -0.06f, -0.05f, -0.06f, -0.05f })); + + //BodyType Fat + splatchAdjust.Add(new key(BodyTypeDefOf.Fat, BodyPartDefOf.Arm), new values(new float[] { -0.3f, 0.05f, 0.3f, 0.05f }, new float[] { 0f, -0.02f, 0f, -0.02f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Fat, BodyPartDefOf.Hand), new values(new float[] { -0.32f, 0.07f, 0.32f, 0.07f }, new float[] { -0.28f, -0.28f, -0.28f, -0.28f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Fat, BodyPartDefOf.Head), new values(new float[] { 0f, -0.23f, 0f, 0.23f }, new float[] { 0.37f, 0.35f, 0.33f, 0.35f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Fat, BodyPartDefOf.Jaw), new values(new float[] { 0f, -0.19f, 0f, 0.19f }, new float[] { 0.15f, 0.15f, 0.15f, 0.15f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Fat, BodyPartDefOf.Leg), new values(new float[] { -0.17f, 0.07f, 0.17f, 0.07f }, new float[] { -0.45f, -0.45f, -0.45f, -0.45f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Fat, BodyPartDefOf.Neck), new values(new float[] { 0f, -0.07f, 0f, 0.07f }, new float[] { 0.06f, 0.06f, 0.06f, 0.06f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Fat, BodyPartDefOf.Torso), new values(new float[] { 0f, -0.15f, 0f, 0.15f }, new float[] { -0.20f, -0.3f, -0.3f, -0.3f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Fat, genitalsDef), new values(new float[] { 0f, -0.25f, 0f, 0.25f }, new float[] { 0, -0.45f, -0.50f, -0.45f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Fat, anusDef), new values(new float[] { 0, 0.35f, 0, -0.35f }, new float[] { -0.5f, -0.4f, 0, -0.4f })); + splatchAdjust.Add(new key(BodyTypeDefOf.Fat, chestDef), new values(new float[] { 0f, -0.27f, 0f, 0.27f }, new float[] { -0.07f, -0.05f, -0.07f, -0.05f })); + + + //now for the layer/plane adjustments: + layerAdjust = new Dictionary(); + + //left body parts: + //in theory, all body parts not coming in pairs should have the bool as false -> be listed as right, so I wouldn't need to add them here, but it doesn't hurt to be safe + layerAdjust.Add(new key_layer(true, BodyPartDefOf.Arm), new values_layer(new float[] { 0f, -99f, 0f, 0f }));//0.00 = drawn over body (=visible) if the pawn looks in any direction except west, in which case it's hidden (-99) + layerAdjust.Add(new key_layer(true, BodyPartDefOf.Hand), new values_layer(new float[] { 0f, -99f, 0f, 0f })); + layerAdjust.Add(new key_layer(true, BodyPartDefOf.Leg), new values_layer(new float[] { 0f, -99f, 0f, 0f })); + + layerAdjust.Add(new key_layer(true, BodyPartDefOf.Head), new values_layer(new float[] { 0.02f, 0.02f, 0.02f, 0.02f }));//drawn from all directions, 0.02 = over hair + layerAdjust.Add(new key_layer(true, BodyPartDefOf.Jaw), new values_layer(new float[] { -9f, 0.01f, 0.01f, 0.01f }));//0.01 = drawn over head but under hair, only hidden if facing north + layerAdjust.Add(new key_layer(true, BodyPartDefOf.Neck), new values_layer(new float[] { 0f, 0f, 0f, 0f })); + layerAdjust.Add(new key_layer(true, BodyPartDefOf.Torso), new values_layer(new float[] { 0f, 0f, 0f, 0f })); + layerAdjust.Add(new key_layer(true, genitalsDef), new values_layer(new float[] { -99f, 0f, 0f, 0f }));//only hidden if facing north + layerAdjust.Add(new key_layer(true, anusDef), new values_layer(new float[] { 0f, 0f, -99f, 0f })); + layerAdjust.Add(new key_layer(true, chestDef), new values_layer(new float[] { -99f, 0f, 0f, 0f })); + + //right body parts: + layerAdjust.Add(new key_layer(false, BodyPartDefOf.Arm), new values_layer(new float[] { 0f, 0f, 0f, -99f })); + layerAdjust.Add(new key_layer(false, BodyPartDefOf.Hand), new values_layer(new float[] { 0f, 0f, 0f, -99f })); + layerAdjust.Add(new key_layer(false, BodyPartDefOf.Leg), new values_layer(new float[] { 0f, 0f, 0f, -99f })); + + layerAdjust.Add(new key_layer(false, BodyPartDefOf.Head), new values_layer(new float[] { 0.02f, 0.02f, 0.02f, 0.02f })); + layerAdjust.Add(new key_layer(false, BodyPartDefOf.Jaw), new values_layer(new float[] { -99f, 0.01f, 0.01f, 0.01f })); + layerAdjust.Add(new key_layer(false, BodyPartDefOf.Neck), new values_layer(new float[] { 0f, 0f, 0f, 0f })); + layerAdjust.Add(new key_layer(false, BodyPartDefOf.Torso), new values_layer(new float[] { 0f, 0f, 0f, 0f })); + layerAdjust.Add(new key_layer(false, genitalsDef), new values_layer(new float[] { -99f, 0f, 0f, 0f })); + layerAdjust.Add(new key_layer(false, anusDef), new values_layer(new float[] { 0f, 0f, -99f, 0f })); + layerAdjust.Add(new key_layer(false, chestDef), new values_layer(new float[] { -99f, 0f, 0f, 0f })); + + } + + //all body parts that cum can theoretically be applied to: + public static List getAllowedBodyParts() + { + List allowedParts = new List(); + + allowedParts.Add(BodyPartDefOf.Arm); + allowedParts.Add(BodyPartDefOf.Hand); + allowedParts.Add(BodyPartDefOf.Leg); + allowedParts.Add(BodyPartDefOf.Head); + allowedParts.Add(BodyPartDefOf.Jaw); + allowedParts.Add(BodyPartDefOf.Neck); + allowedParts.Add(BodyPartDefOf.Torso); + allowedParts.Add(genitalsDef); + allowedParts.Add(anusDef); + allowedParts.Add(chestDef); + + return allowedParts; + } + + //get valid body parts for a specific pawn + public static IEnumerable getAvailableBodyParts(Pawn pawn) + { + //get all non-missing body parts: + IEnumerable bodyParts = pawn.health.hediffSet.GetNotMissingParts(BodyPartHeight.Undefined, BodyPartDepth.Outside, null, null); + BodyPartRecord anus = pawn.def.race.body.AllParts.Find(bpr => string.Equals(bpr.def.defName, "Anus"));//not found by above function since depth is "inside" + + if (anus != null) + { + bodyParts = bodyParts.AddItem(anus); + } + + //filter for allowed body parts (e.g. no single fingers/toes): + List filterParts = CumHelper.getAllowedBodyParts(); + + IEnumerable filteredParts = bodyParts.Where(item1 => filterParts.Any(item2 => item2.Equals(item1.def))); + return filteredParts; + } + + + public const int CUM_NORMAL = 0; + public const int CUM_INSECT = 1; + public const int CUM_MECHA = 2; + + public static readonly Color color_normal = new Color(0.95f, 0.95f, 0.95f); + public static readonly Color color_insect = new Color(0.6f, 0.83f, 0.35f);//green-yellowish + public static readonly Color color_mecha = new Color(0.37f, 0.71f, 0.82f);//cyan-ish + + //name should be self-explanatory: + public static void cumOn(Pawn receiver, BodyPartRecord bodyPart, float amount = 0.2f, Pawn giver = null, int cumType = CUM_NORMAL) + { + Hediff_Cum hediff; + if (cumType == CUM_NORMAL) + { + hediff = (Hediff_Cum)HediffMaker.MakeHediff(HediffDefOf.Hediff_Cum, receiver, null); + } + else if (cumType == CUM_INSECT) + { + hediff = (Hediff_Cum)HediffMaker.MakeHediff(HediffDefOf.Hediff_InsectSpunk, receiver, null); + } + else + { + hediff = (Hediff_Cum)HediffMaker.MakeHediff(HediffDefOf.Hediff_MechaFluids, receiver, null); + } + + hediff.Severity = amount;//if this body part is already maximally full -> spill over to other parts + + //idea: here, a log entry that can act as source could be linked to the hediff - maybe reuse the playlog entry of rjw: + hediff.cumType = cumType; + + try + { + //error when adding to missing part + receiver.health.AddHediff(hediff, bodyPart, null, null); + } + catch + { + + } + + //Log.Message(xxx.get_pawnname(receiver) + " cum amount" + amount); + //causes significant memory leak, fixx someday + //if (amount > 1f)//spillover in case of very large amounts: just apply hediff a second time + //{ + // Hediff_cum hediff2 = (Hediff_cum)HediffMaker.MakeHediff(hediff.def, receiver, null); + // hediff2.cumType = cumType; + // hediff2.Severity = amount - 1f; + // receiver.health.AddHediff(hediff2, bodyPart, null, null); + //} + + //always also add cumcontroller hediff as manager + receiver.health.AddHediff(HediffDefOf.Hediff_CumController); + } + + //if spunk on one body part reaches a certain level, it can spill over to others, this function returns from where to where + //[SyncMethod] + public static BodyPartDef spillover(BodyPartDef sourcePart) + { + //caution: danger of infinite loop if circular spillover between 2 full parts -> don't define possible circles + BodyPartDef newPart = null; + int sel; + //Rand.PopState(); + //Rand.PushState(RJW_Multiplayer.PredictableSeed()); + if (sourcePart == BodyPartDefOf.Torso) + { + sel = Rand.Range(0, 4); + if (sel == 0) + { + newPart = BodyPartDefOf.Arm; + } + else if (sel == 1) + { + newPart = BodyPartDefOf.Leg; + } + else if (sel == 2) + { + newPart = BodyPartDefOf.Neck; + } + else if (sel == 3) + { + newPart = chestDef; + } + } + else if (sourcePart == BodyPartDefOf.Jaw) + { + sel = Rand.Range(0, 4); + if (sel == 0) + { + newPart = BodyPartDefOf.Head; + } + else if (sel == 1) + { + newPart = BodyPartDefOf.Torso; + } + else if (sel == 2) + { + newPart = BodyPartDefOf.Neck; + } + else if (sel == 3) + { + newPart = chestDef; + } + } + else if (sourcePart == genitalsDef) + { + sel = Rand.Range(0, 2); + if (sel == 0) + { + newPart = BodyPartDefOf.Leg; + } + else if (sel == 1) + { + newPart = BodyPartDefOf.Torso; + } + } + else if (sourcePart == anusDef) + { + sel = Rand.Range(0, 2); + if (sel == 0) + { + newPart = BodyPartDefOf.Leg; + } + else if (sel == 1) + { + newPart = BodyPartDefOf.Torso; + } + } + else if (sourcePart == chestDef) + { + sel = Rand.Range(0, 3); + if (sel == 0) + { + newPart = BodyPartDefOf.Arm; + } + else if (sel == 1) + { + newPart = BodyPartDefOf.Torso; + } + else if (sel == 2) + { + newPart = BodyPartDefOf.Neck; + } + } + return newPart; + } + + //determines who is the active male (or equivalent) in the exchange and the amount of cum dispensed and where to + //[SyncMethod] + public static void calculateAndApplyCum(SexProps props) + { + if (!CumBase.cum_on_body) return; + Pawn pawn = props.pawn; + Pawn partner = props.partner; + + Pawn giver, receiver; + //Rand.PopState(); + //Rand.PushState(RJW_Multiplayer.PredictableSeed()); + + List giverparts; + List pawnparts = pawn.GetGenitalsList(); + List partnerparts = partner != pawn ? partner.GetGenitalsList(): null; // masturbation + + //dispenser of the seed + if (xxx.is_mechanoid(pawn) || Genital_Helper.has_penis_fertile(pawn, pawnparts) || Genital_Helper.has_ovipositorF(pawn, pawnparts)) + { + giver = pawn; + giverparts = pawnparts; + receiver = partner; + } + else if (partner != null && props.isCoreLovin && (xxx.is_mechanoid(partner) || Genital_Helper.has_penis_fertile(partner, partnerparts) || Genital_Helper.has_ovipositorF(partner, partnerparts))) + { + giver = partner; + giverparts = partnerparts; + receiver = pawn; + } + else//female on female or genderless - no cum dispensed; maybe add futa support? + { + return; + } + + //slimes do not waste fluids? + //if (xxx.is_slime(giver)) return; + + //determine entity: + int entityType = CumHelper.CUM_NORMAL; + if (xxx.is_mechanoid(giver)) + { + entityType = CumHelper.CUM_MECHA; + } + else if (xxx.is_insect(giver)) + { + entityType = CumHelper.CUM_INSECT; + } + + //ModLog.Message("giver " + xxx.get_pawnname(giver)); + //ModLog.Message("receiver " + xxx.get_pawnname(receiver)); + //ModLog.Message("Cumtype " + entityType); + + //get pawn genitalia: + BodyPartRecord genitals; + if (xxx.is_mechanoid(giver)) + { + genitals = giver.RaceProps.body.AllParts.Find(x => string.Equals(x.def.defName, "MechGenitals")); + } + else//insects, animals, humans + { + genitals = giver.RaceProps.body.AllParts.Find(x => x.def == CumHelper.genitalsDef); + + } + //no cum without genitals + if (genitals == null) + { + return; + } + + float cumAmount = giver.BodySize; //fallback for mechanoinds and w/e without hediffs + float horniness = 1f; + float ageScale = Math.Min(80 / SexUtility.ScaleToHumanAge(giver), 1.0f);//calculation lifted from rjw + + if (xxx.is_mechanoid(giver) && giverparts.NullOrEmpty()) + { + //use default above + } + else if (giverparts.NullOrEmpty()) + return; + else + { + var penisHediff = giverparts.FindAll((Hediff hed) => hed.def.defName.ToLower().Contains("penis")).InRandomOrder().FirstOrDefault(); + + if (penisHediff == null) + penisHediff = giverparts.FindAll((Hediff hed) => hed.def.defName.ToLower().Contains("ovipositorf")).InRandomOrder().FirstOrDefault(); + if (penisHediff == null) + penisHediff = giverparts.FindAll((Hediff hed) => hed.def.defName.ToLower().Contains("ovipositorm")).InRandomOrder().FirstOrDefault(); + if (penisHediff == null) + penisHediff = giverparts.FindAll((Hediff hed) => hed.def.defName.ToLower().Contains("tentacle")).InRandomOrder().FirstOrDefault(); + + if (penisHediff != null) + { + cumAmount = penisHediff.Severity * giver.BodySize; + + CompHediffBodyPart chdf = penisHediff.TryGetComp(); + if (chdf != null) + { + if (chdf.FluidAmmount != 0) + cumAmount = chdf.FluidAmmount * chdf.FluidModifier; + } + //ModLog.Message("cumAmount base " + cumAmount); + + Need sexNeed = giver?.needs?.AllNeeds.Find(x => string.Equals(x.def.defName, "Sex")); + if (sexNeed != null)//non-humans don't have it - therefore just use the default value + { + horniness = 1f - sexNeed.CurLevel; + } + } + else + { + //something is wrong... vagina? + return; + } + } + + cumAmount *= CumBase.cum_on_body_amount; + //ModLog.Message("cumAmount after cum_on_body_amount_adjust after " + cumAmount); + cumAmount *= horniness; + //ModLog.Message("cumAmount after horniness mod " + cumAmount); + cumAmount *= ageScale; + //ModLog.Message("cumAmount after ageScale mod " + cumAmount); + cumAmount /= 10; + //ModLog.Message("cumAmount final " + cumAmount); + + //TODO: cumHelper Autofellatio + //if no partner -> masturbation, apply some cum on self: + //if (partner == null && sextype == xxx.rjwSextype.Autofellatio) + //{ + // if (!xxx.is_slime(giver)) + // cumHelper.cumOn(giver, BodyPartDefOf.Jaw, cumAmount, giver); + // return; + //} + if (props.sexType == xxx.rjwSextype.Masturbation) + { + if (!xxx.is_slime(giver)) + CumHelper.cumOn(giver, genitals, cumAmount * 0.3f, giver);//pawns are usually not super-messy -> only apply 30% + return; + } + else if (receiver != null) + { + List targetParts = new List();//which to apply cum on + IEnumerable availableParts = CumHelper.getAvailableBodyParts(receiver); + BodyPartRecord randomPart;//not always needed + + switch (props.sexType) + { + case rjw.xxx.rjwSextype.Anal: + targetParts.Add(receiver.RaceProps.body.AllParts.Find(x => x.def == CumHelper.anusDef)); + break; + case rjw.xxx.rjwSextype.Boobjob: + targetParts.Add(receiver.RaceProps.body.AllParts.Find(x => x.def == CumHelper.chestDef)); + break; + case rjw.xxx.rjwSextype.DoublePenetration: + targetParts.Add(receiver.RaceProps.body.AllParts.Find(x => x.def == CumHelper.anusDef)); + targetParts.Add(receiver.RaceProps.body.AllParts.Find(x => x.def == CumHelper.genitalsDef)); + break; + case rjw.xxx.rjwSextype.Fingering: + cumAmount = 0; + break; + case rjw.xxx.rjwSextype.Fisting: + cumAmount = 0; + break; + case rjw.xxx.rjwSextype.Footjob: + //random part: + availableParts.TryRandomElement(out randomPart); + targetParts.Add(randomPart); + break; + case rjw.xxx.rjwSextype.Handjob: + //random part: + availableParts.TryRandomElement(out randomPart); + targetParts.Add(randomPart); + break; + case rjw.xxx.rjwSextype.Masturbation: + cumAmount *= 2f; + break; + case rjw.xxx.rjwSextype.MechImplant: + //one of the openings: + int random = Rand.Range(0, 3); + if (random == 0) + { + targetParts.Add(receiver.RaceProps.body.AllParts.Find(x => x.def == CumHelper.genitalsDef)); + } + else if (random == 1) + { + targetParts.Add(receiver.RaceProps.body.AllParts.Find(x => x.def == CumHelper.anusDef)); + } + else if (random == 2) + { + targetParts.Add(receiver.RaceProps.body.AllParts.Find(x => x.def == BodyPartDefOf.Jaw)); + } + break; + case rjw.xxx.rjwSextype.MutualMasturbation: + //random + availableParts.TryRandomElement(out randomPart); + targetParts.Add(randomPart); + break; + case rjw.xxx.rjwSextype.None: + cumAmount = 0; + break; + case rjw.xxx.rjwSextype.Oral: + targetParts.Add(receiver.RaceProps.body.AllParts.Find(x => x.def == BodyPartDefOf.Jaw)); + break; + case rjw.xxx.rjwSextype.Scissoring: + //I guess if it came to here, a male must be involved? + targetParts.Add(receiver.RaceProps.body.AllParts.Find(x => x.def == CumHelper.genitalsDef)); + break; + case rjw.xxx.rjwSextype.Vaginal: + targetParts.Add(receiver.RaceProps.body.AllParts.Find(x => x.def == CumHelper.genitalsDef)); + break; + } + + if (cumAmount > 0) + { + if (receiver != null && xxx.is_slime(receiver)) + { + //slime absorb cum + //this needs balancing, since cumamount ranges 0-10(?) which is fine for cum/hentai but not very realistic for feeding + //using TransferNutrition for now + //Log.Message("cumAmount " + cumAmount); + //float nutrition_amount = cumAmount/10; + + Need_Food need = need = giver.needs.TryGetNeed(); + if (need == null) + { + //Log.Message("xxx::TransferNutrition() " + xxx.get_pawnname(pawn) + " doesn't track nutrition in itself, probably shouldn't feed the others"); + return; + } + + if (receiver?.needs?.TryGetNeed() != null) + { + //Log.Message("xxx::TransferNutrition() " + xxx.get_pawnname(partner) + " can receive"); + float nutrition_amount = Math.Min(need.MaxLevel / 15f, need.CurLevel); //body size is taken into account implicitly by need.MaxLevel + receiver.needs.food.CurLevel += nutrition_amount; + } + } + else + { + CumHelper.cumOn(giver, genitals, cumAmount * 0.3f, giver, entityType);//cum on self - smaller amount + if (receiver != null) + foreach (BodyPartRecord bpr in targetParts) + { + if (bpr != null) + { + CumHelper.cumOn(receiver, bpr, cumAmount, giver, entityType);//cum on partner + } + } + } + } + } + } + + } +} diff --git a/1.3/Source/Mod/DefOf/HediffDefOf.cs b/1.3/Source/Mod/DefOf/HediffDefOf.cs new file mode 100644 index 0000000..46e8255 --- /dev/null +++ b/1.3/Source/Mod/DefOf/HediffDefOf.cs @@ -0,0 +1,17 @@ +using RimWorld; +using Verse; + +namespace rjwcum +{ + [DefOf] + public static class HediffDefOf + { + public static HediffDef Hediff_Cum;//for humans & animals + public static HediffDef Hediff_InsectSpunk; + public static HediffDef Hediff_MechaFluids; + + public static HediffDef Hediff_CumController;//cum hediff manager + + } + +} diff --git a/1.3/Source/Mod/DefOf/JobDefOf.cs b/1.3/Source/Mod/DefOf/JobDefOf.cs new file mode 100644 index 0000000..f8569e6 --- /dev/null +++ b/1.3/Source/Mod/DefOf/JobDefOf.cs @@ -0,0 +1,11 @@ +using RimWorld; +using Verse; + +namespace rjwcum +{ + [DefOf] + public static class JobDefOf + { + public static JobDef CleanSelf; + } +} diff --git a/1.3/Source/Mod/Hediffs/Hediff_Cum.cs b/1.3/Source/Mod/Hediffs/Hediff_Cum.cs new file mode 100644 index 0000000..7652b64 --- /dev/null +++ b/1.3/Source/Mod/Hediffs/Hediff_Cum.cs @@ -0,0 +1,155 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Verse; +using UnityEngine; +//using Multiplayer.API; + +namespace rjwcum +{ + public class Hediff_Cum : HediffWithComps + { + public int cumType = CumHelper.CUM_NORMAL;//-> different colors + + public string giverName = null;//not utilized right now, maybe in the future save origin of the cum + + public override string LabelInBrackets + { + get + { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.Append(base.LabelInBrackets); + if (this.sourceHediffDef != null) + { + if (stringBuilder.Length != 0) + { + stringBuilder.Append(", "); + } + stringBuilder.Append(this.sourceHediffDef.label); + } + else if (this.source != null) + { + if (stringBuilder.Length != 0) + { + stringBuilder.Append(", "); + } + stringBuilder.Append(this.source.label); + if (this.sourceBodyPartGroup != null) + { + stringBuilder.Append(" "); + stringBuilder.Append(this.sourceBodyPartGroup.LabelShort); + } + } + return stringBuilder.ToString(); + } + } + + + public override string SeverityLabel + { + get + { + if (this.Severity == 0f) + { + return null; + } + return this.Severity.ToString("F1"); + } + } + + //[SyncMethod] + public override bool TryMergeWith(Hediff other) + { + //if a new cum hediff is added to the same body part, they are combined. if severity reaches more than 1, spillover to other body parts occurs + + Hediff_Cum hediff_cum = other as Hediff_Cum; + if (hediff_cum != null && hediff_cum.def == this.def && hediff_cum.Part == base.Part && this.def.injuryProps.canMerge) + { + cumType = hediff_cum.cumType;//take over new creature color + + float totalAmount = hediff_cum.Severity + this.Severity; + if (totalAmount > 1.0f) + { + BodyPartDef spillOverTo = CumHelper.spillover(this.Part.def);//cumHelper saves valid other body parts for spillover + if (spillOverTo != null) + { + //Rand.PopState(); + //Rand.PushState(RJW_Multiplayer.PredictableSeed()); + IEnumerable availableParts = CumHelper.getAvailableBodyParts(pawn);//gets all non missing, valid body parts + IEnumerable filteredParts = availableParts.Where(x => x.def == spillOverTo);//filters again for valid spill target + if (!filteredParts.EnumerableNullOrEmpty()) + { + BodyPartRecord spillPart = null; + spillPart = filteredParts.RandomElement();//then pick one + if (spillPart != null) + { + CumHelper.cumOn(pawn, spillPart, totalAmount - this.Severity, null, cumType); + } + } + } + } + + return (base.TryMergeWith(other)); + + } + return (false); + } + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Values.Look(ref cumType, "cumType", CumHelper.CUM_NORMAL); + + if (Scribe.mode == LoadSaveMode.PostLoadInit && base.Part == null) + { + //Log.Error("Hediff_cum has null part after loading.", false); + this.pawn.health.hediffSet.hediffs.Remove(this); + return; + } + } + + //handles the icon in the health tab and its color + public override TextureAndColor StateIcon + { + get + { + TextureAndColor tex = TextureAndColor.None; + Color color = Color.white; + switch (cumType) + { + case CumHelper.CUM_NORMAL: + color = CumHelper.color_normal; + break; + case CumHelper.CUM_INSECT: + color = CumHelper.color_insect; + break; + case CumHelper.CUM_MECHA: + color = CumHelper.color_mecha; + break; + } + + Texture2D tex2d = CumTextures.CumIcon_little; + switch (this.CurStageIndex) + { + case 0: + tex2d = CumTextures.CumIcon_little; + break; + case 1: + tex2d = CumTextures.CumIcon_some; + break; + case 2: + tex2d = CumTextures.CumIcon_dripping; + break; + case 3: + tex2d = CumTextures.CumIcon_drenched; + break; + } + + tex = new TextureAndColor(tex2d, color); + + return tex; + } + } + + } +} diff --git a/1.3/Source/Mod/Hediffs/Hediff_CumController.cs b/1.3/Source/Mod/Hediffs/Hediff_CumController.cs new file mode 100644 index 0000000..a3a3224 --- /dev/null +++ b/1.3/Source/Mod/Hediffs/Hediff_CumController.cs @@ -0,0 +1,272 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Verse; +using RimWorld; +using UnityEngine; +//using Multiplayer.API; + +namespace rjwcum +{ + class Hediff_CumController : HediffWithComps + { + /* + Whenever cum is applied, this hediff is also added to the pawn. + Since there is always only a single hediff of this type on the pawn, it serves as master controller, adding up the individual cum hediffs, applying debuffs and drawing overlays + */ + + private static readonly float cumWeight = 0.2f;//how much individual cum_hediffs contribute to the overall bukkake severity + List hediffs_cum; + Dictionary splatches; + + public override void ExposeData() + { + base.ExposeData(); + //Scribe_Values.Look>(ref splatches, "splatches", new Dictionary()); - causes errors when loading. for now, just make a new dictionary + splatches = new Dictionary();//instead of loading, just recreate anew + hediffs_cum = new List(); + } + + public override void PostMake() + { + base.PostMake(); + splatches = new Dictionary(); + } + + public override void PostTick() + { + if (pawn.RaceProps.Humanlike)//for now, only humans are supported + { + hediffs_cum = this.pawn.health.hediffSet.hediffs.FindAll(x => (x.def == HediffDefOf.Hediff_Cum || x.def == HediffDefOf.Hediff_InsectSpunk || x.def == HediffDefOf.Hediff_MechaFluids)); + float Level = CalculateLevel();//sum of severity of all the cum hediffs x cumWeight + this.Severity = Level; + bool updatePortrait = false; + + //loop through all cum hediffs, add missing ones to dictionary + for (int i = 0; i < hediffs_cum.Count(); i++) + { + Hediff_Cum h = (Hediff_Cum)hediffs_cum[i]; + string ID = h.GetUniqueLoadID();//unique ID for each hediff + if (!splatches.ContainsKey(ID))//if it isn't here yet, make new object + { + updatePortrait = true; + bool leftSide = h.Part.Label.Contains("left") ? true : false;//depending on whether the body part is left or right, drawing-offset on x-aixs may be inverted + + splatches[ID] = new CumSplatch(h, pawn.story.bodyType, h.Part.def, leftSide, h.cumType); + } + } + + + + //remove splatch objects once their respective cum hediff is gone + List removeKeys = new List(); + foreach (string key in splatches.Keys) + { + CumSplatch s = splatches[key]; + + if (!hediffs_cum.Contains(s.hediff_cum)) + { + removeKeys.Add(key); + updatePortrait = true; + } + } + //loop over and remove elements that should be destroyed: + foreach (string key in removeKeys) + { + CumSplatch s = splatches[key]; + splatches.Remove(key); + } + + if (updatePortrait)//right now, portraits are only updated when a completely new cum hediff is added or an old one removed - maybe that should be done more frequently + { + PortraitsCache.SetDirty(pawn); + } + } + } + + //called from the PawnWoundDrawer (see HarmonyPatches) + public void DrawCum(Vector3 drawLoc, Quaternion quat, bool forPortrait, float angle, bool inBed = false) + { + Rot4 bodyFacing = pawn.Rotation; + int facingDir = bodyFacing.AsInt;//0: north, 1:east, 2:south, 3:west + foreach (string key in splatches.Keys) + { + CumSplatch s = splatches[key]; + s.Draw(drawLoc, quat, forPortrait, facingDir, angle, inBed); + } + } + + //new Hediff_CumController added to pawn -> just combine the two + public override bool TryMergeWith(Hediff other) + { + if (other == null || other.def != this.def) + { + return false; + } + return true; + } + + private float CalculateLevel() + { + float num = 0f; + for (int i = 0; i < hediffs_cum.Count; i++) + { + num += hediffs_cum[i].Severity * cumWeight; + } + return num; + } + + //class for handling drawing of the individual splatches + private class CumSplatch + { + public readonly Hediff_Cum hediff_cum; + public readonly Material cumMaterial; + public readonly BodyPartDef bodyPart; + private bool mirrorMesh; + + private const float maxSize = 0.20f;//1.0 = 1 tile + private const float minSize = 0.05f; + + //data taken from CumHelper.cs: + private readonly float[] xAdjust; + private readonly float[] zAdjust; + private readonly float[] yAdjust; + + public CumSplatch(Hediff_Cum hediff, BodyTypeDef bodyType, BodyPartDef bodyPart, bool leftSide = false, int cumType = CumHelper.CUM_NORMAL) + { + hediff_cum = hediff; + cumMaterial = new Material(CumTextures.pickRandomSplatch());//needs to create new material in order to allow for different colors + cumMaterial.SetTextureScale("_MainTex", new Vector2(-1, 1)); + this.bodyPart = bodyPart; + //Rand.PopState(); + //Rand.PushState(RJW_Multiplayer.PredictableSeed()); + + //set color: + switch (cumType) + { + case CumHelper.CUM_NORMAL: + cumMaterial.color = CumHelper.color_normal; + break; + case CumHelper.CUM_INSECT: + cumMaterial.color = CumHelper.color_insect; + break; + case CumHelper.CUM_MECHA: + cumMaterial.color = CumHelper.color_mecha; + break; + } + + //if (!MP.enabled) + mirrorMesh = (Rand.Value > 0.5f);//in 50% of the cases, flip mesh horizontally for more variance + + //x,y,z adjustments to draw splatches over the approximately correct locations; values stored in Cum helper - accessed by unique combinations of bodyTypes and bodyParts + CumHelper.key k = new CumHelper.key(bodyType, bodyPart); + if (CumHelper.splatchAdjust.Keys.Contains(k)) + { + CumHelper.values helperValues = CumHelper.splatchAdjust[k]; + + //invert, x-adjust (horizontal) depending on left/right body side: + if (!leftSide) + { + float[] xAdjTemp = new float[4]; + for (int i = 0; i < xAdjTemp.Length; i++) + { + xAdjTemp[i] = helperValues.x[i] * -1f; + } + xAdjust = xAdjTemp; + } + else + { + xAdjust = helperValues.x; + } + + zAdjust = helperValues.z;//vertical adjustment + + } + else//fallback in the the key can't be found + { + //if (RJWSettings.DevMode) + //{ + // ModLog.Message("created cum splatch for undefined body type or part. BodyType: " + bodyType + " , BodyPart: " + bodyPart); + //} + xAdjust = new float[] { 0f, 0f, 0f, 0f }; + zAdjust = new float[] { 0f, 0f, 0f, 0f }; + } + + + //y adjustments: plane/layer of drawing, > 0 -> above certain objects, < 0 -> below + CumHelper.key_layer k2 = new CumHelper.key_layer(leftSide, bodyPart); + + if (CumHelper.layerAdjust.Keys.Contains(k2)) + { + CumHelper.values_layer helperValues_layer = CumHelper.layerAdjust[k2]; + yAdjust = helperValues_layer.y; + } + else + { + yAdjust = new float[] { 0.02f, 0.02f, 0.02f, 0.02f };//over body in every direction + } + + } + + public void Draw(Vector3 drawPos, Quaternion quat, bool forPortrait, int facingDir = 0, float angle = 0,bool inBed=false) + { + if (inBed) + { + if (this.bodyPart != BodyPartDefOf.Jaw && this.bodyPart != BodyPartDefOf.Head)//when pawn is in bed (=bed with sheets), only draw cum on head + { + return; + } + } + + //these two create new mesh instance and never destroying it, filling ram and crashing + //float size = minSize+((maxSize-minSize)*hediff_cum.Severity); + //mesh = MeshMakerPlanes.NewPlaneMesh(size); + + //use core MeshPool.plane025 instead + + //if (mirrorMesh)//horizontal flip + //{ + //mesh = flipMesh(mesh); + //} + + //rotation: + if (angle == 0)//normal situation (pawn standing upright) + { + drawPos.x += xAdjust[facingDir]; + drawPos.z += zAdjust[facingDir]; + } + else//if downed etc, more complex calculation becomes necessary + { + float radian = angle / 180 * (float)Math.PI; + radian = -radian; + drawPos.x += Mathf.Cos(radian) * xAdjust[hediff_cum.pawn.Rotation.AsInt] - Mathf.Sin(radian) * zAdjust[facingDir];//facingDir doesn't appear to be chosen correctly in all cases + drawPos.z += Mathf.Cos(radian) * zAdjust[hediff_cum.pawn.Rotation.AsInt] + Mathf.Sin(radian) * xAdjust[facingDir]; + } + + //drawPos.y += yAdjust[facingDir];// 0.00: over body; 0.01: over body but under face, 0.02: over face, but under hair, -99 = "never" visible + drawPos.y += yAdjust[facingDir]; + + GenDraw.DrawMeshNowOrLater(MeshPool.plane025, drawPos, quat, cumMaterial, forPortrait); + } + + //flips mesh UV horizontally, thereby mirroring the texture + private Mesh flipMesh(Mesh meshToFlip) + { + var uvs = meshToFlip.uv; + if (uvs.Length != 4) + { + return (meshToFlip); + } + for (var i = 0; i < uvs.Length; i++) + { + if (Mathf.Approximately(uvs[i].x, 1.0f)) + uvs[i].x = 0.0f; + else + uvs[i].x = 1.0f; + } + meshToFlip.uv = uvs; + return (meshToFlip); + } + } + } +} diff --git a/1.3/Source/Mod/JobDrivers/JobDriver_CleanSelf.cs b/1.3/Source/Mod/JobDrivers/JobDriver_CleanSelf.cs new file mode 100644 index 0000000..d1d4ce3 --- /dev/null +++ b/1.3/Source/Mod/JobDrivers/JobDriver_CleanSelf.cs @@ -0,0 +1,53 @@ +using RimWorld; +using System.Collections.Generic; +using Verse; +using Verse.AI; + +namespace rjwcum +{ + class JobDriver_CleanSelf : JobDriver + { + float cleanAmount = 1f;//severity of a single cumHediff removed per cleaning-round; 1f = remove entirely + int cleaningTime = 120;//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() + { + this.FailOn(delegate + { + List hediffs = pawn.health.hediffSet.hediffs; + return !hediffs.Exists(x => x.def == HediffDefOf.Hediff_CumController);//fail if cum disappears - means that also all the cum is gone + }); + Toil cleaning = Toils_General.Wait(cleaningTime, TargetIndex.None);//duration of + cleaning.WithProgressBarToilDelay(TargetIndex.A); + + yield return cleaning; + yield return new Toil() + { + initAction = delegate () + { + //get one of the cum hediffs, reduce its severity + Hediff hediff = pawn.health.hediffSet.hediffs.Find(x => (x.def == HediffDefOf.Hediff_Cum || x.def == HediffDefOf.Hediff_InsectSpunk || x.def == HediffDefOf.Hediff_MechaFluids)); + if (hediff != null) + { + if (hediff.Severity >= 0.5) + { + if (hediff.def == HediffDefOf.Hediff_InsectSpunk) + { + Thing jelly = ThingMaker.MakeThing(ThingDefOf.InsectJelly); + jelly.SetForbidden(true, false); + GenPlace.TryPlaceThing(jelly, pawn.PositionHeld, pawn.MapHeld, ThingPlaceMode.Near); + } + } + hediff.Severity -= cleanAmount; + } + } + }; + yield break; + } + } +} diff --git a/1.3/Source/Mod/Patch_AddCumOnOrgasm.cs b/1.3/Source/Mod/Patch_AddCumOnOrgasm.cs new file mode 100644 index 0000000..e2afe42 --- /dev/null +++ b/1.3/Source/Mod/Patch_AddCumOnOrgasm.cs @@ -0,0 +1,65 @@ +using Verse; +using HarmonyLib; +using rjw; +using System; +//using Multiplayer.API; + +namespace rjwcum +{ + /// + ///apply cum to pawn after vanilla sex + /// + [HarmonyPatch(typeof(SexUtility), "Aftersex")] + [StaticConstructorOnStartup] + static class Aftersex_Cum_Apply + { + [HarmonyPostfix] + private static void Aftersex_Cum_Patch(SexProps props) + { + try + { + if (props.isCoreLovin) + if (!props.usedCondom) + { + CumHelper.calculateAndApplyCum(props); + //SexUtility.CumFilthGenerator(props.pawn); + //SexUtility.CumFilthGenerator(props.partner); + } + } + catch (Exception e) + { + Log.Error(e.ToString()); + } + } + } + + /// + ///apply cum to pawn after rjw orgasm + /// + [HarmonyPatch(typeof(JobDriver_Sex), "Orgasm")] + [StaticConstructorOnStartup] + static class Orgasm_Cum_Apply + { + [HarmonyPostfix] + private static void Orgasm_Cum_Patch(JobDriver_Sex __instance) + { + try + { + if (__instance.sex_ticks > __instance.orgasmstick) //~3s at speed 1 + { + return; + } + var props = __instance.Sexprops; + if (!props.usedCondom) + { + CumHelper.calculateAndApplyCum(props); + //SexUtility.CumFilthGenerator(props.pawn); + } + } + catch (Exception e) + { + Log.Error(e.ToString()); + } + } + } +} diff --git a/1.3/Source/Mod/Patch_AddGizmo.cs b/1.3/Source/Mod/Patch_AddGizmo.cs new file mode 100644 index 0000000..e995f01 --- /dev/null +++ b/1.3/Source/Mod/Patch_AddGizmo.cs @@ -0,0 +1,68 @@ +using System.Collections.Generic; +using Verse; +using HarmonyLib; +using rjw; +//using Multiplayer.API; + +namespace rjwcum +{ + //adds new gizmo for adding cum for testing + [HarmonyPatch(typeof(Pawn), "GetGizmos")] + class Patch_AddGizmo + { + [HarmonyPriority(99),HarmonyPostfix] + static IEnumerable AddCum_test(IEnumerable __result, Pawn __instance) + { + + foreach (Gizmo entry in __result) + { + yield return entry; + } + + if (Prefs.DevMode )//&& RJWSettings.DevMode && !MP.IsInMultiplayer) + { + Command_Action addCum = new Command_Action(); + addCum.defaultDesc = "AddCumHediff"; + addCum.defaultLabel = "AddCum"; + addCum.action = delegate () + { + AddCum(__instance); + }; + + yield return addCum; + } + } + + //[SyncMethod] + static void AddCum(Pawn pawn) + { + //Log.Message("add cum button is pressed for " + pawn); + + if (!pawn.Dead && pawn.records != null) + { + //get all acceptable body parts: + IEnumerable filteredParts = CumHelper.getAvailableBodyParts(pawn); + + //select random part: + BodyPartRecord randomPart; + //filteredParts.TryRandomElement(out randomPart); + //for testing - choose either genitals or anus: + //Rand.PopState(); + //Rand.PushState(RJW_Multiplayer.PredictableSeed()); + if (Rand.Value > 0.5f) + { + randomPart = pawn.RaceProps.body.AllParts.Find(x => x.def == xxx.anusDef); + } + else + { + randomPart = pawn.RaceProps.body.AllParts.Find(x => x.def == xxx.genitalsDef); + } + + if (randomPart != null) + { + CumHelper.cumOn(pawn, randomPart, 0.2f, null, CumHelper.CUM_NORMAL); + } + }; + } + } +} diff --git a/1.3/Source/Mod/Patch_JobDriver_DubsBadHygiene.cs b/1.3/Source/Mod/Patch_JobDriver_DubsBadHygiene.cs new file mode 100644 index 0000000..3ed4168 --- /dev/null +++ b/1.3/Source/Mod/Patch_JobDriver_DubsBadHygiene.cs @@ -0,0 +1,85 @@ +using System; +using HarmonyLib; +using Verse; +using Verse.AI; +using rjw; + +namespace rjwcum +{ + [HarmonyPatch(typeof(JobDriver), "Cleanup")] + internal static class Patch_JobDriver_DubsBadHygiene + { + //not very good solution, some other mod can have same named jobdriver but w/e + + //Dubs Bad Hygiene washing + private readonly static Type JobDriver_useWashBucket = AccessTools.TypeByName("JobDriver_useWashBucket"); + //private readonly static Type JobDriver_washAtCell = AccessTools.TypeByName("JobDriver_washAtCell"); + + private readonly static Type JobDriver_UseHotTub = AccessTools.TypeByName("JobDriver_UseHotTub"); + private readonly static Type JobDriver_takeShower = AccessTools.TypeByName("JobDriver_takeShower"); + private readonly static Type JobDriver_takeBath = AccessTools.TypeByName("JobDriver_takeBath"); + + [HarmonyPostfix] + private static void Cleanup_cum(JobDriver __instance, JobCondition condition) + { + try + { + if (__instance == null) + return; + + if (condition == JobCondition.Succeeded) + { + Do_cleanup_cum(__instance); + } + } + catch (Exception e) + { + Log.Error(e.ToString()); + } + } + + public static void Do_cleanup_cum(JobDriver __instance) + { + Pawn pawn = __instance.pawn; + + //ModLog.Message("patches_DubsBadHygiene::on_cleanup_driver" + xxx.get_pawnname(pawn)); + + if (xxx.DubsBadHygieneIsActive) + //clear one instance of cum + if ( + __instance.GetType() == JobDriver_useWashBucket// || + //__instance.GetType() == JobDriver_washAtCell + ) + { + Hediff hediff = pawn.health.hediffSet.hediffs.Find(x => (x.def == HediffDefOf.Hediff_Cum + || x.def == HediffDefOf.Hediff_InsectSpunk + || x.def == HediffDefOf.Hediff_MechaFluids + )); + if (hediff != null) + { + //ModLog.Message("patches_DubsBadHygiene::" + __instance.GetType() + " clear => " + hediff.Label); + hediff.Severity -= 1f; + } + } + //clear all instance of cum + else if ( + __instance.GetType() == JobDriver_UseHotTub || + __instance.GetType() == JobDriver_takeShower || + __instance.GetType() == JobDriver_takeBath + ) + { + foreach (Hediff hediff in pawn.health.hediffSet.hediffs) + { + if (hediff.def == HediffDefOf.Hediff_Cum || + hediff.def == HediffDefOf.Hediff_InsectSpunk || + hediff.def == HediffDefOf.Hediff_MechaFluids + ) + { + //ModLog.Message("patches_DubsBadHygiene::" + __instance.GetType() + " clear => " + hediff.Label); + hediff.Severity -= 1f; + } + } + } + } + } +} \ No newline at end of file diff --git a/1.3/Source/Mod/Patch_RenderOverBody.cs b/1.3/Source/Mod/Patch_RenderOverBody.cs new file mode 100644 index 0000000..9ecc3c0 --- /dev/null +++ b/1.3/Source/Mod/Patch_RenderOverBody.cs @@ -0,0 +1,52 @@ +using System.Collections.Generic; +using Verse; +using HarmonyLib; +using UnityEngine; +using System; +using RimWorld; +//using Multiplayer.API; + +namespace rjwcum +{ + + [HarmonyPatch(typeof(RimWorld.PawnWoundDrawer))] + [HarmonyPatch("RenderOverBody")] + [HarmonyPatch(new Type[] { typeof(Vector3), typeof(Mesh), typeof(Quaternion), typeof(bool), typeof(BodyTypeDef.WoundLayer), typeof(Rot4), typeof(bool) })] + class Patch_RenderOverBody + { + [HarmonyPostfix] + static void DrawCum(RimWorld.PawnWoundDrawer __instance, Vector3 drawLoc, Mesh bodyMesh, Quaternion quat, bool drawNow, BodyTypeDef.WoundLayer layer, Rot4 pawnRot, bool? overApparel = null) + { + Pawn pawn = Traverse.Create(__instance).Field("pawn").GetValue();//get local variable + + //TODO add support for animals? unlikely as they has weird meshes + //for now, only draw humans + if (pawn.RaceProps.Humanlike) //&& CumOverlayBase.cum_overlays) + { + //find cum hediff. if it exists, use its draw function + List hediffs = pawn.health.hediffSet.hediffs; + if (hediffs.Exists(x => x.def == HediffDefOf.Hediff_CumController)) + { + Hediff_CumController h = hediffs.Find(x => x.def == HediffDefOf.Hediff_CumController) as Hediff_CumController; + + quat.ToAngleAxis(out float angle, out Vector3 axis);//angle changes when pawn is e.g. downed + + //adjustments if the pawn is sleeping in a bed: + bool inBed = false; + Building_Bed building_Bed = pawn.CurrentBed(); + if (building_Bed != null) + { + inBed = !building_Bed.def.building.bed_showSleeperBody; + AltitudeLayer altLayer = (AltitudeLayer)Mathf.Max((int)building_Bed.def.altitudeLayer, 15); + Vector3 vector2 = pawn.Position.ToVector3ShiftedWithAltitude(altLayer); + vector2.y += 0.02734375f+0.01f;//just copied from rimworld code+0.01f + drawLoc.y = vector2.y; + } + + h.DrawCum(drawLoc, quat, layer == BodyTypeDef.WoundLayer.Head, angle); + } + } + + } + } +} diff --git a/1.3/Source/Mod/RimJobWorldCum.csproj b/1.3/Source/Mod/RimJobWorldCum.csproj new file mode 100644 index 0000000..1e94d1f --- /dev/null +++ b/1.3/Source/Mod/RimJobWorldCum.csproj @@ -0,0 +1,80 @@ + + + + + Debug + AnyCPU + {3FC2D442-19B8-4CF9-9D35-CD13B6AC7B28} + Library + rjwcum + RimJobWorldCum + v4.7.2 + 512 + + + AnyCPU + true + full + false + ..\..\Assemblies\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + ..\..\Assemblies\ + TRACE + prompt + 4 + + + + ..\packages\Lib.Harmony.2.2.1\lib\net472\0Harmony.dll + False + + + ..\..\..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll + False + + + ..\..\..\..\..\..\..\workshop\content\294100\818773962\v1.2\Assemblies\HugsLib.dll + False + + + ..\..\..\..\rjw\1.3\Assemblies\RJW.dll + False + + + + + ..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll + False + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/1.3/Source/Mod/Textures.cs b/1.3/Source/Mod/Textures.cs new file mode 100644 index 0000000..6ec85f6 --- /dev/null +++ b/1.3/Source/Mod/Textures.cs @@ -0,0 +1,58 @@ +using Verse; +using UnityEngine; +//using Multiplayer.API; + +namespace rjwcum +{ + [StaticConstructorOnStartup] + public static class CumTextures + { + //UI: + public static readonly Texture2D CumIcon_little = ContentFinder.Get("CumIcon_little", true); + public static readonly Texture2D CumIcon_some = ContentFinder.Get("CumIcon_some", true); + public static readonly Texture2D CumIcon_dripping = ContentFinder.Get("CumIcon_dripping", true); + public static readonly Texture2D CumIcon_drenched = ContentFinder.Get("CumIcon_drenched", true); + + //on pawn: + public static readonly Material cumSplatch1 = MaterialPool.MatFrom("splatch_1", ShaderDatabase.Cutout); + public static readonly Material cumSplatch2 = MaterialPool.MatFrom("splatch_2", ShaderDatabase.Cutout); + public static readonly Material cumSplatch3 = MaterialPool.MatFrom("splatch_3", ShaderDatabase.Cutout); + public static readonly Material cumSplatch4 = MaterialPool.MatFrom("splatch_4", ShaderDatabase.Cutout); + public static readonly Material cumSplatch5 = MaterialPool.MatFrom("splatch_5", ShaderDatabase.Cutout); + public static readonly Material cumSplatch6 = MaterialPool.MatFrom("splatch_6", ShaderDatabase.Cutout); + public static readonly Material cumSplatch7 = MaterialPool.MatFrom("splatch_7", ShaderDatabase.Cutout); + public static readonly Material cumSplatch8 = MaterialPool.MatFrom("splatch_8", ShaderDatabase.Cutout); + public static readonly Material cumSplatch9 = MaterialPool.MatFrom("splatch_9", ShaderDatabase.Cutout); + + + //[SyncMethod] + public static Material pickRandomSplatch() + { + //Rand.PopState(); + //Rand.PushState(RJW_Multiplayer.PredictableSeed()); + int rand = Rand.Range(0, 8); + switch (rand) + { + case 0: + return cumSplatch1; + case 1: + return cumSplatch2; + case 2: + return cumSplatch3; + case 3: + return cumSplatch4; + case 4: + return cumSplatch5; + case 5: + return cumSplatch6; + case 6: + return cumSplatch7; + case 7: + return cumSplatch8; + case 8: + return cumSplatch9; + } + return null; + } + } +} diff --git a/1.3/Source/Mod/WorkGivers/WorkGiver_CleanSelf.cs b/1.3/Source/Mod/WorkGivers/WorkGiver_CleanSelf.cs new file mode 100644 index 0000000..533b827 --- /dev/null +++ b/1.3/Source/Mod/WorkGivers/WorkGiver_CleanSelf.cs @@ -0,0 +1,76 @@ +using RimWorld; +using Verse; +using Verse.AI; +using rjw; + +namespace rjwcum +{ + public class WorkGiver_CleanSelf : WorkGiver_Scanner + { + public override PathEndMode PathEndMode + { + get + { + return PathEndMode.InteractionCell; + } + } + + public override Danger MaxPathDanger(Pawn pawn) + { + return Danger.Deadly; + } + + public override ThingRequest PotentialWorkThingRequest + { + get + { + return ThingRequest.ForGroup(ThingRequestGroup.Pawn); + } + } + + //conditions for self-cleaning job to be available + public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false) + { + if (xxx.DubsBadHygieneIsActive && CumBase.dubsDBH_block_CleanSelf) // selfclean only in shower/bath etc + return false; + + if (pawn != t) + return false; + + if (!pawn.CanReserve(t, 1, -1, null, forced)) + return false; + + if (pawn.IsDesignatedHero()) + { + if (!forced && CumBase.manual_hero_CleanSelf) + { + //ModLog.Message("WorkGiver_CleanSelf::not player interaction for hero, exit"); + return false; + } + if (!pawn.IsHeroOwner()) + { + //ModLog.Message("WorkGiver_CleanSelf::player interaction for not owned hero, exit"); + return false; + } + } + + Hediff hediff = pawn.health.hediffSet.hediffs.Find(x => (x.def == HediffDefOf.Hediff_CumController)); + if (hediff == null) + return false; + + int minAge = 3 * 2500;//3 hours in-game must have passed + if (!forced) + if (!(hediff.ageTicks > minAge)) + { + //ModLog.Message("WorkGiver_CleanSelf:: 3 hours in-game must pass to self-clean, exit"); + return false; + } + return true; + } + + public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false) + { + return JobMaker.MakeJob(JobDefOf.CleanSelf); + } + } +} diff --git a/1.3/Source/Mod/packages.config b/1.3/Source/Mod/packages.config new file mode 100644 index 0000000..4b23a8c --- /dev/null +++ b/1.3/Source/Mod/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/1.3/Source/Properties/AssemblyInfo.cs b/1.3/Source/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..78fe39f --- /dev/null +++ b/1.3/Source/Properties/AssemblyInfo.cs @@ -0,0 +1,32 @@ +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("RimJobWorld Cum")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RimJobWorld Cum")] +[assembly: AssemblyCopyright("Copyright © 2022")] +[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("c2825019-7f0b-456d-85a3-479c1a2a8805")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] diff --git a/1.3/Source/mod.sln b/1.3/Source/mod.sln new file mode 100644 index 0000000..ee41d20 --- /dev/null +++ b/1.3/Source/mod.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30907.101 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RimJobWorldCum", "Mod\RimJobWorldCum.csproj", "{3FC2D442-19B8-4CF9-9D35-CD13B6AC7B28}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3FC2D442-19B8-4CF9-9D35-CD13B6AC7B28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3FC2D442-19B8-4CF9-9D35-CD13B6AC7B28}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3FC2D442-19B8-4CF9-9D35-CD13B6AC7B28}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3FC2D442-19B8-4CF9-9D35-CD13B6AC7B28}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5A0C2732-36A9-4ACA-807E-019E02C37E10} + EndGlobalSection +EndGlobal diff --git a/1.3/Textures/CumIcon_drenched.png b/1.3/Textures/CumIcon_drenched.png new file mode 100644 index 0000000000000000000000000000000000000000..842f804f80c8028e69c0e6dd1f2256a88968fc5d GIT binary patch literal 419 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjY)RhkE4tGzVzuXQ_u8RmNf@|ihf|rVKz=kN>iWtb-Tm)Gi|+`DzQxS8*Ah(nC2|$ z&Nv%#$>WmCqz2yyI}IHRiuidN4zDO>o^l{rpxm*hPu*DhNX%-}C(9Ss#Vmfy!2jj2 z_+vf0SywjB@s`r=ja)VF(Vv+K>=q{~3QV_#C)~;EY7*XlK%|Z#IN|P@vdx@_j_zVT zeuq(iXJ(HyzvZ%3tAf_aEknLAZNLoE{)UrrW3T)qCsevPjDi#t2xIhPzMdg8t1khqK4ik$NTcMpNW+SAp~ JWt~$(6951nsa600 literal 0 HcmV?d00001 diff --git a/1.3/Textures/CumIcon_dripping.png b/1.3/Textures/CumIcon_dripping.png new file mode 100644 index 0000000000000000000000000000000000000000..daea57002a55d7a939c8028d7b21146cb18aa829 GIT binary patch literal 385 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjY)RhkE(e4)v42*o9E{-7{$KOsd^kX&@aJ}EcvCBh) z^=zIMmjElP`U4)BM&^RuG7M4yT^Jos^mL*Z%YW zo>b{?8~GWGt8Z>8n=r%NXmfjuo0xCTjEoPwGNm2++dd>Zg$Fw{%x5TP7dfE$K~d@X zSs71*6;{?PX$O=)u!w|4g0KR4I6DhY4tw2yR4@xKrzBGTn!@WR>Vwd(Afwe#=$ zWHfaa>&=ikyqRZC@#Gm5fg*n;R=@iHHXt-OboB?T@Q*j&FNh48w)Dsjwf&`6)Nl3v ZV0JpNm7#0xl3k#X^mO%eS?83{1OUpCkBI;P literal 0 HcmV?d00001 diff --git a/1.3/Textures/CumIcon_little.png b/1.3/Textures/CumIcon_little.png new file mode 100644 index 0000000000000000000000000000000000000000..f7abde3f82359a56fcc4e12bb10011c6e3f68e63 GIT binary patch literal 226 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 literal 0 HcmV?d00001 diff --git a/1.3/Textures/splatch_2.png b/1.3/Textures/splatch_2.png new file mode 100644 index 0000000000000000000000000000000000000000..514a2f1d2233b7e0467a1e3dcc6df34c222d2317 GIT binary patch literal 3027 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 VKEyIU7|j3x002ovPDHLkV1k@By&V7m literal 0 HcmV?d00001 diff --git a/1.3/Textures/splatch_3.png b/1.3/Textures/splatch_3.png new file mode 100644 index 0000000000000000000000000000000000000000..452bc0c16452014362388ee8458352a75dcbf2e4 GIT binary patch literal 2976 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 Wzi+W0D03$O0000*P4=Q+>&yw7>h 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 kGVw(i2?O(K8gw($ErKp#OC0i=AQoB-VRH-Ci z#XUIcCl7$%w{M?i-@bhgo6S}t2!fbOrBabdWbv!7zKWkacP+kQM9UB|F^3+pLO%V{})dYbnqVZx&ON;e` z4?ft^+S8HpwY80q*H#S#u2`P;`FxhoKmWXC z$BrEv0eFe=0`WXY8KiHd7nsrsJ3N(-fHM zQQq9#TnAuwHBuwLl6>#+c+72WZI9N~)s->2*YduJVunD)1{3vv5rEy}@l?57E)%sr z?zaSh`Z@8$i4*IanwlB`*fflxPmuwH2FS#KWNK?`lecc&T1o}X-;4w@)NgHVEop3Q z+zFtXcwI}=H2oFwe>DJVy-y}UI?Kz;O99OP)&NkwFTDNs+Yg08p$01I3mQhT#>qOA zR>(DEavihF<+3n)><(EqfM~0XzWV_19m2xW2xA9r3=PLwzkzC=~tER2o*Zf*K>FSS%*# z1>dTwD)IgI-!H4LuMd=#mO23-9*-|fOibK5cI;U6+i$;38m%G3e7%3@&>=@*Ow*ZVKL@WLb2)zxdM=*{V56Dw(m9MpS3Re&)7GbG>3 zw2aQ2Ib*$c?b;G09igJ4LOg%|{L>zf=XXx0vzlCAb%0tm*7*JYjW(O@q4DwYQ?<3V zf2Z!L6bit7-mj{v+CdD<=6x%P4|a`i5KLXb1Gq&=BQ-TO6-gu#DfKm<&u6-D;X->& zP0fA)e)3uNo}yZZI2;Ze&-0#0Bw`8#0)NZaT=DsM|M};i-x>%6f=o`Qsml|id;nbJ zcaeGz{nJDM@{=l31@rEuOP3}o4GX=!z58owY7SB7_R<(FSZRqtQ8aG}NP z_5J}srA~FpreL+pwAgI68o%Fv;GK8gS)&I6Z`Av*yz)wuj`le!*m)^{w4}klrZUD& z*bpBa9K3$x#*JkFcW zK3eDTc%C5Om>BH~8cv}53@ar;Q$HW4)87*r2YryrH3?Djxtc8hz=dms}o?=MicV zbP%&qFvNS+i*W#$GWCma=EiH9v0Vw85e|2?r z50k=&9c7hJl-KhNR{#i`$Y9k>$x7?`dVL4o9AyTtJkN_pE5Qu?j~qGTw%Kf(HFCO% z33%D4$!V}bZ(g95trn_9X1$-S<>eR_s5WxRWHOykDa->9cJ10#@ALWG8U>B0L3yp4 z8{LDTjZaY>qL8Pg6b7hFY>LO@i$*KK4E-xBD>o7PYem^&PHGg&c-a7}U@#73z?hz% zzGH*|8TvOjH(Q-fXNYJ~tAgY5(4!I0t5afyVgR>7P}R>T$H&L-8Xbyq0EB0rdFFx2 z%1XCRp4Bo~$zotOQeNxcydVfdE&wuyIvftcYPEWqLWicN*1%ELV1lBdbvEZ4 z8Fv?~ef2()BuPdlLLBaGRht?b8Wf#g9?ZTT%L=2xFdJLMEVTqz00^mgJicr=26(+* zGpWn@kk^R%LPCt&5?j%$2c#0{piC2BgP1%lpgu}ozX4)^ab7K{1-5Q{`21A4neyw<{IW@eK8 z{rzH=7M3lFmZ?UD?d;Su&HODfbw8g)cF2SJEZDcspFe+{0wAjd6aaD}kw`5rE=I_r z#T;#}YOK1IWzzAw)=xc|7@@lnCP-6LQ&S&*{PArD@T?M$0Z7qkbdnfl&9N{p3kZ4# zJ6X;rP3H5wP-0?Y;v%E}tP;qiv#VFHP6C)KpaNSWl1S^6rh-Awb9oL{I1QGCPoF;B zOV(nj63n!wr%s)^H9kImN25+RvX~SV7wF)_8!$efPA}V$8Xg`VIC}KxB-3pwxtbvv zfZWs56OTrtmx&>TEJ&h2NK=w4^vSe*)}R2G`r(Hk{*g!|lE`y+SWRQ;zP`Ty;@;ME zq0i|lRCXxT_ED)Hvf{{SCk|Q38M80Wn zZ|@@#l(NM!J`0^B0LeGrc;i2VgM$ME$wD4mHPYO0MUsFtGc$AL#EBD~BpcBMm!h}0 ztc$vH=MFY+-n>vJIy}kW-cXu~!d|qF&5DHj~GB7Z(^!3+Y_ix&? zDQ&e{%bZT9RcFLbf6mCTGv|04Kx%GoZuH{Cizj#O+Vz)6B(gw^PojWtm=sc-DFEb! zg@yDdpL{an@py*qb~|5DQNiKfBQttCNm3plXze^n0A|O=#(KKCy8d+V;K4JJB*hue z=lva{LIKFk4Zi#CyPv=K;)^RB$4!{c=4DBeN?a~iO5@rJm6wGa*QU=DfS)6gNPk~n zU+3Y&hyUEs(GeyiyX8V?UyNde9%7oPV#o6Av(J|8*|Vo17z~Cy9#2hUVCi%Ahm9Jj@(j3303zXV_~y{iQ1^!)e%N#B)Tt;nZ(zM%P^rF>r@DY&KB#!#_k{w1 zfHfEl+5>@r&FAx#*zI<+AP77F2!ggLUx31W1T(z=A~yHUR?09p+V`@o`z`@bxux5vN-0s)iL=`^KMDdq0n pyXm>Pxg<42O*4bk6?>gN{tq;M$A)Ss(E$Je002ovPDHLkV1lVTlg9u6 literal 0 HcmV?d00001 diff --git a/1.3/Textures/splatch_7.png b/1.3/Textures/splatch_7.png new file mode 100644 index 0000000000000000000000000000000000000000..c28106684561b7eda63f395d689071042f6af4bc GIT binary patch literal 2226 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 + + + RimJobWorld - Cum + Ed86 + https://gitgud.io/Ed86/rjw-cum + +
  • 1.3
  • +
    + rjw.cum + +
  • + rim.job.world + RJW + https://gitgud.io/Ed86/rjw +
  • +
  • + brrainz.harmony + Harmony + https://github.com/pardeike/HarmonyRimWorld/releases/latest + steam://url/CommunityFilePage/2009463077 +
  • +
  • + UnlimitedHugs.HugsLib + HugsLib + https://github.com/UnlimitedHugs/RimworldHugsLib/releases/latest + steam://url/CommunityFilePage/818773962 +
  • +
    + +
  • brrainz.harmony
  • +
  • UnlimitedHugs.HugsLib
  • +
  • erdelf.HumanoidAlienRaces
  • +
  • rim.job.world
  • +
    + + + +
    diff --git a/About/Manifest.xml b/About/Manifest.xml new file mode 100644 index 0000000..c186459 --- /dev/null +++ b/About/Manifest.xml @@ -0,0 +1,13 @@ + + + RimJobWorld Cum + 1.0.0 + +
  • RimJobWorld
  • +
    + +
  • RimJobWorld
  • +
    + https://gitgud.io/Ed86/rjw-cum/raw/master/About/Manifest.xml + https://gitgud.io/Ed86/rjw-cum +
    diff --git a/README.md b/README.md index c6c7b93..72cd491 100644 --- a/README.md +++ b/README.md @@ -1,92 +1,19 @@ -# RJW - CUM +And why would you read me? +Mod git: +- +Discord: +https://discord.gg/CXwHhv8 -## Getting started +LoversLab: +- -To make it easy for you to get started with GitLab, here's a list of recommended next steps. +Requirements: +Harmony +Hugslib +Rimjobworld 5.0+(https://gitgud.io/Ed86/rjw) -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! - -## Add your files - -- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: - -``` -cd existing_repo -git remote add origin https://gitgud.io/Ed86/rjw-cum.git -git branch -M master -git push -uf origin master -``` - -## Integrate with your tools - -- [ ] [Set up project integrations](https://gitgud.io/Ed86/rjw-cum/-/settings/integrations) - -## Collaborate with your team - -- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) -- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) -- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) -- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -- [ ] [Automatically merge when pipeline succeeds](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html) - -## Test and Deploy - -Use the built-in continuous integration in GitLab. - -- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html) -- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) -- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) -- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) -- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) - -*** - -# Editing this README - -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template. - -## Suggestions for a good README -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. - -## Name -Choose a self-explaining name for your project. - -## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. - -## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. - -## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. - -## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. - -## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. - -## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. - -## Roadmap -If you have ideas for releases in the future, it is a good idea to list them in the README. - -## Contributing -State if you are open to contributions and what your requirements are for accepting them. - -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. - -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. - -## Authors and acknowledgment -Show your appreciation to those who have contributed to the project. - -## License -For open source projects, say how it is licensed. - -## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. +Additional features to RimJobWorld: +cum hediffs +cum overlay \ No newline at end of file