using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Verse; using RimWorld; using rjw; using Verse.AI; namespace RJW_ToysAndMasturbation { public class JobDriver_MasturbateWithToy : JobDriver_SexBaseInitiator { public IntVec3 cell => (IntVec3)job.GetTarget(iCell); public Thing dildo => (Thing)job.GetTarget(TargetIndex.A); public override bool TryMakePreToilReservations(bool errorOnFailed) { return ReservationUtility.Reserve(pawn, job.targetA, job, stackCount: 1, errorOnFailed: false); } public new void setup_ticks() { base.setup_ticks(); duration = ticks_left = (int)(xxx.is_frustrated(base.pawn) ? (2500f * Rand.Range(0.2f, 0.7f)) : (2500f * Rand.Range(0.2f, 0.4f))); } protected override IEnumerable MakeNewToils() { setup_ticks(); ToilFailConditions.FailOn(this, () => pawn.Downed); ToilFailConditions.FailOn(this, () => pawn.IsBurning()); ToilFailConditions.FailOn(this, () => pawn.IsFighting()); ToilFailConditions.FailOn(this, () => pawn.Drafted); yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A); yield return Toils_Haul.StartCarryThing(TargetIndex.A); yield return Toils_Goto.GotoCell(TargetIndex.C, PathEndMode.OnCell); Toil masturbationToil = Toils_General.Wait(duration); masturbationToil.handlingFacing = true; masturbationToil.defaultCompleteMode = ToilCompleteMode.Never; masturbationToil.initAction = delegate { Start(); }; masturbationToil.tickAction = delegate { if (Gen.IsHashIntervalTick(pawn, ticks_between_hearts)) { ThrowMetaIconF(pawn.Position, this.pawn.Map, FleckDefOf.Heart); } SexTick(pawn, null); SexUtility.reduce_rest(pawn); if (ticks_left <= 0) ReadyForNextToil(); }; masturbationToil.AddFinishAction(delegate { End(); }); yield return masturbationToil; Toil AfterToil = new Toil(); AfterToil.initAction = delegate { SexUtility.Aftersex(Sexprops); if(SexUtility.ConsiderCleaning(pawn)) { LocalTargetInfo filth = GridsUtility.GetFirstThing(pawn.PositionHeld, pawn.Map); Job cleanup = JobMaker.MakeJob(JobDefOf.Clean); cleanup.AddQueuedTarget(TargetIndex.A, filth); pawn.jobs.jobQueue.EnqueueFirst(cleanup); } //bonus mood pawn.needs?.mood?.thoughts?.memories?.TryGainMemory(MasturbateToyDefOf.UsedSexToy); }; yield return AfterToil; } } }