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

  <HistoryEventDef>
    <defName>DrankMilkRaw</defName>
    Drank milk Raw
  </HistoryEventDef>

  <HistoryEventDef>
    <defName>DrankMilkMeal</defName>
    Drank milk with meal
  </HistoryEventDef>

	<HistoryEventDef>
		<defName>DrankNonMilkMeal</defName>
		Ate meal without milk
	</HistoryEventDef>

</Defs>


code:
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
	<JobDef>
		<defName>MassageBreasts</defName>
		<driverClass>CRIALactation.JobDriver_MassageBreasts</driverClass>
		<reportString>stimulating TargetA's breasts.</reportString>
		<allowOpportunisticPrefix>true</allowOpportunisticPrefix>
	</JobDef>
</Defs>

repo_name: UnknownUse/coffees

license: unknown


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

	<MemeDef>
		<defName>Hucow</defName>
		hucow
		<description>Breast milk should be produced for and consumed by all.</description>
		<iconPath>UI/Memes/Hucow</iconPath>
		<groupDef>Misc</groupDef>
		<impact>3</impact>
		<renderOrder>50</renderOrder>
		<requireOne>

Lactating_Essential

Lactating_MandatoryHucow

IdeoRole_HucowHandler

		</requireOne>
		<generalRules>
			<rulesStrings>

memeAdjective->ranch

memeAdjective->bovine

memeHyphenPrefix->lacto

memeConcept->milk expression

memeLeaderNoun->rancher

memeLeaderNoun->hand

memeLeaderNoun->herder

memeLeaderNoun->sheepdog

			</rulesStrings>
		</generalRules>
		<descriptionMaker>
			<rules>
				<rulesStrings>

creation(tag=meme_Hucow)        ->[deity0_name] gave humankind the gift of bosoms, and the ability to produce breast milk.

episode(uses=1,tag=meme_Hucow)  ->[deity0_name] created all the noble animals and beasts of the land, and said, "Take these noble beasts, and through them make yourselves fruitful in my honor."

intro(tag=meme_Hucow)           ->The early [ranchingAnimal] ranchers of the [place_summary] [place_name] built a great [altarName] to [deity0_name].

conflict(tag=meme_Hucow)        ->A powerful [foeLeader] despised the [memberNamePlural] and their ways, and bought up all the grasslands to grow [Vegetable]s.

founderJoin(tag=meme_Hucow)     ->[memberName]'s savior [founderName] was born on a spring morning in a humble barn, amidst [ranchingAnimal]s, and [founder_possessive] parents were a [rancherParent1] and a [rancherParent2].

victory(tag=meme_Hucow)         ->[founderName] rode to the [place_community] on a fine horse, and challenged the [foeLeader] to a duel with [place_personalWeapon]s at noon. The [foeLeader] could not refuse or else lose the trust of the [foeSoldiers]. [founderName] killed the [foeLeader] dead.

setup(tag=meme_Hucow)           ->The farmers were persecuted, so they escaped to the countryside where they could build a good pastoral society.

story(uses=1,tag=meme_Hucow)    ->The believers spread out onto the land, and grew in number as they lived on their idyllic ranches and farms.

lessonIntro(tag=meme_Hucow)         ->Partner, out on the ranges, we had a saying among the old hands:

lesson(tag=meme_Hucow)              ->good and happiness right livin' is found in the pasture

lessonReinforcement(tag=meme_Hucow) ->It's something you come to accept, partner, on the lonely trails of the range, listenin' to the animals sleepin' while you sit around the fire.

archistFact(tag=meme_Hucow)     ->The archotechs care for humanity like shepherds, for we are their most precious flock.

archistProphecy(tag=meme_Hucow) ->[inTheEnd], the archotechs will depart, and drive before them those who tended their own herds well. The rest will be left behind in the wilderness.

animistFact(tag=meme_Hucow)     ->Nature's animals are the spirits of slaves, and demand to be taken into service.

				</rulesStrings>
			</rules>
		</descriptionMaker>
		<symbolPacks>

				<ideoName>Lactatism</ideoName>
				<theme>lactation</theme>
				<adjective>lactatist</adjective>
				<member>lactatist</member>

				<ideoName>Hucowism</ideoName>
				<theme>hucows</theme>
				<adjective>bovine</adjective>
				<member>Hucowist</member>

		</symbolPacks>
		<ritualsToMake>1</ritualsToMake>
		<replaceRitualsWithTags>

CelebratedDate

		</replaceRitualsWithTags>
	</MemeDef>
</Defs>


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

	<IssueDef>
		<defName>Lactating</defName>
		lactating
		<iconPath>UI/Issues/Lactating</iconPath>
	</IssueDef>

	<PreceptDef>
		<defName>Lactating_Essential</defName>
		<issue>Lactating</issue>
		essential
		<impact>High</impact>
		<displayOrderInIssue>20</displayOrderInIssue>
		<displayOrderInImpact>100</displayOrderInImpact>
		<description>Milk from breasts is creamy and delicious. It should be produced and consumed on a regular basis. Lactating colonists can be converted to hucow, which will produce double the normal amount of milk.</description>
		<comps>

				<thought>Lactating_Essential</thought>
				<description>Sizeable breasts must produce milk</description>
				<tooltipShowMoodRange>true</tooltipShowMoodRange>

				<thought>Lactating_Essential_Social</thought>
				<tooltipShowMoodRange>true</tooltipShowMoodRange>

				<eventDef>DrankNonMilkMeal</eventDef>
				<thought>DrankNonMilkMeal_Essential</thought>

				<eventDef>DrankMilkRaw</eventDef>
				<thought>DrankMilkRaw_Essential</thought>

				<eventDef>DrankMilkMeal</eventDef>
				<thought>DrankMilkMeal_Essential</thought>

		</comps>
	</PreceptDef>

	<ThoughtDef>
		<defName>Lactating_Essential</defName>
		<thoughtClass>Thought_Situational</thoughtClass>
		<workerClass>CRIALactation.ThoughtWorker_Precept_Lactating_Essential</workerClass>
		<stages>

				producing milk (hucow)
				<description>I'm a good cow to be producing milk.  Moo!</description>
				<baseMoodEffect>7</baseMoodEffect>

				producing milk
				<description>I'm glad I can support my colony by producing some milk.</description>
				<baseMoodEffect>3</baseMoodEffect>

				not producing milk
				<description>We live in such difficult times. It's wishful thinking, but I'd like to be producing milk right now.</description>
				<baseMoodEffect>-2</baseMoodEffect>

				not producing milk
				<description>I'm as useless as a dry well. A healthy supply of my milk can benefit the colony, but I'm failing to deliver.</description>
				<baseMoodEffect>-5</baseMoodEffect>

				not producing milk
				<description>Producing milk is a basic responsibility. I'm embarrassed and ashamed to be dry.</description>
				<baseMoodEffect>-8</baseMoodEffect>

		</stages>
	</ThoughtDef>

	<ThoughtDef>
		<defName>Lactating_Essential_Social</defName>
		<thoughtClass>Thought_SituationalSocial</thoughtClass>
		<workerClass>CRIALactation.ThoughtWorker_Precept_Lactating_Essential_Social</workerClass>
		<stages>

				hucow
				<baseOpinionOffset>20</baseOpinionOffset>

				producing milk
				<baseOpinionOffset>15</baseOpinionOffset>

				not producing milk (low expectations)
				<baseOpinionOffset>-5</baseOpinionOffset>

				not producing milk (moderate expectations)
				<baseOpinionOffset>-10</baseOpinionOffset>

				not producing milk (high expectations)
				<baseOpinionOffset>-15</baseOpinionOffset>

		</stages>
	</ThoughtDef>

	<ThoughtDef>
		<defName>DrankMilkRaw_Essential</defName>
		<durationDays>1</durationDays>
		<stages>

				Drank human milk
				<description>The taste of fresh breast milk is sweet, fulfilling, and intimate.</description>
				<baseMoodEffect>6</baseMoodEffect>

		</stages>
	</ThoughtDef>

	<ThoughtDef>
		<defName>DrankMilkMeal_Essential</defName>
		<durationDays>1</durationDays>
		<stages>

				Ate meal with human milk
				<description>The breast milk accentuated my meal beautifully.</description>
				<baseMoodEffect>2</baseMoodEffect>

		</stages>
	</ThoughtDef>

	<ThoughtDef>
		<defName>DrankNonMilkMeal_Essential</defName>
		<durationDays>1</durationDays>
		<stages>

				Ate non-human milk food
				<description>I had to eat food that wasn't produced from a person's breasts. My beliefs strictly forbid such things.</description>
				<baseMoodEffect>-2</baseMoodEffect>

		</stages>
	</ThoughtDef>

	<ThoughtDef>
		<defName>NoRecentHumanMilk_Essential</defName>
		<thoughtClass>Thought_Situational</thoughtClass>
		<workerClass>CRIALactation.ThoughtWorker_Precept_NoRecentHumanMilk</workerClass>
		<doNotApplyToQuestLodgers>True</doNotApplyToQuestLodgers>
		<stages>

				want human milk
				<description>It's been so long since I've tasted the milk of a woman's breasts. I should have had some by now.</description>
				<baseMoodEffect>-6</baseMoodEffect>

		</stages>
	</ThoughtDef>

	<PreceptDef>
		<defName>Lactating_MandatoryHucow</defName>
		<issue>Lactating</issue>
		required (mandatory hucow)
		<impact>High</impact>
		<requiredMemes>

Hucow

		</requiredMemes>
		<displayOrderInIssue>10</displayOrderInIssue>
		<displayOrderInImpact>100</displayOrderInImpact>
		<description>Breast milk is the most natural sustenance. For all sizeable bosoms, maximum expression and hucow conversion is a duty. To not produce or eat a meal without breast milk is unthinkable.</description>
		<comps>

				<thought>Lactating_MandatoryHucow</thought>
				<description>Colonists with sizeable breasts must become hucows</description>
				<tooltipShowMoodRange>true</tooltipShowMoodRange>

				<thought>Lactating_MandatoryHucow_Social</thought>
				<tooltipShowMoodRange>true</tooltipShowMoodRange>

				<eventDef>DrankNonMilkMeal</eventDef>
				<thought>DrankNonMilkMeal_MandatoryHucow</thought>

				<eventDef>DrankMilkRaw</eventDef>
				<thought>DrankMilkRaw_MandatoryHucow</thought>

				<eventDef>DrankMilkMeal</eventDef>
				<thought>DrankMilkMeal_MandatoryHucow</thought>

		</comps>
	</PreceptDef>

	<ThoughtDef>
		<defName>Lactating_MandatoryHucow</defName>
		<thoughtClass>Thought_Situational</thoughtClass>
		<workerClass>CRIALactation.ThoughtWorker_Precept_Lactating_Essential</workerClass>
		<stages>

				producing milk (hucow)
				<description>Watching people's satisfied faces drink what I expressed gives me a motherly sense of pride. I'm the colony's cow. Moo!</description>
				<baseMoodEffect>8</baseMoodEffect>

				producing milk
				<description>I'm producing milk, but I'm not a cow yet.</description>
				<baseMoodEffect>-1</baseMoodEffect>

				not producing milk
				<description>It pains me to think my breasts aren't producing milk when we need it most.</description>
				<baseMoodEffect>-3</baseMoodEffect>

				not producing milk
				<description>My milk has run dry. I'm so embarrassed I don't think I can show my face in public.</description>
				<baseMoodEffect>-6</baseMoodEffect>

				not producing milk
				<description>What's my purpose if I have breasts but can't express milk? I'm useless!</description>
				<baseMoodEffect>-9</baseMoodEffect>

		</stages>
	</ThoughtDef>

	<ThoughtDef>
		<defName>Lactating_MandatoryHucow_Social</defName>
		<thoughtClass>Thought_SituationalSocial</thoughtClass>
		<workerClass>CRIALactation.ThoughtWorker_Precept_Lactating_Essential_Social</workerClass>
		<stages>

				hucow
				<baseOpinionOffset>25</baseOpinionOffset>

				producing milk
				<baseOpinionOffset>-2</baseOpinionOffset>

				not producing milk (low expectations)
				<baseOpinionOffset>-5</baseOpinionOffset>

				not producing milk (moderate expectations)
				<baseOpinionOffset>-10</baseOpinionOffset>

				not producing milk (high expectations)
				<baseOpinionOffset>-15</baseOpinionOffset>

		</stages>
	</ThoughtDef>

	<ThoughtDef>
		<defName>DrankMilkRaw_MandatoryHucow</defName>
		<durationDays>1</durationDays>
		<stages>

				Drank human milk
				<description>So divine, so succulent. Our cows produce delicious milk.</description>
				<baseMoodEffect>7</baseMoodEffect>

		</stages>
	</ThoughtDef>

	<ThoughtDef>
		<defName>DrankMilkMeal_MandatoryHucow</defName>
		<durationDays>1</durationDays>
		<stages>

				Ate meal with human milk
				<description>The breast milk accentuated my meal beautifully.</description>
				<baseMoodEffect>3</baseMoodEffect>

		</stages>
	</ThoughtDef>

	<ThoughtDef>
		<defName>DrankNonMilkMeal_MandatoryHucow</defName>
		<durationDays>1</durationDays>
		<stages>

				Ate non-human milk food
				<description>Gross! I had to eat food that didn't contain breast milk. This is a disgrace to my beliefs.</description>
				<baseMoodEffect>-4</baseMoodEffect>

		</stages>
	</ThoughtDef>

	<ThoughtDef>
		<defName>NoRecentHumanMilk_MandatoryHucow</defName>
		<thoughtClass>Thought_Situational</thoughtClass>
		<workerClass>CRIALactation.ThoughtWorker_Precept_NoRecentHumanMilk</workerClass>
		<doNotApplyToQuestLodgers>True</doNotApplyToQuestLodgers>
		<stages>

				want human milk
				<description>I haven't had breast milk in days. My body feels weak.</description>
				<baseMoodEffect>-7</baseMoodEffect>

		</stages>
	</ThoughtDef>

</Defs>


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

	<PreceptDef ParentName="PreceptRoleSingleBase">
		<defName>IdeoRole_HucowHandler</defName>
		hucow handler
		<description>A special ideoligious status which can convert lactating pawns to hucows, increasing their lactation yield at the cost of their work and movement speed.</description>
		<iconPath>UI/Roles/SpecialistMelee</iconPath>
		<nameMaker>NamerRoleMoralist</nameMaker>
		<roleTags>

HucowHandler

		</roleTags>
		<roleRequirements>

				<labelKey>RoleRequirementLabelSameIdeo</labelKey>

		</roleRequirements>
		<roleApparelRequirements>

				<requirement>
					<bodyPartGroupsMatchAny>

UpperHead

FullHead

					</bodyPartGroupsMatchAny>
					<requiredDefs>

Apparel_Headwrap

					</requiredDefs>
				</requirement>

				<requirement>
					<bodyPartGroupsMatchAny>

UpperHead

FullHead

					</bodyPartGroupsMatchAny>
					<requiredDefs>

Apparel_Broadwrap

					</requiredDefs>
				</requirement>

				<requirement>
					<bodyPartGroupsMatchAny>

Torso

Neck

Shoulders

Arms

Legs

					</bodyPartGroupsMatchAny>
					<requiredDefs>

Apparel_Robe

					</requiredDefs>
				</requirement>

				<requirement>
					<bodyPartGroupsMatchAny>

UpperHead

					</bodyPartGroupsMatchAny>
					<requiredDefs>

Apparel_HatHood

					</requiredDefs>
				</requirement>

				<requirement>
					<bodyPartGroupsMatchAny>

UpperHead

					</bodyPartGroupsMatchAny>
					<requiredDefs>

Apparel_BowlerHat

					</requiredDefs>
				</requirement>

				<requirement>
					<bodyPartGroupsMatchAny>

Torso

					</bodyPartGroupsMatchAny>
					<requiredTags>

Cape

					</requiredTags>
				</requirement>

		</roleApparelRequirements>
		<roleApparelRequirementCountCurve>
			<points>

(0, 1)

(1, 1)

			</points>
		</roleApparelRequirementCountCurve>
		<requiredMemes>

Hucow

		</requiredMemes>
		<grantedAbilities>

ConvertToHucow

		</grantedAbilities>
		<displayOrderInImpact>2</displayOrderInImpact>
	</PreceptDef>

</Defs>


code:
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
	<StatDef>
		<defName>MilkProductionSpeed</defName>
		milk production speed multiplier
		<minValue>0.001</minValue>
		<category>BasicsPawn</category>
		<toStringStyle>PercentZero</toStringStyle>
		<hideAtValue>1</hideAtValue>
		<defaultBaseValue>1</defaultBaseValue>
		<showOnAnimals>false</showOnAnimals>
		<showOnMechanoids>false</showOnMechanoids>
		<displayPriorityInCategory>10000</displayPriorityInCategory>
	</StatDef>

	<StatDef>
		<defName>MilkProductionYield</defName>
		milk production yield multiplier
		<toStringStyle>PercentZero</toStringStyle>
		<minValue>1</minValue>
		<category>BasicsPawn</category>
		<hideAtValue>1</hideAtValue>
		<defaultBaseValue>1</defaultBaseValue>
		<showOnAnimals>false</showOnAnimals>
		<showOnMechanoids>false</showOnMechanoids>
		<displayPriorityInCategory>10001</displayPriorityInCategory>
	</StatDef>
</Defs>


code:
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
	<WorkGiverDef>
		<defName>MassageBreasts</defName>
		massage TargetA's breasts
		<giverClass>CRIALactation.WorkGiver_MassageBreasts</giverClass>
		<workType>Handling</workType>
		<verb>massage</verb>
		<gerund>stimulating the breasts of</gerund>
		<priorityInType>91</priorityInType>
		<requiredCapacities>

Manipulation

		</requiredCapacities>
	</WorkGiverDef>
</Defs>


code:
<?xml version="1.0" encoding="utf-8" ?>
<Patch>
 <Operation Class="PatchOperationSequence">
    <success>Always</success>
    <operations>

        <xpath>/Defs/ThingDef/comps</xpath>
        <success>Always</success>
        <nomatch Class="PatchOperationAdd">
          <xpath>/Defs/ThingDef</xpath>
          <value>
            <comps />
          </value>
        </nomatch>

        <xpath>/Defs/ThingDef[@Name="BasePawn"]/comps</xpath>
        <value>

				<DaysToLactating>15</DaysToLactating>
			    <TimesMassagedADay>2.5</TimesMassagedADay>

        </value>

    </operations>
  </Operation>
</Patch>


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

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("CRIALactation")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CRIALactation")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[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("01be0d84-9292-4f89-90fc-647b66771c61")]

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


code:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using rjw;
using Milk;
using UnityEngine;

namespace CRIALactation
{
    public class CompProperties_AbilityConvertHucow : CompProperties_AbilityEffect
    {

        public CompProperties_AbilityConvertHucow()
        {
            this.compClass = typeof(CompAbilityEffect_ConvertHucow);
        }

    }
}


code:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using rjw;
using Milk;
using UnityEngine;

namespace CRIALactation
{
    public class CompProperties_InduceLactation : CompProperties
    {
        public CompProperties_InduceLactation()
        {
            this.compClass = typeof(CompInduceLactation);
        }

        public float DaysToLactating = 15;
        public float TimesMassagedADay = 2.5f;
    }
}


code:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using rjw;
using Milk;
using UnityEngine;

namespace CRIALactation
{
    public class CompAbilityEffect_ConvertHucow : CompAbilityEffect
    {

        public override bool Valid(LocalTargetInfo target, bool throwMessages = false)
        {
            Pawn pawn = target.Pawn;
            return pawn != null && AbilityUtility.ValidateMustBeHuman(pawn, throwMessages) &&
                AbilityUtility.ValidateNoMentalState(pawn, throwMessages) &&
                AbilityUtility.ValidateSameIdeo(this.parent.pawn, pawn, throwMessages) &&
                LactationUtility.IsLactating(pawn) &&
                !LactationUtility.IsHucow(pawn);

        }

        public override void Apply(LocalTargetInfo target, LocalTargetInfo dest)
        {
            base.Apply(target, dest);
            Pawn pawn = target.Pawn;
            LactationUtility.ExtendLactationDuration(pawn);
        }
    }
}


code:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using rjw;
using Milk;
using UnityEngine;

namespace CRIALactation
{
    public class CompInduceLactation : ThingComp
    {
        private readonly int OneDayInTicks = 60000;
        private int TicksSinceLastMassage = -60000;

        private float InductionCompletionPercent = 0f;

        public bool isActive = false;
        public bool CanMassage = true;

        public int lastHumanLactationIngestedTick = 0;

        public override void CompTick()
        {
            base.CompTick();
            Pawn p = this.parent as Pawn;

            if (!p.IsHashIntervalTick(100))
            {
                return;
            }
            if (LactationUtility.IsLactating(p) || !isActive)
            {
                return;
            }
            if(TicksSinceLastMassage + OneDayInTicks / Props.TimesMassagedADay < GenTicks.TicksGame)
            {
                CanMassage = true;
            }

            if(InductionCompletionPercent >= 1)
            {
                string main = p.Name.ToStringShort + "'s breasts have been stimulated enough to induce lactation! They can now begin producing milk for their colony's consumption.";

                var letter = LetterMaker.MakeLetter(p.Name.ToStringShort + " induced lactation", main, LetterDefOf.PositiveEvent);
                Find.LetterStack.ReceiveLetter(letter);

                LactationUtility.StartLactating(p, true);
                InductionCompletionPercent = 0.90f + Random.Range(0f, 5f); //start at 90-95% in case they ever lose lactating again
            }
        }

        public void MassageBreasts()
        {
            InductionCompletionPercent += (float)1 / (Props.DaysToLactating * (Props.TimesMassagedADay + Rand.Value));
            TicksSinceLastMassage = GenTicks.TicksGame;
            CanMassage = false;
        }

        public CompProperties_InduceLactation Props
        {
            get
            {
                return (CompProperties_InduceLactation)props;
            }
        }

        public override IEnumerable<FloatMenuOption> CompFloatMenuOptions(Pawn pawn)
        {
            if (pawn != this.parent as Pawn && !((this.parent as Pawn).IsSlaveOfColony || (this.parent as Pawn).IsPrisonerOfColony)) yield break;
            if (LactationUtility.IsLactating(pawn)) yield break;
            if(LactationUtility.HasMilkableBreasts(this.parent as Pawn))
            {
                if(isActive)
                {
                    //stop trying to induce lactation
                    yield return new FloatMenuOption("Stop inducing lactation", () =>
                    {
                        isActive = false;
                    });
                }
                else
                {
                    //induce lactation
                    yield return new FloatMenuOption("Start inducing lactation", () =>
                    {
                        isActive = true;
                    });
                }
            }
            else
            {
                yield return new FloatMenuOption("Start inducing lactation (no milkable breasts)", null);
            }

            yield break;
        }

        public override void PostExposeData()
        {
            base.PostExposeData();
            Scribe_Values.Look<float>(ref this.InductionCompletionPercent, "InductionCompletionPercent", 0f);
            Scribe_Values.Look<int>(ref this.TicksSinceLastMassage, "TicksSinceLastMassage", -60000);
            Scribe_Values.Look<int>(ref this.lastHumanLactationIngestedTick, "lastHumanLactationIngestedTick", 0);

            Scribe_Values.Look<bool>(ref this.isActive, "IsActive", false);
            Scribe_Values.Look<bool>(ref this.CanMassage, "CanMassage", false);

        }

        public override string CompInspectStringExtra()
        {
            if (!isActive) return null;

            string result = "Induce lactation completion: " + InductionCompletionPercent.ToStringPercent();

            if(CanMassage)
            {
                result += "\nReady to massage.";
            }

            return result;
        }
    }
}


code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HarmonyLib;
using RimWorld;
using Verse;

namespace CRIALactation
{
    [HarmonyPatch]
    public static class HarmonyPatch_FoodUtility
    {

        [HarmonyReversePatch(HarmonyReversePatchType.Snapshot)]
        [HarmonyPatch(typeof(FoodUtility), "AddThoughtsFromIdeo")]
        public static void AddThoughtsFromIdeo_Patch(HistoryEventDef eventDef, Pawn ingester, ThingDef foodDef, MeatSourceCategory meatSourceCategory)
        {
            //throw new NotImplementedException("thoughts from ideo wasn't implemented!");
        }

        [HarmonyPatch(typeof(FoodUtility), "ThoughtsFromIngesting")]
        public static void Postfix(ref List<FoodUtility.ThoughtFromIngesting> __result, ref List<FoodUtility.ThoughtFromIngesting> ___ingestThoughts,  Pawn ingester, Thing foodSource, ThingDef foodDef)
        {
            /**
             * checks if food has milk or not
             */

            if (ingester.Ideo != null)
            {

                CompIngredients ingredients = foodSource.TryGetComp<CompIngredients>();
                if (foodDef == ThingDefOf_Milk.HumanMilk || foodDef == ThingDefOf_Milk.HumanoidMilk)
                {
                    AddThoughtsFromIdeo_Patch(HistoryEventDefOf_Milk.DrankMilkRaw, ingester, foodDef, FoodUtility.GetMeatSourceCategory(foodDef));

                    __result = ___ingestThoughts;

                }
                else if (ingredients == null
                    || !(ingredients.ingredients.Contains(ThingDefOf_Milk.HumanMilk) || (ingredients.ingredients.Contains(ThingDefOf_Milk.HumanoidMilk)))) {
                    AddThoughtsFromIdeo_Patch(HistoryEventDefOf_Milk.DrankNonMilkMeal, ingester, foodDef, FoodUtility.GetMeatSourceCategory(foodDef));
                    __result = ___ingestThoughts;
                }

            }

        }

        [HarmonyPatch(typeof(FoodUtility), "AddIngestThoughtsFromIngredient")]
        public static void Postfix(ThingDef ingredient, Pawn ingester) {

            MeatSourceCategory meatSourceCategory = FoodUtility.GetMeatSourceCategory(ingredient);

            if (ingester.Ideo != null)
            {

                if (ingredient == ThingDefOf_Milk.HumanoidMilk || ingredient == ThingDefOf_Milk.HumanMilk)
                {
                    AddThoughtsFromIdeo_Patch(HistoryEventDefOf_Milk.DrankMilkMeal, ingester, ingredient, meatSourceCategory);
                }

            }

        }

        [HarmonyPatch(typeof(FoodUtility), "GenerateGoodIngredients")]
        public static void Postfix(Thing meal, Ideo ideo)
        {
            CompIngredients compIngredients = meal.TryGetComp<CompIngredients>();

            if(ideo.HasPrecept(PreceptDefOf_Lactation.Lactating_Essential))
            {
                compIngredients.ingredients.Add(ThingDefOf_Milk.HumanMilk);
                compIngredients.ingredients.Add(ThingDefOf_Milk.HumanoidMilk);
            }
        }

    }
}


code:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using rjw;
using Milk;
using UnityEngine;
using HarmonyLib;

namespace CRIALactation
{

    /** //to be implemented next update
    [HarmonyPatch(typeof(IdeoUtility), "Notify_MemberGenerated")]
    public static class HarmonyPatch_Ideo_Notify_MemberGenerated
    {
        public static void Prefix()
        {

        }

    }**/
}


code:
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;

namespace CRIALactation
{
    [HarmonyPatch(typeof(Thing), "Ingested")]
    public static class HarmonyPatch_Thing
    {
        public static void Prefix(Thing __instance, Pawn ingester)
        {

            if(__instance.def == ThingDefOf_Milk.HumanMilk || __instance.def == ThingDefOf_Milk.HumanoidMilk)
            {
                ingester.TryGetComp<CompInduceLactation>().lastHumanLactationIngestedTick = Find.TickManager.TicksGame;
            }

        }
    }
}


code:
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Verse;

namespace C0ffeeRIA
{

    [StaticConstructorOnStartup]
    public static class Harmony_PatchAll
    {
        static Harmony_PatchAll()
        {
            Harmony harmony = new Harmony("CRIALactation");
            harmony.PatchAll(Assembly.GetExecutingAssembly());
        }

    }
}


code:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using rjw;
using Milk;
using UnityEngine;
using HarmonyLib;
using System.Reflection.Emit;

namespace CRIALactation

{
    [HarmonyPatch(typeof(HumanCompHasGatherableBodyResource), "CompTick")]
    public static class HarmonyPatch_Milk_HumanCompHasGatherableBodyResource
    {
        /*
        public static void Prefix(HumanCompHasGatherableBodyResource __instance)
        {
            if (!__instance.parent.IsHashIntervalTick(100))
            {
                return;
            }
            if (!(__instance.parent is Pawn)) return;

            Pawn p = __instance.parent as Pawn;
            if (p?.health?.hediffSet == null) return;

            if (p.Ideo?.GetRole(p) != null && p.Ideo.GetRole(p).def == PreceptDefOf_Lactation.IdeoRole_Hucow)
            {

                if(p.health.hediffSet.HasHediff(HediffDef.Named("Lactating_Natural"), false))
                {
                    p.health.RemoveHediff(p.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("Lactating_Natural"), false));
                }
                if (p.health.hediffSet.HasHediff(HediffDef.Named("Lactating_Drug"), false))
                {
                    p.health.RemoveHediff(p.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("Lactating_Drug"), false));
                }
                if(!(p.health.hediffSet.HasHediff(HediffDef.Named("Lactating_Permanent"), false) ||
                    p.health.hediffSet.HasHediff(HediffDef.Named("Heavy_Lactating_Permanent"), false)))
                {
                    p.health.AddHediff(HediffDef.Named("Lactating_Permanent"));
                }
            }
        }*/

        public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> codeInstructions)
        {

            var ins = codeInstructions.ToList();

            for(int i = 0; i < ins.Count; i++)
            {

                if (ins[i].opcode == OpCodes.Callvirt && ins.Count > i + 1 && ins[i + 1].OperandIs(60000))
                {

                    yield return ins[i];
                    yield return new CodeInstruction(OpCodes.Ldarg_0);
                    yield return new CodeInstruction(OpCodes.Call, AccessTools.DeclaredMethod(typeof(HarmonyPatch_Milk_HumanCompHasGatherableBodyResource), "AdjustGatherResourceDaysForPrecept"));

                }

                else
                {

                    yield return ins[i];
                }

            }

        }

        public static float AdjustGatherResourceDaysForPrecept(float resourcesIntervalDays, HumanCompHasGatherableBodyResource __instance)
        {

            Pawn pawn = __instance.parent as Pawn;
            if(pawn.Ideo.HasPrecept(PreceptDefOf_Lactation.Lactating_Essential))
            {

                return resourcesIntervalDays * 0.666f * pawn.GetStatValue(StatDefOf_Lactation.MilkProductionSpeed); //1.5x normal rate
            }

            return resourcesIntervalDays;

        }

    }

    [HarmonyPatch(typeof(CompHyperMilkableHuman), "ResourceAmount", MethodType.Getter)]
    public static class HarmonyPatch_IncreaseYieldForHucowHyperMilkable
    {
        public static void Postfix(CompHyperMilkableHuman __instance, ref float __result)
        {
            Pawn p = __instance.parent as Pawn;
            __result *= p.GetStatValue(StatDefOf_Lactation.MilkProductionYield);
        }
    }

    [HarmonyPatch(typeof(CompMilkableHuman), "ResourceAmount", MethodType.Getter)]
    public static class HarmonyPatch_IncreaseYieldForHucowMilkable
    {
        public static void Postfix(CompHyperMilkableHuman __instance, ref float __result)
        {
            Pawn p = __instance.parent as Pawn;
            __result *= p.GetStatValue(StatDefOf_Lactation.MilkProductionYield);
        }
    }
}


code:
using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;

namespace CRIALactation
{
    [DefOf]
    public static class HediffDefOf_Milk {
        static HediffDefOf_Milk()
        {
            DefOfHelper.EnsureInitializedInCtor(typeof(HediffDefOf_Milk));
        }

        public static HediffDef Lactating_Drug;
        public static HediffDef Lactating_Permanent;
        public static HediffDef Heavy_Lactating_Permanent;
        public static HediffDef Lactating_Natural;
        public static HediffDef Hucow;

    }
}


code:
using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;

namespace CRIALactation
{
    public class HediffCompProperties_StopOnceNotLactating : HediffCompProperties
    {
        public HediffCompProperties_StopOnceNotLactating()
        {
            this.compClass = typeof(HediffComp_StopOnceNotLactating);
        }
    }
}


code:
using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;

namespace CRIALactation
{
    public class HediffComp_StopOnceNotLactating : HediffComp
    {

        public override void CompPostTick(ref float severityAdjustment)
        {
            base.CompPostTick(ref severityAdjustment);

            if(!LactationUtility.IsLactating(Pawn))
            {
                LactationUtility.StopBeingHucow(Pawn);

            }
        }

    }
}


code:
using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CRIALactation
{
    [DefOf]
    public static class HistoryEventDefOf_Milk
    {
        static HistoryEventDefOf_Milk()
        {
            DefOfHelper.EnsureInitializedInCtor(typeof(HistoryEventDefOf_Milk));
        }

        public static HistoryEventDef DrankMilkRaw;

        public static HistoryEventDef DrankMilkMeal;

        public static HistoryEventDef DrankNonMilkMeal;
    }
}


code:
using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;

namespace CRIALactation
{
    [DefOf]
    public static class JobDefOf_CRIALactation
    {
        static JobDefOf_CRIALactation()
        {
            DefOfHelper.EnsureInitializedInCtor(typeof(HediffDefOf_Milk));
        }

        public static JobDef MassageBreasts;
    }
}


code:
using Milk;
using rjw;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using Verse.AI;

namespace CRIALactation
{
    public class JobDriver_MassageBreasts : JobDriver
    {
        private readonly float WorkTotal = 300f;

        public override bool TryMakePreToilReservations(bool errorOnFailed)
        {
            LocalTargetInfo Target = job.GetTarget(TargetIndex.A);
            return pawn.Reserve(Target, job, 1, -1, null, errorOnFailed);
        }

        protected override IEnumerable<Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch);
            Toil massage = new Toil();
            massage.FailOnDespawnedOrNull(TargetIndex.A);
            massage.FailOnAggroMentalStateAndHostile(TargetIndex.A);
            massage.initAction = delegate
            {
                Pawn p = job.GetTarget(TargetIndex.A).Thing as Pawn;
                pawn.pather.StopDead();
                PawnUtility.ForceWait(p, 15000, null, true);
            };
            massage.tickAction = delegate ()
            {
                pawn.skills.Learn(SkillDefOf.Animals, 0.13f, false);
                massageProgress += pawn.GetStatValue(StatDefOf.AnimalGatherSpeed, true);

            };
            massage.AddEndCondition(delegate
            {
                Pawn p = job.GetTarget(TargetIndex.A).Thing as Pawn;
                if (massageProgress >= WorkTotal)
                {
                    p.TryGetComp<CompInduceLactation>().MassageBreasts();
                    return JobCondition.Succeeded;
                }

                if (!(p.TryGetComp<CompInduceLactation>().isActive && p.TryGetComp<CompInduceLactation>().CanMassage))
                {
                    return JobCondition.Incompletable;
                }

                return JobCondition.Ongoing;

            });

            massage.AddFinishAction(delegate {
                Pawn pawn = this.job.GetTarget(TargetIndex.A).Thing as Pawn;
                if (pawn != null && pawn.CurJobDef == JobDefOf.Wait_MaintainPosture)
                {
                    pawn.jobs.EndCurrentJob(JobCondition.InterruptForced, true, true);
                }
            });
            massage.defaultCompleteMode = ToilCompleteMode.Never;

            massage.WithProgressBar(TargetIndex.A, () => massageProgress / WorkTotal);
            massage.activeSkill = (() => SkillDefOf.Animals);
            yield return massage;
            yield break;

        }

        float massageProgress = 0f;
    }
}


code:
using Milk;
using rjw;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;

namespace CRIALactation
{
    public static class LactationUtility
    {

        public static bool IsLactating(Pawn p)
        {

            return
                p.health.hediffSet.HasHediff(HediffDefOf_Milk.Lactating_Natural, false) ||
                p.health.hediffSet.HasHediff(HediffDefOf_Milk.Lactating_Drug, false) ||
                p.health.hediffSet.HasHediff(HediffDefOf_Milk.Lactating_Permanent, false) ||
                p.health.hediffSet.HasHediff(HediffDefOf_Milk.Heavy_Lactating_Permanent, false);

        }

        public static bool HasMilkableBreasts(Pawn p)
        {
            if (p.TryGetComp<CompMilkableHuman>() == null) return false;

            if (Genital_Helper.has_breasts(p) && (MilkBase.flatChestGivesMilk || !Genital_Helper.has_male_breasts(p)))
            {
                return true;
            }

            return false;
        }

        public static void StartLactating(Pawn p, bool natural)
        {
            Hediff lactating = HediffMaker.MakeHediff(HediffDefOf_Milk.Lactating_Natural, p, null);
            lactating.Severity = Rand.Value;
            p.health.AddHediff(lactating, Genital_Helper.get_breastsBPR(p));
        }

        public static void StopBeingHucow(Pawn p)
        {
            p.health.RemoveHediff(p.health.hediffSet.GetFirstHediffOfDef(HediffDefOf_Milk.Hucow, false));
        }

        public static bool IsHucow(Pawn p)
        {
            return p.health.hediffSet.HasHediff(HediffDefOf_Milk.Hucow);
        }

        public static bool isMassageable(Pawn p)
        {
            CompInduceLactation c = p.TryGetComp<CompInduceLactation>();
            if (c != null && c.isActive && c.CanMassage)
            {
                return true;
            }

            return false;

        }

        public static void ExtendLactationDuration(Pawn p)
        {

            var drugLact = p.health.hediffSet.GetFirstHediffOfDef(HediffDefOf_Milk.Lactating_Drug);
            if(drugLact != null)
            {
                drugLact.TryGetComp<HediffComp_Disappears>().ticksToDisappear = 1800000;
            }

            var naturalLact = p.health.hediffSet.GetFirstHediffOfDef(HediffDefOf_Milk.Lactating_Natural);
            if (naturalLact != null)
            {
                naturalLact.TryGetComp<HediffComp_Disappears>().ticksToDisappear = 1800000;
            }

        }
    }
}


code:
using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;

namespace CRIALactation
{
    [DefOf]
    public static class PreceptDefOf_Lactation
    {
        static PreceptDefOf_Lactation()
        {
            DefOfHelper.EnsureInitializedInCtor(typeof(PreceptDefOf_Lactation));
        }

        public static PreceptDef Lactating_Essential;
        public static PreceptDef Lactating_MandatoryHucow;
        //public static PreceptDef IdeoRole_Hucow;

    }
}


code:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using rjw;
using Milk;
using UnityEngine;

namespace CRIALactation
{
    public class PreceptComp_Lactation : PreceptComp
    {

        public override void Notify_MemberGenerated(Pawn pawn, Precept precept)
        {

            if((precept.def == PreceptDefOf_Lactation.Lactating_Essential
                || precept.def == PreceptDefOf_Lactation.Lactating_MandatoryHucow)
                && LactationUtility.HasMilkableBreasts(pawn))
            {

                if (!LactationUtility.IsLactating(pawn))
                {
                    LactationUtility.StartLactating(pawn, pawn.relations.ChildrenCount > 0);
                    Log.Message("Creating pawn with lact" + pawn.Name);
                }
            }
        }

    }
}


code:
using Milk;
using RimWorld;
using rjw;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;

namespace CRIALactation
{
    public class RoleEffect_Hucow : RoleEffect
    {
        public override string Label(Pawn pawn, Precept_Role role)
        {
            return "Greatly increased milk yield, permenant lactation, slower speed";
        }

        public RoleEffect_Hucow()
        {

        }
    }
}


code:
using Milk;
using RimWorld;
using rjw;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;

namespace CRIALactation
{
    public class RoleRequirement_Lactating : RoleRequirement
    {

        public override string GetLabel(Precept_Role role)
        {
            return "must be lactating";
        }

        public override bool Met(Pawn p, Precept_Role role)
        {
            if(LactationUtility.IsLactating(p))
            {
                return true;
            }
            return false;
        }
    }
}


code:
using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;

namespace CRIALactation
{
    [DefOf]
    public static class StatDefOf_Lactation
    {
        static StatDefOf_Lactation()
        {
            DefOfHelper.EnsureInitializedInCtor(typeof(StatDefOf_Lactation));
        }

        public static StatDef MilkProductionSpeed;
        public static StatDef MilkProductionYield;

    }
}


code:
using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;

namespace CRIALactation
{
    [DefOf]
    public static class ThingDefOf_Milk
    {
        static ThingDefOf_Milk()
        {
            DefOfHelper.EnsureInitializedInCtor(typeof(ThingDefOf_Milk));
        }

        public static ThingDef HumanMilk;

        public static ThingDef HumanoidMilk;

    }
}


code:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using rjw;
using Milk;
using UnityEngine;

namespace CRIALactation
{
    public class ThoughtWorker_Precept_Lactating_Essential : ThoughtWorker_Precept
    {

        protected override ThoughtState ShouldHaveThought(Pawn p)
        {

            if (!p.IsColonistPlayerControlled) return false;

            if (ThoughtUtility.ThoughtNullified(p, this.def))
            {
                return false;
            }

            if(!LactationUtility.HasMilkableBreasts(p))
            {
                return false;
            }
            if (LactationUtility.IsHucow(p))
            {
                return ThoughtState.ActiveAtStage(0);
            }
            if (LactationUtility.IsLactating(p))
            {
                return ThoughtState.ActiveAtStage(1);
            }

            if (!p.ageTracker.Adult)
            {
                return false;
            }

            if (ExpectationsUtility.CurrentExpectationFor(p).order <= ExpectationDefOf.VeryLow.order)
            {
                return ThoughtState.ActiveAtStage(2);
            }
            else if(ExpectationsUtility.CurrentExpectationFor(p).order <= ExpectationDefOf.Moderate.order)
            {
                return ThoughtState.ActiveAtStage(3);
            }
            else
            {
                return ThoughtState.ActiveAtStage(4);
            }
        }
    }
}


code:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using rjw;
using Milk;
using UnityEngine;

namespace CRIALactation
{
    public class ThoughtWorker_Precept_Lactating_Essential_Social : ThoughtWorker_Precept_Social
    {
        protected override ThoughtState ShouldHaveThought(Pawn p, Pawn otherPawn)
        {

            if (!LactationUtility.HasMilkableBreasts(otherPawn)) return false;

            if (LactationUtility.IsHucow(otherPawn))
            {
                return ThoughtState.ActiveAtStage(0);
            }
            else if (LactationUtility.IsLactating(otherPawn))
            {
                return ThoughtState.ActiveAtStage(1);

            }

            if(!otherPawn.ageTracker.Adult)
            {
                return false;
            }

            if (ExpectationsUtility.CurrentExpectationFor(p).order <= ExpectationDefOf.VeryLow.order)
            {
                return ThoughtState.ActiveAtStage(2);
            }
            else if (ExpectationsUtility.CurrentExpectationFor(p).order <= ExpectationDefOf.Moderate.order)
            {
                return ThoughtState.ActiveAtStage(3);
            }
            else
            {
                return ThoughtState.ActiveAtStage(4);
            }

        }

    }
}


code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using UnityEngine;

namespace CRIALactation
{
    public class ThoughtWorker_Precept_NoRecentHumanMilk : ThoughtWorker_Precept, IPreceptCompDescriptionArgs
    {
        public IEnumerable<NamedArgument> GetDescriptionArgs()
        {
            yield return MinDaysSinceLastHumanMeatForThought.Named("HUMANMILKREQUIREDINTERVAL");
        }

        protected override ThoughtState ShouldHaveThought(Pawn p)
        {
            int num = Mathf.Max(0, p.TryGetComp<CompInduceLactation>().lastHumanLactationIngestedTick);
            return Find.TickManager.TicksGame - num > 480000;
        }

        public const int MinDaysSinceLastHumanMeatForThought = 8;
    }
}


code:
using Milk;
using RimWorld;
using RimWorld.Planet;
using rjw;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using Verse.AI;

namespace CRIALactation
{
    public class WorkGiver_MassageBreasts : WorkGiver_Scanner
    {
        public override IEnumerable<Thing> PotentialWorkThingsGlobal(Pawn pawn)
        {
             return pawn.Map.mapPawns.AllPawnsSpawned;
        }

        public override bool ShouldSkip(Pawn pawn, bool forced = false)
        {
            List<Pawn> list = pawn.Map.mapPawns.AllPawnsSpawned;
            for(int i = 0; i < list.Count; i++)
            {
                if(LactationUtility.isMassageable(list[i]))
                {
                    return false;
                }
            }

            return true;
        }

        public override bool HasJobOnThing(Pawn p, Thing t, bool forced = false)
        {
            Pawn pawn2 = t as Pawn;
            if(pawn2?.TryGetComp<CompInduceLactation>() == null)
            {
                return false;
            }
            CompInduceLactation c = pawn2.TryGetComp<CompInduceLactation>();

            return p != pawn2 && c.isActive && c.CanMassage && !pawn2.Downed && !pawn2.Drafted && !pawn2.InAggroMentalState && !pawn2.IsFormingCaravan() && pawn2.CanCasuallyInteractNow(false, true, false) && p.CanReserve(pawn2, 1, -1, null, forced);

        }

        public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
        {
            return JobMaker.MakeJob(JobDefOf_CRIALactation.MassageBreasts, t);
        }

    }
}


code:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{212ED289-C5A3-4807-B482-A53F36B31F23}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>CRIAOrgy</RootNamespace>
    <AssemblyName>CRIAOrgy</AssemblyName>
    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <Deterministic>true</Deterministic>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>false</DebugSymbols>
    <DebugType>none</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>Assemblies\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="0Harmony">
      <HintPath>..\..\..\..\..\workshop\content\294100\2009463077\Current\Assemblies\0Harmony.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="Assembly-CSharp">
      <HintPath>..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="HugsLib">
      <HintPath>..\..\..\..\..\workshop\content\294100\818773962\v1.3\Assemblies\HugsLib.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="RJW">
      <HintPath>..\..\rjw\1.3\Assemblies\RJW.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Net.Http" />
    <Reference Include="System.Xml" />
    <Reference Include="UnityEngine">
      <HintPath>..\..\..\RimWorldWin64_Data\Managed\UnityEngine.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="UnityEngine.CoreModule">
      <HintPath>..\..\..\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
      <Private>False</Private>
    </Reference>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Properties\AssemblyInfo.cs" />
    <Compile Include="Source\RitualOutcomeEffectWorkers\RitualOutcomeEffectWorker_Orgy.cs" />
  </ItemGroup>
  <ItemGroup>
    <Content Include="Defs\PreceptDefs\Precepts_PublicSex.xml" />
    <Content Include="Defs\ThoughtDefs\Thoughts_Ritual_Orgy.xml" />
  </ItemGroup>
  <ItemGroup>
    <Folder Include="Assemblies\" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>


code:
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
	<PreceptDef ParentName="FestivalBase">
		<defName>OrgyCeremony</defName>
		fertility ritual
		<preceptClass>Precept_Ritual</preceptClass>
		<iconPath>UI/Icons/Rituals/TreeCelebration</iconPath>
		<ritualPatternBase>FertilityRitual</ritualPatternBase>
		<canGenerateAsSpecialPrecept>false</canGenerateAsSpecialPrecept>
		<receivesExpectationsQualityOffset>true</receivesExpectationsQualityOffset>
	</PreceptDef>

	<RitualPatternDef ParentName="CelebrationPartyChat">
		<defName>FertilityRitual</defName>
		<shortDescOverride>fertility ritual</shortDescOverride>
		<descOverride>An orgy ritual.</descOverride>
		<ritualBehavior>FertilityRitual</ritualBehavior>
		<ritualTargetFilter>AltarOrRitualSpot</ritualTargetFilter>
		<ritualObligationTargetFilter>AnyIdeoBuildingOrRitualSpot</ritualObligationTargetFilter>
		<ritualOutcomeEffect>FertilityRitualOutcome</ritualOutcomeEffect>
		<ritualExplanation>ritual orgy.</ritualExplanation>
		<canStartAnytime>true</canStartAnytime>
	</RitualPatternDef>

	<RitualBehaviorDef>
		<defName>FertilityRitual</defName>
		<durationTicks>10000</durationTicks>
		<roles />
		<spectatorsLabel>Participants</spectatorsLabel>
		<spectatorGerund>participate</spectatorGerund>
		<stages>

				<defaultDuty>Orgy</defaultDuty>
				<endTriggers>

						<percentage>1</percentage>

				</endTriggers>

		</stages>
	</RitualBehaviorDef>

	<RitualOutcomeEffectDef>
		<defName>FertilityRitualOutcome</defName>
		<description>orgy ritual outcome</description>
		<workerClass>CRIAOrgy.RitualOutcomeEffectWorker_Orgy</workerClass>
		<comps>

				participant count
				<curve>
					<points>

(1,  0.0)

(5,  0.6)

(10, 0.8)

					</points>
				</curve>

				room impressiveness
				<statDef>Impressiveness</statDef>
				<curve>
					<points>

0,  0

50,  0.1

120, 0.2

					</points>
				</curve>

		</comps>
		<outcomeChances>

				<chance>0.05</chance>
				Terrible
				<memory>TerribleOrgy</memory>
				<description>The {0} was terrible! Participants endured hours of jaw-clenching small talk while waiting for it to end.</description>
				<positivityIndex>-2</positivityIndex>

				<chance>0.15</chance>
				Boring
				<memory>BoringOrgy</memory>
				<description>The {0} was boring. Everyone felt too awkward to open up and laugh.</description>
				<positivityIndex>-1</positivityIndex>

				<chance>0.6</chance>
				Fun
				<memory>FunOrgy</memory>
				<description>The {0} was good. Everyone appreciated the chance to relax and have fun together.</description>
				<potentialExtraOutcomeDesc>There's a 5% chance that a random participant gains an inspiration.</potentialExtraOutcomeDesc>
				<positivityIndex>1</positivityIndex>

				<chance>0.2</chance>
				Unforgettable
				<memory>UnforgettableOrgy</memory>
				<description>The {0} was unforgettable! Everyone learned about each other and felt like a family.</description>
				<potentialExtraOutcomeDesc>There's a 10% chance a random participant gains an inspiration.</potentialExtraOutcomeDesc>
				<positivityIndex>2</positivityIndex>

		</outcomeChances>
	</RitualOutcomeEffectDef>
</Defs>


code:
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
	<ThoughtDef>
		<defName>TerribleOrgy</defName>
		<thoughtClass>Thought_AttendedRitual</thoughtClass>
		<durationDays>6</durationDays>
		<stackLimit>3</stackLimit>
		<stages>

				terrible festival
				<description>That festival was horrible. I'm still cringing from the awkwardness flashbacks.</description>
				<baseMoodEffect>-3</baseMoodEffect>

		</stages>
	</ThoughtDef>

	<ThoughtDef>
		<defName>BoringOrgy</defName>
		<thoughtClass>Thought_AttendedRitual</thoughtClass>
		<durationDays>6</durationDays>
		<stackLimit>3</stackLimit>
		<stages>

				boring festival
				<description>That festival was awkward. I wish I could have left.</description>
				<baseMoodEffect>-1</baseMoodEffect>

		</stages>
	</ThoughtDef>

	<ThoughtDef>
		<defName>FunOrgy</defName>
		<thoughtClass>Thought_AttendedRitual</thoughtClass>
		<durationDays>6</durationDays>
		<stackLimit>3</stackLimit>
		<stages>

				fun festival
				<description>I had fun! We got to hang out and relax.</description>
				<baseMoodEffect>5</baseMoodEffect>

		</stages>
	</ThoughtDef>

	<ThoughtDef>
		<defName>UnforgettableOrgy</defName>
		<thoughtClass>Thought_AttendedRitual</thoughtClass>
		<durationDays>6</durationDays>
		<stackLimit>3</stackLimit>
		<stages>

				unforgettable festival
				<description>That festival was something I'll never forget.</description>
				<baseMoodEffect>8</baseMoodEffect>

		</stages>
	</ThoughtDef>
</Defs>


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

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("CRIAOrgy")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CRIAOrgy")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[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("212ed289-c5a3-4807-b482-a53f36b31f23")]

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


code:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using rjw;
using UnityEngine;

namespace CRIAOrgy
{
    public class RitualOutcomeEffectWorker_Orgy : RitualOutcomeEffectWorker_FromQuality
    {

        public RitualOutcomeEffectWorker_Orgy()
        {

        }

        public RitualOutcomeEffectWorker_Orgy(RitualOutcomeEffectDef def) : base(def)
        {
        }

        public override void Apply(float progress, Dictionary<Pawn, int> totalPresence, LordJob_Ritual jobRitual)
        {
			foreach (KeyValuePair<Pawn, int> keyValuePair in totalPresence)
			{
                Pawn participant = keyValuePair.Key;

                participant.mindState.Notify_OutfitChanged();

                GlobalTextureAtlasManager.TryMarkPawnFrameSetDirty(participant);
                if (xxx.is_human(participant))
                    participant.Drawer.renderer.graphics.ResolveAllGraphics();
            }

            base.Apply(progress, totalPresence, jobRitual);
		}
    }
}


code:
<?xml version="1.0" encoding="utf-8" ?>
<loadFolders>
	<v1.3>

/

1.3

Quests

CRIALactation

CRIALactation/1.3

CRIAOrgy

CRIAOrgy/1.3

	</v1.3>
</loadFolders>


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

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("C0ffee's RJW Ideology Addons")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("C0ffee's RJW Ideology Addons")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[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("d46baa34-7459-482f-b152-321c071dce18")]

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


code:
using 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("Quests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Quests")]
[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("2f260b71-a18b-4291-a55f-33dfed1dbd9a")]

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


code:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{2F260B71-A18B-4291-A55F-33DFED1DBD9A}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>Quests</RootNamespace>
    <AssemblyName>Quests</AssemblyName>
    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <Deterministic>true</Deterministic>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>false</DebugSymbols>
    <DebugType>none</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>Assemblies\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="0Harmony">
      <HintPath>..\..\..\..\..\workshop\content\294100\1127530465\1.3\Assemblies\0Harmony.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="Assembly-CSharp">
      <HintPath>..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="RJW">
      <HintPath>..\..\rjw\1.3\Assemblies\RJW.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Net.Http" />
    <Reference Include="System.Xml" />
    <Reference Include="UnityEngine">
      <HintPath>..\..\..\RimWorldWin64_Data\Managed\UnityEngine.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="UnityEngine.CoreModule">
      <HintPath>..\..\..\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
      <Private>False</Private>
    </Reference>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <ItemGroup>
    <Folder Include="Assemblies\" />
    <Folder Include="Defs\" />
  </ItemGroup>
  <ItemGroup>
    <Content Include="Source\QuestScriptDefs\XMLFile1.xml" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>


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


code:
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using rjw;

namespace C0ffee_s_RJW_Ideology_Addons
{
    public static class CRIAUtility
    {

        public static bool TwoPawnsWillingToHaveSex(Pawn fucker, Pawn fucked)
        {

            if (fucker == fucked) return true; //pawns are always allowed to masturbate

            if (DesignatorsData.rjwComfort.Contains(fucked)) return true; //designated comfort pawns allowed to have sex with

            if (fucked.IsSlaveOfColony || fucked.IsPrisonerOfColony) return true; //prisoners and slaves are free game

            if (PawnsAreDesperate(fucker, fucked)) return true;

            if (!IdeoUtility.DoerWillingToDo(HistoryEventDefOf.SharedBed, fucker) || !IdeoUtility.DoerWillingToDo(HistoryEventDefOf.SharedBed, fucked))
            {
                return false;
            }

            if (fucker.relations.GetDirectRelation(PawnRelationDefOf.Spouse, fucked) != null)
            {

                if (!IdeoUtility.DoerWillingToDo(HistoryEventDefOf.SharedBed_Spouse, fucker) || !IdeoUtility.DoerWillingToDo(HistoryEventDefOf.SharedBed_Spouse, fucked))
                {
                    return false;
                }

            }
            else if (!IdeoUtility.DoerWillingToDo(HistoryEventDefOf.SharedBed_NonSpouse, fucker) || !IdeoUtility.DoerWillingToDo(HistoryEventDefOf.SharedBed_NonSpouse, fucked))
            {
                return false;
            }

            return true;
        }

        public static bool PawnsAreDesperate(Pawn fucker, Pawn fucked)
        {
            if ((IdeoUtility.DoerWillingToDo(HistoryEventDefOf.SharedBed, fucker) || xxx.is_frustrated(fucker) && (IdeoUtility.DoerWillingToDo(HistoryEventDefOf.SharedBed, fucked) || xxx.is_frustrated(fucked)))) return true; //frustrated pawns have to have sex

            return false;
        }

    }
}


code:
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Verse;

namespace C0ffeeRIA
{

    [StaticConstructorOnStartup]
    public static class Harmony_PatchAll
    {
        static Harmony_PatchAll()
        {
            Harmony harmony = new Harmony("C0ffeeRIA");
            harmony.PatchAll(Assembly.GetExecutingAssembly());
        }

    }
}


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

namespace C0ffee_s_RJW_Ideology_Addons
{
    [HarmonyPatch(typeof(JobDriver_SexBaseInitiator), "End")]
    public static class HarmonyPatch_JobDriver_SexBaseInitiator_End
    {

        public static void Prefix(JobDriver_SexBaseInitiator __instance)
        {
            if (__instance is JobDriver_Masturbate || __instance.Partner == null
                || __instance.pawn?.relations == null || __instance.pawn.RaceProps.IsMechanoid) return;

            HistoryEventDef def = __instance.pawn.relations.DirectRelationExists(PawnRelationDefOf.Spouse, __instance.Partner) ? HistoryEventDefOf.GotLovin_Spouse : HistoryEventDefOf.GotLovin_NonSpouse;

            if (!(IdeoUtility.DoerWillingToDo(HistoryEventDefOf.SharedBed_NonSpouse, __instance.Partner) && (__instance.Partner.IsSlaveOfColony || __instance.Partner.IsPrisonerOfColony))) //ensure raped pawns don't enjoy
            {
                Find.HistoryEventsManager.RecordEvent(new HistoryEvent(HistoryEventDefOf.GotLovin, __instance.Partner.Named(HistoryEventArgsNames.Doer)), true);
                Find.HistoryEventsManager.RecordEvent(new HistoryEvent(def, __instance.Partner.Named(HistoryEventArgsNames.Doer)), true);
            }

            if (IdeoUtility.DoerWillingToDo(HistoryEventDefOf.SharedBed_NonSpouse, __instance.pawn) || !(__instance.Partner.IsSlaveOfColony || __instance.Partner.IsPrisonerOfColony)) //ensure slaves are free game, but not otherwise
            {
                Find.HistoryEventsManager.RecordEvent(new HistoryEvent(HistoryEventDefOf.GotLovin, __instance.pawn.Named(HistoryEventArgsNames.Doer)), true);
                Find.HistoryEventsManager.RecordEvent(new HistoryEvent(def, __instance.pawn.Named(HistoryEventArgsNames.Doer)), true);
            }

        }
    }

    [HarmonyPatch(typeof(JobDriver_SexBaseInitiator), "Start")]
    public static class HarmonyPatch_JobDriver_SexBaseInitiator_Start
    {

        public static void Prefix(JobDriver_SexBaseInitiator __instance)
        {

            if (__instance is JobDriver_Masturbate || __instance.Partner == null) return;

            if (IdeoUtility.DoerWillingToDo(HistoryEventDefOf.SharedBed_NonSpouse, __instance.Partner) || !(__instance is JobDriver_Rape)) //ensure raped pawns don't enjoy
            {
                Find.HistoryEventsManager.RecordEvent(new HistoryEvent(HistoryEventDefOf.InitiatedLovin, __instance.pawn.Named(HistoryEventArgsNames.Doer)), true);
            }

        }

    }

}


code:
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using rjw;
using System.Reflection.Emit;

namespace C0ffee_s_RJW_Ideology_Addons
{
    [HarmonyPatch(typeof(CasualSex_Helper), "FindBestPartner")]
    public static class HarmonyPatch_CasualSex_Helper
    {

        public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> codeInstructions)
        {

            var ins = codeInstructions.ToList();
            for(int i = 0; i < ins.Count; i++)
            {

                if(ins[i].OperandIs(AccessTools.DeclaredMethod(typeof(CasualSex_Helper), "HookupAllowedViaSettings")))
                {

                    yield return new CodeInstruction(OpCodes.Call, AccessTools.DeclaredMethod(typeof(HarmonyPatch_CasualSex_Helper), "HookupAllowed"));

                }
                else
                {
                    yield return ins[i];
                }
            }

        }

        public static bool HookupAllowed(Pawn pawn1, Pawn pawn2)
        {
            if(CRIAUtility.TwoPawnsWillingToHaveSex(pawn1, pawn2))
            {
                return CasualSex_Helper.HookupAllowedViaSettings(pawn1, pawn2);
            }
            return false;
        }

    }
}


code:
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using rjw;
using System.Reflection.Emit;

namespace C0ffee_s_RJW_Ideology_Addons
{
    [StaticConstructorOnStartup]
    public static class HarmonyPatch_RMB_Menu
    {
        static HarmonyPatch_RMB_Menu()
        {
            (new Harmony("C0ffeeRIA")).Patch(AccessTools.Method(AccessTools.TypeByName("rjw.RMB_Menu"), "GenerateRMBOptions"),
                            postfix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_RMB_Menu), "Postfix")));

        }

        public static void Postfix(ref List<FloatMenuOption> __result, Pawn pawn, LocalTargetInfo target)
        {

            if (target.Pawn != null)
            {

                if (!CRIAUtility.TwoPawnsWillingToHaveSex(pawn, target.Pawn))
                {
                    for(int i = 0; i < __result.Count; i++)
                    {

                        if(__result[i].Label.StartsWith("RJW_RMB_Sex".Translate()))
                        {
                            __result[i].Label += " (sinful)";
                        }

                    }

                    return;
                }
            }

            return;

        }
    }
}


code:
/*
 * removed because not working
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using rjw;

namespace C0ffee_s_RJW_Ideology_Addons
{
    [StaticConstructorOnStartup]
    public static class SoftDependencyChecker
    {
        static SoftDependencyChecker()
        {

            string missingSoftDependencies = "";

            if (!LoadedModManager.RunningModsListForReading.Any((ModContentPack x) => x.PackageId == "c0ffee.rjw.events"))
            {
                missingSoftDependencies += "missing RJW Events, orgies will NOT be included; ";
            }
            if (!LoadedModManager.RunningModsListForReading.Any((ModContentPack x) => x.PackageId == "rjw.milk.humanoid"))
            {
                missingSoftDependencies += "missing RJW Milkable Colonists, hucow and lactation will NOT be included; ";
            }

            if(missingSoftDependencies != "")
            {
                Log.Warning("[c0ffee's RJW Ideology Addons] Warning, you're missing the following soft dependencies: " + missingSoftDependencies + "Features involving those mods will be disabled.");
            }

        }

    }
}*/


code:
###############################################################################
# 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

path: .gitattributes


code:
## 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

path: .gitignore


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

<ModMetaData>
	<name>Rimworld-Animations</name>
	<author>C0ffee</author>
  <url>https://gitgud.io/Platinumspoons/rimworld-animations/</url>
	<supportedVersions>

1.1

	</supportedVersions>
	<packageId>platinumspoons.rimworld.animations</packageId>
	<modDependencies>

			<packageId>brrainz.harmony</packageId>
			<displayName>Harmony</displayName>
			<steamWorkshopUrl>steam://url/CommunityFilePage/2009463077</steamWorkshopUrl>
			<downloadUrl>https://github.com/pardeike/HarmonyRimWorld/releases/latest</downloadUrl>

			<packageId>UnlimitedHugs.HugsLib</packageId>
			<displayName>HugsLib</displayName>
			<downloadUrl>https://github.com/UnlimitedHugs/RimworldHugsLib/releases/latest</downloadUrl>
			<steamWorkshopUrl>steam://url/CommunityFilePage/818773962</steamWorkshopUrl>

      <packageId>rim.job.world</packageId>
      <displayName>RimJobWorld</displayName>
      <downloadUrl>https://www.loverslab.com/topic/110270-mod-rimjobworld/</downloadUrl>

	</modDependencies>
	<loadAfter>

UnlimitedHugs.HugsLib

brrainz.harmony

rim.job.world

	</loadAfter>
	<description>
    Rimworld Animations! Hurray!

    Questions or bugs?
    Chat with me on the forums: https://www.loverslab.com/topic/140386-rjw-animations/
    Or on the rjw discord: https://discord.gg/CXwHhv8

  </description>
</ModMetaData>