コード例 #1
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //--Log.Message("JobDriver_JoinInBed::MakeNewToils() called");
            this.FailOnDespawnedOrNull(ipartner);
            this.FailOnDespawnedOrNull(ibed);
            this.FailOn(() => !Partner.health.capacities.CanBeAwake);
            this.FailOn(() => !(Partner.InBed() || xxx.in_same_bed(Partner, Top)));
            this.FailOn(() => pawn.Drafted);
            yield return(Toils_Reserve.Reserve(ipartner, xxx.max_rapists_per_prisoner, 0));

            yield return(Toils_Goto.GotoThing(ipartner, PathEndMode.OnCell));

            yield return(new Toil
            {
                initAction = delegate
                {
                    //--Log.Message("JobDriver_JoinInBed::MakeNewToils() - setting initAction");
                    //Rand.PopState();
                    //Rand.PushState(RJW_Multiplayer.PredictableSeed());
                    ticks_left = (int)(2500.0f * Rand.Range(0.30f, 1.30f));
                    Job gettin_loved = new Job(xxx.gettin_loved, Top, Bed);
                    Partner.jobs.StartJob(gettin_loved, JobCondition.InterruptForced);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });

            Toil do_lovin = new Toil {
                defaultCompleteMode = ToilCompleteMode.Never
            };

            do_lovin.FailOn(() => (Partner.CurJob == null) || (Partner.CurJob.def != xxx.gettin_loved));
            do_lovin.AddPreTickAction(delegate
            {
                --ticks_left;
                xxx.reduce_rest(Partner, 1);
                xxx.reduce_rest(Top, 2);
                if (ticks_left <= 0)
                {
                    ReadyForNextToil();
                }
                else if (Top.IsHashIntervalTick(ticks_between_hearts))
                {
                    MoteMaker.ThrowMetaIcon(Top.Position, Top.Map, ThingDefOf.Mote_Heart);
                }
            });
            do_lovin.socialMode = RandomSocialMode.Off;
            yield return(do_lovin);

            yield return(new Toil
            {
                initAction = delegate
                {
                    // Trying to add some interactions and social logs
                    SexUtility.ProcessSex(Top, Partner, false /*rape*/, false /*isCoreLovin*/, false /*whoring*/);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });
        }
コード例 #2
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //Log.Message("[RJW]JobDriver_WhoreIsServingVisitors::MakeNewToils() - making toils");
            this.FailOnDespawnedOrNull(PartnerInd);
            this.FailOnDespawnedNullOrForbidden(BedInd);
            //Log.Message("[RJW]JobDriver_WhoreIsServingVisitors::MakeNewToils() fail conditions check " + (Actor is null) + " " + !xxx.CanUse(Actor, Bed) + " " + !Actor.CanReserve(Partner));
            this.FailOn(() => Actor is null || !xxx.CanUse(Actor, Bed) || !Actor.CanReserve(Partner));
            this.FailOn(() => pawn.Drafted);
            int price = WhoringHelper.PriceOfWhore(Actor);

            yield return(Toils_Reserve.Reserve(PartnerInd, 1, 0));

            //yield return Toils_Reserve.Reserve(BedInd, Bed.SleepingSlotsCount, 0);
            bool partnerHasPenis = Genital_Helper.has_penis(Partner) || Genital_Helper.has_penis_infertile(Partner);

            Toil gotoWhoreBed = new Toil
            {
                initAction = delegate
                {
                    //Log.Message("[RJW]JobDriver_WhoreIsServingVisitors::MakeNewToils() - gotoWhoreBed initAction is called");
                    Actor.pather.StartPath(WhoreSleepSpot, PathEndMode.OnCell);
                    Partner.jobs.StopAll();
                    Partner.pather.StartPath(WhoreSleepSpot, PathEndMode.Touch);
                },
                tickAction = delegate
                {
                    if (Partner.IsHashIntervalTick(150))
                    {
                        Partner.pather.StartPath(Actor, PathEndMode.Touch);
                        //Log.Message(xxx.get_pawnname(Partner) + ": I'm following the w***e");
                    }
                },
                defaultCompleteMode = ToilCompleteMode.PatherArrival
            };

            gotoWhoreBed.FailOnWhorebedNoLongerUsable(BedInd, Bed);
            yield return(gotoWhoreBed);

            Toil waitInBed = new Toil
            {
                initAction = delegate
                {
                    //Rand.PopState();
                    //Rand.PushState(RJW_Multiplayer.PredictableSeed());
                    //Log.Message("JobDriver_WhoreIsServingVisitors::MakeNewToils() - waitInBed, initAction is called");
                    ticksLeftThisToil = 5000;
                    ticks_left        = (int)(2000.0f * Rand.Range(0.30f, 1.30f));
                    //Actor.pather.StopDead();  //Let's just make w****s standing at the bed
                    //JobDriver curDriver = Actor.jobs.curDriver;
                    //curDriver.layingDown = LayingDownState.LayingInBed;
                    //curDriver.asleep = false;
                    var gettin_loved = new Job(xxx.gettin_loved, Actor, Bed);
                    Partner.jobs.StartJob(gettin_loved, JobCondition.InterruptForced);
                },
                tickAction = delegate
                {
                    Actor.GainComfortFromCellIfPossible();
                    if (IsInOrByBed(Bed, Partner))
                    {
                        //Log.Message("JobDriver_WhoreIsServingVisitors::MakeNewToils() - waitInBed, tickAction pass");
                        ticksLeftThisToil = 0;
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Delay,
            };

            waitInBed.FailOn(() => pawn.GetRoom() == null);
            yield return(waitInBed);

            bool canAfford = WhoringHelper.CanAfford(Partner, Actor, price);

            if (canAfford)
            {
                Toil loveToil = new Toil
                {
                    initAction = delegate
                    {
                        //Actor.jobs.curDriver.ticksLeftThisToil = 1200;
                        //Using ticks_left to control the time of sex
                        //--Log.Message("JobDriver_WhoreIsServingVisitors::MakeNewToils() - loveToil, setting initAction");

                        /*
                         * //Hoge: W***e is just work. no feel cheatedOnMe.
                         * if (xxx.HasNonPolyPartner(Actor))
                         * {
                         *      Pawn pawn = LovePartnerRelationUtility.ExistingLovePartner(Actor);
                         *      if (((Partner != pawn) && !pawn.Dead) && ((pawn.Map == Actor.Map) || (Rand.Value < 0.15)))
                         *      {
                         *              pawn.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.CheatedOnMe, Actor);
                         *      }
                         * }
                         */
                        if (xxx.HasNonPolyPartnerOnCurrentMap(Partner))
                        {
                            Pawn lover = LovePartnerRelationUtility.ExistingLovePartner(Partner);
                            //Rand.PopState();
                            //Rand.PushState(RJW_Multiplayer.PredictableSeed());
                            // We have to do a few other checks because the pawn might have multiple lovers and ExistingLovePartner() might return the wrong one
                            if (lover != null && Actor != lover && !lover.Dead && (lover.Map == Partner.Map || Rand.Value < 0.25))
                            {
                                lover.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.CheatedOnMe, Partner);
                            }
                        }
                        if (!partnerHasPenis)
                        {
                            Actor.rotationTracker.Face(Partner.DrawPos);
                        }
                    },
                    defaultCompleteMode = ToilCompleteMode.Never,                     //Changed from Delay
                };
                loveToil.AddPreTickAction(delegate
                {
                    //Actor.Reserve(Partner, 1, 0);
                    --ticks_left;
                    xxx.reduce_rest(Partner);
                    xxx.reduce_rest(Actor, 2);

                    if (ticks_left <= 0)
                    {
                        ReadyForNextToil();
                    }
                    else if (pawn.IsHashIntervalTick(ticks_between_hearts))
                    {
                        MoteMaker.ThrowMetaIcon(Actor.Position, Actor.Map, ThingDefOf.Mote_Heart);
                    }
                    Actor.GainComfortFromCellIfPossible();
                    Partner.GainComfortFromCellIfPossible();
                });
                loveToil.AddFinishAction(delegate
                {
                    //Log.Message("[RJW] JobDriver_WhoreIsServingVisitors::MakeNewToils() - finished loveToil");
                    //// Trying to add some interactions and social logs
                    //xxx.processAnalSex(Partner, Actor, ref isAnalSex, partnerHasPenis);
                });
                loveToil.AddFailCondition(() => Partner.Dead || !IsInOrByBed(Bed, Partner));
                loveToil.socialMode = RandomSocialMode.Off;
                yield return(loveToil);

                Toil afterSex = new Toil
                {
                    initAction = delegate
                    {
                        // Adding interactions, social logs, etc
                        SexUtility.ProcessSex(Actor, Partner, false, false, true);

                        //--Log.Message("JobDriver_WhoreIsServingVisitors::MakeNewToils() - Partner should pay the price now in afterSex.initAction");
                        int remainPrice = WhoringHelper.PayPriceToWhore(Partner, price, Actor);

                        /*if (remainPrice <= 0)
                         * {
                         *      --Log.Message("JobDriver_WhoreIsServingVisitors::MakeNewToils() - Paying price is success");
                         * }
                         * else
                         * {
                         *      --Log.Message("JobDriver_WhoreIsServingVisitors::MakeNewToils() - Paying price failed");
                         * }*/
                        xxx.UpdateRecords(Actor, price - remainPrice);
                        var thought = (Actor.IsPrisoner) ? thought_captive : thought_free;
                        pawn.needs.mood.thoughts.memories.TryGainMemory(thought);
                        if (SexUtility.ConsiderCleaning(pawn))
                        {
                            LocalTargetInfo cum = pawn.PositionHeld.GetFirstThing <Filth>(pawn.Map);

                            Job clean = new Job(JobDefOf.Clean);
                            clean.AddQueuedTarget(TargetIndex.A, cum);

                            pawn.jobs.jobQueue.EnqueueFirst(clean);
                        }
                    },
                    defaultCompleteMode = ToilCompleteMode.Instant
                };
                yield return(afterSex);
            }
        }
コード例 #3
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //Log.Message("[RJW]" + this.GetType().ToString() + "::MakeNewToils() called");
            setup_ticks();

            this.FailOnDespawnedNullOrForbidden(iTarget);
            this.FailOn(() => !pawn.CanReserve(Partner, xxx.max_rapists_per_prisoner, 0));             // Fail if someone else reserves the prisoner before the pawn arrives
            this.FailOn(() => pawn.IsFighting());
            this.FailOn(() => Partner.IsFighting());
            this.FailOn(() => pawn.Drafted);
            yield return(Toils_Goto.GotoThing(iTarget, PathEndMode.OnCell));

            SexUtility.RapeTargetAlert(pawn, Partner);

            Toil StartPartnerJob = new Toil();

            StartPartnerJob.defaultCompleteMode = ToilCompleteMode.Instant;
            StartPartnerJob.socialMode          = RandomSocialMode.Off;
            StartPartnerJob.initAction          = delegate
            {
                var dri = Partner.jobs.curDriver as JobDriver_SexBaseRecieverRaped;
                if (dri == null)
                {
                    Job          gettin_raped = JobMaker.MakeJob(xxx.gettin_raped, pawn);
                    Building_Bed Bed          = null;
                    if (Partner.GetPosture() == PawnPosture.LayingInBed)
                    {
                        Bed = Partner.CurrentBed();
                    }

                    Partner.jobs.StartJob(gettin_raped, JobCondition.InterruptForced, null, false, true, null);
                    if (Bed != null)
                    {
                        (Partner.jobs.curDriver as JobDriver_SexBaseRecieverRaped)?.Set_bed(Bed);
                    }
                }
            };
            yield return(StartPartnerJob);

            var rape = new Toil();

            rape.FailOn(() => Partner.CurJob == null || Partner.CurJob.def != xxx.gettin_raped || Partner.IsFighting() || pawn.IsFighting());
            rape.defaultCompleteMode = ToilCompleteMode.Delay;
            rape.defaultDuration     = duration;
            rape.handlingFacing      = true;
            rape.initAction          = delegate
            {
                Start();
            };
            rape.tickAction = delegate
            {
                if (pawn.IsHashIntervalTick(ticks_between_hearts))
                {
                    ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart);
                }
                if (pawn.IsHashIntervalTick(ticks_between_hits))
                {
                    Roll_to_hit(pawn, Partner);
                }
                SexTick(pawn, Partner);
                SexUtility.reduce_rest(Partner, 1);
                SexUtility.reduce_rest(pawn, 2);
            };
            rape.AddFinishAction(delegate
            {
                End();
            });
            yield return(rape);

            yield return(new Toil
            {
                initAction = delegate
                {
                    //// Trying to add some interactions and social logs
                    SexUtility.ProcessSex(pawn, Partner, usedCondom: usedCondom, rape: isRape, sextype: sexType);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });
        }
コード例 #4
0
        private static bool on_cleanup_driver(JobDriver __instance, JobCondition condition)
        {
            if (__instance == null)
            {
                return(true);
            }

            if (condition == JobCondition.Succeeded)
            {
                Pawn pawn    = __instance.pawn;
                Pawn partner = null;

                //Log.Message("[RJW]patches_lovin::on_cleanup_driver" + xxx.get_pawnname(pawn));

                //[RF] Rational Romance [1.0] loving
                if (xxx.RomanceDiversifiedIsActive && __instance.GetType() == JobDriverDoLovinCasual)
                {
                    // not sure RR can even cause pregnancies but w/e
                    var any_ins = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
                    partner = (Pawn)(__instance.GetType().GetProperty("Partner", any_ins).GetValue(__instance, null));
                    Log.Message("[RJW]patches_lovin::on_cleanup_driver RomanceDiversified/RationalRomance:" + xxx.get_pawnname(pawn) + "+" + xxx.get_pawnname(partner));
                }
                //Vanilla loving
                else if (__instance.GetType() == JobDriverLovin)
                {
                    var any_ins = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
                    partner = (Pawn)(__instance.GetType().GetProperty("Partner", any_ins).GetValue(__instance, null));
                    //CnP loving
                    if (xxx.RimWorldChildrenIsActive && RJWPregnancySettings.humanlike_pregnancy_enabled && xxx.is_human(pawn) && xxx.is_human(partner))
                    {
                        Log.Message("[RJW]patches_lovin:: RimWorldChildren/ChildrenAndPregnancy pregnancy:" + xxx.get_pawnname(pawn) + "+" + xxx.get_pawnname(partner));
                        PregnancyHelper.cleanup_CnP(pawn);
                        PregnancyHelper.cleanup_CnP(partner);
                    }
                    else
                    {
                        Log.Message("[RJW]patches_lovin:: JobDriverLovin pregnancy:" + xxx.get_pawnname(pawn) + "+" + xxx.get_pawnname(partner));
                    }
                }
                //Vanilla mating
                else if (__instance.GetType() == JobDriverMate)
                {
                    var any_ins = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
                    partner = (Pawn)(__instance.GetType().GetProperty("Female", any_ins).GetValue(__instance, null));
                    Log.Message("[RJW]patches_lovin:: JobDriverMate pregnancy:" + xxx.get_pawnname(pawn) + "+" + xxx.get_pawnname(partner));
                }
                else
                {
                    return(true);
                }

                // TODO: Doing TryUseCondom here is a bit weird... it should happen before.
                var usedCondom = CondomUtility.TryUseCondom(pawn) || CondomUtility.TryUseCondom(partner);

                //vanilla will probably be f****d up for non humanlikes... but only humanlikes do loving, right?
                //if rjw pregnancy enabled, remove vanilla for:
                //human-human
                //animal-animal
                //bestiality
                //always remove when someone is insect or mech
                if (RJWPregnancySettings.humanlike_pregnancy_enabled && xxx.is_human(pawn) && xxx.is_human(partner) ||
                    RJWPregnancySettings.animal_pregnancy_enabled && xxx.is_animal(pawn) && xxx.is_animal(partner) ||
                    (RJWPregnancySettings.bestial_pregnancy_enabled && xxx.is_human(pawn) && xxx.is_animal(partner) ||
                     RJWPregnancySettings.bestial_pregnancy_enabled && xxx.is_animal(pawn) && xxx.is_human(partner)) ||
                    xxx.is_insect(pawn) || xxx.is_insect(partner) || xxx.is_mechanoid(pawn) || xxx.is_mechanoid(partner)
                    )
                {
                    Log.Message("[RJW]patches_lovin::on_cleanup_driver vanilla pregnancy:" + xxx.get_pawnname(pawn) + "+" + xxx.get_pawnname(partner));
                    PregnancyHelper.cleanup_vanilla(pawn);
                    PregnancyHelper.cleanup_vanilla(partner);
                }

                SexUtility.ProcessSex(pawn, partner, usedCondom, false, true);
            }
            return(true);
        }
コード例 #5
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            setup_ticks();

            this.FailOnDespawnedOrNull(iTarget);
            this.FailOnDespawnedNullOrForbidden(iBed);
            this.FailOn(() => !pawn.CanReserveAndReach(Partner, PathEndMode.Touch, Danger.Deadly));
            this.FailOn(() => pawn.Drafted);
            this.FailOn(() => Partner.IsFighting());
            this.FailOn(() => !Partner.CanReach(pawn, PathEndMode.Touch, Danger.Deadly));

            yield return(Toils_Reserve.Reserve(iTarget, 1, 0));

            Toil gotoAnimal = Toils_Goto.GotoThing(iTarget, PathEndMode.Touch);

            yield return(gotoAnimal);

            Toil gotoBed = new Toil();

            gotoBed.defaultCompleteMode = ToilCompleteMode.PatherArrival;
            gotoBed.FailOnBedNoLongerUsable(iBed);
            gotoBed.AddFailCondition(() => Partner.Downed);
            gotoBed.initAction = delegate
            {
                pawn.pather.StartPath(SleepSpot, PathEndMode.OnCell);
                Partner.jobs.StopAll();
                Job job = JobMaker.MakeJob(JobDefOf.GotoMindControlled, SleepSpot);
                Partner.jobs.StartJob(job, JobCondition.InterruptForced);
            };
            yield return(gotoBed);

            Toil waitInBed = new Toil();

            waitInBed.FailOn(() => pawn.GetRoom(RegionType.Set_Passable) == null);
            waitInBed.defaultCompleteMode = ToilCompleteMode.Delay;
            waitInBed.initAction          = delegate
            {
                ticksLeftThisToil = 5000;
            };
            waitInBed.tickAction = delegate
            {
                pawn.GainComfortFromCellIfPossible();
                if (IsInOrByBed(Bed, Partner) && pawn.PositionHeld == Partner.PositionHeld)
                {
                    ReadyForNextToil();
                }
            };
            yield return(waitInBed);

            Toil StartPartnerJob = new Toil();

            StartPartnerJob.defaultCompleteMode = ToilCompleteMode.Instant;
            StartPartnerJob.socialMode          = RandomSocialMode.Off;
            StartPartnerJob.initAction          = delegate
            {
                var gettin_loved = JobMaker.MakeJob(xxx.gettin_loved, pawn, Bed);
                Partner.jobs.StartJob(gettin_loved, JobCondition.InterruptForced);
            };
            yield return(StartPartnerJob);

            Toil loveToil = new Toil();

            loveToil.AddFailCondition(() => Partner.Dead || !IsInOrByBed(Bed, Partner));
            loveToil.socialMode          = RandomSocialMode.Off;
            loveToil.defaultCompleteMode = ToilCompleteMode.Never;
            loveToil.handlingFacing      = true;
            loveToil.initAction          = delegate
            {
                usedCondom = CondomUtility.TryUseCondom(pawn);
                Start();
            };
            loveToil.AddPreTickAction(delegate
            {
                --ticks_left;
                if (pawn.IsHashIntervalTick(ticks_between_hearts))
                {
                    if (xxx.is_zoophile(pawn))
                    {
                        ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart);
                    }
                    else
                    {
                        ThrowMetaIcon(pawn.Position, pawn.Map, xxx.mote_noheart);
                    }
                }
                SexTick(pawn, Partner);
                SexUtility.reduce_rest(pawn, 1);
                SexUtility.reduce_rest(Partner, 2);
                if (ticks_left <= 0)
                {
                    ReadyForNextToil();
                }
            });
            loveToil.AddFinishAction(delegate
            {
                End();
            });
            yield return(loveToil);

            Toil afterSex = new Toil
            {
                initAction = delegate
                {
                    //Log.Message("JobDriver_BestialityForFemale::MakeNewToils() - Calling aftersex");
                    SexUtility.ProcessSex(Partner, pawn, usedCondom: usedCondom, sextype: sexType);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            };

            yield return(afterSex);
        }
コード例 #6
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //--Log.Message("[RJW] JobDriver_ViolateCorpse::MakeNewToils() called");
            setup_ticks();

            this.FailOnDespawnedNullOrForbidden(iTarget);
            this.FailOn(() => !pawn.CanReserve(Target, 1, 0));              // Fail if someone else reserves the prisoner before the pawn arrives
            this.FailOn(() => pawn.IsFighting());
            this.FailOn(() => pawn.Drafted);
            this.FailOn(Target.IsBurning);

            //--Log.Message("[RJW] JobDriver_ViolateCorpse::MakeNewToils() - moving towards Target");
            yield return(Toils_Goto.GotoThing(iTarget, PathEndMode.OnCell));

            var alert = RJWPreferenceSettings.rape_attempt_alert == RJWPreferenceSettings.RapeAlert.Disabled ?
                        MessageTypeDefOf.SilentInput : MessageTypeDefOf.NeutralEvent;

            Messages.Message(xxx.get_pawnname(pawn) + " is trying to rape a corpse of " + xxx.get_pawnname(Partner), pawn, alert);

            setup_ticks();            // re-setup ticks on arrival

            var rape = new Toil();

            rape.defaultCompleteMode = ToilCompleteMode.Delay;
            rape.defaultDuration     = duration;
            rape.handlingFacing      = true;
            rape.initAction          = delegate
            {
                //--Log.Message("[RJW] JobDriver_ViolateCorpse::MakeNewToils() - stripping Target");
                (Target as Corpse).Strip();
                Start();
            };
            rape.tickAction = delegate
            {
                if (pawn.IsHashIntervalTick(ticks_between_hearts))
                {
                    if (xxx.is_necrophiliac(pawn))
                    {
                        ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart);
                    }
                    else
                    {
                        ThrowMetaIcon(pawn.Position, pawn.Map, xxx.mote_noheart);
                    }
                }
                //if (pawn.IsHashIntervalTick (ticks_between_hits))
                //	roll_to_hit (pawn, Target);
                SexTick(pawn, Target);
                SexUtility.reduce_rest(pawn, 2);
            };
            rape.AddFinishAction(delegate
            {
                End();
            });
            yield return(rape);

            yield return(new Toil
            {
                initAction = delegate
                {
                    //--Log.Message("[RJW] JobDriver_ViolateCorpse::MakeNewToils() - creating aftersex toil");
                    SexUtility.ProcessSex(pawn, Partner, usedCondom: usedCondom, rape: isRape, sextype: sexType);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });
        }
コード例 #7
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //Log.Message("[RJW]" + this.GetType().ToString() + "::MakeNewToils() called");

            setup_ticks();

            this.FailOnDespawnedOrNull(iTarget);
            this.FailOnDespawnedOrNull(iBed);
            this.FailOn(() => !Partner.health.capacities.CanBeAwake);
            this.FailOn(() => !(Partner.InBed() || xxx.in_same_bed(Partner, pawn)));
            this.FailOn(() => pawn.Drafted);
            yield return(Toils_Reserve.Reserve(iTarget, xxx.max_rapists_per_prisoner, 0));

            yield return(Toils_Goto.GotoThing(iTarget, PathEndMode.OnCell));

            Toil StartPartnerJob = new Toil();

            StartPartnerJob.defaultCompleteMode = ToilCompleteMode.Instant;
            StartPartnerJob.socialMode          = RandomSocialMode.Off;
            StartPartnerJob.initAction          = delegate
            {
                Job gettin_loved = JobMaker.MakeJob(xxx.gettin_loved, pawn, Bed);
                Partner.jobs.StartJob(gettin_loved, JobCondition.InterruptForced);
            };
            yield return(StartPartnerJob);

            Toil do_lovin = new Toil();

            do_lovin.FailOn(() => Partner.CurJob.def != xxx.gettin_loved);
            do_lovin.defaultCompleteMode = ToilCompleteMode.Never;
            do_lovin.socialMode          = RandomSocialMode.Off;
            do_lovin.handlingFacing      = true;
            do_lovin.initAction          = delegate
            {
                usedCondom = CondomUtility.TryUseCondom(pawn) || CondomUtility.TryUseCondom(Partner);
                Start();
            };
            do_lovin.AddPreTickAction(delegate
            {
                --ticks_left;
                if (pawn.IsHashIntervalTick(ticks_between_hearts))
                {
                    ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart);
                }
                SexTick(pawn, Partner);
                SexUtility.reduce_rest(Partner, 1);
                SexUtility.reduce_rest(pawn, 2);
                if (ticks_left <= 0)
                {
                    ReadyForNextToil();
                }
            });
            do_lovin.AddFinishAction(delegate
            {
                End();
            });
            yield return(do_lovin);

            yield return(new Toil
            {
                initAction = delegate
                {
                    // Trying to add some interactions and social logs
                    SexUtility.ProcessSex(pawn, Partner, usedCondom: usedCondom, rape: isRape, whoring: isWhoring, sextype: sexType);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });
        }
コード例 #8
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //Rand.PopState();
            //Rand.PushState(RJW_Multiplayer.PredictableSeed());
            int duration              = (int)(2000.0f * Rand.Range(0.50f, 0.90f));
            int ticks_between_hearts  = Rand.RangeInclusive(70, 130);
            int ticks_between_hits    = Rand.Range(xxx.config.min_ticks_between_hits, xxx.config.max_ticks_between_hits);
            int ticks_between_thrusts = 100;

            //--Log.Message("JobDriver_ComfortPrisonerRapin::MakeNewToils() - setting fail conditions");
            this.FailOnDespawnedNullOrForbidden(PartnerIndex);
            this.FailOn(() => !pawn.CanReserve(Target, BreederHelper.max_animals_at_once, 0));                                      // Fail if someone else reserves the target before the animal arrives.
            this.FailOn(() => !pawn.CanReach(Target, PathEndMode.Touch, Danger.Some));                                              // Fail if animal cannot reach target.
            this.FailOn(() => !(Target.IsDesignatedBreeding() || (RJWSettings.animal_on_animal_enabled && xxx.is_animal(Target)))); // Fail if not designated and not animal-on-animal
            this.FailOn(() => Target.CurJob == null);
            this.FailOn(() => pawn.Drafted);

            // Path to target
            yield return(Toils_Goto.GotoThing(PartnerIndex, PathEndMode.OnCell));

            SexUtility.RapeAttemptAlert(pawn, Target);

            // Breed target
            var breed = new Toil();

            breed.initAction = delegate
            {
                //Log.Message("JobDriver_ComfortPrisonerRapin::MakeNewToils() - Setting victim job driver");
                Job currentJob = Target.jobs.curJob;

                if (currentJob.def != xxx.gettin_raped)
                {
                    Job          gettin_raped = new Job(xxx.gettin_raped, pawn, Target);
                    Building_Bed Bed          = null;
                    //Log.Message(xxx.get_pawnname(pawn) + " LayingInBed:" + pawn.GetPosture());
                    //Log.Message(xxx.get_pawnname(Target) + " LayingInBed:" + Target.GetPosture());
                    if (Target.GetPosture() == PawnPosture.LayingInBed)
                    {
                        Bed = Target.CurrentBed();
                        //Log.Message(xxx.get_pawnname(Target) + ": bed:" + Bed);
                    }

                    Target.jobs.StartJob(gettin_raped, JobCondition.InterruptForced);

                    //var dri = Target.jobs.curDriver as JobDriver_GettinRaped;
                    //if (xxx.is_animal(pawn) && xxx.is_animal(Target)) // No alert spam for animal-on-animal
                    //dri.disable_alert = true;

                    (Target.jobs.curDriver as JobDriver_GettinRaped).increase_time(duration);
                    if (Bed != null)
                    {
                        (Target.jobs.curDriver as JobDriver_GettinRaped)?.set_bed(Bed);
                    }
                }
                else
                {
                    if (Target.jobs.curDriver is JobDriver_GettinRaped dri)
                    {
                        dri.rapist_count += 1;
                        dri.increase_time(duration);
                    }
                }
            };

            breed.tickAction = delegate
            {
                if (pawn.IsHashIntervalTick(ticks_between_hearts))
                {
                    MoteMaker.ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart);
                }
                if (pawn.IsHashIntervalTick(ticks_between_thrusts))
                {
                    xxx.sexTick(pawn, Target);
                }
                if (!xxx.is_zoophile(Target) && pawn.IsHashIntervalTick(ticks_between_hits))
                {
                    roll_to_hit(pawn, Target);
                }

                if (!Target.Dead)
                {
                    xxx.reduce_rest(Target, 1);
                }
                xxx.reduce_rest(pawn, 2);

                if (Genital_Helper.has_penis(pawn) || Genital_Helper.has_penis_infertile(pawn))
                {
                    // Face same direction, most of animal sex is likely doggystyle.
                    Target.Rotation = pawn.Rotation;
                }
            };

            breed.AddFinishAction(delegate
            {
                if ((Target.jobs != null) &&
                    (Target.jobs.curDriver != null) &&
                    (Target.jobs.curDriver as JobDriver_GettinRaped != null))
                {
                    (Target.jobs.curDriver as JobDriver_GettinRaped).rapist_count -= 1;
                }
                pawn.stances.StaggerFor(Rand.Range(0, 50));
                Target.stances.StaggerFor(Rand.Range(10, 300));
            });

            breed.defaultCompleteMode = ToilCompleteMode.Delay;
            breed.defaultDuration     = duration;
            yield return(breed);

            yield return(new Toil
            {
                initAction = delegate
                {
                    //Log.Message("JobDriver_Breeding::MakeNewToils() - Calling aftersex");
                    //// Trying to add some interactions and social logs
                    bool violent = !(pawn.relations.DirectRelationExists(PawnRelationDefOf.Bond, Target) ||
                                     (xxx.is_animal(pawn) && (pawn.RaceProps.wildness - pawn.RaceProps.petness + 0.18f) > Rand.Range(0.36f, 1.8f)));
                    SexUtility.ProcessSex(pawn, Target, violent);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });
        }
コード例 #9
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //Rand.PopState();
            //Rand.PushState(RJW_Multiplayer.PredictableSeed());
            //Log.Message("[RJW]" + this.GetType().ToString() + "::MakeNewToils() called");
            duration              = (int)(2000.0f * Rand.Range(0.50f, 0.90f));
            ticks_between_hearts  = Rand.RangeInclusive(70, 130);
            ticks_between_hits    = Rand.Range(xxx.config.min_ticks_between_hits, xxx.config.max_ticks_between_hits);
            ticks_between_thrusts = 100;

            if (xxx.is_bloodlust(pawn))
            {
                ticks_between_hits = (int)(ticks_between_hits * 0.75);
            }
            if (xxx.is_brawler(pawn))
            {
                ticks_between_hits = (int)(ticks_between_hits * 0.90);
            }

            this.FailOnDespawnedNullOrForbidden(iTarget);
            this.FailOn(() => !pawn.CanReserve(Target, xxx.max_rapists_per_prisoner, 0));             // Fail if someone else reserves the prisoner before the pawn arrives
            this.FailOn(() => pawn.IsFighting());
            this.FailOn(() => Target.IsFighting());
            this.FailOn(() => pawn.Drafted);
            yield return(Toils_Goto.GotoThing(iTarget, PathEndMode.OnCell));

            SexUtility.RapeAttemptAlert(pawn, Target);

            //Log.Message("[RJW] JobDriver_Rape::make toils() called");
            var rape = new Toil();

            rape.initAction = delegate
            {
                //Log.Message("[RJW]" + this.GetType().ToString() + "::initAction() called");
                //pawn.Reserve(Target, comfort_prisoners.max_rapists_per_prisoner, 0);
                //if (!pawnHasPenis)
                //	Target.rotationTracker.Face(pawn.DrawPos);
                JobDriver_GettinRaped dri = Target.jobs.curDriver as JobDriver_GettinRaped;
                if (dri == null)
                {
                    Job          gettin_raped = new Job(xxx.gettin_raped, pawn, Target);
                    Building_Bed Bed          = null;
                    //Log.Message(xxx.get_pawnname(pawn) + " LayingInBed:" + pawn.GetPosture());
                    //Log.Message(xxx.get_pawnname(Target) + " LayingInBed:" + Target.GetPosture());
                    if (Target.GetPosture() == PawnPosture.LayingInBed)
                    {
                        Bed = Target.CurrentBed();
                        //Log.Message(xxx.get_pawnname(Target) + ": bed:" + Bed);
                    }
                    Target.jobs.StartJob(gettin_raped, JobCondition.InterruptForced, null, false, true, null);
                    (Target.jobs.curDriver as JobDriver_GettinRaped)?.increase_time(duration);
                    if (Bed != null)
                    {
                        (Target.jobs.curDriver as JobDriver_GettinRaped)?.set_bed(Bed);
                    }
                }
                else
                {
                    dri.rapist_count += 1;
                    dri.increase_time(duration);
                }
                rape.FailOn(() => Target.CurJob == null || Target.CurJob.def != xxx.gettin_raped || Target.IsFighting() || pawn.IsFighting());
            };
            rape.tickAction = delegate
            {
                //Log.Message("[RJW] JobDriver_Rape::tickAction() called");
                if (pawn.IsHashIntervalTick(ticks_between_hearts))
                {
                    MoteMaker.ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart);
                }
                if (pawn.IsHashIntervalTick(ticks_between_thrusts))
                {
                    xxx.sexTick(pawn, Target, false);
                }
                if (pawn.IsHashIntervalTick(ticks_between_hits))
                {
                    roll_to_hit(pawn, Target);
                }
                xxx.reduce_rest(Target, 1);
                xxx.reduce_rest(pawn, 2);
            };
            rape.AddFinishAction(delegate
            {
                if (Target.jobs?.curDriver is JobDriver_GettinRaped)
                {
                    (Target.jobs.curDriver as JobDriver_GettinRaped).rapist_count -= 1;
                }
            });
            rape.defaultCompleteMode = ToilCompleteMode.Delay;
            rape.defaultDuration     = duration;
            yield return(rape);

            yield return(new Toil
            {
                initAction = delegate
                {
                    //Log.Message("[RJW] JobDriver_Rape::aftersex() called");
                    //// Trying to add some interactions and social logs
                    SexUtility.ProcessSex(pawn, Target, true);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });
        }
コード例 #10
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //Rand.PopState();
            //Rand.PushState(RJW_Multiplayer.PredictableSeed());
            duration              = (int)(2000.0f * Rand.Range(0.50f, 0.90f));
            ticks_between_hearts  = Rand.RangeInclusive(70, 130);
            ticks_between_hits    = Rand.Range(xxx.config.min_ticks_between_hits, xxx.config.max_ticks_between_hits);
            ticks_between_thrusts = 100;
            bool pawnHasPenis = Genital_Helper.has_penis(pawn) || Genital_Helper.has_penis_infertile(pawn);

            if (xxx.is_bloodlust(pawn))
            {
                ticks_between_hits = (int)(ticks_between_hits * 0.75);
            }
            if (xxx.is_brawler(pawn))
            {
                ticks_between_hits = (int)(ticks_between_hits * 0.90);
            }

            //--Log.Message("JobDriver_ComfortPrisonerRapin::MakeNewToils() - setting fail conditions");
            this.FailOnDespawnedNullOrForbidden(iprisoner);
            //this.FailOn(() => (!Target.health.capacities.CanBeAwake) || (!comfort_prisoners.is_designated(Target)));//this is wrong
            this.FailOn(() => (!Target.IsDesignatedComfort()));
            this.FailOn(() => !pawn.CanReserve(Target, xxx.max_rapists_per_prisoner, 0));             // Fail if someone else reserves the prisoner before the pawn arrives
            this.FailOn(() => pawn.Drafted);
            yield return(Toils_Goto.GotoThing(iprisoner, PathEndMode.OnCell));

            SexUtility.RapeAttemptAlert(pawn, Target);

            Toil rape = new Toil();

            rape.initAction = delegate
            {
                //--Log.Message("JobDriver_ComfortPrisonerRapin::MakeNewToils() - reserving prisoner");
                //pawn.Reserve(Target, comfort_prisoners.max_rapists_per_prisoner, 0);
                if (!pawnHasPenis)
                {
                    Target.rotationTracker.Face(pawn.DrawPos);
                }

                //--Log.Message("JobDriver_ComfortPrisonerRapin::MakeNewToils() - Setting victim job driver");
                JobDriver_GettinRaped dri = Target.jobs.curDriver as JobDriver_GettinRaped;
                if (dri == null)
                {
                    Job          gettin_raped = new Job(xxx.gettin_raped, pawn, Target);
                    Building_Bed Bed          = null;
                    //Log.Message(xxx.get_pawnname(pawn) + " LayingInBed:" + pawn.GetPosture());
                    //Log.Message(xxx.get_pawnname(Target) + " LayingInBed:" + Target.GetPosture());
                    if (Target.GetPosture() == PawnPosture.LayingInBed)
                    {
                        Bed = Target.CurrentBed();
                        //Log.Message(xxx.get_pawnname(Target) + ": bed:" + Bed);
                    }

                    Target.jobs.StartJob(gettin_raped, JobCondition.InterruptForced, null, false, true, null);
                    (Target.jobs.curDriver as JobDriver_GettinRaped)?.increase_time(duration);
                    if (Bed != null)
                    {
                        (Target.jobs.curDriver as JobDriver_GettinRaped)?.set_bed(Bed);
                    }
                }
                else
                {
                    dri.rapist_count += 1;
                    dri.increase_time(duration);
                }
            };
            rape.tickAction = delegate
            {
                if (pawn.IsHashIntervalTick(ticks_between_hearts))
                {
                    MoteMaker.ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart);
                }
                if (pawn.IsHashIntervalTick(ticks_between_thrusts))
                {
                    xxx.sexTick(pawn, Target);
                }
                if (pawn.IsHashIntervalTick(ticks_between_hits))
                {
                    roll_to_hit(pawn, Target);
                }
                xxx.reduce_rest(Target, 1);
                xxx.reduce_rest(pawn, 2);
            };
            rape.AddFinishAction(delegate
            {
                //Log.Message("JobDriver_ComfortPrisonerRapin::MakeNewToils() - Clearing victim job");
                if (Target.jobs?.curDriver is JobDriver_GettinRaped)
                {
                    //Log.Message("JobDriver_ComfortPrisonerRapin::MakeNewToils() - Victim present");
                    (Target.jobs.curDriver as JobDriver_GettinRaped).rapist_count -= 1;
                }
            });
            rape.defaultCompleteMode = ToilCompleteMode.Delay;
            rape.defaultDuration     = duration;
            yield return(rape);

            yield return(new Toil
            {
                initAction = delegate
                {
                    // Trying to add some interactions and social logs
                    SexUtility.ProcessSex(pawn, Target, true);
                    Target.records.Increment(xxx.GetRapedAsComfortPrisoner);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });
        }
コード例 #11
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //Log.Message("[RJW]" + this.GetType().ToString() + "::MakeNewToils() called");
            setup_ticks();

            this.FailOnDespawnedNullOrForbidden(iTarget);
            this.FailOn(() => !Partner.health.capacities.CanBeAwake);
            this.FailOn(() => pawn.IsFighting());
            this.FailOn(() => Partner.IsFighting());
            this.FailOn(() => pawn.Drafted);
            yield return(Toils_Goto.GotoThing(iTarget, PathEndMode.OnCell));

            Toil findQuickieSpot = new Toil();

            findQuickieSpot.defaultCompleteMode = ToilCompleteMode.PatherArrival;
            findQuickieSpot.initAction          = delegate
            {
                //Needs this earlier to decide if current place is good enough
                all_pawns = pawn.Map.mapPawns.AllPawnsSpawned.Where(x
                                                                    => x.Position.DistanceTo(pawn.Position) < 100 &&
                                                                    xxx.is_human(x) &&
                                                                    x != pawn &&
                                                                    x != Partner
                                                                    ).ToList();

                temperature = pawn.ComfortableTemperatureRange();
                float cellTemp = pawn.Position.GetTemperature(pawn.Map);

                if (Partner.IsPrisonerInPrisonCell() || (!MightBeSeen(all_pawns, pawn.Position, pawn, Partner) && (cellTemp > temperature.min && cellTemp < temperature.max)))
                {
                    ReadyForNextToil();
                }
                else
                {
                    var spot = FindQuickieLocation(pawn, Partner);
                    pawn.pather.StartPath(spot, PathEndMode.OnCell);
                    Partner.jobs.StopAll();
                    Job job = JobMaker.MakeJob(JobDefOf.GotoMindControlled, spot);
                    Partner.jobs.StartJob(job, JobCondition.InterruptForced);
                }
            };
            yield return(findQuickieSpot);

            Toil WaitForPartner = new Toil();

            WaitForPartner.defaultCompleteMode = ToilCompleteMode.Delay;
            WaitForPartner.initAction          = delegate
            {
                ticksLeftThisToil = 5000;
            };
            WaitForPartner.tickAction = delegate
            {
                pawn.GainComfortFromCellIfPossible();
                if (pawn.Position.DistanceTo(Partner.Position) <= 1f)
                {
                    ReadyForNextToil();
                }
            };
            yield return(WaitForPartner);

            Toil StartPartnerJob = new Toil();

            StartPartnerJob.defaultCompleteMode = ToilCompleteMode.Instant;
            StartPartnerJob.socialMode          = RandomSocialMode.Off;
            StartPartnerJob.initAction          = delegate
            {
                Job gettingQuickie = JobMaker.MakeJob(xxx.getting_quickie, pawn, Partner);
                Partner.jobs.StartJob(gettingQuickie, JobCondition.InterruptForced);
            };
            yield return(StartPartnerJob);


            Toil doQuickie = new Toil();

            doQuickie.defaultCompleteMode = ToilCompleteMode.Never;
            doQuickie.socialMode          = RandomSocialMode.Off;
            doQuickie.defaultDuration     = duration;
            doQuickie.handlingFacing      = true;
            doQuickie.initAction          = delegate
            {
                usedCondom = CondomUtility.TryUseCondom(pawn) || CondomUtility.TryUseCondom(Partner);
                Start();
            };
            doQuickie.AddPreTickAction(delegate
            {
                --ticks_left;
                if (pawn.IsHashIntervalTick(ticks_between_hearts))
                {
                    ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart);
                }
                SexTick(pawn, Partner);
                SexUtility.reduce_rest(Partner, 1);
                SexUtility.reduce_rest(pawn, 1);
                if (ticks_left <= 0)
                {
                    ReadyForNextToil();
                }
            });
            doQuickie.AddFinishAction(delegate
            {
                End();
            });
            yield return(doQuickie);

            yield return(new Toil
            {
                initAction = delegate
                {
                    //// Trying to add some interactions and social logs
                    SexUtility.ProcessSex(pawn, Partner, usedCondom: usedCondom, rape: isRape, sextype: sexType);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });
        }
コード例 #12
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //--Log.Message("[RJW] JobDriver_ViolateCorpse::MakeNewToils() called");
            //Rand.PopState();
            //Rand.PushState(RJW_Multiplayer.PredictableSeed());
            duration              = (int)(2000.0f * Rand.Range(0.50f, 0.90f));
            ticks_between_hearts  = Rand.RangeInclusive(70, 130);
            ticks_between_hits    = Rand.Range(xxx.config.min_ticks_between_hits, xxx.config.max_ticks_between_hits);
            ticks_between_thrusts = 100;

            if (xxx.is_bloodlust(pawn))
            {
                ticks_between_hits = (int)(ticks_between_hits * 0.75);
            }
            if (xxx.is_brawler(pawn))
            {
                ticks_between_hits = (int)(ticks_between_hits * 0.90);
            }

            this.FailOnDespawnedNullOrForbidden(icorpse);
            this.FailOn(() => !pawn.CanReserve(Target, 1, 0));              // Fail if someone else reserves the prisoner before the pawn arrives
            this.FailOn(() => pawn.IsFighting());
            this.FailOn(() => pawn.Drafted);
            this.FailOn(Target.IsBurning);

            //--Log.Message("[RJW] JobDriver_ViolateCorpse::MakeNewToils() - moving towards Target");
            yield return(Toils_Goto.GotoThing(icorpse, PathEndMode.OnCell));

            var alert = RJWPreferenceSettings.rape_alert_sound == RJWPreferenceSettings.RapeAlert.Disabled ?
                        MessageTypeDefOf.SilentInput : MessageTypeDefOf.NeutralEvent;

            Messages.Message(pawn.Name + " is trying to rape a Target.", pawn, alert);

            var rape = new Toil();

            rape.initAction = delegate
            {
                //--Log.Message("[RJW] JobDriver_ViolateCorpse::MakeNewToils() - reserving Target");
                //pawn.Reserve(Target, 1, 0); // Target rapin seems like a solitary activity

                //--Log.Message("[RJW] JobDriver_ViolateCorpse::MakeNewToils() - stripping Target");
                Target.Strip();
            };
            rape.tickAction = delegate
            {
                if (pawn.IsHashIntervalTick(ticks_between_hearts))
                {
                    MoteMaker.ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart);
                }
                if (pawn.IsHashIntervalTick(ticks_between_thrusts))
                {
                    sexTick(pawn, Target);
                }

                /*
                 * if (pawn.IsHashIntervalTick (ticks_between_hits))
                 *      roll_to_hit (pawn, Corpse);
                 */
                xxx.reduce_rest(pawn, 2);
            };
            rape.AddFinishAction(delegate
            {
                if (xxx.is_human(pawn))
                {
                    pawn.Drawer.renderer.graphics.ResolveApparelGraphics();
                }
            });
            rape.defaultCompleteMode = ToilCompleteMode.Delay;
            rape.defaultDuration     = duration;
            yield return(rape);

            yield return(new Toil
            {
                initAction = delegate
                {
                    //--Log.Message("[RJW] JobDriver_ViolateCorpse::MakeNewToils() - creating aftersex toil");
                    //Addded by nizhuan-jjr: Try to apply an aftersex process for the pawn and the Target
                    if (Target.InnerPawn != null)
                    {
                        SexUtility.ProcessSex(pawn, Target.InnerPawn, true);
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });
        }
コード例 #13
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedOrNull(PartnerInd);
            this.FailOnDespawnedNullOrForbidden(BedInd);
            this.FailOn(() => Actor is null || !Actor.CanReserveAndReach(Partner, PathEndMode.Touch, Danger.Deadly));
            this.FailOn(() => pawn.Drafted);
            yield return(Toils_Reserve.Reserve(PartnerInd, 1, 0));

            //yield return Toils_Reserve.Reserve(BedInd, Bed.SleepingSlotsCount, 0);
            Toil gotoAnimal = Toils_Goto.GotoThing(PartnerInd, PathEndMode.Touch);

            yield return(gotoAnimal);

            bool partnerHasPenis = Genital_Helper.has_penis(Partner) || Genital_Helper.has_penis_infertile(Partner);

            Toil gotoBed = new Toil
            {
                initAction = delegate
                {
                    Actor.pather.StartPath(SleepSpot, PathEndMode.OnCell);
                    Partner.pather.StartPath(SleepSpot, PathEndMode.OnCell);
                },
                defaultCompleteMode = ToilCompleteMode.PatherArrival
            };

            gotoBed.FailOnBedNoLongerUsable(BedInd);
            gotoBed.AddFailCondition(() => Partner.Downed);
            yield return(gotoBed);

            gotoBed.AddFinishAction(delegate
            {
                var gettin_loved = new Job(xxx.gettin_loved, Actor, Bed);
                Partner.jobs.StartJob(gettin_loved, JobCondition.InterruptForced, null, false, true, null);
            });

            Toil waitInBed = new Toil
            {
                initAction = delegate
                {
                    //Rand.PopState();
                    //Rand.PushState(RJW_Multiplayer.PredictableSeed());
                    ticksLeftThisToil = 5000;
                    ticks_left        = (int)(2000.0f * Rand.Range(0.30f, 1.30f));
                },
                tickAction = delegate
                {
                    Actor.GainComfortFromCellIfPossible();
                    if (IsInOrByBed(Bed, Partner))
                    {
                        ticksLeftThisToil = 0;
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Delay,
            };

            waitInBed.FailOn(() => pawn.GetRoom(RegionType.Set_Passable) == null);
            yield return(waitInBed);

            Toil loveToil = new Toil
            {
                initAction = delegate
                {
                    if (!partnerHasPenis)
                    {
                        Actor.rotationTracker.Face(Partner.DrawPos);
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Never,                 //Changed from Delay
            };

            loveToil.AddPreTickAction(delegate
            {
                //Actor.Reserve(Partner, 1, 0);
                --ticks_left;
                xxx.reduce_rest(Actor, 1);
                xxx.reduce_rest(Partner, 2);
                if (ticks_left <= 0)
                {
                    ReadyForNextToil();
                }
                else if (pawn.IsHashIntervalTick(ticks_between_hearts))
                {
                    MoteMaker.ThrowMetaIcon(Actor.Position, Actor.Map, ThingDefOf.Mote_Heart);
                }
                Actor.GainComfortFromCellIfPossible();
                Partner.GainComfortFromCellIfPossible();
            });
            loveToil.AddFailCondition(() => Partner.Dead || !IsInOrByBed(Bed, Partner));
            loveToil.socialMode = RandomSocialMode.Off;
            yield return(loveToil);

            Toil afterSex = new Toil
            {
                initAction = delegate
                {
                    //Log.Message("JobDriver_BestialityForFemale::MakeNewToils() - Calling aftersex");
                    // Trying to add some interactions and social logs
                    SexUtility.ProcessSex(Partner, pawn);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            };

            yield return(afterSex);
        }
コード例 #14
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            setup_ticks();

            //--Log.Message("JobDriver_Breeding::MakeNewToils() - setting fail conditions");
            this.FailOnDespawnedNullOrForbidden(iTarget);
            this.FailOn(() => !pawn.CanReserve(Partner, BreederHelper.max_animals_at_once, 0));     // Fail if someone else reserves the target before the animal arrives.
            this.FailOn(() => !pawn.CanReach(Partner, PathEndMode.Touch, Danger.Some));             // Fail if animal cannot reach target.
            this.FailOn(() => pawn.Drafted);

            // Path to target
            yield return(Toils_Goto.GotoThing(iTarget, PathEndMode.OnCell));

            //if (!(pawn.IsDesignatedBreedingAnimal() && Partner.IsDesignatedBreeding()));
            if (!(pawn.IsAnimal() && Partner.IsAnimal()))
            {
                SexUtility.RapeTargetAlert(pawn, Partner);
            }

            Toil StartPartnerJob = new Toil();

            StartPartnerJob.defaultCompleteMode = ToilCompleteMode.Instant;
            StartPartnerJob.socialMode          = RandomSocialMode.Off;
            StartPartnerJob.initAction          = delegate
            {
                var dri = Partner.jobs.curDriver as JobDriver_SexBaseRecieverRaped;
                if (dri == null)
                {
                    Job          gettin_raped = JobMaker.MakeJob(xxx.gettin_raped, pawn);
                    Building_Bed Bed          = null;
                    if (Partner.GetPosture() == PawnPosture.LayingInBed)
                    {
                        Bed = Partner.CurrentBed();
                    }

                    Partner.jobs.StartJob(gettin_raped, JobCondition.InterruptForced, null, false, true, null);
                    if (Bed != null)
                    {
                        (Partner.jobs.curDriver as JobDriver_SexBaseRecieverRaped)?.Set_bed(Bed);
                    }
                }
            };
            yield return(StartPartnerJob);

            // Breed target
            var breed = new Toil();

            breed.defaultCompleteMode = ToilCompleteMode.Delay;
            breed.defaultDuration     = duration;
            breed.handlingFacing      = true;
            breed.initAction          = delegate
            {
                Start();
            };
            breed.tickAction = delegate
            {
                if (pawn.IsHashIntervalTick(ticks_between_hearts))
                {
                    if (xxx.is_zoophile(pawn) || xxx.is_animal(pawn))
                    {
                        ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart);
                    }
                    else
                    {
                        ThrowMetaIcon(pawn.Position, pawn.Map, xxx.mote_noheart);
                    }
                }
                if (pawn.IsHashIntervalTick(ticks_between_hits) && !xxx.is_zoophile(Partner))
                {
                    Roll_to_hit(pawn, Partner);
                }
                SexTick(pawn, Partner);
                if (!Partner.Dead)
                {
                    SexUtility.reduce_rest(Partner, 1);
                }
                SexUtility.reduce_rest(pawn, 2);
            };
            breed.AddFinishAction(delegate
            {
                End();
            });
            yield return(breed);

            yield return(new Toil
            {
                initAction = delegate
                {
                    //Log.Message("JobDriver_Breeding::MakeNewToils() - Calling aftersex");
                    //// Trying to add some interactions and social logs
                    bool isRape = !(pawn.relations.DirectRelationExists(PawnRelationDefOf.Bond, Partner) ||
                                    (xxx.is_animal(pawn) && (pawn.RaceProps.wildness - pawn.RaceProps.petness + 0.18f) > Rand.Range(0.36f, 1.8f)));
                    SexUtility.ProcessSex(pawn, Partner, usedCondom: usedCondom, rape: isRape, sextype: sexType);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });
        }
コード例 #15
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //Log.Message("[RJW]JobDriver_WhoreIsServingVisitors::MakeNewToils() - making toils");
            setup_ticks();

            this.FailOnDespawnedOrNull(iTarget);
            this.FailOnDespawnedNullOrForbidden(iBed);
            //Log.Message("[RJW]JobDriver_WhoreIsServingVisitors::MakeNewToils() fail conditions check " + !xxx.CanUse(pawn, Bed) + " " + !pawn.CanReserve(Partner));
            this.FailOn(() => !xxx.CanUse(pawn, Bed) || !pawn.CanReserve(Partner));
            this.FailOn(() => pawn.Drafted);
            this.FailOn(() => Partner.IsFighting());
            this.FailOn(() => !Partner.CanReach(pawn, PathEndMode.Touch, Danger.Deadly));

            yield return(Toils_Reserve.Reserve(iTarget, 1, 0));

            //yield return Toils_Reserve.Reserve(BedInd, Bed.SleepingSlotsCount, 0);

            //Log.Message("[RJW]JobDriver_WhoreIsServingVisitors::MakeNewToils() - generate toils");
            Toil gotoBed = new Toil();

            gotoBed.defaultCompleteMode = ToilCompleteMode.PatherArrival;
            gotoBed.FailOnWhorebedNoLongerUsable(iBed, Bed);
            gotoBed.AddFailCondition(() => Partner.Downed);
            gotoBed.FailOn(() => !Partner.CanReach(Bed, PathEndMode.Touch, Danger.Deadly));
            gotoBed.initAction = delegate
            {
                //Log.Message("[RJW]JobDriver_WhoreIsServingVisitors::MakeNewToils() - gotoWhoreBed initAction is called");
                pawn.pather.StartPath(SleepSpot, PathEndMode.OnCell);
                Partner.jobs.StopAll();
                Job job = JobMaker.MakeJob(JobDefOf.GotoMindControlled, SleepSpot);
                Partner.jobs.StartJob(job, JobCondition.InterruptForced);
            };
            yield return(gotoBed);

            ticks_left = (int)(2000.0f * Rand.Range(0.30f, 1.30f));

            Toil waitInBed = new Toil();

            waitInBed.initAction = delegate
            {
                ticksLeftThisToil = 5000;
            };
            waitInBed.tickAction = delegate
            {
                pawn.GainComfortFromCellIfPossible();
                if (IsInOrByBed(Bed, Partner) && pawn.PositionHeld == Partner.PositionHeld)
                {
                    ReadyForNextToil();
                }
            };
            waitInBed.defaultCompleteMode = ToilCompleteMode.Delay;
            yield return(waitInBed);

            Toil StartPartnerJob = new Toil();

            StartPartnerJob.defaultCompleteMode = ToilCompleteMode.Instant;
            StartPartnerJob.socialMode          = RandomSocialMode.Off;
            StartPartnerJob.initAction          = delegate
            {
                //Log.Message("[RJW]JobDriver_WhoreIsServingVisitors::MakeNewToils() - StartPartnerJob");
                var gettin_loved = JobMaker.MakeJob(xxx.gettin_loved, pawn, Bed);
                Partner.jobs.StartJob(gettin_loved, JobCondition.InterruptForced);
            };
            yield return(StartPartnerJob);

            Toil loveToil = new Toil();

            loveToil.AddFailCondition(() => Partner.Dead || Partner.CurJobDef != xxx.gettin_loved);
            loveToil.defaultCompleteMode = ToilCompleteMode.Never;
            loveToil.socialMode          = RandomSocialMode.Off;
            loveToil.handlingFacing      = true;
            loveToil.initAction          = delegate
            {
                //Log.Message("[RJW]JobDriver_WhoreIsServingVisitors::MakeNewToils() - loveToil");
                // TODO: replace this quick n dirty way
                CondomUtility.GetCondomFromRoom(pawn);

                // Try to use w***e's condom first, then client's
                usedCondom = CondomUtility.TryUseCondom(pawn) || CondomUtility.TryUseCondom(Partner);

                Start();

                if (xxx.HasNonPolyPartnerOnCurrentMap(Partner))
                {
                    Pawn lover = LovePartnerRelationUtility.ExistingLovePartner(Partner);
                    // We have to do a few other checks because the pawn might have multiple lovers and ExistingLovePartner() might return the wrong one
                    if (lover != null && pawn != lover && !lover.Dead && (lover.Map == Partner.Map || Rand.Value < 0.25))
                    {
                        lover.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.CheatedOnMe, Partner);
                    }
                }
            };
            loveToil.AddPreTickAction(delegate
            {
                --ticks_left;
                if (pawn.IsHashIntervalTick(ticks_between_hearts))
                {
                    if (xxx.is_nympho(pawn))
                    {
                        ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart);
                    }
                    else
                    {
                        ThrowMetaIcon(pawn.Position, pawn.Map, xxx.mote_noheart);
                    }
                }
                SexUtility.reduce_rest(Partner, 1);
                SexUtility.reduce_rest(pawn, 2);
                if (ticks_left <= 0)
                {
                    ReadyForNextToil();
                }
            });
            loveToil.AddFinishAction(delegate
            {
                End();
            });
            yield return(loveToil);

            Toil afterSex = new Toil
            {
                initAction = delegate
                {
                    // Adding interactions, social logs, etc
                    SexUtility.ProcessSex(pawn, Partner, usedCondom: usedCondom, whoring: isWhoring, sextype: sexType);

                    if (!(Partner.IsColonist && (pawn.IsPrisonerOfColony || pawn.IsColonist)))
                    {
                        int price = WhoringHelper.PriceOfWhore(pawn);
                        //--Log.Message("JobDriver_WhoreIsServingVisitors::MakeNewToils() - Partner should pay the price now in afterSex.initAction");
                        int remainPrice = WhoringHelper.PayPriceToWhore(Partner, price, pawn);

                        /*if (remainPrice <= 0)
                         * {
                         *      --Log.Message("JobDriver_WhoreIsServingVisitors::MakeNewToils() - Paying price is success");
                         * }
                         * else
                         * {
                         *      --Log.Message("JobDriver_WhoreIsServingVisitors::MakeNewToils() - Paying price failed");
                         * }*/
                        xxx.UpdateRecords(pawn, price - remainPrice);
                    }
                    var thought = (pawn.IsPrisoner || xxx.is_slave(pawn)) ? thought_captive : thought_free;
                    pawn.needs.mood.thoughts.memories.TryGainMemory(thought);
                    if (SexUtility.ConsiderCleaning(pawn))
                    {
                        LocalTargetInfo cum = pawn.PositionHeld.GetFirstThing <Filth>(pawn.Map);

                        Job clean = JobMaker.MakeJob(JobDefOf.Clean);
                        clean.AddQueuedTarget(TargetIndex.A, cum);

                        pawn.jobs.jobQueue.EnqueueFirst(clean);
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            };

            yield return(afterSex);
        }