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 }); }
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 }); }