mirror of
https://gitgud.io/c0ffeeeeeeee/coffees-rjw-ideology-addons.git
synced 2024-08-14 23:57:38 +00:00
Induce lactation
This commit is contained in:
parent
616d83ba08
commit
f21812a3eb
11 changed files with 382 additions and 0 deletions
Binary file not shown.
|
@ -70,10 +70,14 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Source\CompProperties\CompProperties_InduceLactation.cs" />
|
||||||
|
<Compile Include="Source\Comps\CompInduceLactation.cs" />
|
||||||
<Compile Include="Source\HarmonyPatches\HarmonyPatch_Ideo.cs" />
|
<Compile Include="Source\HarmonyPatches\HarmonyPatch_Ideo.cs" />
|
||||||
<Compile Include="Source\HarmonyPatches\Harmony_PatchAll.cs" />
|
<Compile Include="Source\HarmonyPatches\Harmony_PatchAll.cs" />
|
||||||
<Compile Include="Source\HarmonyPatches\RJW\HarmonyPatch_Milk_HumanCompHasGatherableBodyResource.cs" />
|
<Compile Include="Source\HarmonyPatches\RJW\HarmonyPatch_Milk_HumanCompHasGatherableBodyResource.cs" />
|
||||||
<Compile Include="Source\HediffDefOf\HediffDefOf_Milk.cs" />
|
<Compile Include="Source\HediffDefOf\HediffDefOf_Milk.cs" />
|
||||||
|
<Compile Include="Source\JobDefOf\JobDefOf_CRIALactation.cs" />
|
||||||
|
<Compile Include="Source\JobDrivers\JobDriver_MassageBreasts.cs" />
|
||||||
<Compile Include="Source\LactationUtility.cs" />
|
<Compile Include="Source\LactationUtility.cs" />
|
||||||
<Compile Include="Source\PreceptDefOf\PreceptDefOf_Lactation.cs" />
|
<Compile Include="Source\PreceptDefOf\PreceptDefOf_Lactation.cs" />
|
||||||
<Compile Include="Source\Precepts\Precept_Lactation.cs" />
|
<Compile Include="Source\Precepts\Precept_Lactation.cs" />
|
||||||
|
@ -81,12 +85,16 @@
|
||||||
<Compile Include="Source\RoleRequirements\RoleRequirement_Lactating.cs" />
|
<Compile Include="Source\RoleRequirements\RoleRequirement_Lactating.cs" />
|
||||||
<Compile Include="Source\Thoughts\ThoughtWorker_Precept_Lactating_Essential.cs" />
|
<Compile Include="Source\Thoughts\ThoughtWorker_Precept_Lactating_Essential.cs" />
|
||||||
<Compile Include="Source\Thoughts\ThoughtWorker_Precept_Lactating_Essential_Social.cs" />
|
<Compile Include="Source\Thoughts\ThoughtWorker_Precept_Lactating_Essential_Social.cs" />
|
||||||
|
<Compile Include="Source\WorkGivers\WorkGiver_MassageBreasts.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
<ItemGroup />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Content Include="Defs\JobDefs\Jobs_CRIALactation.xml" />
|
||||||
<Content Include="Defs\MemeDefs\Memes_Hucow.xml" />
|
<Content Include="Defs\MemeDefs\Memes_Hucow.xml" />
|
||||||
<Content Include="Defs\PreceptDefs\Precepts_Lactating.xml" />
|
<Content Include="Defs\PreceptDefs\Precepts_Lactating.xml" />
|
||||||
<Content Include="Defs\PreceptDefs\Precepts_Lactating_Role.xml" />
|
<Content Include="Defs\PreceptDefs\Precepts_Lactating_Role.xml" />
|
||||||
|
<Content Include="Defs\WorkGiverDefs\WorkGiver_MassageBreasts.xml" />
|
||||||
|
<Content Include="Patches\Patch_LactationInduction.xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
9
CRIALactation/Defs/JobDefs/Jobs_CRIALactation.xml
Normal file
9
CRIALactation/Defs/JobDefs/Jobs_CRIALactation.xml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?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>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<Defs>
|
||||||
|
<WorkGiverDef>
|
||||||
|
<defName>MassageBreasts</defName>
|
||||||
|
<label>massage TargetA's breasts</label>
|
||||||
|
<giverClass>CRIALactation.WorkGiver_MassageBreasts</giverClass>
|
||||||
|
<workType>Handling</workType>
|
||||||
|
<verb>massage</verb>
|
||||||
|
<gerund>stimulating the breasts of</gerund>
|
||||||
|
<priorityInType>91</priorityInType>
|
||||||
|
<requiredCapacities>
|
||||||
|
<li>Manipulation</li>
|
||||||
|
</requiredCapacities>
|
||||||
|
</WorkGiverDef>
|
||||||
|
</Defs>
|
28
CRIALactation/Patches/Patch_LactationInduction.xml
Normal file
28
CRIALactation/Patches/Patch_LactationInduction.xml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<Patch>
|
||||||
|
<Operation Class="PatchOperationSequence">
|
||||||
|
<success>Always</success>
|
||||||
|
<operations>
|
||||||
|
<li Class="PatchOperationConditional">
|
||||||
|
<xpath>/Defs/ThingDef/comps</xpath>
|
||||||
|
<success>Always</success>
|
||||||
|
<nomatch Class="PatchOperationAdd">
|
||||||
|
<xpath>/Defs/ThingDef</xpath>
|
||||||
|
<value>
|
||||||
|
<comps />
|
||||||
|
</value>
|
||||||
|
</nomatch>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li Class="PatchOperationAdd">
|
||||||
|
<xpath>/Defs/ThingDef[@Name="BasePawn"]/comps</xpath>
|
||||||
|
<value>
|
||||||
|
<li Class="CRIALactation.CompProperties_InduceLactation">
|
||||||
|
<DaysToLactating>15</DaysToLactating>
|
||||||
|
<TimesMassagedADay>2.5</TimesMassagedADay>
|
||||||
|
</li>
|
||||||
|
</value>
|
||||||
|
</li>
|
||||||
|
</operations>
|
||||||
|
</Operation>
|
||||||
|
</Patch>
|
|
@ -0,0 +1,23 @@
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
131
CRIALactation/Source/Comps/CompInduceLactation.cs
Normal file
131
CRIALactation/Source/Comps/CompInduceLactation.cs
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
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 override void CompTick()
|
||||||
|
{
|
||||||
|
base.CompTick();
|
||||||
|
Pawn p = this.parent as Pawn;
|
||||||
|
|
||||||
|
if (!isActive)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!p.IsHashIntervalTick(100))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LactationUtility.IsLactating(p))
|
||||||
|
{
|
||||||
|
isActive = false;
|
||||||
|
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);
|
||||||
|
isActive = false;
|
||||||
|
InductionCompletionPercent = 0.6f; //start at 60% 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) 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("Undesignate induce lactation", () =>
|
||||||
|
{
|
||||||
|
isActive = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//induce lactation
|
||||||
|
yield return new FloatMenuOption("Designate induce lactation", () =>
|
||||||
|
{
|
||||||
|
isActive = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
yield return new FloatMenuOption("Designate induce 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<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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
CRIALactation/Source/JobDefOf/JobDefOf_CRIALactation.cs
Normal file
21
CRIALactation/Source/JobDefOf/JobDefOf_CRIALactation.cs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
79
CRIALactation/Source/JobDrivers/JobDriver_MassageBreasts.cs
Normal file
79
CRIALactation/Source/JobDrivers/JobDriver_MassageBreasts.cs
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,5 +38,17 @@ namespace CRIALactation
|
||||||
lactating.Severity = Rand.Value;
|
lactating.Severity = Rand.Value;
|
||||||
p.health.AddHediff(lactating, Genital_Helper.get_breastsBPR(p));
|
p.health.AddHediff(lactating, Genital_Helper.get_breastsBPR(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool isMassageable(Pawn p)
|
||||||
|
{
|
||||||
|
CompInduceLactation c = p.TryGetComp<CompInduceLactation>();
|
||||||
|
if (c != null && c.isActive && c.CanMassage)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
56
CRIALactation/Source/WorkGivers/WorkGiver_MassageBreasts.cs
Normal file
56
CRIALactation/Source/WorkGivers/WorkGiver_MassageBreasts.cs
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
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.SpawnedPawnsInFaction(pawn.Faction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool ShouldSkip(Pawn pawn, bool forced = false)
|
||||||
|
{
|
||||||
|
List<Pawn> list = pawn.Map.mapPawns.SpawnedPawnsInFaction(pawn.Faction);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue