diff --git a/1.3/Source/Mod/RimJobWorldCum.csproj b/1.3/Source/Mod/RimJobWorldCum.csproj index 1e94d1f..148b9d0 100644 --- a/1.3/Source/Mod/RimJobWorldCum.csproj +++ b/1.3/Source/Mod/RimJobWorldCum.csproj @@ -40,7 +40,7 @@ False - ..\..\..\..\..\..\..\workshop\content\294100\818773962\v1.2\Assemblies\HugsLib.dll + ..\..\..\..\..\..\..\workshop\content\294100\818773962\v1.3\Assemblies\HugsLib.dll False diff --git a/1.4/Assemblies/RimJobWorldCum.dll b/1.4/Assemblies/RimJobWorldCum.dll new file mode 100644 index 0000000..dbec018 Binary files /dev/null and b/1.4/Assemblies/RimJobWorldCum.dll differ diff --git a/1.4/Defs/HediffsDef/Hediff_CumController.xml b/1.4/Defs/HediffsDef/Hediff_CumController.xml new file mode 100644 index 0000000..854f8e0 --- /dev/null +++ b/1.4/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.4/Defs/HediffsDef/Hediffs_Cum.xml b/1.4/Defs/HediffsDef/Hediffs_Cum.xml new file mode 100644 index 0000000..3a77e61 --- /dev/null +++ b/1.4/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.4/Defs/JobDefs/Jobs_CleanSelf.xml b/1.4/Defs/JobDefs/Jobs_CleanSelf.xml new file mode 100644 index 0000000..12ae606 --- /dev/null +++ b/1.4/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.4/Defs/WorkGiverDefs/WorkGivers_CleanSelf.xml b/1.4/Defs/WorkGiverDefs/WorkGivers_CleanSelf.xml new file mode 100644 index 0000000..62b7637 --- /dev/null +++ b/1.4/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.4/Languages/English/Keyed/Cum.xml b/1.4/Languages/English/Keyed/Cum.xml new file mode 100644 index 0000000..54ce568 --- /dev/null +++ b/1.4/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.4/Patches/FacialAnimation_compatibility.xml b/1.4/Patches/FacialAnimation_compatibility.xml new file mode 100644 index 0000000..7a6b70e --- /dev/null +++ b/1.4/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.4/Source/Mod/CumBase.cs b/1.4/Source/Mod/CumBase.cs new file mode 100644 index 0000000..294e079 --- /dev/null +++ b/1.4/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() + { + debug = 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.4/Source/Mod/CumHelper.cs b/1.4/Source/Mod/CumHelper.cs new file mode 100644 index 0000000..9de0f69 --- /dev/null +++ b/1.4/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.4/Source/Mod/DefOf/HediffDefOf.cs b/1.4/Source/Mod/DefOf/HediffDefOf.cs new file mode 100644 index 0000000..46e8255 --- /dev/null +++ b/1.4/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.4/Source/Mod/DefOf/JobDefOf.cs b/1.4/Source/Mod/DefOf/JobDefOf.cs new file mode 100644 index 0000000..f8569e6 --- /dev/null +++ b/1.4/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.4/Source/Mod/Hediffs/Hediff_Cum.cs b/1.4/Source/Mod/Hediffs/Hediff_Cum.cs new file mode 100644 index 0000000..7652b64 --- /dev/null +++ b/1.4/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.4/Source/Mod/Hediffs/Hediff_CumController.cs b/1.4/Source/Mod/Hediffs/Hediff_CumController.cs new file mode 100644 index 0000000..a3a3224 --- /dev/null +++ b/1.4/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.4/Source/Mod/JobDrivers/JobDriver_CleanSelf.cs b/1.4/Source/Mod/JobDrivers/JobDriver_CleanSelf.cs new file mode 100644 index 0000000..d1d4ce3 --- /dev/null +++ b/1.4/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.4/Source/Mod/Patch_AddCumOnOrgasm.cs b/1.4/Source/Mod/Patch_AddCumOnOrgasm.cs new file mode 100644 index 0000000..a348076 --- /dev/null +++ b/1.4/Source/Mod/Patch_AddCumOnOrgasm.cs @@ -0,0 +1,66 @@ +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 + { + [HarmonyPrefix] + private static bool Orgasm_Cum_Patch(JobDriver_Sex __instance) + { + try + { + if (__instance.sex_ticks > __instance.orgasmstick) //~3s at speed 1 + { + return true; + } + var props = __instance.Sexprops; + if (!props.usedCondom) + { + CumHelper.calculateAndApplyCum(props); + //SexUtility.CumFilthGenerator(props.pawn); + } + } + catch (Exception e) + { + Log.Error(e.ToString()); + } + return true; + } + } +} diff --git a/1.4/Source/Mod/Patch_AddGizmo.cs b/1.4/Source/Mod/Patch_AddGizmo.cs new file mode 100644 index 0000000..e995f01 --- /dev/null +++ b/1.4/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.4/Source/Mod/Patch_JobDriver_DubsBadHygiene.cs b/1.4/Source/Mod/Patch_JobDriver_DubsBadHygiene.cs new file mode 100644 index 0000000..3ed4168 --- /dev/null +++ b/1.4/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.4/Source/Mod/Patch_RenderOverBody.cs b/1.4/Source/Mod/Patch_RenderOverBody.cs new file mode 100644 index 0000000..1437182 --- /dev/null +++ b/1.4/Source/Mod/Patch_RenderOverBody.cs @@ -0,0 +1,54 @@ +using System.Collections.Generic; +using Verse; +using HarmonyLib; +using UnityEngine; +using System; +using RimWorld; +//using Multiplayer.API; + +namespace rjwcum +{ + + [HarmonyPatch(typeof(RimWorld.PawnOverlayDrawer))] + [HarmonyPatch("RenderPawnOverlay")] + [HarmonyPatch(new Type[] { typeof(Vector3), typeof(Mesh), typeof(Quaternion), typeof(bool), typeof(PawnOverlayDrawer.OverlayLayer), typeof(Rot4), typeof(bool) })] + class Patch_RenderPawnOverlay + { + [HarmonyPostfix] + static void DrawCum(RimWorld.PawnOverlayDrawer __instance, Vector3 drawLoc, Mesh bodyMesh, Quaternion quat, bool drawNow, PawnOverlayDrawer.OverlayLayer layer, Rot4 pawnRot, bool? overApparel = null) + { + if (!CumBase.cum_overlays) return; + + 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 == PawnOverlayDrawer.OverlayLayer.Head, angle); + } + } + + } + } +} diff --git a/1.4/Source/Mod/RimJobWorldCum.csproj b/1.4/Source/Mod/RimJobWorldCum.csproj new file mode 100644 index 0000000..6cff0eb --- /dev/null +++ b/1.4/Source/Mod/RimJobWorldCum.csproj @@ -0,0 +1,79 @@ + + + + + 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.2\lib\net472\0Harmony.dll + + + ..\..\..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll + False + + + ..\..\..\..\..\..\..\workshop\content\294100\818773962\v1.4\Assemblies\HugsLib.dll + False + + + ..\..\..\..\rjw\1.4\Assemblies\RJW.dll + False + + + + + ..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll + False + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/1.4/Source/Mod/Textures.cs b/1.4/Source/Mod/Textures.cs new file mode 100644 index 0000000..6ec85f6 --- /dev/null +++ b/1.4/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.4/Source/Mod/WorkGivers/WorkGiver_CleanSelf.cs b/1.4/Source/Mod/WorkGivers/WorkGiver_CleanSelf.cs new file mode 100644 index 0000000..533b827 --- /dev/null +++ b/1.4/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.4/Source/Mod/packages.config b/1.4/Source/Mod/packages.config new file mode 100644 index 0000000..c5bef78 --- /dev/null +++ b/1.4/Source/Mod/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/1.4/Source/Properties/AssemblyInfo.cs b/1.4/Source/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..78fe39f --- /dev/null +++ b/1.4/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.4/Source/mod.sln b/1.4/Source/mod.sln new file mode 100644 index 0000000..ee41d20 --- /dev/null +++ b/1.4/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.4/Textures/CumIcon_drenched.png b/1.4/Textures/CumIcon_drenched.png new file mode 100644 index 0000000..842f804 Binary files /dev/null and b/1.4/Textures/CumIcon_drenched.png differ diff --git a/1.4/Textures/CumIcon_dripping.png b/1.4/Textures/CumIcon_dripping.png new file mode 100644 index 0000000..daea570 Binary files /dev/null and b/1.4/Textures/CumIcon_dripping.png differ diff --git a/1.4/Textures/CumIcon_little.png b/1.4/Textures/CumIcon_little.png new file mode 100644 index 0000000..f7abde3 Binary files /dev/null and b/1.4/Textures/CumIcon_little.png differ diff --git a/1.4/Textures/CumIcon_some.png b/1.4/Textures/CumIcon_some.png new file mode 100644 index 0000000..d36e3f1 Binary files /dev/null and b/1.4/Textures/CumIcon_some.png differ diff --git a/1.4/Textures/splatch_1.png b/1.4/Textures/splatch_1.png new file mode 100644 index 0000000..1e930d3 Binary files /dev/null and b/1.4/Textures/splatch_1.png differ diff --git a/1.4/Textures/splatch_2.png b/1.4/Textures/splatch_2.png new file mode 100644 index 0000000..514a2f1 Binary files /dev/null and b/1.4/Textures/splatch_2.png differ diff --git a/1.4/Textures/splatch_3.png b/1.4/Textures/splatch_3.png new file mode 100644 index 0000000..452bc0c Binary files /dev/null and b/1.4/Textures/splatch_3.png differ diff --git a/1.4/Textures/splatch_4.png b/1.4/Textures/splatch_4.png new file mode 100644 index 0000000..7f21495 Binary files /dev/null and b/1.4/Textures/splatch_4.png differ diff --git a/1.4/Textures/splatch_5.png b/1.4/Textures/splatch_5.png new file mode 100644 index 0000000..ee101c1 Binary files /dev/null and b/1.4/Textures/splatch_5.png differ diff --git a/1.4/Textures/splatch_6.png b/1.4/Textures/splatch_6.png new file mode 100644 index 0000000..b9de710 Binary files /dev/null and b/1.4/Textures/splatch_6.png differ diff --git a/1.4/Textures/splatch_7.png b/1.4/Textures/splatch_7.png new file mode 100644 index 0000000..c281066 Binary files /dev/null and b/1.4/Textures/splatch_7.png differ diff --git a/1.4/Textures/splatch_8.png b/1.4/Textures/splatch_8.png new file mode 100644 index 0000000..0fe2c43 Binary files /dev/null and b/1.4/Textures/splatch_8.png differ diff --git a/1.4/Textures/splatch_9.png b/1.4/Textures/splatch_9.png new file mode 100644 index 0000000..0e6a788 Binary files /dev/null and b/1.4/Textures/splatch_9.png differ diff --git a/About/About.xml b/About/About.xml index 94baf15..b3d2aaa 100644 --- a/About/About.xml +++ b/About/About.xml @@ -6,6 +6,7 @@ https://gitgud.io/Ed86/rjw-cum
  • 1.3
  • +
  • 1.4
  • rjw.cum